Merge branch 'infostuff' into blankart-dev

This commit is contained in:
NepDisk 2025-05-20 09:40:44 -04:00
commit 869255f9ec
25 changed files with 698 additions and 779 deletions

View file

@ -1,5 +1,6 @@
qs22j.c
string.c
strbuf.c
d_main.cpp
d_clisrv.c
d_net.c

View file

@ -83,30 +83,13 @@ static bool ACS_GetMobjTypeFromString(const char *word, mobjtype_t *type)
word += 3;
}
for (int i = 0; i < NUMMOBJFREESLOTS; i++)
{
if (!FREE_MOBJS[i])
{
break;
}
mobjtype_t i = DEH_FindMobjtype(word);
if (fastcmp(word, FREE_MOBJS[i]))
{
*type = static_cast<mobjtype_t>(static_cast<int>(MT_FIRSTFREESLOT) + i);
return true;
}
}
if (i == NUMMOBJTYPES)
return false;
for (int i = 0; i < MT_FIRSTFREESLOT; i++)
{
if (fastcmp(word, MOBJTYPE_LIST[i] + 3))
{
*type = static_cast<mobjtype_t>(i);
return true;
}
}
return false;
*type = i;
return true;
}
/*--------------------------------------------------
@ -234,30 +217,13 @@ static bool ACS_GetStateFromString(const char *word, statenum_t *type)
word += 2;
}
for (int i = 0; i < NUMMOBJFREESLOTS; i++)
{
if (!FREE_STATES[i])
{
break;
}
statenum_t i = DEH_FindState(word);
if (fastcmp(word, FREE_STATES[i]))
{
*type = static_cast<statenum_t>(static_cast<int>(S_FIRSTFREESLOT) + i);
return true;
}
}
if (i == NUMSTATES)
return false;
for (int i = 0; i < S_FIRSTFREESLOT; i++)
{
if (fastcmp(word, STATE_LIST[i] + 2))
{
*type = static_cast<statenum_t>(i);
return true;
}
}
return false;
*type = i;
return true;
}
/*--------------------------------------------------
@ -2336,16 +2302,9 @@ bool CallFunc_GetObjectClass(ACSVM::Thread *thread, const ACSVM::Word *argV, ACS
mobj_t *mobj = P_FindMobjFromTID(argV[0], NULL, info->mo);
if (mobj != NULL && P_MobjWasRemoved(mobj) == false)
{
if (mobj->type >= MT_FIRSTFREESLOT)
{
std::string prefix = "MT_";
std::string full = prefix + FREE_MOBJS[mobj->type - MT_FIRSTFREESLOT];
mobjClass = static_cast<INT32>( ~env->getString( full.c_str() )->idx );
}
else
{
mobjClass = static_cast<INT32>( ~env->getString( MOBJTYPE_LIST[ mobj->type ] )->idx );
}
std::string prefix = "MT_";
std::string full = prefix + DEH_MobjtypeName(mobj->type);
mobjClass = static_cast<INT32>( ~env->getString( full.c_str() )->idx );
}
thread->dataStk.push(mobjClass);
@ -4397,16 +4356,9 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
#define PROP_TYPE(x, y) \
case x: \
{ \
if (mobj->y >= MT_FIRSTFREESLOT) \
{ \
std::string prefix = "MT_"; \
std::string full = prefix + FREE_MOBJS[mobj->y - MT_FIRSTFREESLOT]; \
value = static_cast<INT32>( ~env->getString( full.c_str() )->idx ); \
} \
else \
{ \
value = static_cast<INT32>( ~env->getString( MOBJTYPE_LIST[ mobj->y ] )->idx ); \
} \
std::string prefix = "MT_"; \
std::string full = prefix + DEH_MobjtypeName(mobj->y); \
value = static_cast<INT32>( ~env->getString( full.c_str() )->idx ); \
break; \
}
@ -4430,16 +4382,9 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
case x: \
{ \
statenum_t stateID = static_cast<statenum_t>(mobj->y - states); \
if (stateID >= S_FIRSTFREESLOT) \
{ \
std::string prefix = "S_"; \
std::string full = prefix + FREE_STATES[stateID - S_FIRSTFREESLOT]; \
value = static_cast<INT32>( ~env->getString( full.c_str() )->idx ); \
} \
else \
{ \
value = static_cast<INT32>( ~env->getString( STATE_LIST[ stateID ] )->idx ); \
} \
std::string prefix = "S_"; \
std::string full = prefix + DEH_StateName(stateID); \
value = static_cast<INT32>( ~env->getString( full.c_str() )->idx ); \
break; \
}

View file

@ -1277,9 +1277,6 @@ void D_SRB2Main(void)
// MAINCFG is now taken care of where "OBJCTCFG" is handled
G_LoadGameSettings();
// Test Dehacked lists
DEH_TableCheck();
// Netgame URL special case: change working dir to EXE folder.
ChangeDirForUrlHandler();
@ -1395,10 +1392,6 @@ void D_SRB2Main(void)
if (M_CheckParm("-password") && M_IsNextParm())
D_SetPassword(M_GetNextParm());
// player setup menu colors must be initialized before
// any wad file is added, as they may contain colors themselves
M_InitPlayerSetupColors();
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init();
CON_SetLoadingProgress(LOADED_ZINIT);
@ -1430,7 +1423,7 @@ void D_SRB2Main(void)
netgame = server = true;
// adapt tables to SRB2's needs, including extra slots for dehacked file support
P_PatchInfoTables();
P_ResetData(15);
// initiate menu metadata before SOCcing them
M_InitMenuPresTables();
@ -1446,9 +1439,6 @@ void D_SRB2Main(void)
I_InitializeTime();
CON_SetLoadingProgress(LOADED_ISTARTUPTIMER);
// Make backups of some SOCcable tables.
P_BackupTables();
// Setup default unlockable conditions
M_SetupDefaultConditionSets();
@ -1510,7 +1500,6 @@ void D_SRB2Main(void)
R_InitPaletteRemap();
// now do it again for the SOC colors in main.pk3!
M_InitPlayerSetupColors();
// Do it before P_InitMapData because PNG patch

View file

@ -4904,10 +4904,10 @@ static void Command_ListDoomednums_f(void)
CONS_Printf(" doomednum \x82""%d""\x80 is \x85""double-defined\x80 by ", j+1);
if (i < MT_FIRSTFREESLOT)
{
CONS_Printf("\x87""hardcode %s <-- MAJOR ERROR\n", MOBJTYPE_LIST[i]);
CONS_Printf("\x87""hardcode MT_%s <-- MAJOR ERROR\n", DEH_MobjtypeName(i));
continue;
}
CONS_Printf("\x81""freeslot MT_""%s\n", FREE_MOBJS[i-MT_FIRSTFREESLOT]);
CONS_Printf("\x81""freeslot MT_""%s\n", DEH_MobjtypeName(i));
continue;
}
table[j] = i;
@ -4940,10 +4940,10 @@ static void Command_ListDoomednums_f(void)
CONS_Printf(" doomednum \x82""%d""\x80 is used by ", i+1);
if (table[i] < MT_FIRSTFREESLOT)
{
CONS_Printf("\x87""hardcode %s\n", MOBJTYPE_LIST[table[i]]);
CONS_Printf("\x87""hardcode MT_%s\n", DEH_MobjtypeName(i));
continue;
}
CONS_Printf("\x81""freeslot MT_""%s\n", FREE_MOBJS[table[i]-MT_FIRSTFREESLOT]);
CONS_Printf("\x81""freeslot MT_""%s\n", DEH_MobjtypeName(i));
}
}

View file

@ -12,7 +12,6 @@
#include "deh_lua.h"
#include "deh_tables.h"
#include "k_hud.h"
// freeslot takes a name (string only!)
// and allocates it to the appropriate free slot.
@ -47,165 +46,25 @@ static inline int lib_freeslot(lua_State *L)
Z_Free(s);
return luaL_error(L, "Missing enum name in '%s'\n", luaL_checkstring(L, 1));
}
if (fastcmp(type, "SFX")) {
sfxenum_t sfx;
if (fastcmp(type, "SFX"))
strlwr(word);
CONS_Printf("Sound sfx_%s allocated.\n",word);
sfx = S_AddSoundFx(word, false, 0, false);
if (sfx != sfx_None) {
lua_pushinteger(L, sfx);
r++;
} else
CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n");
}
else if (fastcmp(type, "SPR"))
INT32 index;
if (!DEH_ReadFreeslot(type, word, &index))
{
spritenum_t j;
for (j = SPR_FIRSTFREESLOT; j <= SPR_LASTFREESLOT; j++)
if (lua_compatmode)
{
if (used_spr[(j-SPR_FIRSTFREESLOT)/8] & (1<<(j%8)))
continue; // Already allocated, next.
// Found a free slot!
CONS_Printf("Sprite SPR_%s allocated.\n",word);
strncpy(sprnames[j],word,4);
used_spr[(j-SPR_FIRSTFREESLOT)/8] |= 1<<(j%8); // Okay, this sprite slot has been named now.
// Lua needs to update the value in _G if it exists
LUA_UpdateSprName(word, j);
lua_pushinteger(L, j);
r++;
break;
if (fastcmp(type, "MT"))
index -= MT_FIRSTFREESLOT;
if (fastcmp(type, "S"))
index -= S_FIRSTFREESLOT;
}
if (j > SPR_LASTFREESLOT)
CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n");
}
else if (fastcmp(type, "S"))
{
statenum_t i;
for (i = 0; i < NUMSTATEFREESLOTS; i++)
if (!FREE_STATES[i]) {
CONS_Printf("State S_%s allocated.\n",word);
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_STATES[i],word);
freeslotusage[0][0]++;
lua_pushinteger(L, S_FIRSTFREESLOT + i);
r++;
break;
}
if (i == NUMSTATEFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n");
}
else if (fastcmp(type, "MT"))
{
mobjtype_t i;
for (i = 0; i < NUMMOBJFREESLOTS; i++)
if (!FREE_MOBJS[i]) {
CONS_Printf("MobjType MT_%s allocated.\n",word);
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MOBJS[i],word);
freeslotusage[1][0]++;
lua_pushinteger(L, MT_FIRSTFREESLOT + i);
r++;
break;
}
if (i == NUMMOBJFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
}
else if (fastcmp(type, "SKINCOLOR"))
{
skincolornum_t i;
for (i = 0; i < NUMCOLORFREESLOTS; i++)
if (!FREE_SKINCOLORS[i]) {
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_SKINCOLORS[i],word);
M_AddMenuColor(numskincolors++);
K_ReloadHUDColorCvar();
lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT + i);
r++;
break;
}
if (i == NUMCOLORFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n");
}
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
playersprite_t i;
for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++)
if (memcmp(spr2names[i],word,4) == 0)
break;
// We don't, so allocate a new one.
if (i >= free_spr2) {
if (free_spr2 < NUMPLAYERSPRITES)
{
CONS_Printf("Sprite SPR2_%s allocated.\n",word);
strncpy(spr2names[free_spr2],word,4);
spr2defaults[free_spr2] = 0;
lua_pushinteger(L, free_spr2);
r++;
spr2names[free_spr2++][4] = 0;
} else
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
}
}
else if (fastcmp(type, "TOL"))
{
// Search if we already have a typeoflevel by that name...
int i;
for (i = 0; TYPEOFLEVEL[i].name; i++)
if (fastcmp(word, TYPEOFLEVEL[i].name))
break;
// We don't, so allocate a new one.
if (TYPEOFLEVEL[i].name == NULL) {
if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
else {
CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word);
G_AddTOL(lastcustomtol, word);
lua_pushinteger(L, lastcustomtol);
lastcustomtol <<= 1;
r++;
}
}
lua_pushinteger(L, index);
r++;
}
else if (fastcmp(type, "PRECIP"))
{
// Search if we already have a PRECIP by that name...
preciptype_t i;
for (i = PRECIP_FIRSTFREESLOT; i < precip_freeslot; i++)
if (fastcmp(word, precipprops[i].name))
break;
// We don't, so allocate a new one.
if (i >= precip_freeslot) {
if (precip_freeslot < MAXPRECIP)
{
CONS_Printf("Weather PRECIP_%s allocated.\n",word);
precipprops[i].name = Z_StrDup(word);
lua_pushinteger(L, precip_freeslot);
r++;
precip_freeslot++;
} else
CONS_Alert(CONS_WARNING, "Ran out of free PRECIP slots!\n");
}
}
else if (fastcmp(type, "MN"))
{
menutype_t i;
for (i = 0; i < NUMMENUFREESLOTS; i++)
if (!FREE_MENUS[i]) {
CONS_Printf("Menu MN_%s allocated.\n",word);
FREE_MENUS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MENUS[i],word);
lua_pushinteger(L, MN_FIRSTFREESLOT + i);
r++;
break;
}
if (i == NUMMENUFREESLOTS)
CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n");
}
Z_Free(s);
lua_remove(L, 1);
continue;
}
@ -252,7 +111,7 @@ static void CacheAndPushConstant(lua_State *L, const char *name, lua_Integer val
static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
{
const char *p;
fixed_t i;
size_t i;
if (strlen(word) == 1) { // Assume sprite frame if length 1.
if (*word >= 'A' && *word <= '~')
@ -426,19 +285,12 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
lua_pushinteger(L, S_FIRSTFREESLOT);
return 1;
}
for (i = 0; i < NUMSTATEFREESLOTS; i++) {
if (!FREE_STATES[i])
break;
if (fastcmp(p, FREE_STATES[i])) {
CacheAndPushConstant(L, word, S_FIRSTFREESLOT+i);
return 1;
}
i = DEH_FindState(p);
if (i != NUMSTATES)
{
CacheAndPushConstant(L, word, i);
return 1;
}
for (i = 0; i < S_FIRSTFREESLOT; i++)
if (fastcmp(p, STATE_LIST[i]+2)) {
CacheAndPushConstant(L, word, i);
return 1;
}
if (lua_compatmode)
for (i = 0; STATE_ALIASES[i].n; i++)
if (fastcmp(p, STATE_ALIASES[i].n)) {
@ -454,20 +306,12 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
lua_pushinteger(L, MT_FIRSTFREESLOT);
return 1;
}
for (i = 0; i < NUMMOBJFREESLOTS; i++) {
if (!FREE_MOBJS[i])
break;
if (fastcmp(p, FREE_MOBJS[i])) {
CacheAndPushConstant(L, word, MT_FIRSTFREESLOT+i);
return 1;
}
i = DEH_FindMobjtype(p);
if (i != NUMMOBJTYPES)
{
CacheAndPushConstant(L, word, i);
return 1;
}
for (i = 0; i < MT_FIRSTFREESLOT; i++)
if (fastcmp(p, MOBJTYPE_LIST[i]+3)) {
CacheAndPushConstant(L, word, i);
return 1;
}
if (lua_compatmode)
for (i = 0; MOBJ_ALIASES[i].n; i++)
if (fastcmp(p, MOBJ_ALIASES[i].n)) {
@ -498,7 +342,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
}
else if (fastncmp("SPR2_",word,5)) {
p = word+5;
for (i = 0; i < (fixed_t)free_spr2; i++)
for (i = 0; i < free_spr2; i++)
if (!spr2names[i][4])
{
// special 3-char cases, e.g. SPR2_RUN
@ -601,36 +445,22 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
}
else if (fastncmp("SKINCOLOR_",word,10)) {
p = word+10;
for (i = 0; i < NUMCOLORFREESLOTS; i++) {
if (!FREE_SKINCOLORS[i])
break;
if (fastcmp(p, FREE_SKINCOLORS[i])) {
CacheAndPushConstant(L, word, SKINCOLOR_FIRSTFREESLOT+i);
return 1;
}
i = DEH_FindSkincolor(p);
if (i != MAXSKINCOLORS)
{
CacheAndPushConstant(L, word, i);
return 1;
}
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++)
if (fastcmp(p, COLOR_ENUMS[i])) {
CacheAndPushConstant(L, word, i);
return 1;
}
return luaL_error(L, "skincolor '%s' could not be found.\n", word);
}
else if (fastncmp("MN_",word,3)) {
p = word+3;
for (i = 0; i < NUMMENUFREESLOTS; i++) {
if (!FREE_MENUS[i])
break;
if (fastcmp(p, FREE_MENUS[i])) {
CacheAndPushConstant(L, word, MN_FIRSTFREESLOT+i);
return 1;
}
i = DEH_FindMenutype(p);
if (i != MAXMENUTYPES)
{
CacheAndPushConstant(L, word, i);
return 1;
}
for (i = 0; i < MN_FIRSTFREESLOT; i++)
if (fastcmp(p, MENUTYPES_LIST[i])) {
CacheAndPushConstant(L, word, i);
return 1;
}
if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word);
return 0;
}

View file

@ -52,7 +52,6 @@
// SRB2Kart
#include "filesrch.h" // refreshdirmenu
#include "k_follower.h"
#include "k_hud.h"
#include "doomstat.h" // MAXMUSNAMES
// Loops through every constant and operation in word and performs its calculations, returning the final value.
@ -392,7 +391,6 @@ void readfreeslots(MYFILE *f)
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word,*type;
char *tmp;
int i;
do
{
@ -419,130 +417,8 @@ void readfreeslots(MYFILE *f)
else
break;
// TODO: Check for existing freeslot mobjs/states/etc. and make errors.
// TODO: Out-of-slots warnings/errors.
// TODO: Name too long (truncated) warnings.
if (fastcmp(type, "SFX"))
{
CONS_Printf("Sound sfx_%s allocated.\n",word);
S_AddSoundFx(word, false, 0, false);
}
else if (fastcmp(type, "SPR"))
{
for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++)
{
if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8)))
continue; // Already allocated, next.
// Found a free slot!
CONS_Printf("Sprite SPR_%s allocated.\n",word);
strncpy(sprnames[i],word,4);
used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now.
// Lua needs to update the value in _G if it exists
LUA_UpdateSprName(word, i);
break;
}
}
else if (fastcmp(type, "S"))
{
for (i = 0; i < NUMSTATEFREESLOTS; i++)
if (!FREE_STATES[i]) {
CONS_Printf("State S_%s allocated.\n",word);
FREE_STATES[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_STATES[i],word);
freeslotusage[0][0]++;
break;
}
}
else if (fastcmp(type, "MT"))
{
for (i = 0; i < NUMMOBJFREESLOTS; i++)
if (!FREE_MOBJS[i]) {
CONS_Printf("MobjType MT_%s allocated.\n",word);
FREE_MOBJS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MOBJS[i],word);
freeslotusage[1][0]++;
break;
}
}
else if (fastcmp(type, "SKINCOLOR"))
{
for (i = 0; i < NUMCOLORFREESLOTS; i++)
if (!FREE_SKINCOLORS[i]) {
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_SKINCOLORS[i],word);
M_AddMenuColor(numskincolors++);
K_ReloadHUDColorCvar();
break;
}
}
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
for (i = SPR2_FIRSTFREESLOT; i < (int)free_spr2; i++)
if (memcmp(spr2names[i],word,4) == 0)
break;
// We found it? (Two mods using the same SPR2 name?) Then don't allocate another one.
if (i < (int)free_spr2)
continue;
// Copy in the spr2 name and increment free_spr2.
if (free_spr2 < NUMPLAYERSPRITES) {
strncpy(spr2names[free_spr2],word,4);
spr2defaults[free_spr2] = 0;
spr2names[free_spr2++][4] = 0;
} else
deh_warning("Ran out of free SPR2 slots!\n");
}
else if (fastcmp(type, "TOL"))
{
// Search if we already have a typeoflevel by that name...
for (i = 0; TYPEOFLEVEL[i].name; i++)
if (fastcmp(word, TYPEOFLEVEL[i].name))
break;
// We found it? Then don't allocate another one.
if (TYPEOFLEVEL[i].name)
continue;
// We don't, so freeslot it.
if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
deh_warning("Ran out of free typeoflevel slots!\n");
else
{
G_AddTOL(lastcustomtol, word);
lastcustomtol <<= 1;
}
}
else if (fastcmp(type, "PRECIP"))
{
// Search if we already have a PRECIP by that name...
for (i = PRECIP_FIRSTFREESLOT; i < (int)precip_freeslot; i++)
if (fastcmp(word, precipprops[i].name))
break;
// We found it? Then don't allocate another one.
if (i < (int)precip_freeslot)
continue;
// We don't, so allocate a new one.
if (precip_freeslot < MAXPRECIP)
{
precipprops[i].name = Z_StrDup(word);
precip_freeslot++;
} else
deh_warning("Ran out of free PRECIP slots!\n");
}
else if (fastcmp(type, "MN"))
{
for (i = 0; i < NUMMENUFREESLOTS; i++)
if (!FREE_MENUS[i]) {
CONS_Printf("Menu MN_%s allocated.\n",word);
FREE_MENUS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
strcpy(FREE_MENUS[i],word);
break;
}
}
else
INT32 index;
if (DEH_ReadFreeslot(type, word, &index) == -2)
deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
}
} while (!myfeof(f)); // finish when the line is empty
@ -1284,7 +1160,7 @@ void readlevelheader(MYFILE *f, char * name)
if (fastncmp(tmp, "MT_", 3)) // support for specified mobjtypes...
{
i = get_mobjtype(tmp);
if (i == -1)
if (i == NUMMOBJTYPES)
{
//deh_warning("Level header %d: unknown flicky mobj type %s\n", num, tmp); -- no need for this line as get_mobjtype complains too
continue;
@ -2154,21 +2030,6 @@ void readtextprompt(MYFILE *f, INT32 num)
Z_Free(s);
}
static menu_t *allocmenu(INT32 num)
{
if (num < 0 || num >= NUMMENUTYPES)
I_Error("Tried to allocate out-of-range menu number");
menu_t *menu = menudefs[num];
if (menu == NULL)
{
menudefs[num] = menu = Z_Calloc(sizeof(menu_t), PU_STATIC, NULL);
menu->drawroutine = M_DrawGenericMenu;
}
return menu;
}
// super secret menu cvars... :shushing_face:
static struct { const char *name; consvar_t *var; } HIDDENVARS[] = {
{ "CHOOSESKIN", &cv_chooseskin },
@ -2311,14 +2172,13 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
continue;
}
menutype_t mn = get_menutype(word2);
if (mn == MN_NONE)
if (mn == MAXMENUTYPES)
{
WARN("unknown menu '%s'", word2);
continue;
}
actionset = true;
status |= IT_SUBMENU;
allocmenu(mn);
menuitem->itemaction.submenu = mn;
}
else if (fastncmp(word, "CALL", 4) || fastcmp(word, "KEYHANDLER") || fastcmp(word, "ARROWS"))
@ -2372,7 +2232,7 @@ static void readmenuitem(MYFILE *f, menuitem_t *menuitem)
#undef WARN
#undef WARN0
#define WARN(str, ...) deh_warning("Menu %s: " str, num < MN_FIRSTFREESLOT ? MENUTYPES_LIST[num] : FREE_MENUS[num - MN_FIRSTFREESLOT], __VA_ARGS__)
#define WARN(str, ...) deh_warning("Menu %s: " str, DEH_MenutypeName(num), __VA_ARGS__)
void readmenu(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@ -2381,7 +2241,7 @@ void readmenu(MYFILE *f, INT32 num)
char *tmp;
INT32 value;
menu_t *menudef = allocmenu(num);
menu_t *menudef = &menudefs[num];
do
{
@ -2679,7 +2539,7 @@ void readframe(MYFILE *f, INT32 num)
else if (fastcmp(word1, "NEXT"))
{
statenum_t state = get_state(word2);
states[num].nextstate = state == (statenum_t)-1 ? S_NULL : state;
states[num].nextstate = state == NUMSTATES ? S_NULL : state;
}
else if (fastcmp(word1, "VAR1"))
{
@ -4007,7 +3867,7 @@ void readfollower(MYFILE *f)
else
{
skincolornum_t color = get_skincolor(word2);
followers[numfollowers].defaultcolor = color == (skincolornum_t)-1 ? SKINCOLOR_GREEN : color;
followers[numfollowers].defaultcolor = color == MAXSKINCOLORS ? SKINCOLOR_GREEN : color;
}
}
else if (fastcmp(word, "SCALE"))
@ -4241,7 +4101,7 @@ void readweather(MYFILE *f, INT32 num)
if (fastcmp(word, "TYPE"))
{
mobjtype_t mt = get_mobjtype(word2);
precipprops[num].type = mt == (mobjtype_t)-1 ? MT_NULL : mt;
precipprops[num].type = mt == NUMMOBJTYPES ? MT_NULL : mt;
}
else if (fastcmp(word, "EFFECTS"))
{
@ -4266,17 +4126,10 @@ mobjtype_t get_mobjtype(const char *word)
return atoi(word);
if (fastncmp("MT_",word,3))
word += 3; // take off the MT_
for (i = 0; i < NUMMOBJFREESLOTS; i++) {
if (!FREE_MOBJS[i])
break;
if (fastcmp(word, FREE_MOBJS[i]))
return MT_FIRSTFREESLOT+i;
}
for (i = 0; i < MT_FIRSTFREESLOT; i++)
if (fastcmp(word, MOBJTYPE_LIST[i]+3))
return i;
deh_warning("Couldn't find mobjtype named 'MT_%s'",word);
return -1;
i = DEH_FindMobjtype(word);
if (i == NUMMOBJTYPES)
deh_warning("Couldn't find mobjtype named 'MT_%s'", word);
return i;
}
statenum_t get_state(const char *word)
@ -4286,17 +4139,10 @@ statenum_t get_state(const char *word)
return atoi(word);
if (fastncmp("S_",word,2))
word += 2; // take off the S_
for (i = 0; i < NUMSTATEFREESLOTS; i++) {
if (!FREE_STATES[i])
break;
if (fastcmp(word, FREE_STATES[i]))
return S_FIRSTFREESLOT+i;
}
for (i = 0; i < S_FIRSTFREESLOT; i++)
if (fastcmp(word, STATE_LIST[i]+2))
return i;
deh_warning("Couldn't find state named 'S_%s'",word);
return -1;
i = DEH_FindState(word);
if (i == NUMSTATES)
deh_warning("Couldn't find state named 'S_%s'", word);
return i;
}
skincolornum_t get_skincolor(const char *word)
@ -4306,17 +4152,10 @@ skincolornum_t get_skincolor(const char *word)
return atoi(word);
if (fastncmp("SKINCOLOR_",word,10))
word += 10; // take off the SKINCOLOR_
for (i = 0; i < NUMCOLORFREESLOTS; i++) {
if (!FREE_SKINCOLORS[i])
break;
if (fastcmp(word, FREE_SKINCOLORS[i]))
return SKINCOLOR_FIRSTFREESLOT+i;
}
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++)
if (fastcmp(word, COLOR_ENUMS[i]))
return i;
deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'",word);
return -1;
i = DEH_FindSkincolor(word);
if (i == MAXSKINCOLORS)
deh_warning("Couldn't find skincolor named 'SKINCOLOR_%s'", word);
return i;
}
spritenum_t get_sprite(const char *word)
@ -4370,17 +4209,10 @@ menutype_t get_menutype(const char *word)
return atoi(word);
if (fastncmp("MN_",word,3))
word += 3; // take off the MN_
for (i = 0; i < NUMMENUFREESLOTS; i++) {
if (!FREE_MENUS[i])
break;
if (fastcmp(word, FREE_MENUS[i]))
return MN_FIRSTFREESLOT+i;
}
for (i = 0; i < MN_FIRSTFREESLOT; i++)
if (fastcmp(word, MENUTYPES_LIST[i]))
return i;
deh_warning("Couldn't find menutype named 'MN_%s'",word);
return MN_NONE;
i = DEH_FindMenutype(word);
if (i == MAXMENUTYPES)
deh_warning("Couldn't find menutype named 'MN_%s'", word);
return i;
}
void (*get_menuroutine(const char *word))(INT32)

View file

@ -31,13 +31,86 @@
#include "k_kart.h" // awardscaledrings_t
#include "deh_tables.h"
#include "fastcmp.h"
char *FREE_STATES[NUMSTATEFREESLOTS];
char *FREE_MOBJS[NUMMOBJFREESLOTS];
char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
char *FREE_MENUS[NUMMENUFREESLOTS];
strbuf_t *statenames;
strbuf_t *mobjnames;
strbuf_t *skincolornames;
strbuf_t *menunames;
UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
const char *DEH_MobjtypeName(mobjtype_t i)
{
return strbuf_get(mobjnames, mobjinfo[i].info.nameofs);
}
const char *DEH_StateName(statenum_t i)
{
return strbuf_get(statenames, states[i].info.nameofs);
}
const char *DEH_SkincolorName(skincolornum_t i)
{
return strbuf_get(skincolornames, skincolors[i].info.nameofs);
}
const char *DEH_MenutypeName(menutype_t i)
{
return strbuf_get(menunames, menudefs[i].info.nameofs);
}
mobjtype_t DEH_FindMobjtype(const char *word)
{
mobjtype_t i;
UINT32 hash = HASH32(word, strlen(word));
for (i = 0; i < nummobjtypes; i++) {
if (hash != mobjinfo[i].info.namehash)
continue;
if (fastcmp(word, DEH_MobjtypeName(i)))
return i;
}
return NUMMOBJTYPES;
}
statenum_t DEH_FindState(const char *word)
{
statenum_t i;
UINT32 hash = HASH32(word, strlen(word));
for (i = 0; i < numstates; i++) {
if (hash != states[i].info.namehash)
continue;
if (fastcmp(word, DEH_StateName(i)))
return i;
}
return NUMSTATES;
}
skincolornum_t DEH_FindSkincolor(const char *word)
{
skincolornum_t i;
UINT32 hash = HASH32(word, strlen(word));
for (i = 0; i < numskincolors; i++) {
if (hash != skincolors[i].info.namehash)
continue;
if (fastcmp(word, DEH_SkincolorName(i)))
return i;
}
return MAXSKINCOLORS;
}
menutype_t DEH_FindMenutype(const char *word)
{
menutype_t i;
UINT32 hash = HASH32(word, strlen(word));
for (i = 0; i < nummenutypes; i++) {
if (hash != menudefs[i].info.namehash)
continue;
if (fastcmp(word, DEH_MenutypeName(i)))
return i;
}
return MAXMENUTYPES;
}
struct flickytypes_s FLICKYTYPES[] = {
{"BLUEBIRD", MT_FLICKY_01}, // Flicky (Flicky)
{"RABBIT", MT_FLICKY_02}, // Pocky (1)
@ -83,12 +156,6 @@ actionpointer_t actionpointers[] =
// TODO: Make the lists public so we can start using actual mobj
// and state names in warning and error messages! :D
const char *const STATE_LIST[] = { // array length left dynamic for sanity testing later.
#define _(name, ...) "S_"#name,
#include "info/states.h"
#undef _
};
struct int_const_s const STATE_ALIASES[] = {
{"KART_STND1", S_KART_STILL},
{"KART_STND2" , S_KART_STILL},
@ -123,12 +190,6 @@ struct int_const_s const STATE_ALIASES[] = {
{ NULL, 0 }
};
const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity testing later.
#define _(name, ...) "MT_"#name,
#include "info/mobjs.h"
#undef _
};
struct int_const_s const MOBJ_ALIASES[] = {
{"BIRD", MT_FLICKY_01},
{"BUNNY" , MT_FLICKY_02},
@ -438,12 +499,6 @@ const char *const TO_LIST[] = {
NULL
};
const char *COLOR_ENUMS[] = {
#define _(name, ...) #name,
#include "info/skincolors.h"
#undef _
};
const char *const POWERS_LIST[] = {
"INVULNERABILITY",
"SNEAKERS",
@ -618,12 +673,6 @@ const char *const HUDITEMS_LIST[] = {
"POWERUPS"
};
const char *const MENUTYPES_LIST[] = {
#define _(name, ...) #name,
#include "info/menus.h"
#undef _
};
struct menu_routine_s const MENU_ROUTINES[] = {
{ "SINGLEPLAYERMENU", &M_SinglePlayerMenu },
{ "OPTIONS", &M_Options },
@ -1523,23 +1572,3 @@ struct int_const_s const INT_CONST[] = {
{NULL,0}
};
// For this to work compile-time without being in this file,
// this function would need to check sizes at runtime, without sizeof
void DEH_TableCheck(void)
{
#if defined(_DEBUG) || defined(PARANOIA)
const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
const size_t dehmobjs = sizeof(MOBJTYPE_LIST)/sizeof(const char*);
const size_t dehcolors = sizeof(COLOR_ENUMS)/sizeof(const char*);
if (dehstates != S_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked states list, you dolt!\n(%d states defined, versus %s in the Dehacked list)\n", S_FIRSTFREESLOT, sizeu1(dehstates));
if (dehmobjs != MT_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked mobjtype list, you dolt!\n(%d mobj types defined, versus %s in the Dehacked list)\n", MT_FIRSTFREESLOT, sizeu1(dehmobjs));
if (dehcolors != SKINCOLOR_FIRSTFREESLOT)
I_Error("You forgot to update the Dehacked colors list, you dolt!\n(%d colors defined, versus %s in the Dehacked list)\n", SKINCOLOR_FIRSTFREESLOT, sizeu1(dehcolors));
#endif
}

View file

@ -16,8 +16,9 @@
#include "doomdef.h" // Constants
#include "d_think.h" // actionf_t
#include "info.h" // Mobj, state, sprite, etc constants
#include "m_menu.h" // NUMMENUFREESLOTS
#include "lua_script.h"
#include "strbuf.h"
#include "m_menu.h" // menutype_t
#ifdef __cplusplus
extern "C" {
@ -25,18 +26,21 @@ extern "C" {
// Free slot names
// The crazy word-reading stuff uses these.
extern char *FREE_STATES[NUMSTATEFREESLOTS];
extern char *FREE_MOBJS[NUMMOBJFREESLOTS];
extern char *FREE_SKINCOLORS[NUMCOLORFREESLOTS];
extern char *FREE_MENUS[NUMMENUFREESLOTS];
extern strbuf_t *statenames;
extern strbuf_t *mobjnames;
extern strbuf_t *skincolornames;
extern strbuf_t *menunames;
extern UINT8 used_spr[(NUMSPRITEFREESLOTS / 8) + 1]; // Bitwise flag for sprite freeslot in use! I would use ceil() here if I could, but it only saves 1 byte of memory anyway.
#define initfreeslots() {\
memset(FREE_STATES,0,sizeof(char *) * NUMSTATEFREESLOTS);\
memset(FREE_MOBJS,0,sizeof(char *) * NUMMOBJFREESLOTS);\
memset(FREE_SKINCOLORS,0,sizeof(char *) * NUMCOLORFREESLOTS);\
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
}
const char *DEH_MobjtypeName(mobjtype_t i);
const char *DEH_StateName(statenum_t i);
const char *DEH_SkincolorName(skincolornum_t i);
const char *DEH_MenutypeName(menutype_t i);
mobjtype_t DEH_FindMobjtype(const char *word);
statenum_t DEH_FindState(const char *word);
skincolornum_t DEH_FindSkincolor(const char *word);
menutype_t DEH_FindMenutype(const char *word);
struct flickytypes_s {
const char *name;
@ -71,9 +75,7 @@ struct int_const_s {
extern struct flickytypes_s FLICKYTYPES[];
extern actionpointer_t actionpointers[]; // Array mapping action names to action functions.
extern const char *const STATE_LIST[];
extern struct int_const_s const STATE_ALIASES[];
extern const char *const MOBJTYPE_LIST[];
extern struct int_const_s const MOBJ_ALIASES[];
extern const char *const MOBJFLAG_LIST[];
extern const char *const MOBJFLAG2_LIST[]; // \tMF2_(\S+).*// (.+) --> \t"\1", // \2
@ -88,20 +90,15 @@ extern const char *const MSF_LIST[]; // Sector flags
extern const char *const SSF_LIST[]; // Sector special flags
extern const char *const SD_LIST[]; // Sector damagetype
extern const char *const TO_LIST[]; // Sector triggerer
extern const char *COLOR_ENUMS[];
extern const char *const POWERS_LIST[];
extern const char *const KARTSTUFF_LIST[];
extern const char *const KARTHUD_LIST[];
extern const char *const HUDITEMS_LIST[];
extern const char *const MENUTYPES_LIST[];
extern struct menu_routine_s const MENU_ROUTINES[];
extern struct menu_drawer_s const MENU_DRAWERS[];
extern struct int_const_s const INT_CONST[];
// Moved to this file because it can't work compile-time otherwise
void DEH_TableCheck(void);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -13,9 +13,9 @@
#include "doomdef.h"
#include "m_cond.h"
#include "deh_soc.h"
#include "deh_lua.h"
#include "deh_tables.h"
boolean deh_loaded = false;
#include "k_hud.h"
boolean gamedataadded = false;
boolean titlechanged = false;
@ -176,6 +176,182 @@ static void ignorelines(MYFILE *f)
Z_Free(s);
}
void DEH_Link(const char *name, dehinfo_t *info, strbuf_t **buf)
{
info->namehash = HASH32(name, strlen(name));
info->nameofs = strbuf_append(buf, name);
}
INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out)
{
size_t i;
// TODO: Check for existing freeslot mobjs/states/etc. and make errors.
// TODO: Name too long (truncated) warnings.
if (fastcmp(type, "SFX"))
{
CONS_Printf("Sound sfx_%s allocated.\n", word);
i = S_AddSoundFx(word, false, 0, false);
if (i != sfx_None)
{
*out = i;
return 0;
}
CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n");
return -1;
}
else if (fastcmp(type, "SPR"))
{
for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++)
{
if (used_spr[(i-SPR_FIRSTFREESLOT)/8] & (1<<(i%8)))
continue; // Already allocated, next.
// Found a free slot!
CONS_Printf("Sprite SPR_%s allocated.\n",word);
strncpy(sprnames[i],word,4);
used_spr[(i-SPR_FIRSTFREESLOT)/8] |= 1<<(i%8); // Okay, this sprite slot has been named now.
// Lua needs to update the value in _G if it exists
LUA_UpdateSprName(word, i);
*out = i;
return 0;
}
CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n");
return -1;
}
else if (fastcmp(type, "S"))
{
*out = DEH_FindState(word);
if (*out != NUMSTATES)
return 0; // already allocated
if (numstates == NUMSTATES) {
CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n");
return -1;
}
CONS_Printf("State S_%s allocated.\n",word);
DEH_Link(word, &states[numstates].info, &statenames);
*out = numstates++;
freeslotusage[0][0]++;
return 0;
}
else if (fastcmp(type, "MT"))
{
*out = DEH_FindMobjtype(word);
if (*out != NUMMOBJTYPES)
return 0; // already allocated
if (nummobjtypes == NUMMOBJTYPES) {
CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
return -1;
}
CONS_Printf("MobjType MT_%s allocated.\n",word);
DEH_Link(word, &mobjinfo[nummobjtypes].info, &mobjnames);
*out = nummobjtypes++;
freeslotusage[1][0]++;
return 0;
}
else if (fastcmp(type, "SKINCOLOR"))
{
*out = DEH_FindSkincolor(word);
if (*out != MAXSKINCOLORS)
return 0; // already allocated
if (numskincolors == MAXSKINCOLORS) {
CONS_Alert(CONS_WARNING, "Ran out of free skincolor slots!\n");
return -1;
}
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
DEH_Link(word, &skincolors[numskincolors].info, &skincolornames);
M_AddMenuColor(numskincolors);
K_ReloadHUDColorCvar();
*out = numskincolors++;
return 0;
}
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++)
if (memcmp(spr2names[i],word,4) == 0)
break;
// We don't, so allocate a new one.
if (i >= free_spr2) {
if (free_spr2 < NUMPLAYERSPRITES)
{
CONS_Printf("Sprite SPR2_%s allocated.\n",word);
strncpy(spr2names[free_spr2],word,4);
spr2defaults[free_spr2] = 0;
*out = free_spr2;
spr2names[free_spr2++][4] = 0;
return 0;
} else {
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
return -1;
}
}
}
else if (fastcmp(type, "TOL"))
{
// Search if we already have a typeoflevel by that name...
for (i = 0; TYPEOFLEVEL[i].name; i++)
if (fastcmp(word, TYPEOFLEVEL[i].name))
break;
// We don't, so allocate a new one.
if (TYPEOFLEVEL[i].name == NULL) {
if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
{
CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
return -1;
} else {
CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word);
G_AddTOL(lastcustomtol, word);
*out = lastcustomtol;
lastcustomtol <<= 1;
return 0;
}
}
}
else if (fastcmp(type, "PRECIP"))
{
// Search if we already have a PRECIP by that name...
for (i = PRECIP_FIRSTFREESLOT; i < precip_freeslot; i++)
if (fastcmp(word, precipprops[i].name))
break;
// We don't, so allocate a new one.
if (i >= precip_freeslot) {
if (precip_freeslot < MAXPRECIP)
{
CONS_Printf("Weather PRECIP_%s allocated.\n",word);
precipprops[i].name = Z_StrDup(word);
*out = precip_freeslot;
precip_freeslot++;
return 0;
} else {
CONS_Alert(CONS_WARNING, "Ran out of free PRECIP slots!\n");
return -1;
}
}
}
else if (fastcmp(type, "MN"))
{
*out = DEH_FindMenutype(word);
if (*out != MAXMENUTYPES)
return 0; // already allocated
if (nummenutypes == MAXMENUTYPES) {
CONS_Alert(CONS_WARNING, "Ran out of free menu slots!\n");
return -1;
}
CONS_Printf("Menu MN_%s allocated.\n",word);
DEH_Link(word, &menudefs[nummenutypes].info, &menunames);
*out = nummenutypes++;
return 0;
}
return -2;
}
static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@ -184,9 +360,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
char *word2;
INT32 i;
if (!deh_loaded)
initfreeslots();
deh_num_warning = 0;
gamedataadded = titlechanged = introchanged = false;
@ -476,12 +649,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_menutype(word2); // find a huditem by name
if (i >= 1 && i < NUMMENUTYPES)
if (i >= 1 && i < nummenutypes)
readmenu(f, i);
else
{
// zero-based, but let's start at 1
deh_warning("Menu number %d out of range (1 - %d)", i, NUMMENUTYPES-1);
deh_warning("Menu number %d out of range (1 - %d)", i, nummenutypes-1);
ignorelines(f);
}
}
@ -685,7 +858,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
}
}
deh_loaded = true;
Z_Free(s);
}

View file

@ -19,33 +19,25 @@
extern "C" {
#endif
typedef enum
struct dehinfo_t
{
UNDO_NONE = 0x00,
UNDO_NEWLINE = 0x01,
UNDO_SPACE = 0x02,
UNDO_CUTLINE = 0x04,
UNDO_HEADER = 0x07,
UNDO_ENDTEXT = 0x08,
UNDO_TODO = 0,
UNDO_DONE = 0,
} undotype_f;
UINT32 namehash; // excluding prefix (no MT_ or S_)
UINT32 nameofs; // into strbuf_t
};
void DEH_LoadDehackedLump(lumpnum_t lumpnum);
void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile);
void DEH_Link(const char *name, dehinfo_t *info, strbuf_t **buf);
INT32 DEH_ReadFreeslot(const char *type, const char *word, INT32 *out);
// SRB2Kart
extern int freeslotusage[2][2];
void DEH_UpdateMaxFreeslots(void);
void DEH_Check(void);
fixed_t get_number(const char *word);
FUNCPRINTF void deh_warning(const char *first, ...);
void deh_strlcpy(char *dst, const char *src, size_t size, const char *warntext);
extern boolean deh_loaded;
extern boolean gamedataadded;
extern boolean titlechanged;
extern boolean introchanged;

View file

@ -211,7 +211,7 @@ extern char logfilename[1024];
#define COLORRAMPSIZE 16
#define MAXCOLORNAME 32
#define NUMCOLORFREESLOTS UINT16_MAX
#define NUMCOLORFREESLOTS 32768
// surely nobody's gonna change the palette a second time :Clueless:
#define FADECOLOR 0 // 120
@ -220,34 +220,6 @@ extern char logfilename[1024];
// Master Server compatibility ONLY
#define MSCOMPAT_MAXPLAYERS (32)
struct skincolor_t
{
char name[MAXCOLORNAME+1]; // Skincolor name
UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp
UINT16 invcolor; // Signpost color
UINT8 invshade; // Signpost color shade
UINT16 chatcolor; // Chat color
boolean accessible; // Accessible by the color command + setup menu
};
typedef enum
{
#define _(name, ...) SKINCOLOR_##name,
#include "info/skincolors.h"
#undef _
SKINCOLOR_FIRSTFREESLOT,
SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1,
MAXSKINCOLORS,
FIRSTRAINBOWCOLOR = SKINCOLOR_PINK,
FIRSTSUPERCOLOR = SKINCOLOR_SUPER1,
NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5)
} skincolornum_t;
extern UINT16 numskincolors;
extern skincolor_t skincolors[MAXSKINCOLORS];
// State updates, number of tics / second.
// NOTE: used to setup the timer rate, see I_StartupTimer().
#define TICRATE 35
@ -512,13 +484,6 @@ extern int compuncommitted;
/// Shuffle's incomplete OpenGL sorting code.
#define SHUFFLE // This has nothing to do with sorting, why was it disabled?
/// Allow the use of the SOC RESETINFO command.
/// \note Builds that are tight on memory should disable this.
/// This stops the game from storing backups of the states, sprites, and mobjinfo tables.
/// Though this info is compressed under normal circumstances, it's still a lot of extra
/// memory that never gets touched.
#define ALLOW_RESETDATA
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG

View file

@ -14,15 +14,12 @@
// Data.
#include "info.h"
#include "doomdef.h"
#include "doomstat.h"
#include "sounds.h"
#include "p_mobj.h"
#include "p_local.h" // DMG_ constants
#include "m_misc.h"
#include "z_zone.h"
#include "d_player.h"
#include "v_video.h" // V_*MAP constants
#include "lzf.h"
#include "w_wad.h"
#include "dehacked.h"
#include "d_main.h"
#include "m_menu.h"
#include "deh_tables.h"
// Hey, moron! If you wanna change this table, you can just change the sprite enum in info/sprites.h,
// so you don't have to copy and paste the list of sprite names back in here :^)
@ -84,128 +81,155 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
// Doesn't work with g++, needs actionf_p1 (don't modify this comment)
state_t states[NUMSTATES] = {0};
UINT16 numstates;
mobjinfo_t mobjinfo[NUMMOBJTYPES] = {0};
UINT16 nummobjtypes;
skincolor_t skincolors[MAXSKINCOLORS] = {0};
/** Patches the mobjinfo, state, and skincolor tables.
* Free slots are emptied out and set to initial values.
*/
void P_PatchInfoTables(void)
{
INT32 i;
char *tempname;
#if NUMSPRITEFREESLOTS > 9999 //tempname numbering actually starts at SPR_FIRSTFREESLOT, so the limit is actually 9999 + SPR_FIRSTFREESLOT-1, but the preprocessor doesn't understand enums, so its left at 9999 for safety
#error "Update P_PatchInfoTables, you big dumb head"
#endif
// empty out free slots
for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++)
{
tempname = sprnames[i];
tempname[0] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)/1000));
tempname[1] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/100)%10));
tempname[2] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/10)%10));
tempname[3] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)%10));
tempname[4] = '\0';
}
sprnames[i][0] = '\0'; // i == NUMSPRITES
memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS);
memset(&mobjinfo[MT_FIRSTFREESLOT], 0, sizeof (mobjinfo_t) * NUMMOBJFREESLOTS);
memset(&skincolors[SKINCOLOR_FIRSTFREESLOT], 0, sizeof (skincolor_t) * NUMCOLORFREESLOTS);
for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++) {
skincolors[i].accessible = false;
skincolors[i].name[0] = '\0';
}
for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++)
mobjinfo[i].doomednum = -1;
}
static const char *hardcodemobjs =
#define _(name, ...) #name "\0"
#include "info/mobjs.h"
#undef _
;
#ifdef ALLOW_RESETDATA
static char *sprnamesbackup;
static state_t *statesbackup;
static mobjinfo_t *mobjinfobackup;
static skincolor_t *skincolorsbackup;
static size_t sprnamesbackupsize, statesbackupsize, mobjinfobackupsize, skincolorsbackupsize;
#endif
static const char *hardcodestates =
#define _(name, ...) #name "\0"
#include "info/states.h"
#undef _
;
void P_BackupTables(void)
{
#ifdef ALLOW_RESETDATA
// Allocate buffers in size equal to that of the uncompressed data to begin with
sprnamesbackup = Z_Malloc(sizeof(sprnames), PU_STATIC, NULL);
statesbackup = Z_Malloc(sizeof(states), PU_STATIC, NULL);
mobjinfobackup = Z_Malloc(sizeof(mobjinfo), PU_STATIC, NULL);
skincolorsbackup = Z_Malloc(sizeof(skincolors), PU_STATIC, NULL);
static const char *hardcodeskincolors =
#define _(name, ...) #name "\0"
#include "info/skincolors.h"
#undef _
;
// Sprite names
sprnamesbackupsize = lzf_compress(sprnames, sizeof(sprnames), sprnamesbackup, sizeof(sprnames));
if (sprnamesbackupsize > 0)
sprnamesbackup = Z_Realloc(sprnamesbackup, sprnamesbackupsize, PU_STATIC, NULL);
else
M_Memcpy(sprnamesbackup, sprnames, sizeof(sprnames));
// States
statesbackupsize = lzf_compress(states, sizeof(states), statesbackup, sizeof(states));
if (statesbackupsize > 0)
statesbackup = Z_Realloc(statesbackup, statesbackupsize, PU_STATIC, NULL);
else
M_Memcpy(statesbackup, states, sizeof(states));
// Mobj info
mobjinfobackupsize = lzf_compress(mobjinfo, sizeof(mobjinfo), mobjinfobackup, sizeof(mobjinfo));
if (mobjinfobackupsize > 0)
mobjinfobackup = Z_Realloc(mobjinfobackup, mobjinfobackupsize, PU_STATIC, NULL);
else
M_Memcpy(mobjinfobackup, mobjinfo, sizeof(mobjinfo));
//Skincolor info
skincolorsbackupsize = lzf_compress(skincolors, sizeof(skincolors), skincolorsbackup, sizeof(skincolors));
if (skincolorsbackupsize > 0)
skincolorsbackup = Z_Realloc(skincolorsbackup, skincolorsbackupsize, PU_STATIC, NULL);
else
M_Memcpy(skincolorsbackup, skincolors, sizeof(skincolors));
#endif
}
static const char *hardcodemenus =
#define _(name, ...) #name "\0"
#include "info/menus.h"
#undef _
;
void P_ResetData(INT32 flags)
{
#ifndef ALLOW_RESETDATA
(void)flags;
CONS_Alert(CONS_NOTICE, M_GetText("P_ResetData(): not supported in this build.\n"));
#else
INT32 i;
UINT16 lumpnum;
boolean init = numwadfiles == 0;
const char *name;
// sprnames
if (flags & 1)
{
if (sprnamesbackupsize > 0)
lzf_decompress(sprnamesbackup, sprnamesbackupsize, sprnames, sizeof(sprnames));
else
M_Memcpy(sprnames, sprnamesbackup, sizeof(sprnamesbackup));
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));
// vanilla sprnames are immutable
for (i = SPR_FIRSTFREESLOT; i <= SPR_LASTFREESLOT; i++)
{
char *tempname = sprnames[i];
tempname[0] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)/1000));
tempname[1] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/100)%10));
tempname[2] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/10)%10));
tempname[3] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)%10));
tempname[4] = '\0';
}
sprnames[i][0] = '\0'; // i == NUMSPRITES
}
// states
if (flags & 2)
{
if (statesbackupsize > 0)
lzf_decompress(statesbackup, statesbackupsize, states, sizeof(states));
else
M_Memcpy(states, statesbackup, sizeof(statesbackup));
if (!init)
memset(states, 0, sizeof(states));
numstates = S_FIRSTFREESLOT;
if (statenames)
Z_Free(statenames);
statenames = strbuf_alloc();
name = hardcodestates;
for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1)
DEH_Link(name, &states[i].info, &statenames);
if (!init)
{
lumpnum = W_CheckNumForLongNamePwadNoUpper("states", MAINWAD_MAIN, 0);
DEH_LoadDehackedLumpPwad(MAINWAD_MAIN, lumpnum, true);
}
}
// mobjinfo
if (flags & 4)
{
if (mobjinfobackupsize > 0)
lzf_decompress(mobjinfobackup, mobjinfobackupsize, mobjinfo, sizeof(mobjinfo));
else
M_Memcpy(mobjinfo, mobjinfobackup, sizeof(mobjinfobackup));
if (!init)
memset(mobjinfo, 0, sizeof(mobjinfo));
nummobjtypes = MT_FIRSTFREESLOT;
if (mobjnames)
Z_Free(mobjnames);
mobjnames = strbuf_alloc();
name = hardcodemobjs;
for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1)
DEH_Link(name, &mobjinfo[i].info, &mobjnames);
for (i = MT_FIRSTFREESLOT; i <= MT_LASTFREESLOT; i++)
mobjinfo[i].doomednum = -1;
if (!init)
{
lumpnum = W_CheckNumForLongNamePwadNoUpper("mobjs", MAINWAD_MAIN, 0);
DEH_LoadDehackedLumpPwad(MAINWAD_MAIN, lumpnum, true);
}
}
// skincolors
if (flags & 8)
{
if (skincolorsbackupsize > 0)
lzf_decompress(skincolorsbackup, skincolorsbackupsize, skincolors, sizeof(skincolors));
else
M_Memcpy(skincolors, skincolorsbackup, sizeof(skincolorsbackup));
if (!init)
memset(skincolors, 0, sizeof(skincolors));
numskincolors = SKINCOLOR_FIRSTFREESLOT;
if (skincolornames)
Z_Free(skincolornames);
skincolornames = strbuf_alloc();
name = hardcodeskincolors;
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1)
DEH_Link(name, &skincolors[i].info, &skincolornames);
for (i = SKINCOLOR_FIRSTFREESLOT; i <= SKINCOLOR_LASTFREESLOT; i++)
{
skincolors[i].accessible = false;
skincolors[i].name[0] = '\0';
}
if (!init)
{
lumpnum = W_CheckNumForLongNamePwadNoUpper("skincolors", MAINWAD_MAIN, 0);
DEH_LoadDehackedLumpPwad(MAINWAD_MAIN, lumpnum, true);
}
}
// menudefs (TODO: actually reset this with resetdata?)
if (init)
{
memset(menudefs, 0, sizeof(menudefs));
for (i = 0; i < MAXMENUTYPES; i++)
menudefs[i].drawroutine = M_DrawGenericMenu;
nummenutypes = MN_FIRSTFREESLOT;
if (menunames)
Z_Free(menunames);
menunames = strbuf_alloc();
name = hardcodemenus;
for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1)
DEH_Link(name, &menudefs[i].info, &menunames);
}
#endif
}

View file

@ -18,6 +18,7 @@
#include "d_think.h"
#include "sounds.h"
#include "m_fixed.h"
#include "dehacked.h"
#ifdef __cplusplus
extern "C" {
@ -79,6 +80,7 @@ typedef enum state
struct state_t
{
dehinfo_t info;
spritenum_t sprite;
UINT32 frame; // we use the upper 16 bits for translucency and other shade effects
INT32 tics;
@ -89,6 +91,7 @@ struct state_t
};
extern state_t states[NUMSTATES];
extern UINT16 numstates;
extern char sprnames[NUMSPRITES + 1][5];
extern char spr2names[NUMPLAYERSPRITES][5];
extern playersprite_t spr2defaults[NUMPLAYERSPRITES];
@ -107,6 +110,7 @@ typedef enum mobj_type
struct mobjinfo_t
{
dehinfo_t info;
INT32 doomednum;
statenum_t spawnstate;
INT32 spawnhealth;
@ -134,10 +138,35 @@ struct mobjinfo_t
};
extern mobjinfo_t mobjinfo[NUMMOBJTYPES];
extern UINT16 nummobjtypes;
void P_PatchInfoTables(void);
typedef enum
{
#define _(name, ...) SKINCOLOR_##name,
#include "info/skincolors.h"
#undef _
SKINCOLOR_FIRSTFREESLOT,
SKINCOLOR_LASTFREESLOT = SKINCOLOR_FIRSTFREESLOT + NUMCOLORFREESLOTS - 1,
MAXSKINCOLORS,
void P_BackupTables(void);
FIRSTRAINBOWCOLOR = SKINCOLOR_PINK,
FIRSTSUPERCOLOR = SKINCOLOR_SUPER1,
NUMSUPERCOLORS = ((SKINCOLOR_FIRSTFREESLOT - FIRSTSUPERCOLOR)/5)
} skincolornum_t;
struct skincolor_t
{
dehinfo_t info; // Internal name hash and offset
char name[MAXCOLORNAME+1]; // Skincolor name
UINT8 ramp[COLORRAMPSIZE]; // Colormap ramp
UINT16 invcolor; // Signpost color
UINT8 invshade; // Signpost color shade
UINT16 chatcolor; // Chat color
boolean accessible; // Accessible by the color command + setup menu
};
extern skincolor_t skincolors[MAXSKINCOLORS];
extern UINT16 numskincolors;
void P_ResetData(INT32 flags);

View file

@ -12,7 +12,7 @@
#ifndef __K_COLOR__
#define __K_COLOR__
#include "doomdef.h"
#include "info.h"
#include "doomtype.h"
#ifdef __cplusplus

View file

@ -752,7 +752,7 @@ static int lib_setState(lua_State *L)
return luaL_error(L, "Do not alter states in CMD building code!");
// clear the state to start with, in case of missing table elements
memset(state,0,sizeof(state_t));
memset((char *)state + sizeof(dehinfo_t), 0, sizeof(*state) - sizeof(dehinfo_t));
state->tics = -1;
lua_pushnil(L);
@ -975,16 +975,9 @@ static int state_get(lua_State *L)
else if (fastcmp(field,"string"))
{
statenum_t id = st-states;
if (id < S_FIRSTFREESLOT)
if (id < NUMSTATES)
{
lua_pushstring(L, STATE_LIST[id]+2);
return 1;
}
id -= S_FIRSTFREESLOT;
if (id < NUMSTATEFREESLOTS && FREE_STATES[id])
{
lua_pushstring(L, FREE_STATES[id]);
lua_pushstring(L, DEH_StateName(id));
return 1;
}
@ -1114,7 +1107,7 @@ static int lib_setMobjInfo(lua_State *L)
return luaL_error(L, "Do not alter mobjinfo in CMD building code!");
// clear the mobjinfo to start with, in case of missing table elements
memset(info,0,sizeof(mobjinfo_t));
memset((char *)info + sizeof(dehinfo_t), 0, sizeof(*info) - sizeof(dehinfo_t));
info->doomednum = -1; // default to no editor value
info->spawnhealth = 1; // avoid 'dead' noclip behaviors
@ -1257,16 +1250,9 @@ static int mobjinfo_get(lua_State *L)
lua_pushinteger(L, info->raisestate);
else if (fastcmp(field,"string")) {
mobjtype_t id = info-mobjinfo;
if (id < MT_FIRSTFREESLOT)
if (id < NUMMOBJTYPES)
{
lua_pushstring(L, MOBJTYPE_LIST[id]+3);
return 1;
}
id -= MT_FIRSTFREESLOT;
if (id < NUMMOBJFREESLOTS && FREE_MOBJS[id])
{
lua_pushstring(L, FREE_MOBJS[id]);
lua_pushstring(L, DEH_MobjtypeName(id));
return 1;
}
@ -1671,7 +1657,7 @@ static int lib_setSkinColor(lua_State *L)
return luaL_error(L, "Do not alter skincolors in CMD building code!");
// clear the skincolor to start with, in case of missing table elements
memset(info,0,sizeof(skincolor_t));
memset((char *)info + sizeof(dehinfo_t), 0, sizeof(*info) - sizeof(dehinfo_t));
Color_cons_t[cnum].value = cnum;
lua_pushnil(L);
@ -1913,7 +1899,7 @@ static int lib_setPrecipProps(lua_State *L)
// clear the precipprops to start with, in case of missing table elements
// make sure we do not clear the name
memset(props + sizeof(props->name), 0, sizeof(precipprops_t) - sizeof(props->name));
memset((char *)props + sizeof(props->name), 0, sizeof(*props) - sizeof(props->name));
lua_pushnil(L);
while (lua_next(L, 1)) {

View file

@ -13,7 +13,7 @@
#ifndef __M_COND_H__
#define __M_COND_H__
#include "doomdef.h"
#include "info.h"
#ifdef __cplusplus
extern "C" {

View file

@ -166,7 +166,8 @@ static UINT32 serverlistpage;
INT16 startmap; // Mario, NiGHTS, or just a plain old normal game?
menu_t *menudefs[NUMMENUTYPES] = {NULL}; // pointers to all menudefs
menu_t menudefs[MAXMENUTYPES]; // array of all menudefs
UINT16 nummenutypes;
menutype_t menustack[NUMMENULEVELS]; // stack of active menus, [0] == current menu
static menu_t *currentMenu; // current menudef
static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002
@ -237,8 +238,7 @@ static void Dummystaff_OnChange(void);
menuitem_t *M_CheckMenuItem(menutype_t type, const char *name)
{
INT16 i;
menu_t *menu = menudefs[type];
I_Assert(menu);
menu_t *menu = &menudefs[type];
for (i = 0; i < menu->numitems; i++)
if (!strncmp(menu->menuitems[i].itemname, name, ITEMNAMELEN))
@ -256,7 +256,7 @@ menuitem_t *M_GetMenuItem(menutype_t type, const char *name)
static INT16 M_GetMenuIndex(menutype_t type, const char *name)
{
return M_GetMenuItem(type, name) - menudefs[type]->menuitems;
return M_GetMenuItem(type, name) - menudefs[type].menuitems;
}
// an array of macros for getting/setting menuitem properties
@ -757,7 +757,7 @@ void Moviemode_option_Onchange(void)
// MENU PRESENTATION PARAMETER HANDLING (BACKGROUNDS)
// =========================================================================
menupres_t menupres[NUMMENUTYPES];
menupres_t menupres[MAXMENUTYPES];
void M_InitMenuPresTables(void)
{
@ -765,7 +765,7 @@ void M_InitMenuPresTables(void)
// Called in d_main before SOC can get to the tables
// Set menupres defaults
for (i = 0; i < NUMMENUTYPES; i++)
for (i = 0; i < MAXMENUTYPES; i++)
{
// so-called "undefined"
menupres[i].fadestrength = -1;
@ -1716,8 +1716,7 @@ void M_ClearMenus(boolean callexitmenufunc)
static void M_SetupNextMenu(menutype_t menunum, boolean callexit)
{
INT16 i;
menu_t *menudef = menudefs[menunum];
I_Assert(menudef);
menu_t *menudef = &menudefs[menunum];
// If you're going from a menu to itself, why are you running the quitroutine? You're not quitting it! -SH
if (callexit && currentMenu && currentMenu != menudef && currentMenu->quitroutine)
@ -4578,7 +4577,7 @@ void M_Options(INT32 choice)
M_SetItemStatus(MN_OP_GAME, "ENCORE", M_SecretUnlocked(SECRET_ENCORE) ? IT_CVAR|IT_STRING : IT_SECRET);
M_SetItemStatus(MN_OP_MAIN, "CUSTOM", !menudefs[MN_OP_CUSTOM]->numitems ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU);
M_SetItemStatus(MN_OP_MAIN, "CUSTOM", !menudefs[MN_OP_CUSTOM].numitems ? IT_GRAYEDOUT : IT_STRING|IT_SUBMENU);
M_EnterMenu(MN_OP_MAIN, true);
}
@ -6413,7 +6412,7 @@ void M_DrawConnectMenu(void)
UINT32 serversperpage = M_ServersPerPage(); // server sperpage?
INT32 numPages = (serverlistcount+(serversperpage-1))/serversperpage;
int waiting;
menu_t *conmenu = menudefs[MN_MP_CONNECT]; // meh, whatever
menu_t *conmenu = &menudefs[MN_MP_CONNECT]; // meh, whatever
for (i = firstserverline; i < firstserverline+serversperpage; i++)
conmenu->menuitems[i].status = IT_STRING | IT_SPACE;
@ -7177,8 +7176,8 @@ void M_DrawSetupMultiPlayerMenu(void)
char *fname;
INT16 i;
mx = menudefs[MN_MP_PLAYERSETUP]->x;
my = menudefs[MN_MP_PLAYERSETUP]->y;
mx = menudefs[MN_MP_PLAYERSETUP].x;
my = menudefs[MN_MP_PLAYERSETUP].y;
statx = (BASEVIDWIDTH - mx - 118);
staty = (my+62);
@ -7995,7 +7994,6 @@ UINT16 M_GetColorAfter(UINT16 color) {
void M_InitPlayerSetupColors(void) {
UINT16 i;
numskincolors = SKINCOLOR_FIRSTFREESLOT;
menucolorhead = menucolortail = NULL;
for (i=0; i<numskincolors; i++)
M_AddMenuColor(i);
@ -8092,7 +8090,7 @@ void M_DrawJoystick(void)
for (i = 0; i <= MAXGAMEPADS; i++)
{
M_DrawTextBox(menudefs[MN_OP_JOYSTICKSET]->x-8, menudefs[MN_OP_JOYSTICKSET]->y+LINEHEIGHT*i-12, 28, 1);
M_DrawTextBox(menudefs[MN_OP_JOYSTICKSET].x-8, menudefs[MN_OP_JOYSTICKSET].y+LINEHEIGHT*i-12, 28, 1);
#ifdef JOYSTICK_HOTPLUG
if (atoi(cv_usejoystick[setupcontrolplayer-1].string) > I_NumJoys())
@ -8101,7 +8099,7 @@ void M_DrawJoystick(void)
#endif
compareval = cv_usejoystick[setupcontrolplayer-1].value;
V_DrawString(menudefs[MN_OP_JOYSTICKSET]->x, menudefs[MN_OP_JOYSTICKSET]->y+LINEHEIGHT*i-4, ((i == compareval) ? V_GREENMAP : 0)|MENUCAPS, joystickInfo[i]);
V_DrawString(menudefs[MN_OP_JOYSTICKSET].x, menudefs[MN_OP_JOYSTICKSET].y+LINEHEIGHT*i-4, ((i == compareval) ? V_GREENMAP : 0)|MENUCAPS, joystickInfo[i]);
}
}
@ -8750,11 +8748,11 @@ void M_DrawVideoMode(void)
// draw title
M_DrawMenuTitle();
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y,
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y,
MENUCAPS|highlightflags, "Choose mode, reselect to change default");
row = 41;
col = menudefs[MN_OP_VIDEOMODE]->y + 14;
col = menudefs[MN_OP_VIDEOMODE].y + 14;
for (i = 0; i < vidm_nummodes; i++)
{
if (i == vidm_selected)
@ -8767,7 +8765,7 @@ void M_DrawVideoMode(void)
if ((i % vidm_column_size) == (vidm_column_size-1))
{
row += 7*13;
col = menudefs[MN_OP_VIDEOMODE]->y + 14;
col = menudefs[MN_OP_VIDEOMODE].y + 14;
}
}
@ -8775,40 +8773,40 @@ void M_DrawVideoMode(void)
{
INT32 testtime = (vidm_testingmode/TICRATE) + 1;
M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 116,
M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 116,
va("Previewing mode %c%dx%d",
(SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80,
vid.width, vid.height));
M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 138,
M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 138,
"Press ENTER again to keep this mode");
M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 150,
M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 150,
va("Wait %d second%s", testtime, (testtime > 1) ? "s" : ""));
M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 158,
M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 158,
"or press ESC to return");
}
else
{
M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 116,
M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 116,
va("Current mode is %c%dx%d",
(SCR_IsAspectCorrect(vid.width, vid.height)) ? 0x83 : 0x80,
vid.width, vid.height));
M_CentreText(menudefs[MN_OP_VIDEOMODE]->y + 124,
M_CentreText(menudefs[MN_OP_VIDEOMODE].y + 124,
va("Default mode is %c%dx%d",
(SCR_IsAspectCorrect(cv_scr_width.value, cv_scr_height.value)) ? 0x83 : 0x80,
cv_scr_width.value, cv_scr_height.value));
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 138,
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y + 138,
MENUCAPS|recommendedflags, "Marked modes are recommended.");
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 146,
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y + 146,
MENUCAPS|highlightflags, "Other modes may have visual errors.");
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE]->y + 158,
V_DrawCenteredString(BASEVIDWIDTH/2, menudefs[MN_OP_VIDEOMODE].y + 158,
MENUCAPS|highlightflags, "Larger modes may have performance issues.");
}
// Draw the cursor for the VidMode menu
i = 41 - 10 + ((vidm_selected / vidm_column_size)*7*13);
j = menudefs[MN_OP_VIDEOMODE]->y + 14 + ((vidm_selected % vidm_column_size)*8);
j = menudefs[MN_OP_VIDEOMODE].y + 14 + ((vidm_selected % vidm_column_size)*8);
V_DrawScaledPatch(i - 8, j, 0,
W_CachePatchName("M_CURSOR", PU_CACHE));

View file

@ -46,11 +46,9 @@ typedef enum
MN_FIRSTFREESLOT,
MN_LASTFREESLOT = MN_FIRSTFREESLOT + 128,
NUMMENUTYPES,
MAXMENUTYPES,
} menutype_t;
#define NUMMENUFREESLOTS (NUMMENUTYPES - MN_FIRSTFREESLOT)
extern menu_t *menudefs[NUMMENUTYPES];
extern menutype_t menustack[NUMMENULEVELS];
typedef struct
@ -85,7 +83,7 @@ typedef struct
INT16 exitwipe; // wipe type to run on menu exit, -1 means default
} menupres_t;
extern menupres_t menupres[NUMMENUTYPES];
extern menupres_t menupres[MAXMENUTYPES];
void M_InitMenuPresTables(void);
//UINT8 M_GetYoungestChildMenu(void);
@ -249,6 +247,7 @@ struct menuitem_t
struct menu_t
{
dehinfo_t info;
const char *headerpic;
INT16 numitems; // # of menu items
menuitem_t *menuitems; // menu items
@ -258,6 +257,9 @@ struct menu_t
void (*quitroutine)(INT32 choice); // called before quit a menu
};
extern menu_t menudefs[MAXMENUTYPES];
extern UINT16 nummenutypes;
void M_EnterMenu(menutype_t menu, boolean callexit);
void M_ExitMenu(void);
void M_ClearMenus(boolean callexitmenufunc);

View file

@ -1190,10 +1190,7 @@ static void P_WriteSkincolor(INT32 constant, char **target)
|| constant >= (INT32)numskincolors)
return;
if (constant >= SKINCOLOR_FIRSTFREESLOT)
color_name = FREE_SKINCOLORS[constant - SKINCOLOR_FIRSTFREESLOT];
else
color_name = COLOR_ENUMS[constant];
color_name = DEH_SkincolorName(constant);
P_WriteDuplicateText(
va("SKINCOLOR_%s", color_name),

View file

@ -263,13 +263,13 @@ static const char *MobjTypeName(const mobj_t *mobj)
if (p1 == (actionf_p1)P_MobjThinker)
{
return MOBJTYPE_LIST[mobj->type];
return DEH_MobjtypeName(mobj->type);
}
else if (p1 == (actionf_p1)P_RemoveThinkerDelayed)
{
if (mobj->thinker.debug_mobjtype != MT_NULL)
{
return MOBJTYPE_LIST[mobj->thinker.debug_mobjtype];
return DEH_MobjtypeName(mobj->thinker.debug_mobjtype);
}
}
@ -331,7 +331,7 @@ void P_RemoveThinkerDelayed(thinker_t *thinker)
else if ((thinker->debug_time + delay) <= leveltime)
{
CONS_Printf(
"PARANOIA/P_RemoveThinkerDelayed: %p %s references=%d\n",
"PARANOIA/P_RemoveThinkerDelayed: %p MT_%s references=%d\n",
(void*)thinker,
MobjTypeName((mobj_t*)thinker),
thinker->references
@ -423,7 +423,7 @@ mobj_t *P_SetTarget2(mobj_t **mop, mobj_t *targ
if ((*mop)->thinker.references < 0)
{
CONS_Printf(
"PARANOIA/P_SetTarget: %p %s %s references=%d, references go negative! (%s:%d)\n",
"PARANOIA/P_SetTarget: %p MT_%s %s references=%d, references go negative! (%s:%d)\n",
(void*)*mop,
MobjTypeName(*mop),
MobjThinkerName(*mop),

49
src/strbuf.c Normal file
View file

@ -0,0 +1,49 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Team BlanKart.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file strbuf.c
/// \brief string buffer library, for making chunks of many small strings
#include "doomdef.h"
#include "strbuf.h"
#include "z_zone.h"
#define STRBUF_BLOCKSIZE 16384 // 16K pages are the future, son!
// allocates and returns a new string buffer
// free with Z_Free
strbuf_t *strbuf_alloc(void)
{
strbuf_t *buf = Z_Malloc(STRBUF_BLOCKSIZE, PU_STATIC, NULL);
if (!buf)
I_Error("Failed to allocate string buffer");
buf->size = sizeof(UINT32);
return buf;
}
// appends a string to the buffer
// returns an offset to the newly appended string
UINT32 strbuf_append(strbuf_t **strbuf, const char *str)
{
strbuf_t *buf = *strbuf;
size_t addbytes = strlen(str) + 1;
UINT32 oldsize = buf->size;
buf->size += addbytes;
if ((oldsize % STRBUF_BLOCKSIZE) + addbytes >= STRBUF_BLOCKSIZE) {
UINT32 newsize = buf->size + STRBUF_BLOCKSIZE - (buf->size % STRBUF_BLOCKSIZE);
if (newsize <= oldsize)
I_Error("String buffer size wrapped around!?");
buf = *strbuf = Z_Realloc(buf, newsize, PU_STATIC, NULL);
if (!buf)
I_Error("Failed to allocate string buffer");
}
strcpy(buf->buf - sizeof(UINT32) + oldsize, str);
return oldsize;
}

38
src/strbuf.h Normal file
View file

@ -0,0 +1,38 @@
// BLANKART
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Team BlanKart.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file strbuf.h
/// \brief string buffer library, for making chunks of many small strings
#ifdef __cplusplus
extern "C" {
#endif
// for simplicity's sake, the header is included in the size (keeps the allocation aligned!)
struct strbuf_t
{
UINT32 size;
char buf[];
};
strbuf_t *strbuf_alloc(void);
UINT32 strbuf_append(strbuf_t **strbuf, const char *str);
// returns the string at the given offset
FUNCINLINE static ATTRINLINE char *strbuf_get(strbuf_t *strbuf, UINT32 ofs)
{
#ifdef __cplusplus
return reinterpret_cast<char *>(strbuf) + ofs;
#else
return (char *)strbuf + ofs;
#endif
}
#ifdef __cplusplus
}
#endif

View file

@ -88,6 +88,7 @@ TYPEDEF (ticcmd_t);
TYPEDEF (actionpointer_t);
// dehacked.h
TYPEDEF (dehinfo_t);
TYPEDEF (MYFILE);
// domdata.h
@ -393,6 +394,9 @@ TYPEDEF (vmode_t);
// sounds.h
TYPEDEF (sfxinfo_t);
// strbuf.h
TYPEDEF (strbuf_t);
// taglist.h
TYPEDEF (taglist_t);
TYPEDEF (taggroup_t);

View file

@ -1292,6 +1292,45 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
return INT16_MAX;
}
//
// Like W_CheckNumForLongNamePwad, but doesn't uppercase the search string AAAAAAAAAAAAA
//
UINT16 W_CheckNumForLongNamePwadNoUpper(const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 i;
char uname[8+1];
UINT32 hash;
if (!TestValidLump(wad,0))
return INT16_MAX;
strncpy(uname, name, sizeof uname);
strupr(uname);
hash = quickncasehash(uname, 8); // Not a mistake, legacy system for short lumpnames
//
// scan forward
// start at 'startlump', useful parameter when there are multiple
// resources with the same name
//
if (startlump < wadfiles[wad]->numlumps)
{
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (lump_p->hash != hash)
continue;
if (strcmp(lump_p->longname, name))
continue;
return i;
}
}
// not found.
return INT16_MAX;
}
UINT16
W_CheckNumForMarkerStartPwad (const char *name, UINT16 wad, UINT16 startlump)
{

View file

@ -169,6 +169,7 @@ UINT16 W_FindNextEmptyInPwad(UINT16 wad, UINT16 startlump); // checks only in on
UINT16 W_CheckNumForMapPwad(const char *name, UINT32 hash, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad
UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump);
UINT16 W_CheckNumForLongNamePwadNoUpper(const char *name, UINT16 wad, UINT16 startlump);
/* Find the first lump after F_START for instance. */
UINT16 W_CheckNumForMarkerStartPwad(const char *name, UINT16 wad, UINT16 startlump);