- transitioned Blood to the common mapinfo system.

This commit is contained in:
Christoph Oelckers 2019-12-11 00:57:53 +01:00
parent cc33c6a0ed
commit 5c0cd5114d
11 changed files with 75 additions and 87 deletions

View file

@ -542,6 +542,7 @@ void StartLevel(GAMEOPTIONS *gameOptions)
return;
}
char levelName[BMAX_PATH];
currentLevel = &mapList[gGameOptions.nEpisode * kMaxLevels + gGameOptions.nLevel];
STAT_NewLevel(gameOptions->zLevelName);
G_LoadMapHack(levelName, gameOptions->zLevelName);
wsrand(gameOptions->uMapCRC);
@ -1444,9 +1445,8 @@ static int32_t S_DefineMusic(const char *ID, const char *name)
return -1;
}
int nEpisode = sel/kMaxLevels;
int nLevel = sel%kMaxLevels;
return S_DefineAudioIfSupported(gEpisodeInfo[nEpisode].at28[nLevel].atd0, name);
quoteMgr.InitializeQuote(sel, name);
return 0;
}
static int parsedefinitions_game(scriptfile *, int);
@ -1988,9 +1988,7 @@ bool fileExistsRFF(int id, const char *ext) {
int sndTryPlaySpecialMusic(int nMusic)
{
int nEpisode = nMusic/kMaxLevels;
int nLevel = nMusic%kMaxLevels;
if (Mus_Play(gEpisodeInfo[nEpisode].at28[nLevel].at0, gEpisodeInfo[nEpisode].at28[nLevel].atd0, true))
if (Mus_Play(nullptr, quoteMgr.GetQuote(nMusic), true))
{
return 0;
}

View file

@ -146,48 +146,48 @@ void CheckKeyAbend(const char *pzSection, const char *pzKey)
ThrowError("Key %s expected in section [%s] of BLOOD.INI", pzKey, pzSection);
}
LEVELINFO * levelGetInfoPtr(int nEpisode, int nLevel)
MapRecord * levelGetInfoPtr(int nEpisode, int nLevel)
{
dassert(nEpisode >= 0 && nEpisode < gEpisodeCount);
EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[nEpisode];
dassert(nLevel >= 0 && nLevel < pEpisodeInfo->nLevels);
return &pEpisodeInfo->at28[nLevel];
return &pEpisodeInfo->levels[nLevel];
}
char * levelGetFilename(int nEpisode, int nLevel)
const char * levelGetFilename(int nEpisode, int nLevel)
{
dassert(nEpisode >= 0 && nEpisode < gEpisodeCount);
EPISODEINFO *pEpisodeInfo = &gEpisodeInfo[nEpisode];
dassert(nLevel >= 0 && nLevel < pEpisodeInfo->nLevels);
return pEpisodeInfo->at28[nLevel].at0;
return pEpisodeInfo->levels[nLevel].labelName;
}
char * levelGetMessage(int nMessage)
const char * levelGetMessage(int nMessage)
{
int nEpisode = gGameOptions.nEpisode;
int nLevel = gGameOptions.nLevel;
dassert(nMessage < kMaxMessages);
char *pMessage = gEpisodeInfo[nEpisode].at28[nLevel].atec[nMessage];
const char *pMessage = gEpisodeInfo[nEpisode].levels[nLevel].GetMessage(nMessage);
if (*pMessage == 0)
return NULL;
return pMessage;
}
char * levelGetTitle(void)
const char * levelGetTitle(void)
{
int nEpisode = gGameOptions.nEpisode;
int nLevel = gGameOptions.nLevel;
char *pTitle = gEpisodeInfo[nEpisode].at28[nLevel].at90;
const char *pTitle = gEpisodeInfo[nEpisode].levels[nLevel].DisplayName();
if (*pTitle == 0)
return NULL;
return pTitle;
}
char * levelGetAuthor(void)
const char * levelGetAuthor(void)
{
int nEpisode = gGameOptions.nEpisode;
int nLevel = gGameOptions.nLevel;
char *pAuthor = gEpisodeInfo[nEpisode].at28[nLevel].atb0;
const char *pAuthor = gEpisodeInfo[nEpisode].levels[nLevel].author;
if (*pAuthor == 0)
return NULL;
return pAuthor;
@ -197,26 +197,27 @@ void levelSetupOptions(int nEpisode, int nLevel)
{
gGameOptions.nEpisode = nEpisode;
gGameOptions.nLevel = nLevel;
strcpy(gGameOptions.zLevelName, gEpisodeInfo[nEpisode].at28[nLevel].at0);
strcpy(gGameOptions.zLevelName, gEpisodeInfo[nEpisode].levels[nLevel].labelName);
gGameOptions.uMapCRC = dbReadMapCRC(gGameOptions.zLevelName);
gGameOptions.nTrackNumber = gEpisodeInfo[nEpisode].at28[nLevel].ate0;
gGameOptions.nTrackNumber = gEpisodeInfo[nEpisode].levels[nLevel].cdSongId;
}
void levelLoadMapInfo(IniFile *pIni, LEVELINFO *pLevelInfo, const char *pzSection)
void levelLoadMapInfo(IniFile *pIni, MapRecord *pLevelInfo, const char *pzSection, int epinum, int mapnum)
{
char buffer[16];
strncpy(pLevelInfo->at90, pIni->GetKeyString(pzSection, "Title", pLevelInfo->at0), 31);
strncpy(pLevelInfo->atb0, pIni->GetKeyString(pzSection, "Author", ""), 31);
strncpy(pLevelInfo->atd0, pIni->GetKeyString(pzSection, "Song", ""), BMAX_PATH);
pLevelInfo->ate0 = pIni->GetKeyInt(pzSection, "Track", -1);
pLevelInfo->ate4 = pIni->GetKeyInt(pzSection, "EndingA", -1);
pLevelInfo->ate8 = pIni->GetKeyInt(pzSection, "EndingB", -1);
pLevelInfo->at8ec = pIni->GetKeyInt(pzSection, "Fog", -0);
pLevelInfo->at8ed = pIni->GetKeyInt(pzSection, "Weather", -0);
pLevelInfo->SetName(pIni->GetKeyString(pzSection, "Title", pLevelInfo->labelName));
pLevelInfo->author = pIni->GetKeyString(pzSection, "Author", "");
pLevelInfo->music.Format("%s.%s", pIni->GetKeyString(pzSection, "Song", ""), ".mid");
pLevelInfo->cdSongId = pIni->GetKeyInt(pzSection, "Track", -1);
pLevelInfo->nextLevel = pIni->GetKeyInt(pzSection, "EndingA", -1); //if (pLevelInfo->nextLevel >= 0) pLevelInfo->nextLevel +epinum * kMaxLevels;
pLevelInfo->nextSecret = pIni->GetKeyInt(pzSection, "EndingB", -1); //if (pLevelInfo->nextSecret >= 0) pLevelInfo->nextSecret + epinum * kMaxLevels;
pLevelInfo->fog = pIni->GetKeyInt(pzSection, "Fog", -0);
pLevelInfo->weather = pIni->GetKeyInt(pzSection, "Weather", -0);
pLevelInfo->messageStart = 1024 + ((epinum * kMaxLevels) + mapnum) * kMaxMessages;
for (int i = 0; i < kMaxMessages; i++)
{
sprintf(buffer, "Message%d", i+1);
strncpy(pLevelInfo->atec[i], pIni->GetKeyString(pzSection, buffer, ""), 63);
quoteMgr.InitializeQuote(pLevelInfo->messageStart + i, pIni->GetKeyString(pzSection, buffer, ""), true);
}
}
@ -226,7 +227,7 @@ void levelLoadDefaults(void)
char buffer2[16];
levelInitINI(G_ConFile()); // This doubles for the INI in the global code.
memset(gEpisodeInfo, 0, sizeof(gEpisodeInfo));
strncpy(gEpisodeInfo[MUS_INTRO/kMaxLevels].at28[MUS_INTRO%kMaxLevels].atd0, "PESTIS", BMAX_PATH);
quoteMgr.InitializeQuote(MUS_INTRO, "PESTIS.MID");
int i;
for (i = 0; i < kMaxEpisodes; i++)
{
@ -253,17 +254,19 @@ 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++)
{
LEVELINFO *pLevelInfo = &pEpisodeInfo->at28[j];
auto pLevelInfo = &pEpisodeInfo->levels[j];
sprintf(buffer2, "Map%d", j+1);
if (!BloodINI->KeyExists(buffer, buffer2))
break;
const char *pMap = BloodINI->GetKeyString(buffer, buffer2, NULL);
CheckSectionAbend(pMap);
strncpy(pLevelInfo->at0, pMap, BMAX_PATH);
levelLoadMapInfo(BloodINI, pLevelInfo, pMap);
pLevelInfo->labelName = pMap;
pLevelInfo->fileName.Format("%s.map", pMap);
levelLoadMapInfo(BloodINI, pLevelInfo, pMap, i, j);
}
pEpisodeInfo->nLevels = j;
}
@ -289,24 +292,24 @@ void levelAddUserMap(const char *pzMap)
}
nLevel = pEpisodeInfo->nLevels++;
}
LEVELINFO *pLevelInfo = &pEpisodeInfo->at28[nLevel];
auto pLevelInfo = &pEpisodeInfo->levels[nLevel];
ChangeExtension(buffer, "");
strncpy(pLevelInfo->at0, buffer, BMAX_PATH);
levelLoadMapInfo(&UserINI, pLevelInfo, NULL);
pLevelInfo->name = buffer;
levelLoadMapInfo(&UserINI, pLevelInfo, NULL, nEpisode, nLevel);
gGameOptions.nEpisode = nEpisode;
gGameOptions.nLevel = nLevel;
gGameOptions.uMapCRC = dbReadMapCRC(pLevelInfo->at0);
strcpy(gGameOptions.zLevelName, pLevelInfo->at0);
gGameOptions.uMapCRC = dbReadMapCRC(pLevelInfo->name);
strcpy(gGameOptions.zLevelName, pLevelInfo->name);
}
void levelGetNextLevels(int nEpisode, int nLevel, int *pnEndingA, int *pnEndingB)
{
dassert(pnEndingA != NULL && pnEndingB != NULL);
LEVELINFO *pLevelInfo = &gEpisodeInfo[nEpisode].at28[nLevel];
int nEndingA = pLevelInfo->ate4;
auto pLevelInfo = &gEpisodeInfo[nEpisode].levels[nLevel];
int nEndingA = pLevelInfo->nextLevel;
if (nEndingA >= 0)
nEndingA--;
int nEndingB = pLevelInfo->ate8;
int nEndingB = pLevelInfo->nextSecret;
if (nEndingB >= 0)
nEndingB--;
*pnEndingA = nEndingA;
@ -396,14 +399,14 @@ int levelGetMusicIdx(const char *str)
bool levelTryPlayMusic(int nEpisode, int nLevel, bool bSetLevelSong)
{
char buffer[BMAX_PATH];
if (mus_redbook && gEpisodeInfo[nEpisode].at28[nLevel].ate0 > 0)
snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].at28[nLevel].ate0);
if (mus_redbook && gEpisodeInfo[nEpisode].levels[nLevel].cdSongId > 0)
snprintf(buffer, BMAX_PATH, "blood%02i.ogg", gEpisodeInfo[nEpisode].levels[nLevel].cdSongId);
else
{
strncpy(buffer, gEpisodeInfo[nEpisode].at28[nLevel].atd0, BMAX_PATH);
strncpy(buffer, gEpisodeInfo[nEpisode].levels[nLevel].music, BMAX_PATH);
}
if (!strchr(buffer, '.')) strcat(buffer, ".mid");
return !!Mus_Play(gEpisodeInfo[nEpisode].at28[nLevel].at0, buffer, true);
return !!Mus_Play(gEpisodeInfo[nEpisode].levels[nLevel].labelName, buffer, true);
}
void levelTryPlayMusicOrNothing(int nEpisode, int nLevel)

View file

@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma once
#include "common_game.h"
#include "inifile.h"
#include "mapinfo.h"
BEGIN_BLD_NS
@ -68,27 +69,13 @@ enum {
MUS_LOADING = MUS_FIRST_SPECIAL + 1,
};
struct LEVELINFO
{
char at0[BMAX_PATH]; // Filename
char at90[32]; // Title
char atb0[32]; // Author
char atd0[BMAX_PATH]; // Song;
int ate0; // SongId
int ate4; // EndingA
int ate8; // EndingB
char atec[kMaxMessages][64]; // Messages
char at8ec; // Fog
char at8ed; // Weather
}; // 0x8ee bytes
struct EPISODEINFO
{
//char at0[32]; removed, so that the global episode name table can be used for consistency
int nLevels;
unsigned int bloodbath : 1;
unsigned int cutALevel : 4;
LEVELINFO at28[kMaxLevels];
MapRecord* levels; // points into the global table.
char at8f08[BMAX_PATH];
char at8f98[BMAX_PATH];
int at9028;
@ -118,13 +105,12 @@ void levelSetupSecret(int nCount);
void levelTriggerSecret(int nSecret);
void CheckSectionAbend(const char *pzSection);
void CheckKeyAbend(const char *pzSection, const char *pzKey);
LEVELINFO * levelGetInfoPtr(int nEpisode, int nLevel);
char * levelGetFilename(int nEpisode, int nLevel);
char * levelGetMessage(int nMessage);
char * levelGetTitle(void);
char * levelGetAuthor(void);
MapRecord * levelGetInfoPtr(int nEpisode, int nLevel);
const char * levelGetFilename(int nEpisode, int nLevel);
const char * levelGetMessage(int nMessage);
const char * levelGetTitle(void);
const char * levelGetAuthor(void);
void levelSetupOptions(int nEpisode, int nLevel);
void levelLoadMapInfo(IniFile *pIni, LEVELINFO *pLevelInfo, const char *pzSection);
void levelLoadDefaults(void);
void levelAddUserMap(const char *pzMap);
// EndingA is normal ending, EndingB is secret level

View file

@ -209,13 +209,6 @@ bool GameInterface::SaveGame(FSaveGameNode* node)
Printf(TEXTCOLOR_RED "%s\n", err.what());
return false;
}
auto & li = gEpisodeInfo[gGameOptions.nEpisode].at28[gGameOptions.nLevel];
// workaround until the level info here has been transitioned.
MapRecord mr;
mr.name = li.at90;
mr.labelName = li.at0;
mr.fileName.Format("%s.map", li.at0);
currentLevel = &mr;
G_WriteSaveHeader(node->SaveTitle);
LoadSave::hSFile = NULL;

View file

@ -197,8 +197,8 @@ void CViewMap::sub_25C74(void)
videoClearScreen(0);
renderDrawMapView(x,y,nZoom>>2,angle);
sub_2541C(x,y,nZoom>>2,angle);
char *pTitle = levelGetTitle();
char *pFilename = levelGetFilename(gGameOptions.nEpisode, gGameOptions.nLevel);
const char *pTitle = levelGetTitle();
const char *pFilename = levelGetFilename(gGameOptions.nEpisode, gGameOptions.nLevel);
if (pTitle)
sprintf(pBuffer, "%s: %s", pFilename, pTitle);
else

View file

@ -4769,7 +4769,7 @@ void trInit(void)
void trTextOver(int nId)
{
char *pzMessage = levelGetMessage(nId);
const char *pzMessage = levelGetMessage(nId);
if (pzMessage)
viewSetMessage(pzMessage, VanillaMode() ? 0 : 8, MESSAGE_PRIORITY_INI); // 8: gold
}

View file

@ -2,6 +2,10 @@
#include "gstrings.h"
#include "cmdlib.h"
#include "quotemgr.h"
#ifdef GetMessage
#undef GetMessage // Windows strikes...
#endif
// Localization capable replacement of the game specific solutions.
@ -18,21 +22,21 @@ enum
struct MapRecord
{
int parTime;
int designerTime;
int parTime = -1;
int designerTime = -1;
FString fileName;
FString labelName;
FString name;
FString music;
int cdSongId;
int cdSongId = -1;
int flags = -1;
// The rest is only used by Blood
int nextLevel;
int nextSecret;
int messageStart; // messages are stored in the quote array to reduce clutter.
int nextLevel = -1;
int nextSecret = -1;
int messageStart = 0; // messages are stored in the quote array to reduce clutter.
FString author;
// bool fog, weather; // Blood defines these but they aren't used.
int flags;
int8_t fog = -1, weather = -1; // Blood defines these but they aren't used.
const char *DisplayName()
{
@ -49,6 +53,10 @@ struct MapRecord
fileName = n;
labelName = ExtractFileBase(n);
}
const char* GetMessage(int num)
{
return quoteMgr.GetQuote(messageStart + num);
}
};

View file

@ -601,7 +601,7 @@ CCMD(printstats)
ADD_STAT(statistics)
{
if (*StartEpisode == 0 || *LevelName == 0) return;
if (*StartEpisode == 0 || *LevelName == 0) return "";
StoreLevelStats(); // Refresh the current level's results.
return GetStatString();
}

View file

@ -419,7 +419,7 @@ void G_CacheMapData(void)
if (ud.recstat == 2)
return;
S_TryPlaySpecialMusic(MUS_LOADING);
//S_TryPlaySpecialMusic(MUS_LOADING);
uint32_t const cacheStartTime = timerGetTicks();

View file

@ -149,7 +149,7 @@ void S_PlayLevelMusicOrNothing(unsigned int m)
{
// Thanks to scripting that stupid slot hijack cannot be refactored - but we'll store the real data elsewhere anyway!
auto &mr = m == USERMAPMUSICFAKESLOT ? userMapRecord : mapList[m];
Mus_Play(mr.fileName, mr.music, true);
Mus_Play(mr.labelName, mr.music, true);
S_SetMusicIndex(m);
}
}

View file

@ -125,7 +125,7 @@ void S_MenuSound(void)
void S_PlayLevelMusicOrNothing(unsigned int m)
{
Mus_Play(mapList[m].fileName, RR ? nullptr : mapList[m].music, true);
Mus_Play(mapList[m].labelName, RR ? nullptr : mapList[m].music, true);
}
int S_TryPlaySpecialMusic(unsigned int m)