Use strings in the map header for next level, marathon next, thumbnails, minimaps, encoremaps, and tweakmaps

This commit is contained in:
Sally Coolatta 2021-04-09 21:10:46 -04:00
parent 359cf86efb
commit de1f67b72a
23 changed files with 355 additions and 511 deletions

View file

@ -1594,13 +1594,18 @@ void D_SRB2Main(void)
// rei/miru: bootmap (Idea: starts the game on a predefined map) // rei/miru: bootmap (Idea: starts the game on a predefined map)
if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm())) if (bootmap && !(M_CheckParm("-warp") && M_IsNextParm()))
{ {
pstartmap = bootmap; const INT32 bootMapNum = G_MapNumber(bootmap);
if (pstartmap < 1 || pstartmap > NUMMAPS) if (mapheaderinfo[bootMapNum])
I_Error("Cannot warp to map %d (out of range)\n", pstartmap);
else
{ {
autostart = true; pstartmap = bootMapNum;
if (pstartmap < 1 || pstartmap > NUMMAPS)
I_Error("Cannot warp to map %d (out of range)\n", pstartmap);
else
{
autostart = true;
}
} }
} }

View file

@ -2791,6 +2791,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
INT32 resetplayer = 1, lastgametype; INT32 resetplayer = 1, lastgametype;
UINT8 skipprecutscene, FLS; UINT8 skipprecutscene, FLS;
boolean pencoremode; boolean pencoremode;
INT16 mapnumber;
forceresetplayers = deferencoremode = false; forceresetplayers = deferencoremode = false;
@ -2848,13 +2849,13 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
memset(&luabanks, 0, sizeof(luabanks)); memset(&luabanks, 0, sizeof(luabanks));
} }
demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING;
demo.savebutton = 0;
// Sal: Is this needed? // Sal: Is this needed?
// From experimenting with Lua scripts in vanilla I found a lot of annoying & potentially desync-y things with MapChange. // From experimenting with Lua scripts in vanilla I found a lot of annoying & potentially desync-y things with MapChange.
LUAh_MapChange(mapnumber); LUAh_MapChange(mapnumber);
demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING;
demo.savebutton = 0;
G_InitNew(pencoremode, mapnumber, resetplayer, skipprecutscene, FLS); G_InitNew(pencoremode, mapnumber, resetplayer, skipprecutscene, FLS);
if (demo.playback && !demo.timing) if (demo.playback && !demo.timing)
precache = true; precache = true;

View file

@ -24,10 +24,7 @@
#include "dehacked.h" #include "dehacked.h"
#include "deh_lua.h" #include "deh_lua.h"
#include "deh_tables.h" #include "deh_tables.h"
#include "deh_soc.h" // freeslotusage
#ifdef MUSICSLOT_COMPATIBILITY
#include "deh_soc.h" // for get_mus
#endif
// freeslot takes a name (string only!) // freeslot takes a name (string only!)
// and allocates it to the appropriate free slot. // 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); if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word);
return 0; 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)) { else if (!mathlib && fastncmp("pw_",word,3)) {
p = word+3; p = word+3;
for (i = 0; i < NUMPOWERS; i++) for (i = 0; i < NUMPOWERS; i++)

View file

@ -152,7 +152,10 @@ void clear_levels(void)
// we may as well try to save some memory, right? // we may as well try to save some memory, right?
for (i = 0; i < NUMMAPS; ++i) 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; continue;
// Custom map header info // Custom map header info
@ -1256,18 +1259,38 @@ void readgametype(MYFILE *f, char *gtname)
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]); 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 *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word; char *word;
char *word2; char *word2;
//char *word3; // Non-uppercase version of word2 //char *word3; // Non-uppercase version of word2
char *tmp; char *tmp;
INT32 i; 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 // Reset all previous map header information
P_AllocMapHeader((INT16)(num-1)); P_AllocMapHeader((INT16)(num-1));
if (mapheaderinfo[num-1]->lumpname == NULL)
{
mapheaderinfo[num-1]->lumpname = Z_StrDup(name);
}
do do
{ {
if (myfgets(s, MAXLINELEN, f)) if (myfgets(s, MAXLINELEN, f))
@ -1434,6 +1457,30 @@ void readlevelheader(MYFILE *f, INT32 num)
} }
// Strings that can be truncated // 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")) else if (fastcmp(word, "ZONETITLE"))
{ {
deh_strlcpy(mapheaderinfo[num-1]->zonttl, word2, deh_strlcpy(mapheaderinfo[num-1]->zonttl, word2,
@ -1456,38 +1503,6 @@ void readlevelheader(MYFILE *f, INT32 num)
else else
deh_warning("Level header %d: invalid act number %d", num, i); 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")) else if (fastcmp(word, "TYPEOFLEVEL"))
{ {
if (i) // it's just a number 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)); 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")) else if (fastcmp(word, "MUSICTRACK"))
mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1); mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
else if (fastcmp(word, "MUSICPOS")) 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); strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7);
cutscenes[num]->scene[scenenum].musswitch[6] = 0; 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")) else if (fastcmp(word, "MUSICTRACK"))
{ {
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; 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); strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7);
textprompts[num]->page[pagenum].musswitch[6] = 0; 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")) else if (fastcmp(word, "MUSICTRACK"))
{ {
textprompts[num]->page[pagenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; textprompts[num]->page[pagenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
@ -2388,20 +2364,6 @@ void readmenu(MYFILE *f, INT32 num)
menupres[num].musname[6] = 0; menupres[num].musname[6] = 0;
titlechanged = true; 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")) else if (fastcmp(word, "MUSICTRACK"))
{ {
menupres[num].mustrack = ((UINT16)value - 1); menupres[num].mustrack = ((UINT16)value - 1);
@ -2794,14 +2756,7 @@ void reademblemdata(MYFILE *f, INT32 num)
emblemlocations[num-1].tag = (INT16)value; emblemlocations[num-1].tag = (INT16)value;
else if (fastcmp(word, "MAPNUM")) else if (fastcmp(word, "MAPNUM"))
{ {
// Support using the actual map name, emblemlocations[num-1].level = Z_StrDup(word2);
// 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;
} }
else if (fastcmp(word, "SPRITE")) else if (fastcmp(word, "SPRITE"))
{ {
@ -3022,13 +2977,7 @@ void readunlockable(MYFILE *f, INT32 num)
} }
else if (fastcmp(word, "VAR")) else if (fastcmp(word, "VAR"))
{ {
// Support using the actual map name, // TODO: different field for level name string
// 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]);
unlockables[num].variable = (INT16)i; unlockables[num].variable = (INT16)i;
} }
else else
@ -3107,12 +3056,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
{ {
PARAMCHECK(1); PARAMCHECK(1);
ty = UC_MAPVISITED + offset; ty = UC_MAPVISITED + offset;
re = G_MapNumber(params[1]);
// 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]);
if (re < 0 || re >= NUMMAPS) if (re < 0 || re >= NUMMAPS)
{ {
@ -3125,12 +3069,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
PARAMCHECK(2); PARAMCHECK(2);
ty = UC_MAPTIME; ty = UC_MAPTIME;
re = atoi(params[2]); re = atoi(params[2]);
x1 = G_MapNumber(params[1]);
// 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]);
if (x1 < 0 || x1 >= NUMMAPS) if (x1 < 0 || x1 >= NUMMAPS)
{ {
@ -3333,56 +3272,23 @@ void readmaincfg(MYFILE *f)
else if (fastcmp(word, "SPSTAGE_START")) else if (fastcmp(word, "SPSTAGE_START"))
{ {
// Support using the actual map name, // TODO: Use map name string
// i.e., Level AB, Level FZ, etc. // Haven't done it because of how special stage ends are handled
// Though, we likely won't be using these for Kart anyhow
// Convert to map number spstage_start = spmarathon_start = (INT16)G_MapNumber(word2);
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;
} }
else if (fastcmp(word, "SPMARATHON_START")) else if (fastcmp(word, "SPMARATHON_START"))
{ {
// Support using the actual map name, spmarathon_start = (INT16)G_MapNumber(word2);
// 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;
} }
else if (fastcmp(word, "SSTAGE_START")) else if (fastcmp(word, "SSTAGE_START"))
{ {
// Support using the actual map name, sstage_start = (INT16)G_MapNumber(word2);
// 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_end = (INT16)(sstage_start+7); // 7 special stages total plus one weirdo sstage_end = (INT16)(sstage_start+7); // 7 special stages total plus one weirdo
} }
else if (fastcmp(word, "SMPSTAGE_START")) else if (fastcmp(word, "SMPSTAGE_START"))
{ {
// Support using the actual map name, smpstage_start = (INT16)G_MapNumber(word2);
// 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_end = (INT16)(smpstage_start+6); // 7 special stages total smpstage_end = (INT16)(smpstage_start+6); // 7 special stages total
} }
else if (fastcmp(word, "REDTEAM")) else if (fastcmp(word, "REDTEAM"))
@ -3467,16 +3373,7 @@ void readmaincfg(MYFILE *f)
} }
else if (fastcmp(word, "TITLEMAP")) else if (fastcmp(word, "TITLEMAP"))
{ {
// Support using the actual map name, titlemap = Z_StrDup(word2);
// 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;
titlechanged = true; titlechanged = true;
} }
else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "TITLEPICSHIDE")) else if (fastcmp(word, "HIDETITLEPICS") || fastcmp(word, "TITLEPICSHIDE"))
@ -3606,30 +3503,12 @@ void readmaincfg(MYFILE *f)
} }
else if (fastcmp(word, "BOOTMAP")) else if (fastcmp(word, "BOOTMAP"))
{ {
// Support using the actual map name, bootmap = Z_StrDup(word2);
// 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;
//titlechanged = true; //titlechanged = true;
} }
else if (fastcmp(word, "TUTORIALMAP")) else if (fastcmp(word, "TUTORIALMAP"))
{ {
// Support using the actual map name, tutorialmap = Z_StrDup(word2);
// 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;
} }
else else
deh_warning("Maincfg: unknown word '%s'", word); deh_warning("Maincfg: unknown word '%s'", word);
@ -3852,37 +3731,23 @@ void readcupheader(MYFILE *f, cupheader_t *cup)
tmp = strtok(word2,","); tmp = strtok(word2,",");
do { 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) if (cup->numlevels >= MAXLEVELLIST)
{ {
deh_warning("%s Cup: reached max levellist (%d)\n", cup->name, MAXLEVELLIST); deh_warning("%s Cup: reached max levellist (%d)\n", cup->name, MAXLEVELLIST);
break; break;
} }
cup->levellist[cup->numlevels] = map - 1; cup->levellist[cup->numlevels] = Z_StrDup(word2);
cup->numlevels++; cup->numlevels++;
} while((tmp = strtok(NULL,",")) != NULL); } while((tmp = strtok(NULL,",")) != NULL);
} }
else if (fastcmp(word, "BONUSGAME")) else if (fastcmp(word, "BONUSGAME"))
{ {
// Convert to map number cup->bonusgame = Z_StrDup(word2);
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
i = M_MapNumber(word2[0], word2[1]);
cup->bonusgame = (INT16)i - 1;
} }
else if (fastcmp(word, "SPECIALSTAGE")) else if (fastcmp(word, "SPECIALSTAGE"))
{ {
// Convert to map number cup->specialstage = Z_StrDup(word2);
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
i = M_MapNumber(word2[0], word2[1]);
cup->specialstage = (INT16)i - 1;
} }
else if (fastcmp(word, "EMERALDNUM")) else if (fastcmp(word, "EMERALDNUM"))
{ {
@ -4257,46 +4122,6 @@ sfxenum_t get_sfx(const char *word)
return sfx_None; 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) hudnum_t get_huditem(const char *word)
{ // Returns the value of HUD_ enumerations { // Returns the value of HUD_ enumerations
hudnum_t i; hudnum_t i;
@ -4527,13 +4352,6 @@ static fixed_t find_const(const char **rword)
free(word); free(word);
return r; 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)) { else if (fastncmp("PW_",word,3)) {
r = get_power(word); r = get_power(word);
free(word); free(word);

View file

@ -43,7 +43,7 @@
#include "info.h" #include "info.h"
#include "dehacked.h" #include "dehacked.h"
#include "doomdef.h" // MUSICSLOT_COMPATIBILITY, HWRENDER #include "doomdef.h" // HWRENDER
// Crazy word-reading stuff // Crazy word-reading stuff
/// \todo Put these in a seperate file or something. /// \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); spritenum_t get_sprite(const char *word);
playersprite_t get_sprite2(const char *word); playersprite_t get_sprite2(const char *word);
sfxenum_t get_sfx(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); hudnum_t get_huditem(const char *word);
menutype_t get_menutype(const char *word); menutype_t get_menutype(const char *word);
//INT16 get_gametype(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 readmenu(MYFILE *f, INT32 num);
void readtextprompt(MYFILE *f, INT32 num); void readtextprompt(MYFILE *f, INT32 num);
void readcutscene(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 readgametype(MYFILE *f, char *gtname);
void readsprite2(MYFILE *f, INT32 num); void readsprite2(MYFILE *f, INT32 num);
void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2); void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2);

View file

@ -400,27 +400,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
} }
else if (fastcmp(word, "LEVEL")) else if (fastcmp(word, "LEVEL"))
{ {
// Support using the actual map name, readlevelheader(f, word2);
// 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);
}
} }
else if (fastcmp(word, "GAMETYPE")) else if (fastcmp(word, "GAMETYPE"))
{ {

View file

@ -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.) /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG //#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. /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
//#define PAPER_COLLISIONCORRECTION //#define PAPER_COLLISIONCORRECTION

View file

@ -177,11 +177,11 @@ extern boolean splitscreen_partied[MAXPLAYERS];
extern INT16 spstage_start, spmarathon_start; extern INT16 spstage_start, spmarathon_start;
extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end;
extern INT16 titlemap; extern char * titlemap;
extern boolean hidetitlepics; 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 boolean tutorialmode; // are we in a tutorial right now?
extern INT32 tutorialgcs; // which control scheme is loaded? extern INT32 tutorialgcs; // which control scheme is loaded?
@ -326,81 +326,100 @@ typedef struct
*/ */
typedef struct typedef struct
{ {
char * lumpname; ///< Lump name can be really long 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 * thumbnailLump; ///< Lump name for the level select thumbnail.
char zonttl[22]; ///< "ZONE" replacement name char * minimapLump; ///< Lump name for the minimap graphic.
UINT8 actnum; ///< Act number or 0 for none. char * encoreLump; ///< Lump name for the Encore Mode remap.
UINT32 typeoflevel; ///< Combination of typeoflevel flags. char * tweakLump; ///< Lump name for the palette tweak remap.
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 lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway)
char keywords[33]; ///< Keywords separated by space to search for. 32 characters. char subttl[33]; ///< Subtitle for level
char musname[7]; ///< Music track to play. "" for no music. char zonttl[22]; ///< "ZONE" replacement name
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT8 actnum; ///< Act number or 0 for none.
UINT32 muspos; ///< Music position to jump to.
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. UINT32 typeoflevel; ///< Combination of typeoflevel flags.
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. char * nextlevel; ///< Map name of next level.
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.) char * marathonnext; ///< See nextlevel, but for Marathon mode.
INT16 skybox_scaley; ///< Skybox Y axis scale.
INT16 skybox_scalez; ///< Skybox Z axis scale. 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. // Extra information.
char interscreen[8]; ///< 320x200 patch to display at intermission. 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.)
UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63)
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus 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. UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts.
UINT16 startrings; ///< Number of rings players start with. UINT8 cutscenenum; ///< Cutscene number to use, 0 for none.
INT32 sstimer; ///< Timer for special stages.
UINT32 ssspheres; ///< Sphere requirement in special stages. INT16 countdown; ///< Countdown until level end?
fixed_t gravity; ///< Map-wide gravity.
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. // Title card.
char ltzzpatch[8]; ///< Zig zag patch. char ltzzpatch[8]; ///< Zig zag patch.
char ltzztext[8]; ///< Zig zag text. char ltzztext[8]; ///< Zig zag text.
char ltactdiamond[8]; ///< Act diamond. char ltactdiamond[8]; ///< Act diamond.
// Freed animals stuff. // Freed animals stuff.
UINT8 numFlickies; ///< Internal. For freed flicky support. UINT8 numFlickies; ///< Internal. For freed flicky support.
mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful. mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful.
// NiGHTS stuff. // NiGHTS stuff.
UINT8 numGradedMares; ///< Internal. For grade support. UINT8 numGradedMares; ///< Internal. For grade support.
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful. 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
// Music stuff. // Music stuff.
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
char musintername[7]; ///< Intermission screen music. char musintername[7]; ///< Intermission screen music.
char muspostbossname[7]; ///< Post-bossdeath music. char muspostbossname[7]; ///< Post-bossdeath music.
UINT16 muspostbosstrack; ///< Post-bossdeath track. UINT16 muspostbosstrack; ///< Post-bossdeath track.
UINT32 muspostbosspos; ///< Post-bossdeath position UINT32 muspostbosspos; ///< Post-bossdeath position
UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds. 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. // Lua stuff.
// (This is not ifdeffed so the map header structure can stay identical, just in case.) // (This is not ifdeffed so the map header structure can stay identical, just in case.)
UINT8 numCustomOptions; ///< Internal. For Lua custom value support. UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful.
} mapheader_t; } mapheader_t;
// level flags // level flags
@ -426,10 +445,10 @@ typedef struct cupheader_s
UINT16 id; ///< Cup ID UINT16 id; ///< Cup ID
char name[15]; ///< Cup title (14 chars) char name[15]; ///< Cup title (14 chars)
char icon[9]; ///< Name of the icon patch 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 UINT8 numlevels; ///< Number of levels defined in levellist
INT16 bonusgame; ///< Map number to use for bonus game char * bonusgame; ///< Map number to use for bonus game
INT16 specialstage; ///< Map number to use for special stage 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) 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. SINT8 unlockrequired; ///< An unlockable is required to select this cup. -1 for no unlocking required.
struct cupheader_s *next; ///< Next cup in linked list struct cupheader_s *next; ///< Next cup in linked list

View file

@ -1812,6 +1812,8 @@ static void F_CacheTitleScreen(void)
void F_StartTitleScreen(void) void F_StartTitleScreen(void)
{ {
const INT32 titleMapNum = G_MapNumber(titlemap);
if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS)
{ {
ttuser_count = 0; ttuser_count = 0;
@ -1821,20 +1823,20 @@ void F_StartTitleScreen(void)
else else
wipegamestate = GS_TITLESCREEN; wipegamestate = GS_TITLESCREEN;
if (titlemap) if (mapheaderinfo[titleMapNum])
{ {
mapthing_t *startpos; mapthing_t *startpos;
gamestate_t prevwipegamestate = wipegamestate; gamestate_t prevwipegamestate = wipegamestate;
titlemapinaction = TITLEMAP_LOADING; titlemapinaction = TITLEMAP_LOADING;
titlemapcameraref = NULL; titlemapcameraref = NULL;
gamemap = titlemap; gamemap = titleMapNum;
maptol = mapheaderinfo[gamemap-1]->typeoflevel; maptol = mapheaderinfo[gamemap-1]->typeoflevel;
globalweather = mapheaderinfo[gamemap-1]->weather; globalweather = mapheaderinfo[gamemap-1]->weather;
G_DoLoadLevel(true); G_DoLoadLevel(true);
if (!titlemap) if (!titleMapNum)
return; return;
players[displayplayers[0]].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater) players[displayplayers[0]].playerstate = PST_DEAD; // Don't spawn the player in dummy (I'm still a filthy cheater)

View file

@ -3467,6 +3467,7 @@ void G_DoPlayMetal(void)
thinker_t *th; thinker_t *th;
// it's an internal demo // it's an internal demo
// TODO: Use map header to determine lump name
if ((l = W_CheckNumForName(va("%sMS",G_BuildMapName(gamemap)))) == LUMPERROR) if ((l = W_CheckNumForName(va("%sMS",G_BuildMapName(gamemap)))) == LUMPERROR)
{ {
CONS_Alert(CONS_WARNING, M_GetText("No bot recording for this map.\n")); CONS_Alert(CONS_WARNING, M_GetText("No bot recording for this map.\n"));

View file

@ -149,11 +149,11 @@ tic_t timeinmap; // Ticker for time spent in level (used for levelcard display)
INT16 spstage_start, spmarathon_start; INT16 spstage_start, spmarathon_start;
INT16 sstage_start, sstage_end, smpstage_start, smpstage_end; INT16 sstage_start, sstage_end, smpstage_start, smpstage_end;
INT16 titlemap = 0; char * titlemap = NULL;
boolean hidetitlepics = false; 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? boolean tutorialmode = false; // are we in a tutorial right now?
INT32 tutorialgcs = gcs_custom; // which control scheme is loaded? INT32 tutorialgcs = gcs_custom; // which control scheme is loaded?
@ -3340,6 +3340,7 @@ tryagain:
if (pprevmap == -2) // title demo hack if (pprevmap == -2) // title demo hack
{ {
lumpnum_t l; lumpnum_t l;
// TODO: Use map header to determine lump name
if ((l = W_CheckNumForLongName(va("%sS01",G_BuildMapName(ix+1)))) == LUMPERROR) if ((l = W_CheckNumForLongName(va("%sS01",G_BuildMapName(ix+1)))) == LUMPERROR)
continue; continue;
} }
@ -3529,7 +3530,12 @@ static void G_DoCompleted(void)
} }
else if (marathonmode && mapheaderinfo[gamemap-1]->marathonnext) 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) else if (grandprixinfo.gp == true)
{ {
@ -3546,16 +3552,27 @@ static void G_DoCompleted(void)
else else
{ {
// Proceed to next map // 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++; grandprixinfo.roundnum++;
} }
} }
} }
else else
{ {
nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1); const INT32 nextNum = G_MapNumber(mapheaderinfo[gamemap-1]->nextlevel);
if (marathonmode && nextmap == spmarathon_start-1)
nextmap = 1100-1; // No infinite loop for you 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. // Remember last map for when you come out of the special stage.
@ -3582,9 +3599,23 @@ static void G_DoCompleted(void)
if (!mapheaderinfo[cm]) if (!mapheaderinfo[cm])
cm = -1; // guarantee error execution cm = -1; // guarantee error execution
else if (marathonmode && mapheaderinfo[cm]->marathonnext) 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 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) if (cm >= NUMMAPS || cm < 0) // out of range (either 1100ish or error)
{ {

View file

@ -3015,7 +3015,7 @@ static void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx, INT32
static void K_drawKartMinimap(void) static void K_drawKartMinimap(void)
{ {
INT32 lumpnum; INT32 lumpnum = LUMPERROR;
patch_t *AutomapPic; patch_t *AutomapPic;
INT32 i = 0; INT32 i = 0;
INT32 x, y; INT32 x, y;
@ -3037,7 +3037,10 @@ static void K_drawKartMinimap(void)
if (stplyr != &players[displayplayers[0]]) if (stplyr != &players[displayplayers[0]])
return; return;
lumpnum = W_CheckNumForLongName(va("%sR", G_BuildMapName(gamemap))); if (mapheaderinfo[gamemap-1])
{
lumpnum = W_CheckNumForLongName(mapheaderinfo[gamemap-1]->minimapLump);
}
if (lumpnum != -1) if (lumpnum != -1)
AutomapPic = W_CachePatchNum(lumpnum, PU_HUDGFX); AutomapPic = W_CachePatchNum(lumpnum, PU_HUDGFX);

View file

@ -2435,39 +2435,6 @@ static int lib_sStopSoundByID(lua_State *L)
static int lib_sChangeMusic(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); const char *music_name = luaL_checkstring(L, 1);
UINT32 position, prefadems, fadeinms; UINT32 position, prefadems, fadeinms;
boolean looping = (boolean)lua_opttrueboolean(L, 2); boolean looping = (boolean)lua_opttrueboolean(L, 2);
@ -2475,7 +2442,6 @@ static int lib_sChangeMusic(lua_State *L)
UINT16 music_flags = 0; UINT16 music_flags = 0;
//NOHUD //NOHUD
#endif
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{ {
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); 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"); 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); music_flags = (UINT16)luaL_optinteger(L, 4, 0);
position = (UINT32)luaL_optinteger(L, 5, 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) 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); const char *music_name = luaL_checkstring(L, 1);
#endif
NOHUD NOHUD
lua_pushboolean(L, S_MusicExists(music_name)); lua_pushboolean(L, S_MusicExists(music_name));
return 1; return 1;

View file

@ -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. boolean centered; // the patch is centered and doesn't need readjusting on x/y coordinates.
// variables used to replicate k_kart's mmap drawer: // variables used to replicate k_kart's mmap drawer:
INT32 lumpnum; INT32 lumpnum = LUMPERROR;
patch_t *AutomapPic; patch_t *AutomapPic;
INT32 mx, my; INT32 mx, my;
INT32 splitflags, minimaptrans; INT32 splitflags, minimaptrans;
@ -738,7 +738,10 @@ static int libd_drawOnMinimap(lua_State *L)
if (stplyr != &players[displayplayers[0]]) if (stplyr != &players[displayplayers[0]])
return 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) if (lumpnum != -1)
AutomapPic = W_CachePatchNum(lumpnum, PU_HUDGFX); AutomapPic = W_CachePatchNum(lumpnum, PU_HUDGFX);

View file

@ -2128,9 +2128,9 @@ static int mapheaderinfo_get(lua_State *L)
else if (fastcmp(field,"typeoflevel")) else if (fastcmp(field,"typeoflevel"))
lua_pushinteger(L, header->typeoflevel); lua_pushinteger(L, header->typeoflevel);
else if (fastcmp(field,"nextlevel")) else if (fastcmp(field,"nextlevel"))
lua_pushinteger(L, header->nextlevel); lua_pushstring(L, header->nextlevel);
else if (fastcmp(field,"marathonnext")) else if (fastcmp(field,"marathonnext"))
lua_pushinteger(L, header->marathonnext); lua_pushstring(L, header->marathonnext);
else if (fastcmp(field,"keywords")) else if (fastcmp(field,"keywords"))
lua_pushstring(L, header->keywords); lua_pushstring(L, header->keywords);
else if (fastcmp(field,"musname")) else if (fastcmp(field,"musname"))

View file

@ -230,16 +230,16 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, smpstage_end); lua_pushinteger(L, smpstage_end);
return 1; return 1;
} else if (fastcmp(word,"titlemap")) { } else if (fastcmp(word,"titlemap")) {
lua_pushinteger(L, titlemap); lua_pushstring(L, titlemap);
return 1; return 1;
} else if (fastcmp(word,"titlemapinaction")) { } else if (fastcmp(word,"titlemapinaction")) {
lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF)); lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF));
return 1; return 1;
} else if (fastcmp(word,"bootmap")) { } else if (fastcmp(word,"bootmap")) {
lua_pushinteger(L, bootmap); lua_pushstring(L, bootmap);
return 1; return 1;
} else if (fastcmp(word,"tutorialmap")) { } else if (fastcmp(word,"tutorialmap")) {
lua_pushinteger(L, tutorialmap); lua_pushstring(L, tutorialmap);
return 1; return 1;
} else if (fastcmp(word,"tutorialmode")) { } else if (fastcmp(word,"tutorialmode")) {
lua_pushboolean(L, tutorialmode); lua_pushboolean(L, tutorialmode);

View file

@ -283,10 +283,17 @@ UINT8 M_CheckLevelEmblems(void)
// Update Score, Time, Rings emblems // Update Score, Time, Rings emblems
for (i = 0; i < numemblems; ++i) for (i = 0; i < numemblems; ++i)
{ {
INT32 checkLevel;
if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected) if (emblemlocations[i].type < ET_TIME || emblemlocations[i].collected)
continue; continue;
levelnum = emblemlocations[i].level; checkLevel = G_MapNumber(emblemlocations[i].level);
if (!mapheaderinfo[checkLevel])
continue;
levelnum = checkLevel;
valToReach = emblemlocations[i].var; valToReach = emblemlocations[i].var;
switch (emblemlocations[i].type) 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) 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; continue;
levelnum = emblemlocations[i].level; checkLevel = G_MapNumber(emblemlocations[i].level);
if (!mapheaderinfo[checkLevel])
continue;
levelnum = checkLevel;
embtype = emblemlocations[i].var; embtype = emblemlocations[i].var;
flags = MV_BEATEN; flags = MV_BEATEN;
@ -472,7 +486,12 @@ emblem_t *M_GetLevelEmblems(INT32 mapnum)
while (--i >= 0) 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 &emblemlocations[i];
} }
return NULL; return NULL;

View file

@ -73,7 +73,7 @@ typedef struct
{ {
UINT8 type; ///< Emblem type UINT8 type; ///< Emblem type
INT16 tag; ///< Tag of emblem mapthing 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 UINT8 sprite; ///< emblem sprite to use, 0 - 25
UINT16 color; ///< skincolor to use UINT16 color; ///< skincolor to use
INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin) INT32 var; ///< If needed, specifies information on the target amount to achieve (or target skin)

View file

@ -2219,6 +2219,7 @@ static void Dummystaff_OnChange(void)
dummystaffname[0] = '\0'; dummystaffname[0] = '\0';
// TODO: Use map header to determine lump name
if ((l = W_CheckNumForLongName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) == LUMPERROR) if ((l = W_CheckNumForLongName(va("%sS01",G_BuildMapName(cv_nextmap.value)))) == LUMPERROR)
{ {
CV_StealthSetValue(&cv_dummystaff, 0); CV_StealthSetValue(&cv_dummystaff, 0);
@ -5498,7 +5499,7 @@ static void M_HandleReplayHutList(INT32 choice)
#define SCALEDVIEWHEIGHT (vid.height/vid.dupy) #define SCALEDVIEWHEIGHT (vid.height/vid.dupy)
static void DrawReplayHutReplayInfo(void) static void DrawReplayHutReplayInfo(void)
{ {
lumpnum_t lumpnum; lumpnum_t lumpnum = LUMPERROR;
patch_t *patch; patch_t *patch;
UINT8 *colormap; UINT8 *colormap;
INT32 x, y, w, h; INT32 x, y, w, h;
@ -5525,7 +5526,12 @@ static void DrawReplayHutReplayInfo(void)
// A 160x100 image of the level as entry MAPxxP // 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)); //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) if (lumpnum != LUMPERROR)
patch = W_CachePatchNum(lumpnum, PU_CACHE); patch = W_CachePatchNum(lumpnum, PU_CACHE);
else else
@ -6548,8 +6554,15 @@ static void M_DrawEmblemHints(void)
for (i = 0; i < numemblems; i++) for (i = 0; i < numemblems; i++)
{ {
INT32 checkLevel;
emblem = &emblemlocations[i]; 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; continue;
if (emblem->collected) if (emblem->collected)
@ -7709,6 +7722,7 @@ static void M_GrandPrixTemp(INT32 choice)
static void M_StartGrandPrix(INT32 choice) static void M_StartGrandPrix(INT32 choice)
{ {
cupheader_t *gpcup = kartcupheaders; cupheader_t *gpcup = kartcupheaders;
INT32 levelNum;
(void)choice; (void)choice;
@ -7760,9 +7774,11 @@ static void M_StartGrandPrix(INT32 choice)
grandprixinfo.initalize = true; grandprixinfo.initalize = true;
levelNum = G_MapNumber(grandprixinfo.cup->levellist[0]);
G_DeferedInitNew( G_DeferedInitNew(
false, false,
grandprixinfo.cup->levellist[0] + 1, levelNum + 1,
(UINT8)(cv_chooseskin.value - 1), (UINT8)(cv_chooseskin.value - 1),
(UINT8)(cv_splitplayers.value - 1), (UINT8)(cv_splitplayers.value - 1),
false false
@ -8866,14 +8882,18 @@ static void M_StartServer(INT32 choice)
static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
{ {
lumpnum_t lumpnum; lumpnum_t lumpnum = LUMPERROR;
patch_t *PictureOfLevel; patch_t *PictureOfLevel;
INT32 x, y, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1; INT32 x, y, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1;
// A 160x100 image of the level as entry MAPxxP // A 160x100 image of the level as entry MAPxxP
if (cv_nextmap.value) 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) if (lumpnum != LUMPERROR)
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
else else
@ -8939,7 +8959,11 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
// A 160x100 image of the level as entry MAPxxP // A 160x100 image of the level as entry MAPxxP
if (i+1) 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) if (lumpnum != LUMPERROR)
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
else else
@ -8977,7 +9001,11 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
// A 160x100 image of the level as entry MAPxxP // A 160x100 image of the level as entry MAPxxP
if (i+1) 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) if (lumpnum != LUMPERROR)
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
else else

View file

@ -354,6 +354,42 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
{ {
const INT16 num = (INT16)(i-1); 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]->lvlttl[0] = '\0';
mapheaderinfo[num]->selectheading[0] = '\0'; mapheaderinfo[num]->selectheading[0] = '\0';
mapheaderinfo[num]->subttl[0] = '\0'; mapheaderinfo[num]->subttl[0] = '\0';
@ -363,8 +399,6 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->ltactdiamond[0] = '\0'; mapheaderinfo[num]->ltactdiamond[0] = '\0';
mapheaderinfo[num]->actnum = 0; mapheaderinfo[num]->actnum = 0;
mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->typeoflevel = 0;
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
mapheaderinfo[num]->marathonnext = 0;
mapheaderinfo[num]->startrings = 0; mapheaderinfo[num]->startrings = 0;
mapheaderinfo[num]->sstimer = 90; mapheaderinfo[num]->sstimer = 90;
mapheaderinfo[num]->ssspheres = 1; 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] = Z_Malloc(sizeof(mapheader_t), PU_STATIC, NULL);
mapheaderinfo[i]->lumpname = 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]->flickies = NULL;
mapheaderinfo[i]->grades = NULL; mapheaderinfo[i]->grades = NULL;
nummapheaders++; nummapheaders++;
@ -3713,6 +3753,7 @@ static void P_LoadRecordGhosts(void)
{ {
lumpnum_t l; lumpnum_t l;
UINT8 j = 1; 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) while (j <= 99 && (l = W_CheckNumForLongName(va("%sS%02u",G_BuildMapName(gamemap),j))) != LUMPERROR)
{ {
G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j)); G_AddGhost(va("%sS%02u",G_BuildMapName(gamemap),j));
@ -4057,8 +4098,23 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
if (lastloadedmaplumpnum == LUMPERROR) if (lastloadedmaplumpnum == LUMPERROR)
I_Error("Map %s not found.\n", maplumpname); 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(); CON_SetupBackColormap();
// SRB2 determines the sky texture to be used depending on the map header. // SRB2 determines the sky texture to be used depending on the map header.

View file

@ -1557,28 +1557,6 @@ void S_InitSfxChannels(INT32 sfxVolume)
/// Music /// 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 char music_name[7]; // up to 6-character name
static void *music_data; static void *music_data;
static UINT16 music_flags; static UINT16 music_flags;

View file

@ -314,10 +314,4 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
#define S_StartScreamSound S_StartSound #define S_StartScreamSound S_StartSound
#endif #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 #endif

View file

@ -1738,7 +1738,7 @@ void Y_StartVote(void)
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
{ {
lumpnum_t lumpnum; lumpnum_t lumpnum = LUMPERROR;
// set up the encore // set up the encore
levelinfo[i].encore = (votelevels[i][1] & 0x80); levelinfo[i].encore = (votelevels[i][1] & 0x80);
@ -1788,7 +1788,11 @@ void Y_StartVote(void)
levelinfo[i].gts = NULL; levelinfo[i].gts = NULL;
// set up the pic // 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) if (lumpnum != LUMPERROR)
levelinfo[i].pic = W_CachePatchNum(lumpnum, PU_STATIC); levelinfo[i].pic = W_CachePatchNum(lumpnum, PU_STATIC);
else else