Refactor info table initialization

We SOCced this stuff ages ago, time to exploit it
Also fixes resetdata kek
This commit is contained in:
GenericHeroGuy 2025-05-14 17:28:41 +02:00
parent e3f8019b84
commit 1fa9a7cb8e
9 changed files with 156 additions and 179 deletions

View file

@ -1427,7 +1427,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();
@ -1443,9 +1443,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();

View file

@ -32,14 +32,6 @@ 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() {\
statenames = strbuf_alloc();\
mobjnames = strbuf_alloc();\
skincolornames = strbuf_alloc();\
menunames = strbuf_alloc();\
memset(used_spr,0,sizeof(UINT8) * ((NUMSPRITEFREESLOTS / 8) + 1));\
}
struct flickytypes_s {
const char *name;
const mobjtype_t type;

View file

@ -15,8 +15,6 @@
#include "deh_soc.h"
#include "deh_tables.h"
boolean deh_loaded = false;
boolean gamedataadded = false;
boolean titlechanged = false;
boolean introchanged = false;
@ -176,30 +174,6 @@ static void ignorelines(MYFILE *f)
Z_Free(s);
}
static const char *hardcodemobjs =
#define _(name, ...) #name "\0"
#include "info/mobjs.h"
#undef _
;
static const char *hardcodestates =
#define _(name, ...) #name "\0"
#include "info/states.h"
#undef _
;
static const char *hardcodeskincolors =
#define _(name, ...) #name "\0"
#include "info/skincolors.h"
#undef _
;
static const char *hardcodemenus =
#define _(name, ...) #name "\0"
#include "info/menus.h"
#undef _
;
static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
@ -208,28 +182,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
char *word2;
INT32 i;
if (!deh_loaded)
{
initfreeslots();
const char *name;
name = hardcodemobjs;
for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1)
mobjinfo[i].nameofs = strbuf_append(&mobjnames, name);
name = hardcodestates;
for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1)
states[i].nameofs = strbuf_append(&statenames, name);
name = hardcodeskincolors;
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1)
skincolors[i].nameofs = strbuf_append(&skincolornames, name);
name = hardcodemenus;
for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1)
menudefs[i].nameofs = strbuf_append(&menunames, name);
}
deh_num_warning = 0;
gamedataadded = titlechanged = introchanged = false;
@ -728,7 +680,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
}
}
deh_loaded = true;
Z_Free(s);
}

View file

@ -42,8 +42,6 @@ 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

@ -513,13 +513,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,16 +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 :^)
@ -90,126 +86,140 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {0};
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);
memset(&menudefs[MN_FIRSTFREESLOT], 0, sizeof (menu_t) * NUMMENUFREESLOTS);
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;
for (i = 0; i < NUMMENUTYPES; i++)
menudefs[i].drawroutine = M_DrawGenericMenu;
}
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));
if (statenames)
Z_Free(statenames);
statenames = strbuf_alloc();
name = hardcodestates;
for (i = 0; i < S_FIRSTFREESLOT; i++, name += strlen(name)+1)
states[i].nameofs = strbuf_append(&statenames, name);
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));
if (mobjnames)
Z_Free(mobjnames);
mobjnames = strbuf_alloc();
name = hardcodemobjs;
for (i = 0; i < MT_FIRSTFREESLOT; i++, name += strlen(name)+1)
mobjinfo[i].nameofs = strbuf_append(&mobjnames, name);
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));
if (skincolornames)
Z_Free(skincolornames);
skincolornames = strbuf_alloc();
name = hardcodeskincolors;
for (i = 0; i < SKINCOLOR_FIRSTFREESLOT; i++, name += strlen(name)+1)
skincolors[i].nameofs = strbuf_append(&skincolornames, name);
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[MN_FIRSTFREESLOT], 0, sizeof (menu_t) * NUMMENUFREESLOTS);
for (i = 0; i < NUMMENUTYPES; i++)
menudefs[i].drawroutine = M_DrawGenericMenu;
if (menunames)
Z_Free(menunames);
menunames = strbuf_alloc();
name = hardcodemenus;
for (i = 0; i < MN_FIRSTFREESLOT; i++, name += strlen(name)+1)
menudefs[i].nameofs = strbuf_append(&menunames, name);
}
#endif
}

View file

@ -139,10 +139,6 @@ struct mobjinfo_t
extern mobjinfo_t mobjinfo[NUMMOBJTYPES];
void P_PatchInfoTables(void);
void P_BackupTables(void);
void P_ResetData(INT32 flags);
#ifdef __cplusplus

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);