From de1f67b72a196bc228832ca848f54a34b03c36b0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 9 Apr 2021 21:10:46 -0400 Subject: [PATCH] Use strings in the map header for next level, marathon next, thumbnails, minimaps, encoremaps, and tweakmaps --- src/d_main.c | 15 ++- src/d_netcmd.c | 7 +- src/deh_lua.c | 28 +---- src/deh_soc.c | 314 ++++++++++------------------------------------ src/deh_soc.h | 7 +- src/dehacked.c | 22 +--- src/doomdef.h | 4 - src/doomstat.h | 147 ++++++++++++---------- src/f_finale.c | 8 +- src/g_demo.c | 1 + src/g_game.c | 51 ++++++-- src/k_hud.c | 7 +- src/lua_baselib.c | 65 ---------- src/lua_hudlib.c | 7 +- src/lua_maplib.c | 4 +- src/lua_script.c | 6 +- src/m_cond.c | 27 +++- src/m_cond.h | 2 +- src/m_menu.c | 44 +++++-- src/p_setup.c | 64 +++++++++- src/s_sound.c | 22 ---- src/s_sound.h | 6 - src/y_inter.c | 8 +- 23 files changed, 355 insertions(+), 511 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c623a0097..9f87bb59c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1594,13 +1594,18 @@ void D_SRB2Main(void) // rei/miru: bootmap (Idea: starts the game on a predefined map) if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm())) { - pstartmap = bootmap; + const INT32 bootMapNum = G_MapNumber(bootmap); - if (pstartmap < 1 || pstartmap > NUMMAPS) - I_Error("Cannot warp to map %d (out of range)\n", pstartmap); - else + if (mapheaderinfo[bootMapNum]) { - autostart = true; + pstartmap = bootMapNum; + + if (pstartmap < 1 || pstartmap > NUMMAPS) + I_Error("Cannot warp to map %d (out of range)\n", pstartmap); + else + { + autostart = true; + } } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index fbf205479..b56c6e18b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2791,6 +2791,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) INT32 resetplayer = 1, lastgametype; UINT8 skipprecutscene, FLS; boolean pencoremode; + INT16 mapnumber; forceresetplayers = deferencoremode = false; @@ -2848,13 +2849,13 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) memset(&luabanks, 0, sizeof(luabanks)); } + demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING; + demo.savebutton = 0; + // Sal: Is this needed? // From experimenting with Lua scripts in vanilla I found a lot of annoying & potentially desync-y things with MapChange. LUAh_MapChange(mapnumber); - demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING; - demo.savebutton = 0; - G_InitNew(pencoremode, mapnumber, resetplayer, skipprecutscene, FLS); if (demo.playback && !demo.timing) precache = true; diff --git a/src/deh_lua.c b/src/deh_lua.c index c36ebc034..2154a1416 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -24,10 +24,7 @@ #include "dehacked.h" #include "deh_lua.h" #include "deh_tables.h" - -#ifdef MUSICSLOT_COMPATIBILITY -#include "deh_soc.h" // for get_mus -#endif +#include "deh_soc.h" // freeslotusage // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. @@ -422,29 +419,6 @@ static inline int lib_getenum(lua_State *L) if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word); return 0; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (!mathlib && fastncmp("mus_",word,4)) { - p = word+4; - if ((i = get_mus(p, false)) == 0) - return 0; - lua_pushinteger(L, i); - return 1; - } - else if (mathlib && fastncmp("MUS_",word,4)) { // SOCs are ALL CAPS! - p = word+4; - if ((i = get_mus(p, false)) == 0) - return luaL_error(L, "music '%s' could not be found.\n", word); - lua_pushinteger(L, i); - return 1; - } - else if (mathlib && (fastncmp("O_",word,2) || fastncmp("D_",word,2))) { - p = word+2; - if ((i = get_mus(p, false)) == 0) - return luaL_error(L, "music '%s' could not be found.\n", word); - lua_pushinteger(L, i); - return 1; - } -#endif else if (!mathlib && fastncmp("pw_",word,3)) { p = word+3; for (i = 0; i < NUMPOWERS; i++) diff --git a/src/deh_soc.c b/src/deh_soc.c index c6ad81b7b..774f5ffed 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -152,7 +152,10 @@ void clear_levels(void) // we may as well try to save some memory, right? for (i = 0; i < NUMMAPS; ++i) { - if (!mapheaderinfo[i] || i == (tutorialmap-1)) + if (!mapheaderinfo[i]) + continue; + + if (strcmp(mapheaderinfo[i]->lumpname, tutorialmap) == 0) // Sal: Is this needed...? continue; // Custom map header info @@ -1256,18 +1259,38 @@ void readgametype(MYFILE *f, char *gtname) CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]); } -void readlevelheader(MYFILE *f, INT32 num) +void readlevelheader(MYFILE *f, char * name) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word; char *word2; //char *word3; // Non-uppercase version of word2 + char *tmp; INT32 i; + const INT32 num = G_MapNumber(name); + + if (num > NUMMAPS) + { + I_Error("Too many maps!"); + } + + if (f->wad > mainwads && num <= nummapheaders) + { + // only mark as a major mod if it replaces an already-existing mapheaderinfo + G_SetGameModified(multiplayer, true); + } + // Reset all previous map header information P_AllocMapHeader((INT16)(num-1)); + if (mapheaderinfo[num-1]->lumpname == NULL) + { + mapheaderinfo[num-1]->lumpname = Z_StrDup(name); + } + do { if (myfgets(s, MAXLINELEN, f)) @@ -1434,6 +1457,30 @@ void readlevelheader(MYFILE *f, INT32 num) } // Strings that can be truncated + else if (fastcmp(word, "THUMBNAIL")) + { + mapheaderinfo[num-1]->thumbnailLump = Z_StrDup(word2); + } + else if (fastcmp(word, "MINIMAP")) + { + mapheaderinfo[num-1]->minimapLump = Z_StrDup(word2); + } + else if (fastcmp(word, "ENCOREMAP")) + { + mapheaderinfo[num-1]->encoreLump = Z_StrDup(word2); + } + else if (fastcmp(word, "TWEAKMAP")) + { + mapheaderinfo[num-1]->tweakLump = Z_StrDup(word2); + } + else if (fastcmp(word, "NEXTLEVEL")) + { + mapheaderinfo[num-1]->nextlevel = Z_StrDup(word2); + } + else if (fastcmp(word, "MARATHONNEXT")) + { + mapheaderinfo[num-1]->marathonnext = Z_StrDup(word2); + } else if (fastcmp(word, "ZONETITLE")) { deh_strlcpy(mapheaderinfo[num-1]->zonttl, word2, @@ -1456,38 +1503,6 @@ void readlevelheader(MYFILE *f, INT32 num) else deh_warning("Level header %d: invalid act number %d", num, i); } - else if (fastcmp(word, "NEXTLEVEL")) - { - if (fastcmp(word2, "TITLE")) i = 1100; - else if (fastcmp(word2, "EVALUATION")) i = 1101; - else if (fastcmp(word2, "CREDITS")) i = 1102; - else if (fastcmp(word2, "ENDING")) i = 1103; - else - // Support using the actual map name, - // i.e., Nextlevel = AB, Nextlevel = FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0') - i = M_MapNumber(word2[0], word2[1]); - - mapheaderinfo[num-1]->nextlevel = (INT16)i; - } - else if (fastcmp(word, "MARATHONNEXT")) - { - if (fastcmp(word2, "TITLE")) i = 1100; - else if (fastcmp(word2, "EVALUATION")) i = 1101; - else if (fastcmp(word2, "CREDITS")) i = 1102; - else if (fastcmp(word2, "ENDING")) i = 1103; - else - // Support using the actual map name, - // i.e., MarathonNext = AB, MarathonNext = FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0') - i = M_MapNumber(word2[0], word2[1]); - - mapheaderinfo[num-1]->marathonnext = (INT16)i; - } else if (fastcmp(word, "TYPEOFLEVEL")) { if (i) // it's just a number @@ -1522,19 +1537,6 @@ void readlevelheader(MYFILE *f, INT32 num) sizeof(mapheaderinfo[num-1]->musname), va("Level header %d: music", num)); } } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - i = get_mus(word2, true); - if (i && i <= 1035) - snprintf(mapheaderinfo[num-1]->musname, 7, "%sM", G_BuildMapName(i)); - else if (i && i <= 1050) - strncpy(mapheaderinfo[num-1]->musname, compat_special_music_slots[i - 1036], 7); - else - mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string - mapheaderinfo[num-1]->musname[6] = 0; - } -#endif else if (fastcmp(word, "MUSICTRACK")) mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1); else if (fastcmp(word, "MUSICPOS")) @@ -1777,19 +1779,6 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7); cutscenes[num]->scene[scenenum].musswitch[6] = 0; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - i = get_mus(word2, true); - if (i && i <= 1035) - snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i)); - else if (i && i <= 1050) - strncpy(cutscenes[num]->scene[scenenum].musswitch, compat_special_music_slots[i - 1036], 7); - else - cutscenes[num]->scene[scenenum].musswitch[0] = 0; // becomes empty string - cutscenes[num]->scene[scenenum].musswitch[6] = 0; - } -#endif else if (fastcmp(word, "MUSICTRACK")) { cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; @@ -2052,19 +2041,6 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7); textprompts[num]->page[pagenum].musswitch[6] = 0; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - i = get_mus(word2, true); - if (i && i <= 1035) - snprintf(textprompts[num]->page[pagenum].musswitch, 7, "%sM", G_BuildMapName(i)); - else if (i && i <= 1050) - strncpy(textprompts[num]->page[pagenum].musswitch, compat_special_music_slots[i - 1036], 7); - else - textprompts[num]->page[pagenum].musswitch[0] = 0; // becomes empty string - textprompts[num]->page[pagenum].musswitch[6] = 0; - } -#endif else if (fastcmp(word, "MUSICTRACK")) { textprompts[num]->page[pagenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; @@ -2388,20 +2364,6 @@ void readmenu(MYFILE *f, INT32 num) menupres[num].musname[6] = 0; titlechanged = true; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastcmp(word, "MUSICSLOT")) - { - value = get_mus(word2, true); - if (value && value <= 1035) - snprintf(menupres[num].musname, 7, "%sM", G_BuildMapName(value)); - else if (value && value <= 1050) - strncpy(menupres[num].musname, compat_special_music_slots[value - 1036], 7); - else - menupres[num].musname[0] = 0; // becomes empty string - menupres[num].musname[6] = 0; - titlechanged = true; - } -#endif else if (fastcmp(word, "MUSICTRACK")) { menupres[num].mustrack = ((UINT16)value - 1); @@ -2794,14 +2756,7 @@ void reademblemdata(MYFILE *f, INT32 num) emblemlocations[num-1].tag = (INT16)value; else if (fastcmp(word, "MAPNUM")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - - emblemlocations[num-1].level = (INT16)value; + emblemlocations[num-1].level = Z_StrDup(word2); } else if (fastcmp(word, "SPRITE")) { @@ -3022,13 +2977,7 @@ void readunlockable(MYFILE *f, INT32 num) } else if (fastcmp(word, "VAR")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - i = M_MapNumber(word2[0], word2[1]); - + // TODO: different field for level name string unlockables[num].variable = (INT16)i; } else @@ -3107,12 +3056,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) { PARAMCHECK(1); ty = UC_MAPVISITED + offset; - - // Convert to map number if it appears to be one - if (params[1][0] >= 'A' && params[1][0] <= 'Z') - re = M_MapNumber(params[1][0], params[1][1]); - else - re = atoi(params[1]); + re = G_MapNumber(params[1]); if (re < 0 || re >= NUMMAPS) { @@ -3125,12 +3069,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) PARAMCHECK(2); ty = UC_MAPTIME; re = atoi(params[2]); - - // Convert to map number if it appears to be one - if (params[1][0] >= 'A' && params[1][0] <= 'Z') - x1 = (INT16)M_MapNumber(params[1][0], params[1][1]); - else - x1 = (INT16)atoi(params[1]); + x1 = G_MapNumber(params[1]); if (x1 < 0 || x1 >= NUMMAPS) { @@ -3333,56 +3272,23 @@ void readmaincfg(MYFILE *f) else if (fastcmp(word, "SPSTAGE_START")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - else - value = get_number(word2); - - spstage_start = spmarathon_start = (INT16)value; + // TODO: Use map name string + // Haven't done it because of how special stage ends are handled + // Though, we likely won't be using these for Kart anyhow + spstage_start = spmarathon_start = (INT16)G_MapNumber(word2); } else if (fastcmp(word, "SPMARATHON_START")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - else - value = get_number(word2); - - spmarathon_start = (INT16)value; + spmarathon_start = (INT16)G_MapNumber(word2); } else if (fastcmp(word, "SSTAGE_START")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - else - value = get_number(word2); - - sstage_start = (INT16)value; + sstage_start = (INT16)G_MapNumber(word2); sstage_end = (INT16)(sstage_start+7); // 7 special stages total plus one weirdo } else if (fastcmp(word, "SMPSTAGE_START")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - else - value = get_number(word2); - - smpstage_start = (INT16)value; + smpstage_start = (INT16)G_MapNumber(word2); smpstage_end = (INT16)(smpstage_start+6); // 7 special stages total } else if (fastcmp(word, "REDTEAM")) @@ -3467,16 +3373,7 @@ void readmaincfg(MYFILE *f) } else if (fastcmp(word, "TITLEMAP")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - else - value = get_number(word2); - - titlemap = (INT16)value; + titlemap = Z_StrDup(word2); titlechanged = true; } else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "TITLEPICSHIDE")) @@ -3606,30 +3503,12 @@ void readmaincfg(MYFILE *f) } else if (fastcmp(word, "BOOTMAP")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - else - value = get_number(word2); - - bootmap = (INT16)value; + bootmap = Z_StrDup(word2); //titlechanged = true; } else if (fastcmp(word, "TUTORIALMAP")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - value = M_MapNumber(word2[0], word2[1]); - else - value = get_number(word2); - - tutorialmap = (INT16)value; + tutorialmap = Z_StrDup(word2); } else deh_warning("Maincfg: unknown word '%s'", word); @@ -3852,37 +3731,23 @@ void readcupheader(MYFILE *f, cupheader_t *cup) tmp = strtok(word2,","); do { - INT32 map = atoi(tmp); - - if (tmp[0] >= 'A' && tmp[0] <= 'Z' && tmp[2] == '\0') - map = M_MapNumber(tmp[0], tmp[1]); - - if (!map) - break; - if (cup->numlevels >= MAXLEVELLIST) { deh_warning("%s Cup: reached max levellist (%d)\n", cup->name, MAXLEVELLIST); break; } - cup->levellist[cup->numlevels] = map - 1; + cup->levellist[cup->numlevels] = Z_StrDup(word2); cup->numlevels++; } while((tmp = strtok(NULL,",")) != NULL); } else if (fastcmp(word, "BONUSGAME")) { - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0') - i = M_MapNumber(word2[0], word2[1]); - cup->bonusgame = (INT16)i - 1; + cup->bonusgame = Z_StrDup(word2); } else if (fastcmp(word, "SPECIALSTAGE")) { - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0') - i = M_MapNumber(word2[0], word2[1]); - cup->specialstage = (INT16)i - 1; + cup->specialstage = Z_StrDup(word2); } else if (fastcmp(word, "EMERALDNUM")) { @@ -4257,46 +4122,6 @@ sfxenum_t get_sfx(const char *word) return sfx_None; } -#ifdef MUSICSLOT_COMPATIBILITY -UINT16 get_mus(const char *word, UINT8 dehacked_mode) -{ // Returns the value of MUS_ enumerations - UINT16 i; - char lumptmp[4]; - - if (*word >= '0' && *word <= '9') - return atoi(word); - if (!word[2] && toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z') - return (UINT16)M_MapNumber(word[0], word[1]); - - if (fastncmp("MUS_",word,4)) - word += 4; // take off the MUS_ - else if (fastncmp("O_",word,2) || fastncmp("D_",word,2)) - word += 2; // take off the O_ or D_ - - strncpy(lumptmp, word, 4); - lumptmp[3] = 0; - if (fasticmp("MAP",lumptmp)) - { - word += 3; - if (toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z') - return (UINT16)M_MapNumber(word[0], word[1]); - else if ((i = atoi(word))) - return i; - - word -= 3; - if (dehacked_mode) - deh_warning("Couldn't find music named 'MUS_%s'",word); - return 0; - } - for (i = 0; compat_special_music_slots[i][0]; ++i) - if (fasticmp(word, compat_special_music_slots[i])) - return i + 1036; - if (dehacked_mode) - deh_warning("Couldn't find music named 'MUS_%s'",word); - return 0; -} -#endif - hudnum_t get_huditem(const char *word) { // Returns the value of HUD_ enumerations hudnum_t i; @@ -4527,13 +4352,6 @@ static fixed_t find_const(const char **rword) free(word); return r; } -#ifdef MUSICSLOT_COMPATIBILITY - else if (fastncmp("MUS_",word,4) || fastncmp("O_",word,2)) { - r = get_mus(word, true); - free(word); - return r; - } -#endif else if (fastncmp("PW_",word,3)) { r = get_power(word); free(word); diff --git a/src/deh_soc.h b/src/deh_soc.h index ee518c55b..cdc75975d 100644 --- a/src/deh_soc.h +++ b/src/deh_soc.h @@ -43,7 +43,7 @@ #include "info.h" #include "dehacked.h" -#include "doomdef.h" // MUSICSLOT_COMPATIBILITY, HWRENDER +#include "doomdef.h" // HWRENDER // Crazy word-reading stuff /// \todo Put these in a seperate file or something. @@ -52,9 +52,6 @@ statenum_t get_state(const char *word); spritenum_t get_sprite(const char *word); playersprite_t get_sprite2(const char *word); sfxenum_t get_sfx(const char *word); -#ifdef MUSICSLOT_COMPATIBILITY -UINT16 get_mus(const char *word, UINT8 dehacked_mode); -#endif hudnum_t get_huditem(const char *word); menutype_t get_menutype(const char *word); //INT16 get_gametype(const char *word); @@ -73,7 +70,7 @@ void readhuditem(MYFILE *f, INT32 num); void readmenu(MYFILE *f, INT32 num); void readtextprompt(MYFILE *f, INT32 num); void readcutscene(MYFILE *f, INT32 num); -void readlevelheader(MYFILE *f, INT32 num); +void readlevelheader(MYFILE *f, char * name); void readgametype(MYFILE *f, char *gtname); void readsprite2(MYFILE *f, INT32 num); void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2); diff --git a/src/dehacked.c b/src/dehacked.c index 9b81a7c13..c4c15efd1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -400,27 +400,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) } else if (fastcmp(word, "LEVEL")) { - // Support using the actual map name, - // i.e., Level AB, Level FZ, etc. - - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z') - i = M_MapNumber(word2[0], word2[1]); - - if (i > 0 && i <= NUMMAPS) - { - if (mapheaderinfo[i]) - { - G_SetGameModified(multiplayer, true); // Only a major mod if editing stuff that isn't your own! - } - - readlevelheader(f, i); - } - else - { - deh_warning("Level number %d out of range (1 - %d)", i, NUMMAPS); - ignorelines(f); - } + readlevelheader(f, word2); } else if (fastcmp(word, "GAMETYPE")) { diff --git a/src/doomdef.h b/src/doomdef.h index e0bd46ab8..0907df0ac 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -628,10 +628,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) //#define REDSANALOG -/// Backwards compatibility with musicslots. -/// \note You should leave this enabled unless you're working with a future SRB2 version. -//#define MUSICSLOT_COMPATIBILITY - /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. //#define PAPER_COLLISIONCORRECTION diff --git a/src/doomstat.h b/src/doomstat.h index 0854b3196..6169e8b0e 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -177,11 +177,11 @@ extern boolean splitscreen_partied[MAXPLAYERS]; extern INT16 spstage_start, spmarathon_start; extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; -extern INT16 titlemap; +extern char * titlemap; extern boolean hidetitlepics; -extern INT16 bootmap; //bootmap for loading a map on startup +extern char * bootmap; //bootmap for loading a map on startup -extern INT16 tutorialmap; // map to load for tutorial +extern char * tutorialmap; // map to load for tutorial extern boolean tutorialmode; // are we in a tutorial right now? extern INT32 tutorialgcs; // which control scheme is loaded? @@ -326,81 +326,100 @@ typedef struct */ typedef struct { - char * lumpname; ///< Lump name can be really long - char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) - char subttl[33]; ///< Subtitle for level - char zonttl[22]; ///< "ZONE" replacement name - UINT8 actnum; ///< Act number or 0 for none. - UINT32 typeoflevel; ///< Combination of typeoflevel flags. - INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. - INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI. - char keywords[33]; ///< Keywords separated by space to search for. 32 characters. - char musname[7]; ///< Music track to play. "" for no music. - UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. - UINT32 muspos; ///< Music position to jump to. - char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. - UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. - char skytexture[9]; ///< Sky texture to use. - INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.) - INT16 skybox_scaley; ///< Skybox Y axis scale. - INT16 skybox_scalez; ///< Skybox Z axis scale. + char * lumpname; ///< Lump name can be really long + + char * thumbnailLump; ///< Lump name for the level select thumbnail. + char * minimapLump; ///< Lump name for the minimap graphic. + char * encoreLump; ///< Lump name for the Encore Mode remap. + char * tweakLump; ///< Lump name for the palette tweak remap. + + char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) + char subttl[33]; ///< Subtitle for level + char zonttl[22]; ///< "ZONE" replacement name + UINT8 actnum; ///< Act number or 0 for none. + + UINT32 typeoflevel; ///< Combination of typeoflevel flags. + + char * nextlevel; ///< Map name of next level. + char * marathonnext; ///< See nextlevel, but for Marathon mode. + + char keywords[33]; ///< Keywords separated by space to search for. 32 characters. + + char musname[7]; ///< Music track to play. "" for no music. + UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. + UINT32 muspos; ///< Music position to jump to. + + char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. + + UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. + char skytexture[9]; ///< Sky texture to use. + INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.) + INT16 skybox_scaley; ///< Skybox Y axis scale. + INT16 skybox_scalez; ///< Skybox Z axis scale. // Extra information. - char interscreen[8]; ///< 320x200 patch to display at intermission. - char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63) - char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191) - UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts. - UINT8 cutscenenum; ///< Cutscene number to use, 0 for none. - INT16 countdown; ///< Countdown until level end? - UINT16 palette; ///< PAL lump to use on this map - UINT16 encorepal; ///< PAL for encore mode - UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden. - SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no. - UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in? - SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.) - SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.) + char interscreen[8]; ///< 320x200 patch to display at intermission. - UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below - UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus + char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63) + char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191) - char selectheading[22]; ///< Level select heading. Allows for controllable grouping. - UINT16 startrings; ///< Number of rings players start with. - INT32 sstimer; ///< Timer for special stages. - UINT32 ssspheres; ///< Sphere requirement in special stages. - fixed_t gravity; ///< Map-wide gravity. + UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts. + UINT8 cutscenenum; ///< Cutscene number to use, 0 for none. + + INT16 countdown; ///< Countdown until level end? + + UINT16 palette; ///< PAL lump to use on this map + UINT16 encorepal; ///< PAL for encore mode + + UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden. + + SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no. + UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in? + + SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.) + SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.) + + UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below + UINT16 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus + + char selectheading[22]; ///< Level select heading. Allows for controllable grouping. + UINT16 startrings; ///< Number of rings players start with. + INT32 sstimer; ///< Timer for special stages. + UINT32 ssspheres; ///< Sphere requirement in special stages. + fixed_t gravity; ///< Map-wide gravity. // Title card. - char ltzzpatch[8]; ///< Zig zag patch. - char ltzztext[8]; ///< Zig zag text. - char ltactdiamond[8]; ///< Act diamond. + char ltzzpatch[8]; ///< Zig zag patch. + char ltzztext[8]; ///< Zig zag text. + char ltactdiamond[8]; ///< Act diamond. // Freed animals stuff. - UINT8 numFlickies; ///< Internal. For freed flicky support. - mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful. + UINT8 numFlickies; ///< Internal. For freed flicky support. + mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful. // NiGHTS stuff. - UINT8 numGradedMares; ///< Internal. For grade support. - nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. - - // SRB2kart - fixed_t mobj_scale; ///< Replacement for TOL_ERZ3 - fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale + UINT8 numGradedMares; ///< Internal. For grade support. + nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. // Music stuff. - UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds - char musintername[7]; ///< Intermission screen music. + UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds + char musintername[7]; ///< Intermission screen music. - char muspostbossname[7]; ///< Post-bossdeath music. - UINT16 muspostbosstrack; ///< Post-bossdeath track. - UINT32 muspostbosspos; ///< Post-bossdeath position - UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds. + char muspostbossname[7]; ///< Post-bossdeath music. + UINT16 muspostbosstrack; ///< Post-bossdeath track. + UINT32 muspostbosspos; ///< Post-bossdeath position + UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds. - SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on) + SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on) + + // SRB2kart + fixed_t mobj_scale; ///< Replacement for TOL_ERZ3 + fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale // Lua stuff. // (This is not ifdeffed so the map header structure can stay identical, just in case.) - UINT8 numCustomOptions; ///< Internal. For Lua custom value support. - customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. + UINT8 numCustomOptions; ///< Internal. For Lua custom value support. + customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. } mapheader_t; // level flags @@ -426,10 +445,10 @@ typedef struct cupheader_s UINT16 id; ///< Cup ID char name[15]; ///< Cup title (14 chars) char icon[9]; ///< Name of the icon patch - INT16 levellist[MAXLEVELLIST]; ///< List of levels that belong to this cup + char * levellist[MAXLEVELLIST]; ///< List of levels that belong to this cup UINT8 numlevels; ///< Number of levels defined in levellist - INT16 bonusgame; ///< Map number to use for bonus game - INT16 specialstage; ///< Map number to use for special stage + char * bonusgame; ///< Map number to use for bonus game + char * specialstage; ///< Map number to use for special stage UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald) SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required. struct cupheader_s *next; ///< Next cup in linked list diff --git a/src/f_finale.c b/src/f_finale.c index bfea19d24..f3e26c97c 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1812,6 +1812,8 @@ static void F_CacheTitleScreen(void) void F_StartTitleScreen(void) { + const INT32 titleMapNum = G_MapNumber(titlemap); + if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) { ttuser_count = 0; @@ -1821,20 +1823,20 @@ void F_StartTitleScreen(void) else wipegamestate = GS_TITLESCREEN; - if (titlemap) + if (mapheaderinfo[titleMapNum]) { mapthing_t *startpos; gamestate_t prevwipegamestate = wipegamestate; titlemapinaction = TITLEMAP_LOADING; titlemapcameraref = NULL; - gamemap = titlemap; + gamemap = titleMapNum; maptol = mapheaderinfo[gamemap-1]->typeoflevel; globalweather = mapheaderinfo[gamemap-1]->weather; G_DoLoadLevel(true); - if (!titlemap) + if (!titleMapNum) return; players[displayplayers[0]].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater) diff --git a/src/g_demo.c b/src/g_demo.c index 46e814634..b0f3c7a01 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -3467,6 +3467,7 @@ void G_DoPlayMetal(void) thinker_t *th; // it's an internal demo + // TODO: Use map header to determine lump name if ((l = W_CheckNumForName(va("%sMS",G_BuildMapName(gamemap)))) == LUMPERROR) { CONS_Alert(CONS_WARNING, M_GetText("No bot recording for this map.\n")); diff --git a/src/g_game.c b/src/g_game.c index d05266cd0..8589c4ebf 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -149,11 +149,11 @@ tic_t timeinmap; // Ticker for time spent in level (used for levelcard display) INT16 spstage_start, spmarathon_start; INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; -INT16 titlemap = 0; +char * titlemap = NULL; boolean hidetitlepics = false; -INT16 bootmap; //bootmap for loading a map on startup +char * bootmap = NULL; //bootmap for loading a map on startup -INT16 tutorialmap = 0; // map to load for tutorial +char * tutorialmap = NULL; // map to load for tutorial boolean tutorialmode = false; // are we in a tutorial right now? INT32 tutorialgcs = gcs_custom; // which control scheme is loaded? @@ -3340,6 +3340,7 @@ tryagain: if (pprevmap == -2) // title demo hack { lumpnum_t l; + // TODO: Use map header to determine lump name if ((l = W_CheckNumForLongName(va("%sS01",G_BuildMapName(ix+1)))) == LUMPERROR) continue; } @@ -3529,7 +3530,12 @@ static void G_DoCompleted(void) } else if (marathonmode && mapheaderinfo[gamemap-1]->marathonnext) { - nextmap = (INT16)(mapheaderinfo[gamemap-1]->marathonnext-1); + const INT32 mNextNum = G_MapNumber(mapheaderinfo[gamemap-1]->marathonnext); + + if (mapheaderinfo[mNextNum]) + { + nextmap = (INT16)(mNextNum-1); + } } else if (grandprixinfo.gp == true) { @@ -3546,16 +3552,27 @@ static void G_DoCompleted(void) else { // Proceed to next map - nextmap = grandprixinfo.cup->levellist[grandprixinfo.roundnum]; + const INT32 cupLevelNum = G_MapNumber(grandprixinfo.cup->levellist[grandprixinfo.roundnum]); + + if (mapheaderinfo[cupLevelNum]) + { + nextmap = cupLevelNum; + } + grandprixinfo.roundnum++; } } } else { - nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1); - if (marathonmode && nextmap == spmarathon_start-1) - nextmap = 1100-1; // No infinite loop for you + const INT32 nextNum = G_MapNumber(mapheaderinfo[gamemap-1]->nextlevel); + + if (mapheaderinfo[nextNum]) + { + nextmap = (INT16)(nextNum-1); + if (marathonmode && nextmap == spmarathon_start-1) + nextmap = 1100-1; // No infinite loop for you + } } // Remember last map for when you come out of the special stage. @@ -3582,9 +3599,23 @@ static void G_DoCompleted(void) if (!mapheaderinfo[cm]) cm = -1; // guarantee error execution else if (marathonmode && mapheaderinfo[cm]->marathonnext) - cm = (INT16)(mapheaderinfo[cm]->marathonnext-1); + { + const INT32 mNextNum = G_MapNumber(mapheaderinfo[gamemap-1]->marathonnext); + + if (!mapheaderinfo[mNextNum]) + cm = -1; // guarantee error execution + else + cm = (INT16)(mNextNum-1); + } else - cm = (INT16)(mapheaderinfo[cm]->nextlevel-1); + { + const INT32 nextNum = G_MapNumber(mapheaderinfo[gamemap-1]->nextlevel); + + if (!mapheaderinfo[nextNum]) + cm = -1; // guarantee error execution + else + cm = (INT16)(nextNum-1); + } if (cm >= NUMMAPS || cm < 0) // out of range (either 1100ish or error) { diff --git a/src/k_hud.c b/src/k_hud.c index 6bf9b153b..1f2465152 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3015,7 +3015,7 @@ static void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx, INT32 static void K_drawKartMinimap(void) { - INT32 lumpnum; + INT32 lumpnum = LUMPERROR; patch_t *AutomapPic; INT32 i = 0; INT32 x, y; @@ -3037,7 +3037,10 @@ static void K_drawKartMinimap(void) if (stplyr != &players[displayplayers[0]]) return; - lumpnum = W_CheckNumForLongName(va("%sR", G_BuildMapName(gamemap))); + if (mapheaderinfo[gamemap-1]) + { + lumpnum = W_CheckNumForLongName(mapheaderinfo[gamemap-1]->minimapLump); + } if (lumpnum != -1) AutomapPic = W_CachePatchNum(lumpnum, PU_HUDGFX); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index eb2411f20..4ccb4b841 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2435,39 +2435,6 @@ static int lib_sStopSoundByID(lua_State *L) static int lib_sChangeMusic(lua_State *L) { -#ifdef MUSICSLOT_COMPATIBILITY - const char *music_name; - UINT32 music_num, position, prefadems, fadeinms; - char music_compat_name[7]; - - boolean looping; - player_t *player = NULL; - UINT16 music_flags = 0; - //NOHUD - - if (lua_isnumber(L, 1)) - { - music_num = (UINT32)luaL_checkinteger(L, 1); - music_flags = (UINT16)(music_num & 0x0000FFFF); - if (music_flags && music_flags <= 1035) - snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags)); - else if (music_flags && music_flags <= 1050) - strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7); - else - music_compat_name[0] = 0; // becomes empty string - music_compat_name[6] = 0; - music_name = (const char *)&music_compat_name; - music_flags = 0; - } - else - { - music_num = 0; - music_name = luaL_checkstring(L, 1); - } - - looping = (boolean)lua_opttrueboolean(L, 2); - -#else const char *music_name = luaL_checkstring(L, 1); UINT32 position, prefadems, fadeinms; boolean looping = (boolean)lua_opttrueboolean(L, 2); @@ -2475,7 +2442,6 @@ static int lib_sChangeMusic(lua_State *L) UINT16 music_flags = 0; //NOHUD -#endif if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) { player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); @@ -2483,11 +2449,6 @@ static int lib_sChangeMusic(lua_State *L) return LUA_ErrInvalid(L, "player_t"); } -#ifdef MUSICSLOT_COMPATIBILITY - if (music_num) - music_flags = (UINT16)((music_num & 0x7FFF0000) >> 16); - else -#endif music_flags = (UINT16)luaL_optinteger(L, 4, 0); position = (UINT32)luaL_optinteger(L, 5, 0); @@ -2593,33 +2554,7 @@ static int lib_sMusicName(lua_State *L) static int lib_sMusicExists(lua_State *L) { -#ifdef MUSICSLOT_COMPATIBILITY - const char *music_name; - UINT32 music_num; - char music_compat_name[7]; - UINT16 music_flags = 0; - NOHUD - if (lua_isnumber(L, 1)) - { - music_num = (UINT32)luaL_checkinteger(L, 1); - music_flags = (UINT16)(music_num & 0x0000FFFF); - if (music_flags && music_flags <= 1035) - snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags)); - else if (music_flags && music_flags <= 1050) - strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7); - else - music_compat_name[0] = 0; // becomes empty string - music_compat_name[6] = 0; - music_name = (const char *)&music_compat_name; - } - else - { - music_num = 0; - music_name = luaL_checkstring(L, 1); - } -#else const char *music_name = luaL_checkstring(L, 1); -#endif NOHUD lua_pushboolean(L, S_MusicExists(music_name)); return 1; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 78f273311..3610e54c7 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -652,7 +652,7 @@ static int libd_drawOnMinimap(lua_State *L) boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates. // variables used to replicate k_kart's mmap drawer: - INT32 lumpnum; + INT32 lumpnum = LUMPERROR; patch_t *AutomapPic; INT32 mx, my; INT32 splitflags, minimaptrans; @@ -738,7 +738,10 @@ static int libd_drawOnMinimap(lua_State *L) if (stplyr != &players[displayplayers[0]]) return 0; - lumpnum = W_CheckNumForLongName(va("%sR", G_BuildMapName(gamemap))); + if (mapheaderinfo[gamemap-1]) + { + lumpnum = W_CheckNumForLongName(mapheaderinfo[gamemap-1]->minimapLump); + } if (lumpnum != -1) AutomapPic = W_CachePatchNum(lumpnum, PU_HUDGFX); diff --git a/src/lua_maplib.c b/src/lua_maplib.c index e537160da..ec5f18127 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2128,9 +2128,9 @@ static int mapheaderinfo_get(lua_State *L) else if (fastcmp(field,"typeoflevel")) lua_pushinteger(L, header->typeoflevel); else if (fastcmp(field,"nextlevel")) - lua_pushinteger(L, header->nextlevel); + lua_pushstring(L, header->nextlevel); else if (fastcmp(field,"marathonnext")) - lua_pushinteger(L, header->marathonnext); + lua_pushstring(L, header->marathonnext); else if (fastcmp(field,"keywords")) lua_pushstring(L, header->keywords); else if (fastcmp(field,"musname")) diff --git a/src/lua_script.c b/src/lua_script.c index 4d02ee413..d0e98a66e 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -230,16 +230,16 @@ int LUA_PushGlobals(lua_State *L, const char *word) lua_pushinteger(L, smpstage_end); return 1; } else if (fastcmp(word,"titlemap")) { - lua_pushinteger(L, titlemap); + lua_pushstring(L, titlemap); return 1; } else if (fastcmp(word,"titlemapinaction")) { lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF)); return 1; } else if (fastcmp(word,"bootmap")) { - lua_pushinteger(L, bootmap); + lua_pushstring(L, bootmap); return 1; } else if (fastcmp(word,"tutorialmap")) { - lua_pushinteger(L, tutorialmap); + lua_pushstring(L, tutorialmap); return 1; } else if (fastcmp(word,"tutorialmode")) { lua_pushboolean(L, tutorialmode); diff --git a/src/m_cond.c b/src/m_cond.c index d8194d4d1..b632aa267 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -283,10 +283,17 @@ UINT8 M_CheckLevelEmblems(void) // Update Score, Time, Rings emblems for (i = 0; i < numemblems; ++i) { + INT32 checkLevel; + if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected) continue; - levelnum = emblemlocations[i].level; + checkLevel = G_MapNumber(emblemlocations[i].level); + + if (!mapheaderinfo[checkLevel]) + continue; + + levelnum = checkLevel; valToReach = emblemlocations[i].var; switch (emblemlocations[i].type) @@ -316,10 +323,17 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa for (i = 0; i < numemblems; ++i) { - if (emblemlocations[i].type != ET_MAP || emblemlocations[i].collected) + INT32 checkLevel; + + if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected) continue; - levelnum = emblemlocations[i].level; + checkLevel = G_MapNumber(emblemlocations[i].level); + + if (!mapheaderinfo[checkLevel]) + continue; + + levelnum = checkLevel; embtype = emblemlocations[i].var; flags = MV_BEATEN; @@ -472,7 +486,12 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum) while (--i >= 0) { - if (emblemlocations[i].level == map) + INT32 checkLevel = G_MapNumber(emblemlocations[i].level); + + if (!mapheaderinfo[checkLevel]) + continue; + + if (checkLevel == map) return &emblemlocations[i]; } return NULL; diff --git a/src/m_cond.h b/src/m_cond.h index ed29fe326..323c84347 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -73,7 +73,7 @@ typedef struct { UINT8 type; ///< Emblem type INT16 tag; ///< Tag of emblem mapthing - INT16 level; ///< Level on which this emblem can be found. + char * level; ///< Level on which this emblem can be found. UINT8 sprite; ///< emblem sprite to use, 0 - 25 UINT16 color; ///< skincolor to use INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) diff --git a/src/m_menu.c b/src/m_menu.c index 06985d923..4c1eca56b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2219,6 +2219,7 @@ static void Dummystaff_OnChange(void) dummystaffname[0] = '\0'; + // TODO: Use map header to determine lump name if ((l = W_CheckNumForLongName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) == LUMPERROR) { CV_StealthSetValue(&cv_dummystaff, 0); @@ -5498,7 +5499,7 @@ static void M_HandleReplayHutList(INT32 choice) #define SCALEDVIEWHEIGHT (vid.height/vid.dupy) static void DrawReplayHutReplayInfo(void) { - lumpnum_t lumpnum; + lumpnum_t lumpnum = LUMPERROR; patch_t *patch; UINT8 *colormap; INT32 x, y, w, h; @@ -5525,7 +5526,12 @@ static void DrawReplayHutReplayInfo(void) // A 160x100 image of the level as entry MAPxxP //CONS_Printf("%d %s\n", demolist[dir_on[menudepthleft]].map, G_BuildMapName(demolist[dir_on[menudepthleft]].map)); - lumpnum = W_CheckNumForLongName(va("%sP", G_BuildMapName(demolist[dir_on[menudepthleft]].map))); + + if (mapheaderinfo[demolist[dir_on[menudepthleft]].map]) + { + lumpnum = W_CheckNumForLongName(mapheaderinfo[demolist[dir_on[menudepthleft]].map]->thumbnailLump); + } + if (lumpnum != LUMPERROR) patch = W_CachePatchNum(lumpnum, PU_CACHE); else @@ -6548,8 +6554,15 @@ static void M_DrawEmblemHints(void) for (i = 0; i < numemblems; i++) { + INT32 checkLevel; + emblem = &emblemlocations[i]; - if (emblem->level != gamemap || emblem->type != ET_GLOBAL) + if (emblem->type != ET_GLOBAL) + continue; + + checkLevel = G_MapNumber(emblem->level); + + if (!mapheaderinfo[checkLevel] || gamemap != checkLevel) continue; if (emblem->collected) @@ -7709,6 +7722,7 @@ static void M_GrandPrixTemp(INT32 choice) static void M_StartGrandPrix(INT32 choice) { cupheader_t *gpcup = kartcupheaders; + INT32 levelNum; (void)choice; @@ -7760,9 +7774,11 @@ static void M_StartGrandPrix(INT32 choice) grandprixinfo.initalize = true; + levelNum = G_MapNumber(grandprixinfo.cup->levellist[0]); + G_DeferedInitNew( false, - grandprixinfo.cup->levellist[0] + 1, + levelNum + 1, (UINT8)(cv_chooseskin.value - 1), (UINT8)(cv_splitplayers.value - 1), false @@ -8866,14 +8882,18 @@ static void M_StartServer(INT32 choice) static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) { - lumpnum_t lumpnum; + lumpnum_t lumpnum = LUMPERROR; patch_t *PictureOfLevel; INT32 x, y, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1; // A 160x100 image of the level as entry MAPxxP if (cv_nextmap.value) { - lumpnum = W_CheckNumForLongName(va("%sP", G_BuildMapName(cv_nextmap.value))); + if (mapheaderinfo[cv_nextmap.value]) + { + lumpnum = W_CheckNumForLongName(mapheaderinfo[cv_nextmap.value]->thumbnailLump); + } + if (lumpnum != LUMPERROR) PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); else @@ -8939,7 +8959,11 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) // A 160x100 image of the level as entry MAPxxP if (i+1) { - lumpnum = W_CheckNumForLongName(va("%sP", G_BuildMapName(i+1))); + if (mapheaderinfo[i+1]) + { + lumpnum = W_CheckNumForLongName(mapheaderinfo[i+1]->thumbnailLump); + } + if (lumpnum != LUMPERROR) PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); else @@ -8977,7 +9001,11 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) // A 160x100 image of the level as entry MAPxxP if (i+1) { - lumpnum = W_CheckNumForLongName(va("%sP", G_BuildMapName(i+1))); + if (mapheaderinfo[i+1]) + { + lumpnum = W_CheckNumForLongName(mapheaderinfo[i+1]->thumbnailLump); + } + if (lumpnum != LUMPERROR) PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); else diff --git a/src/p_setup.c b/src/p_setup.c index df6fe3ecc..d587df732 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -354,6 +354,42 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) { const INT16 num = (INT16)(i-1); + if (mapheaderinfo[num]->thumbnailLump) + { + Z_Free(mapheaderinfo[num]->thumbnailLump); + mapheaderinfo[num]->thumbnailLump = NULL; + } + + if (mapheaderinfo[num]->minimapLump) + { + Z_Free(mapheaderinfo[num]->minimapLump); + mapheaderinfo[num]->minimapLump = NULL; + } + + if (mapheaderinfo[num]->encoreLump) + { + Z_Free(mapheaderinfo[num]->encoreLump); + mapheaderinfo[num]->encoreLump = NULL; + } + + if (mapheaderinfo[num]->tweakLump) + { + Z_Free(mapheaderinfo[num]->tweakLump); + mapheaderinfo[num]->tweakLump = NULL; + } + + if (mapheaderinfo[num]->nextlevel) + { + Z_Free(mapheaderinfo[num]->nextlevel); + mapheaderinfo[num]->nextlevel = NULL; + } + + if (mapheaderinfo[num]->marathonnext) + { + Z_Free(mapheaderinfo[num]->marathonnext); + mapheaderinfo[num]->marathonnext = NULL; + } + mapheaderinfo[num]->lvlttl[0] = '\0'; mapheaderinfo[num]->selectheading[0] = '\0'; mapheaderinfo[num]->subttl[0] = '\0'; @@ -363,8 +399,6 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->ltactdiamond[0] = '\0'; mapheaderinfo[num]->actnum = 0; mapheaderinfo[num]->typeoflevel = 0; - mapheaderinfo[num]->nextlevel = (INT16)(i + 1); - mapheaderinfo[num]->marathonnext = 0; mapheaderinfo[num]->startrings = 0; mapheaderinfo[num]->sstimer = 90; mapheaderinfo[num]->ssspheres = 1; @@ -426,6 +460,12 @@ void P_AllocMapHeader(INT16 i) { mapheaderinfo[i] = Z_Malloc(sizeof(mapheader_t), PU_STATIC, NULL); mapheaderinfo[i]->lumpname = NULL; + mapheaderinfo[i]->thumbnailLump = NULL; + mapheaderinfo[i]->minimapLump = NULL; + mapheaderinfo[i]->encoreLump = NULL; + mapheaderinfo[i]->tweakLump = NULL; + mapheaderinfo[i]->nextlevel = NULL; + mapheaderinfo[i]->marathonnext = NULL; mapheaderinfo[i]->flickies = NULL; mapheaderinfo[i]->grades = NULL; nummapheaders++; @@ -3713,6 +3753,7 @@ static void P_LoadRecordGhosts(void) { lumpnum_t l; UINT8 j = 1; + // TODO: Use map header to determine lump name while (j <= 99 && (l = W_CheckNumForLongName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR) { G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j)); @@ -4057,8 +4098,23 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) if (lastloadedmaplumpnum == LUMPERROR) I_Error("Map %s not found.\n", maplumpname); - R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, - W_CheckNumForName(va("%s%c", maplumpname, (encoremode ? 'E' : 'T')))); + { + INT32 encoreLump = LUMPERROR; + + if (mapheaderinfo[gamemap-1]) + { + if (encoremode) + { + encoreLump = W_CheckNumForLongName(mapheaderinfo[gamemap-1]->encoreLump); + } + else + { + encoreLump = W_CheckNumForLongName(mapheaderinfo[gamemap-1]->tweakLump); + } + } + + R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette, encoreLump); + } CON_SetupBackColormap(); // SRB2 determines the sky texture to be used depending on the map header. diff --git a/src/s_sound.c b/src/s_sound.c index 4c36325c6..fa5726516 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1557,28 +1557,6 @@ void S_InitSfxChannels(INT32 sfxVolume) /// Music /// ------------------------ -#ifdef MUSICSLOT_COMPATIBILITY -const char *compat_special_music_slots[16] = -{ - "_title", // 1036 title screen - "_intro", // 1037 intro - "_clear", // 1038 level clear - "_inv", // 1039 invincibility - "_shoes", // 1040 super sneakers - "_minv", // 1041 Mario invincibility - "_drown", // 1042 drowning - "_gover", // 1043 game over - "_1up", // 1044 extra life - "_conti", // 1045 continue screen - "_super", // 1046 Super Sonic - "_chsel", // 1047 character select - "_creds", // 1048 credits - "_inter", // 1049 Race Results - "_stjr", // 1050 Sonic Team Jr. Presents - "" -}; -#endif - static char music_name[7]; // up to 6-character name static void *music_data; static UINT16 music_flags; diff --git a/src/s_sound.h b/src/s_sound.h index 80a53fb3e..8d1fccee4 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -314,10 +314,4 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #define S_StartScreamSound S_StartSound #endif -#ifdef MUSICSLOT_COMPATIBILITY -// For compatibility with code/scripts relying on older versions -// This is a list of all the "special" slot names and their associated numbers -extern const char *compat_special_music_slots[16]; -#endif - #endif diff --git a/src/y_inter.c b/src/y_inter.c index 40451a775..6174bf86d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1738,7 +1738,7 @@ void Y_StartVote(void) for (i = 0; i < 5; i++) { - lumpnum_t lumpnum; + lumpnum_t lumpnum = LUMPERROR; // set up the encore levelinfo[i].encore = (votelevels[i][1] & 0x80); @@ -1788,7 +1788,11 @@ void Y_StartVote(void) levelinfo[i].gts = NULL; // set up the pic - lumpnum = W_CheckNumForLongName(va("%sP", G_BuildMapName(votelevels[i][0]+1))); + if (mapheaderinfo[votelevels[i][0]+1]) + { + lumpnum = W_CheckNumForLongName(mapheaderinfo[votelevels[i][0]+1]->thumbnailLump); + } + if (lumpnum != LUMPERROR) levelinfo[i].pic = W_CachePatchNum(lumpnum, PU_STATIC); else