From 35a5c4e23cdb63d612f56cb31d54a88a6aa3c8f5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 3 Aug 2020 20:11:30 +0200 Subject: [PATCH] - undid hardcoded coupling of Mapinfo slots with episode/level pairs in Blood. This both lifts the imposed limit of 16 levels and will allow dynamic management of global mapinfo data. --- source/blood/src/blood.cpp | 7 ++++--- source/blood/src/levels.cpp | 35 ++++++++++++++++++++------------- source/blood/src/levels.h | 2 -- source/core/mapinfo.h | 19 +++++++++++++++++- source/games/duke/src/inlines.h | 16 --------------- 5 files changed, 43 insertions(+), 36 deletions(-) diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index dd103c65a..276e014c9 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -366,6 +366,8 @@ void StartLevel(GAMEOPTIONS *gameOptions) gStartNewGame = 0; ready2send = 0; netWaitForEveryone(0); + currentLevel = FindMapByLevelNum(levelnum(gGameOptions.nEpisode, gGameOptions.nLevel)); + if (gGameOptions.nGameType == 0) { if (!(gGameOptions.uGameFlags&1)) @@ -415,14 +417,13 @@ void StartLevel(GAMEOPTIONS *gameOptions) memset(xsprite,0,sizeof(xsprite)); memset(sprite,0,kMaxSprites*sizeof(spritetype)); //drawLoadingScreen(); - if (dbLoadMap(gameOptions->zLevelName,(int*)&startpos.x,(int*)&startpos.y,(int*)&startpos.z,&startang,&startsectnum,(unsigned int*)&gameOptions->uMapCRC)) + if (dbLoadMap(currentLevel->fileName,(int*)&startpos.x,(int*)&startpos.y,(int*)&startpos.z,&startang,&startsectnum,(unsigned int*)&gameOptions->uMapCRC)) { I_Error("Unable to load map"); } - currentLevel = &mapList[gGameOptions.nEpisode * kMaxLevels + gGameOptions.nLevel]; SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name); STAT_NewLevel(currentLevel->fileName); - G_LoadMapHack(gameOptions->zLevelName); + G_LoadMapHack(currentLevel->fileName); wsrand(gameOptions->uMapCRC); gKillMgr.Clear(); gSecretMgr.Clear(); diff --git a/source/blood/src/levels.cpp b/source/blood/src/levels.cpp index 545249b6b..19c64c889 100644 --- a/source/blood/src/levels.cpp +++ b/source/blood/src/levels.cpp @@ -46,7 +46,7 @@ BEGIN_BLD_NS GAMEOPTIONS gGameOptions; GAMEOPTIONS gSingleGameOptions = { - 0, 2, 0, 0, "", 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200 + 0, 2, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3600, 1800, 1800, 7200 }; EPISODEINFO gEpisodeInfo[kMaxEpisodes+1]; @@ -114,9 +114,10 @@ void levelSetupOptions(int nEpisode, int nLevel) { gGameOptions.nEpisode = nEpisode; gGameOptions.nLevel = nLevel; - strcpy(gGameOptions.zLevelName, gEpisodeInfo[nEpisode].levels[nLevel].labelName); - gGameOptions.uMapCRC = dbReadMapCRC(gGameOptions.zLevelName); - gGameOptions.nTrackNumber = gEpisodeInfo[nEpisode].levels[nLevel].cdSongId; + auto level = FindMapByLevelNum(levelnum(nEpisode, nLevel)); + if (!level) return; + gGameOptions.uMapCRC = dbReadMapCRC(level->LabelName()); + gGameOptions.nTrackNumber = level->cdSongId; } void levelLoadMapInfo(IniFile *pIni, MapRecord *pLevelInfo, const char *pzSection, int epinum, int mapnum) @@ -177,16 +178,16 @@ void levelLoadDefaults(void) pEpisodeInfo->cutALevel = BloodINI->GetKeyInt(buffer, "CutSceneALevel", 0); if (pEpisodeInfo->cutALevel > 0) pEpisodeInfo->cutALevel--; - pEpisodeInfo->levels = mapList + i * kMaxLevels; int j; for (j = 0; j < kMaxLevels; j++) { - auto pLevelInfo = &pEpisodeInfo->levels[j]; sprintf(buffer2, "Map%d", j+1); if (!BloodINI->KeyExists(buffer, buffer2)) break; + auto pLevelInfo = AllocateMap(); const char *pMap = BloodINI->GetKeyString(buffer, buffer2, NULL); CheckSectionAbend(pMap); + pLevelInfo->levelNumber = levelnum(i, j); pLevelInfo->labelName = pMap; pLevelInfo->fileName.Format("%s.map", pMap); levelLoadMapInfo(BloodINI, pLevelInfo, pMap, i, j); @@ -198,7 +199,8 @@ void levelLoadDefaults(void) void levelAddUserMap(const char *pzMap) { - // FIXME: Make this work with the reworked map system +// FIXME: Make this work with the reworked map system +#if 0 char buffer[BMAX_PATH]; strncpy(buffer, pzMap, BMAX_PATH); ChangeExtension(buffer, ".DEF"); @@ -222,14 +224,16 @@ void levelAddUserMap(const char *pzMap) levelLoadMapInfo(&UserINI, pLevelInfo, NULL, nEpisode, nLevel); gGameOptions.nEpisode = nEpisode; gGameOptions.nLevel = nLevel; - gGameOptions.uMapCRC = dbReadMapCRC(pLevelInfo->name); - strcpy(gGameOptions.zLevelName, pLevelInfo->name); + gGameOptions.uMapCRC = dbReadMapCRC(pLevelInfo->name); +#else + auto map = SetupUserMap(pzMap); +#endif } void levelGetNextLevels(int nEpisode, int nLevel, int *pnEndingA, int *pnEndingB) { dassert(pnEndingA != NULL && pnEndingB != NULL); - auto pLevelInfo = &gEpisodeInfo[nEpisode].levels[nLevel]; + auto pLevelInfo = FindMapByLevelNum(levelnum(nEpisode, nLevel)); int nEndingA = pLevelInfo->nextLevel; if (nEndingA >= 0) nEndingA--; @@ -305,15 +309,18 @@ int levelGetMusicIdx(const char *str) bool levelTryPlayMusic(int nEpisode, int nLevel, bool bSetLevelSong) { + auto level = FindMapByLevelNum(levelnum(nEpisode, nLevel)); + if (!level) return false; FString buffer; - if (mus_redbook && gEpisodeInfo[nEpisode].levels[nLevel].cdSongId > 0) - buffer.Format("blood%02i.ogg", gEpisodeInfo[nEpisode].levels[nLevel].cdSongId); + if (mus_redbook && level->cdSongId > 0) + buffer.Format("blood%02i.ogg", level->cdSongId); else { - buffer = gEpisodeInfo[nEpisode].levels[nLevel].music; + buffer = level->music; + if (Mus_Play(level->labelName, buffer, true)) return true; DefaultExtension(buffer, ".mid"); } - return !!Mus_Play(gEpisodeInfo[nEpisode].levels[nLevel].labelName, buffer, true); + return !!Mus_Play(level->labelName, buffer, true); } void levelTryPlayMusicOrNothing(int nEpisode, int nLevel) diff --git a/source/blood/src/levels.h b/source/blood/src/levels.h index 6d8788852..51a15cf25 100644 --- a/source/blood/src/levels.h +++ b/source/blood/src/levels.h @@ -40,7 +40,6 @@ struct GAMEOPTIONS { unsigned char nDifficulty; int nEpisode; int nLevel; - char zLevelName[BMAX_PATH]; int nTrackNumber; //at12a; short nSaveGameSlot; int picEntry; @@ -75,7 +74,6 @@ struct EPISODEINFO int nLevels; unsigned int bloodbath : 1; unsigned int cutALevel : 4; - MapRecord* levels; // points into the global table. char cutsceneAName[BMAX_PATH]; char cutsceneBName[BMAX_PATH]; int at9028; diff --git a/source/core/mapinfo.h b/source/core/mapinfo.h index 340184e40..d1ad6e3b2 100644 --- a/source/core/mapinfo.h +++ b/source/core/mapinfo.h @@ -80,7 +80,24 @@ MapRecord *FindNextMap(MapRecord *thismap); MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic = nullptr); MapRecord* AllocateMap(); +// These should be the only places converting between level numbers and volume/map pairs +constexpr inline int levelnum(int vol, int map) +{ + return vol * 1000 + map; +} + +constexpr inline int volfromlevelnum(int num) +{ + return num > 0 ? num / 1000 : 0; +} + +constexpr inline int mapfromlevelnum(int num) +{ + return num > 0 ? num % 1000 : -1; +} + + enum { RRENDSLOT = 127 -}; \ No newline at end of file +}; diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index fcdca0a08..862b83805 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -198,22 +198,6 @@ inline double get16thOfHoriz(int snum, bool interpolate, double smoothratio) } -// These should be the only places converting between level numbers and volume/map pairs -constexpr inline int levelnum(int vol, int map) -{ - return vol * 1000 + map; -} - -constexpr inline int volfromlevelnum(int num) -{ - return num > 0 ? num / 1000 : 0; -} - -constexpr inline int mapfromlevelnum(int num) -{ - return num > 0 ? num % 1000 : -1; -} - //--------------------------------------------------------------------------- // //