- added JFDuke's label type checker and did some cleanup on the CON init code.

Most importantly: Use dynamic buffers for managing the labels instead of hijacking some other storage space.
This commit is contained in:
Christoph Oelckers 2020-07-15 12:34:42 +02:00
parent 866be28da0
commit a9f152c1fe
16 changed files with 316 additions and 273 deletions

View file

@ -218,11 +218,17 @@ void levelLoadMapInfo(IniFile *pIni, MapRecord *pLevelInfo, const char *pzSectio
} }
} }
static const char* DefFile(void)
{
// The command line parser stores this in the CON field.
return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : "blood.ini";
}
void levelLoadDefaults(void) void levelLoadDefaults(void)
{ {
char buffer[64]; char buffer[64];
char buffer2[16]; char buffer2[16];
levelInitINI(G_ConFile()); // This doubles for the INI in the global code. levelInitINI(DefFile());
memset(gEpisodeInfo, 0, sizeof(gEpisodeInfo)); memset(gEpisodeInfo, 0, sizeof(gEpisodeInfo));
quoteMgr.InitializeQuote(MUS_INTRO, "PESTIS.MID"); quoteMgr.InitializeQuote(MUS_INTRO, "PESTIS.MID");
int i; int i;

View file

@ -541,7 +541,7 @@ DEFINE_ACTION_FUNCTION(_CVar, FindCVar)
// //
// //
//============================================================================= //=============================================================================
#if 0
DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind) DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
@ -606,7 +606,7 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
C_DoCommand(cmd); C_DoCommand(cmd);
return 0; return 0;
} }
#endif
DEFINE_ACTION_FUNCTION(_Console, MidPrint) DEFINE_ACTION_FUNCTION(_Console, MidPrint)
{ {
PARAM_PROLOGUE; PARAM_PROLOGUE;

View file

@ -406,6 +406,32 @@ void UserConfig::ProcessOptions()
} }
//==========================================================================
//
//
//
//==========================================================================
void CheckUserMap()
{
if (userConfig.CommandMap.IsEmpty()) return;
FString startupMap = userConfig.CommandMap;
if (startupMap.IndexOfAny("/\\") < 0) startupMap.Insert(0, "/");
DefaultExtension(startupMap, ".map");
startupMap.Substitute("\\", "/");
NormalizeFileName(startupMap);
if (fileSystem.FileExists(startupMap))
{
Printf("Using level: \"%s\".\n", startupMap.GetChars());
}
else
{
Printf("Level \"%s\" not found.\n", startupMap.GetChars());
startupMap = "";
}
userConfig.CommandMap = startupMap;
}
//========================================================================== //==========================================================================
// //
@ -798,6 +824,7 @@ int RunGame()
{ {
playername = userConfig.CommandName; playername = userConfig.CommandName;
} }
CheckUserMap();
GPalette.Init(MAXPALOOKUPS + 2); // one slot for each translation, plus a separate one for the base palettes and the internal one GPalette.Init(MAXPALOOKUPS + 2); // one slot for each translation, plus a separate one for the base palettes and the internal one
TexMan.Init([]() {}, [](BuildInfo &) {}); TexMan.Init([]() {}, [](BuildInfo &) {});
V_InitFonts(); V_InitFonts();
@ -811,7 +838,6 @@ int RunGame()
LoadScripts(); LoadScripts();
M_Init(); M_Init();
SetDefaultStrings(); SetDefaultStrings();
if (g_gameType & (GAMEFLAG_RR)) InitRREndMap(); // this needs to be done better later
if (Args->CheckParm("-sounddebug")) if (Args->CheckParm("-sounddebug"))
C_DoCommand("stat sounddebug"); C_DoCommand("stat sounddebug");

View file

@ -146,8 +146,6 @@ struct GrpEntry
extern int g_gameType; extern int g_gameType;
const char* G_DefaultDefFile(void); const char* G_DefaultDefFile(void);
const char* G_DefFile(void); const char* G_DefFile(void);
const char* G_DefaultConFile(void);
const char* G_ConFile(void);
// game check shortcuts // game check shortcuts
inline bool isNam() inline bool isNam()

View file

@ -134,13 +134,3 @@ MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic)
map->music = G_SetupFilenameBasedMusic(boardfilename, defaultmusic); map->music = G_SetupFilenameBasedMusic(boardfilename, defaultmusic);
return map; return map;
} }
void InitRREndMap()
{
// RR defines its end map ad-hoc so give it a proper entry to reference (the last one in episode 2 because it needs to be in Ep. 2.)
mapList[127].SetName("$TXT_CLOSEENCOUNTERS");
mapList[127].SetFileName("endgame.map");
mapList[127].levelNumber = 163; // last one in Ep. 2.
}

View file

@ -73,7 +73,6 @@ extern MapRecord mapList[512];
extern MapRecord *currentLevel; extern MapRecord *currentLevel;
bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false); bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false);
void InitRREndMap();
MapRecord *FindMapByName(const char *nm); MapRecord *FindMapByName(const char *nm);
MapRecord *FindMapByLevelNum(int num); MapRecord *FindMapByLevelNum(int num);

View file

@ -58,6 +58,7 @@ FSavegameManager savegameManager;
void FSavegameManager::LoadGame(FSaveGameNode* node) void FSavegameManager::LoadGame(FSaveGameNode* node)
{ {
inputState.ClearAllInput();
if (gi->CleanupForLoad()) if (gi->CleanupForLoad())
{ {
if (OpenSaveGameForRead(node->Filename)) if (OpenSaveGameForRead(node->Filename))

View file

@ -924,53 +924,6 @@ const char* G_DefFile(void)
} }
//==========================================================================
//
// Fallback in case nothing got defined.
// Also used by 'includedefault' which forces this to be statically defined
//
//==========================================================================
const char* G_DefaultConFile(void)
{
if (g_gameType & GAMEFLAG_BLOOD)
return "blood.ini"; // Blood doesn't have CON files but the common code treats its INI files the same, so return that here.
if (g_gameType & GAMEFLAG_WW2GI)
{
if (fileSystem.FindFile("ww2gi.con") >= 0) return "ww2gi.con";
}
if (g_gameType & (GAMEFLAG_SW|GAMEFLAG_PSEXHUMED))
return nullptr; // Exhumed and SW have no scripts of any kind.
if (g_gameType & GAMEFLAG_NAM)
{
if (fileSystem.FindFile("nam.con") >= 0) return "nam.con";
if (fileSystem.FindFile("napalm.con") >= 0) return "napalm.con";
}
if (g_gameType & GAMEFLAG_NAPALM)
{
if (fileSystem.FindFile("napalm.con") >= 0) return "napalm.con";
if (fileSystem.FindFile("nam.con") >= 0) return "nam.con";
}
if (g_gameType & GAMEFLAG_DUKE)
{
if (fileSystem.FindFile("eduke.con") >= 0) return "eduke.con"; // No, we're not EDUKE, but several mods expect this to work.
}
// the other games only use game.con.
return "game.con";
}
const char* G_ConFile(void)
{
return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : G_DefaultConFile();
}
#if 0 #if 0
// Should this be added to the game data collector? // Should this be added to the game data collector?
bool AddINIFile(const char* pzFile, bool bForce = false) bool AddINIFile(const char* pzFile, bool bForce = false)

View file

@ -572,7 +572,7 @@ void dobonus_r(bool bonusonly, CompletionFunc completion)
} }
else if (!bonusonly && ud.multimode <= 1) else if (!bonusonly && ud.multimode <= 1)
{ {
if (isRRRA() && !boardfilename[0] && currentLevel->levelNumber < 106) // fixme: The logic here is awful. Shift more control to the map records. if (isRRRA() && !(currentLevel->flags & MI_USERMAP) && currentLevel->levelNumber < 106) // fixme: The logic here is awful. Shift more control to the map records.
{ {
jobs[job++] = { Create<DRRLevelSummaryScreen>(true) }; jobs[job++] = { Create<DRRLevelSummaryScreen>(true) };
int levnum = clamp((currentLevel->levelNumber / 100) * 7 + (currentLevel->levelNumber % 100), 0, 13); int levnum = clamp((currentLevel->levelNumber / 100) * 7 + (currentLevel->levelNumber % 100), 0, 13);

View file

@ -161,6 +161,8 @@ static int ccmd_restartmap(CCmdFuncPtr)
return CCMD_OK; return CCMD_OK;
} }
int getlabelvalue(const char* text);
static int ccmd_spawn(CCmdFuncPtr parm) static int ccmd_spawn(CCmdFuncPtr parm)
{ {
int x = 0, y = 0, z = 0; int x = 0, y = 0, z = 0;
@ -191,20 +193,8 @@ static int ccmd_spawn(CCmdFuncPtr parm)
picnum = (unsigned short)atol(parm->parms[0]); picnum = (unsigned short)atol(parm->parms[0]);
} }
else { else {
int i, j; picnum = getlabelvalue(parm->parms[0]);
for (j = 0; j < 2; j++) { if (picnum < 0) {
for (i = 0; i < labelcnt; i++) {
if (
(j == 0 && !strcmp(label + (i * MAXLABELLEN), parm->parms[0])) ||
(j == 1 && !stricmp(label + (i * MAXLABELLEN), parm->parms[0]))
) {
picnum = (unsigned short)labelcode[i];
break;
}
}
if (i < labelcnt) break;
}
if (i == labelcnt) {
Printf("spawn: Invalid tile label given\n"); Printf("spawn: Invalid tile label given\n");
return CCMD_OK; return CCMD_OK;
} }

View file

@ -43,8 +43,6 @@ extern int rtsplaying;
#ifndef ONLY_USERDEFS #ifndef ONLY_USERDEFS
extern char boardfilename[BMAX_PATH];
extern int32_t g_Shareware; extern int32_t g_Shareware;
extern int32_t cameraclock; extern int32_t cameraclock;
extern int32_t cameradist; extern int32_t cameradist;

View file

@ -46,11 +46,10 @@ into many sub-files.
BEGIN_DUKE_NS BEGIN_DUKE_NS
// parser state: todo: turn into a class // parser state: todo: turn into a class
char* textptr; char* textptr;
char* label;
int line_number; int line_number;
int labelcnt;
int errorcount, warningcount; // was named 'error' and 'warning' which is too generic for public variables and may clash with other code. int errorcount, warningcount; // was named 'error' and 'warning' which is too generic for public variables and may clash with other code.
int g_currentSourceFile; int g_currentSourceFile;
uint32_t parsing_actor, parsing_event; uint32_t parsing_actor, parsing_event;
@ -60,7 +59,6 @@ int checking_ifelse;
//G_EXTERN char tempbuf[MAXSECTORS << 1], buf[1024]; todo - move to compile state. tempbuf gets used nearly everywhere as scratchpad memory. //G_EXTERN char tempbuf[MAXSECTORS << 1], buf[1024]; todo - move to compile state. tempbuf gets used nearly everywhere as scratchpad memory.
extern char tempbuf[]; extern char tempbuf[];
extern int* labelcode;
TArray<int> ScriptCode; TArray<int> ScriptCode;
@ -111,6 +109,62 @@ void SortCommands()
qsort(cmdList, countof(cmdList), sizeof(ConCommand), cmdCmp); qsort(cmdList, countof(cmdList), sizeof(ConCommand), cmdCmp);
} }
//---------------------------------------------------------------------------
//
// label data
//
//---------------------------------------------------------------------------
enum labeltypes {
LABEL_ANY = -1,
LABEL_DEFINE = 1,
LABEL_STATE = 2,
LABEL_ACTOR = 4,
LABEL_ACTION = 8,
LABEL_AI = 16,
LABEL_MOVE = 32,
};
static const char* labeltypenames[] = {
"define",
"state",
"actor",
"action",
"ai",
"move"
};
class labelstring
{
char text[64];
public:
char& operator[](size_t pos)
{
return text[pos];
}
operator const char* () { return text; }
const char* GetChars() { return text; }
int compare(const char* c) const { return strcmp(text, c); }
int comparei(const char* c) const { return stricmp(text, c); }
labelstring& operator=(const char* c) { strncpy(text, c, 64); text[63] = 0; }
};
struct labeldef
{
labelstring name;
labeltypes type;
int value;
int compare(const char* c) const { return name.compare(c); }
const char* GetChars() { return name.GetChars(); }
};
TArray<labeldef> labels;
static labelstring parselabel;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //
@ -138,7 +192,7 @@ void ReportError(int iError)
{ {
case ERROR_ISAKEYWORD: case ERROR_ISAKEYWORD:
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Symbol '%s' is a key word.\n", Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Symbol '%s' is a key word.\n",
fn, line_number, label + (labelcnt << 6)); fn, line_number, parselabel.GetChars());
break; break;
case ERROR_PARMUNDEFINED: case ERROR_PARMUNDEFINED:
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Parameter '%s' is undefined.\n", Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Parameter '%s' is undefined.\n",
@ -146,23 +200,23 @@ void ReportError(int iError)
break; break;
case WARNING_DUPLICATEDEFINITION: case WARNING_DUPLICATEDEFINITION:
Printf(TEXTCOLOR_YELLOW " * WARNING.(%s, line %d) Duplicate definition '%s' ignored.\n", Printf(TEXTCOLOR_YELLOW " * WARNING.(%s, line %d) Duplicate definition '%s' ignored.\n",
fn, line_number, label + (labelcnt << 6)); fn, line_number, parselabel.GetChars());
break; break;
case ERROR_COULDNOTFIND: case ERROR_COULDNOTFIND:
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Could not find '%s'.\n", Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Could not find '%s'.\n",
fn, line_number, label + (labelcnt << 6)); fn, line_number, parselabel.GetChars());
break; break;
case ERROR_VARREADONLY: case ERROR_VARREADONLY:
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Variable '%s' is read-only.\n", Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Variable '%s' is read-only.\n",
fn, line_number, label + (labelcnt << 6)); fn, line_number, parselabel.GetChars());
break; break;
case ERROR_NOTAGAMEDEF: case ERROR_NOTAGAMEDEF:
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Symbol '%s' is not a Game Definition.\n", Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Symbol '%s' is not a Game Definition.\n",
fn, line_number, label + (labelcnt << 6)); fn, line_number, parselabel.GetChars());
break; break;
case ERROR_NOTAGAMEVAR: case ERROR_NOTAGAMEVAR:
Printf(TEXTCOLOR_RED " * ERROR! (%s, line %d) Symbol '%s' is not a defined Game Variable.\n", Printf(TEXTCOLOR_RED " * ERROR! (%s, line %d) Symbol '%s' is not a defined Game Variable.\n",
fn, line_number, label + (labelcnt << 6)); fn, line_number, parselabel.GetChars());
break; break;
case ERROR_OPENBRACKET: case ERROR_OPENBRACKET:
Printf(TEXTCOLOR_RED " * ERROR! (%s, line %d) Found more '{' than '}' before '%s'.\n", Printf(TEXTCOLOR_RED " * ERROR! (%s, line %d) Found more '{' than '}' before '%s'.\n",
@ -218,18 +272,48 @@ int getkeyword(const char* text)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int findlabel(const char* text) FString translatelabeltype(int type)
{ {
for (int j = 0; j < labelcnt; j++) FString buf;
for (int i = 0; i < 6; i++)
{ {
if (strcmp(label + (j << 6), text) == 0) if (!(type & (1 << i))) continue;
if (buf.Len()) buf += " or ";
buf += labeltypenames[i];
}
return buf;
}
int findlabel(const char* text, bool ignorecase = false)
{
for (unsigned j = 0; j < labels.Size(); j++)
{
if (labels[j].compare(text) == 0)
{ {
return j; return j;
} }
} }
if (ignorecase)
{
for (unsigned j = 0; j < labels.Size(); j++)
{
if (labels[j].name.comparei(text) == 0)
{
return j;
}
}
}
return -1; return -1;
} }
// This is for the 'spawn' CCMD.
int getlabelvalue(const char* text)
{
int lnum = findlabel(text, true);
if (labels[lnum].type != LABEL_DEFINE) return -1;
return lnum < 0 ? -1 : labels[lnum].value;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //
@ -367,9 +451,9 @@ void getlabel(void)
i = 0; i = 0;
while (ispecial(*textptr) == 0) while (ispecial(*textptr) == 0)
label[(labelcnt << 6) + i++] = *(textptr++); parselabel[i++] = *(textptr++);
label[(labelcnt << 6) + i] = 0; parselabel[i] = 0;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -413,21 +497,20 @@ void pushlabeladdress()
} }
*/ */
void appendlabelvalue(labeltypes type, int value)
void appendlabeladdress(int offset = 0)
{ {
labelcode[labelcnt++] = ScriptCode.Size() + offset; labels.Reserve(1);
labelcnt++; labels.Last().type = type;
labels.Last().name = parselabel;
labels.Last().value = value;
} }
void appendlabelvalue(int value) void appendlabeladdress(labeltypes type, int offset = 0)
{ {
labelcode[labelcnt++] = value; appendlabelvalue(type, ScriptCode.Size() + offset);
labelcnt++;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //
@ -493,9 +576,9 @@ int transword(void) //Returns its code #
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int transnum(void) int transnum(int type)
{ {
int i, l; int l;
while (isaltok(*textptr) == 0) while (isaltok(*textptr) == 0)
{ {
@ -525,13 +608,24 @@ int transnum(void)
} }
for (i = 0; i < labelcnt; i++) for (unsigned i = 0; i < labels.Size(); i++)
{ {
if (strcmp(tempbuf, label + (i << 6)) == 0) if (labels[i].compare(tempbuf) == 0)
{ {
appendscriptvalue(labelcode[i]); // Non-values can be compared with 0.
if (labels[i].type & type || (labels[i].value == 0))
{
appendscriptvalue(labels[i].value);
textptr += l;
return labels[i].value;
}
appendscriptvalue(0);
textptr += l; textptr += l;
return labelcode[i]; auto el = translatelabeltype(type);
auto gl = translatelabeltype(labels[i].type);
const char* fn = fileSystem.GetFileFullName(g_currentSourceFile);
Printf(TEXTCOLOR_YELLOW " * WARNING.(%s, line %d) %s: Expected a '%s' label but found a '%s' label instead.\n", fn, line_number, labels[i].GetChars(), el.GetChars(), gl.GetChars());
return -1; // valid label name, but wrong type
} }
} }
@ -553,14 +647,22 @@ int transnum(void)
// that ignores octal conversion. // that ignores octal conversion.
int64_t value; int64_t value;
char *outp; char *outp;
bool ishex = (textptr[0] == 0 && tolower(textptr[1]) == 'x') || (textptr[0] == '-' && textptr[1] == 0 && tolower(textptr[2]) == 'x'); bool ishex = (textptr[0] == '0' && tolower(textptr[1]) == 'x') || (textptr[0] == '-' && textptr[1] == '0' && tolower(textptr[2]) == 'x');
if (*textptr == '-') value = strtoll(textptr, &outp, ishex? 16 : 10); if (*textptr == '-') value = strtoll(textptr, &outp, ishex? 0 : 10);
else value = strtoull(textptr, &outp, ishex ? 16 : 10); else value = strtoull(textptr, &outp, ishex ? 0 : 10);
if (*outp != 0) if (*outp != 0)
{ {
// conversion was not successful. // conversion was not successful.
} }
appendscriptvalue(int(value)); // truncate the parsed value to 32 bit. appendscriptvalue(int(value)); // truncate the parsed value to 32 bit.
if (type != LABEL_DEFINE && value != 0)
{
const char* fn = fileSystem.GetFileFullName(g_currentSourceFile);
Printf(TEXTCOLOR_YELLOW " * WARNING.(%s, line %d) Expected an identifier, got a numeric literal %d.\n", fn, line_number, (int)value);
}
textptr += l; textptr += l;
return int(value); return int(value);
} }
@ -574,7 +676,7 @@ int transnum(void)
void checkforkeyword() void checkforkeyword()
{ {
if (getkeyword(label + (labelcnt << 6)) >= 0) if (getkeyword(parselabel) >= 0)
{ {
errorcount++; errorcount++;
ReportError(ERROR_ISAKEYWORD); ReportError(ERROR_ISAKEYWORD);
@ -614,7 +716,7 @@ int parsecommand()
{ {
getlabel(); getlabel();
popscriptvalue(); popscriptvalue();
appendlabeladdress(); appendlabeladdress(LABEL_STATE);
parsing_state = 1; parsing_state = 1;
@ -624,14 +726,14 @@ int parsecommand()
getlabel(); getlabel();
checkforkeyword(); checkforkeyword();
lnum = findlabel(label + (labelcnt << 6)); lnum = findlabel(parselabel);
if (lnum < 0) if (lnum < 0)
{ {
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) State '%s' not found.\n", fn, line_number, label + (labelcnt << 6)); Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) State '%s' not found.\n", fn, line_number, parselabel.GetChars());
errorcount++; errorcount++;
} }
appendscriptvalue(labelcode[lnum]); appendscriptvalue(labels[lnum].value);
return 0; return 0;
case concmd_ends: case concmd_ends:
@ -665,25 +767,25 @@ int parsecommand()
// Check to see it's already defined // Check to see it's already defined
popscriptvalue(); popscriptvalue();
if (getkeyword(label + (labelcnt << 6)) >= 0) if (getkeyword(parselabel) >= 0)
{ {
errorcount++; errorcount++;
ReportError(ERROR_ISAKEYWORD); ReportError(ERROR_ISAKEYWORD);
return 0; return 0;
} }
transnum(); // get initial value transnum(LABEL_DEFINE); // get initial value
j = popscriptvalue(); j = popscriptvalue();
transnum(); // get flags transnum(LABEL_DEFINE); // get flags
lnum = popscriptvalue(); lnum = popscriptvalue();
AddGameVar(label + (labelcnt << 6), j, lnum & (~(GAMEVAR_FLAG_DEFAULT | GAMEVAR_FLAG_SECRET))); AddGameVar(parselabel, j, lnum & (~(GAMEVAR_FLAG_DEFAULT | GAMEVAR_FLAG_SECRET)));
return 0; return 0;
case concmd_define: case concmd_define:
getlabel(); getlabel();
checkforkeyword(); checkforkeyword();
lnum = findlabel(label + (labelcnt << 6)); lnum = findlabel(parselabel);
if (lnum >= 0) if (lnum >= 0)
{ {
warningcount++; warningcount++;
@ -691,11 +793,11 @@ int parsecommand()
break; break;
} }
transnum(); transnum(LABEL_DEFINE);
i = popscriptvalue(); i = popscriptvalue();
if (lnum < 0) if (lnum < 0)
{ {
appendlabelvalue(i); appendlabelvalue(LABEL_DEFINE, i);
} }
popscriptvalue(); popscriptvalue();
return 0; return 0;
@ -705,7 +807,7 @@ int parsecommand()
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
{ {
if (keyword() == -1) if (keyword() == -1)
transnum(); transnum(LABEL_DEFINE);
else break; else break;
} }
@ -719,12 +821,12 @@ int parsecommand()
case concmd_move: case concmd_move:
if (parsing_actor || parsing_state) if (parsing_actor || parsing_state)
{ {
transnum(); transnum(LABEL_MOVE);
j = 0; j = 0;
while (keyword() == -1) while (keyword() == -1)
{ {
transnum(); transnum(LABEL_DEFINE);
j |= popscriptvalue(); j |= popscriptvalue();
} }
appendscriptvalue(j); appendscriptvalue(j);
@ -737,19 +839,19 @@ int parsecommand()
checkforkeyword(); checkforkeyword();
for (i = 0; i < labelcnt; i++) for (i = 0; i < (int)labels.Size(); i++)
if (strcmp(label + (labelcnt << 6), label + (i << 6)) == 0) if (labels[i].compare(parselabel) == 0)
{ {
warningcount++; warningcount++;
Printf(TEXTCOLOR_RED " * WARNING.(%s, line %d) Duplicate move '%s' ignored.\n", fn, line_number, label + (labelcnt << 6)); Printf(TEXTCOLOR_RED " * WARNING.(%s, line %d) Duplicate move '%s' ignored.\n", fn, line_number, parselabel);
break; break;
} }
if (i == labelcnt) if (i == labels.Size())
appendlabeladdress(); appendlabeladdress(LABEL_MOVE);
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
{ {
if (keyword() >= 0) break; if (keyword() >= 0) break;
transnum(); transnum(LABEL_DEFINE);
} }
for (k = j; k < 2; k++) for (k = j; k < 2; k++)
{ {
@ -761,7 +863,7 @@ int parsecommand()
case concmd_music: case concmd_music:
{ {
popscriptvalue(); popscriptvalue();
transnum(); // Volume Number (0/4) transnum(LABEL_DEFINE); // Volume Number (0/4)
k = popscriptvalue() - 1; k = popscriptvalue() - 1;
if (k < 0) specialmusic.Clear(); if (k < 0) specialmusic.Clear();
@ -856,20 +958,20 @@ int parsecommand()
case concmd_ai: case concmd_ai:
if (parsing_actor || parsing_state) if (parsing_actor || parsing_state)
transnum(); transnum(LABEL_AI);
else else
{ {
popscriptvalue(); popscriptvalue();
getlabel(); getlabel();
checkforkeyword(); checkforkeyword();
lnum = findlabel(label + (labelcnt << 6)); lnum = findlabel(parselabel);
if (lnum >= 0) if (lnum >= 0)
{ {
warningcount++; warningcount++;
Printf(TEXTCOLOR_RED " * WARNING.(%s, line %d) Duplicate ai '%s' ignored.\n", fn, line_number, label + (labelcnt << 6)); Printf(TEXTCOLOR_RED " * WARNING.(%s, line %d) Duplicate ai '%s' ignored.\n", fn, line_number, parselabel);
} }
else appendlabeladdress(); else appendlabeladdress(LABEL_AI);
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
{ {
@ -879,13 +981,13 @@ int parsecommand()
k = 0; k = 0;
while (keyword() == -1) while (keyword() == -1)
{ {
transnum(); transnum(LABEL_DEFINE);
k |= popscriptvalue(); k |= popscriptvalue();
} }
appendscriptvalue(k); appendscriptvalue(k);
return 0; return 0;
} }
else transnum(); else transnum(j==0? LABEL_ACTION : LABEL_MOVE);
} }
for (k = j; k < 3; k++) for (k = j; k < 3; k++)
{ {
@ -896,25 +998,25 @@ int parsecommand()
case concmd_action: case concmd_action:
if (parsing_actor || parsing_state) if (parsing_actor || parsing_state)
transnum(); transnum(LABEL_ACTION);
else else
{ {
popscriptvalue(); popscriptvalue();
getlabel(); getlabel();
checkforkeyword(); checkforkeyword();
lnum = findlabel(label + (labelcnt << 6)); lnum = findlabel(parselabel);
if (lnum >= 0) if (lnum >= 0)
{ {
warningcount++; warningcount++;
Printf(TEXTCOLOR_RED " * WARNING.(%s, line %d) Duplicate event '%s' ignored.\n", fn, line_number, label + (labelcnt << 6)); Printf(TEXTCOLOR_RED " * WARNING.(%s, line %d) Duplicate event '%s' ignored.\n", fn, line_number, parselabel);
} }
else appendlabeladdress(); else appendlabeladdress(LABEL_ACTION);
for (j = 0; j < 5; j++) for (j = 0; j < 5; j++)
{ {
if (keyword() >= 0) break; if (keyword() >= 0) break;
transnum(); transnum(LABEL_DEFINE);
} }
for (k = j; k < 5; k++) for (k = j; k < 5; k++)
{ {
@ -944,11 +1046,11 @@ int parsecommand()
if (tw == concmd_useractor) if (tw == concmd_useractor)
{ {
transnum(); transnum(LABEL_DEFINE);
j = popscriptvalue(); j = popscriptvalue();
} }
transnum(); transnum(LABEL_DEFINE);
lnum = popscriptvalue(); lnum = popscriptvalue();
actorinfo[lnum].scriptaddress = parsing_actor; // TRANSITIONAL should only store an index actorinfo[lnum].scriptaddress = parsing_actor; // TRANSITIONAL should only store an index
@ -969,7 +1071,7 @@ int parsecommand()
j = 0; j = 0;
while (keyword() == -1) while (keyword() == -1)
{ {
transnum(); transnum(LABEL_DEFINE);
j |= popscriptvalue(); j |= popscriptvalue();
} }
@ -983,7 +1085,12 @@ int parsecommand()
reservescriptspace(4 - j); reservescriptspace(4 - j);
break; break;
} }
transnum(); switch (j)
{
case 0: transnum(LABEL_DEFINE); break;
case 1: transnum(LABEL_ACTION); break;
case 2: transnum(LABEL_MOVE | LABEL_DEFINE); break;
}
// This code was originally here but is a no-op, because both source and destination are the same here. // This code was originally here but is a no-op, because both source and destination are the same here.
//*(parsing_actor + j) = *(scriptaddress - 1); //*(parsing_actor + j) = *(scriptaddress - 1);
} }
@ -1011,7 +1118,7 @@ int parsecommand()
popscriptvalue(); popscriptvalue();
parsing_event = parsing_actor = scriptpos(); parsing_event = parsing_actor = scriptpos();
transnum(); transnum(LABEL_DEFINE);
j = popscriptvalue(); j = popscriptvalue();
if (j< 0 || j> EVENT_MAXEVENT) if (j< 0 || j> EVENT_MAXEVENT)
{ {
@ -1027,7 +1134,7 @@ int parsecommand()
case concmd_cstat: case concmd_cstat:
transnum(); transnum(LABEL_DEFINE);
#if 0 #if 0
// the following checks are being performed by EDuke32 and RedNukem - not sure if this really should be done. // the following checks are being performed by EDuke32 and RedNukem - not sure if this really should be done.
// DukeGDX and RedneckGDX do not perform these checks. Code pasted here for making a decision later. // DukeGDX and RedneckGDX do not perform these checks. Code pasted here for making a decision later.
@ -1076,7 +1183,7 @@ int parsecommand()
case concmd_isdrunk: case concmd_isdrunk:
case concmd_iseat: case concmd_iseat:
case concmd_newpic: case concmd_newpic:
transnum(); transnum(LABEL_DEFINE);
return 0; return 0;
case concmd_addammo: case concmd_addammo:
@ -1086,16 +1193,16 @@ int parsecommand()
case concmd_debris: case concmd_debris:
case concmd_addinventory: case concmd_addinventory:
case concmd_guts: case concmd_guts:
transnum(); transnum(LABEL_DEFINE);
transnum(); transnum(LABEL_DEFINE);
return 0; return 0;
case concmd_hitradius: case concmd_hitradius:
transnum(); transnum(LABEL_DEFINE);
transnum(); transnum(LABEL_DEFINE);
transnum(); transnum(LABEL_DEFINE);
transnum(); transnum(LABEL_DEFINE);
transnum(); transnum(LABEL_DEFINE);
break; break;
case concmd_else: case concmd_else:
@ -1127,7 +1234,7 @@ int parsecommand()
// Check to see if it's a keyword // Check to see if it's a keyword
checkforkeyword(); checkforkeyword();
i = GetDefID(label + (labelcnt << 6)); i = GetDefID(parselabel);
if (i < 0) if (i < 0)
{ // not a defined DEF { // not a defined DEF
errorcount++; errorcount++;
@ -1143,7 +1250,7 @@ int parsecommand()
} }
appendscriptvalue(i); // the ID of the DEF (offset into array...) appendscriptvalue(i); // the ID of the DEF (offset into array...)
transnum(); // the number to check against... transnum(LABEL_DEFINE); // the number to check against...
return 0; return 0;
case concmd_setvarvar: case concmd_setvarvar:
@ -1157,7 +1264,7 @@ int parsecommand()
checkforkeyword(); checkforkeyword();
i = GetDefID(label + (labelcnt << 6)); i = GetDefID(parselabel);
if (i < 0) if (i < 0)
{ // not a defined DEF { // not a defined DEF
errorcount++; errorcount++;
@ -1177,7 +1284,7 @@ int parsecommand()
getlabel(); //GetGameVarLabel(); getlabel(); //GetGameVarLabel();
checkforkeyword(); checkforkeyword();
i = GetDefID(label + (labelcnt << 6)); i = GetDefID(parselabel);
if (i < 0) if (i < 0)
{ // not a defined DEF { // not a defined DEF
errorcount++; errorcount++;
@ -1197,7 +1304,7 @@ int parsecommand()
checkforkeyword(); checkforkeyword();
i = GetDefID(label + (labelcnt << 6)); i = GetDefID(parselabel);
if (i < 0) if (i < 0)
{ // not a defined DEF { // not a defined DEF
errorcount++; errorcount++;
@ -1211,7 +1318,7 @@ int parsecommand()
checkforkeyword(); checkforkeyword();
i = GetDefID(label + (labelcnt << 6)); i = GetDefID(parselabel);
if (i < 0) if (i < 0)
{ // not a defined DEF { // not a defined DEF
errorcount++; errorcount++;
@ -1229,7 +1336,7 @@ int parsecommand()
getlabel(); //GetGameVarLabel(); getlabel(); //GetGameVarLabel();
checkforkeyword(); checkforkeyword();
i = GetDefID(label + (labelcnt << 6)); i = GetDefID(parselabel);
if (i < 0) if (i < 0)
{ // not a defined DEF { // not a defined DEF
errorcount++; errorcount++;
@ -1238,7 +1345,7 @@ int parsecommand()
} }
appendscriptvalue(i); // the ID of the DEF (offset into array...) appendscriptvalue(i); // the ID of the DEF (offset into array...)
transnum(); // the number to check against... transnum(LABEL_DEFINE); // the number to check against...
goto if_common; goto if_common;
case concmd_addlogvar: case concmd_addlogvar:
@ -1252,7 +1359,7 @@ int parsecommand()
checkforkeyword(); checkforkeyword();
i = GetDefID(label + (labelcnt << 6)); i = GetDefID(parselabel);
if (i < 0) if (i < 0)
{ // not a defined DEF { // not a defined DEF
errorcount++; errorcount++;
@ -1277,14 +1384,14 @@ int parsecommand()
j = 0; j = 0;
do do
{ {
transnum(); transnum(LABEL_DEFINE);
j |= popscriptvalue(); j |= popscriptvalue();
} while (keyword() == -1); } while (keyword() == -1);
appendscriptvalue(j); appendscriptvalue(j);
goto if_common; goto if_common;
case concmd_ifpinventory: case concmd_ifpinventory:
transnum(); transnum(LABEL_DEFINE);
case concmd_ifrnd: case concmd_ifrnd:
case concmd_ifpdistl: case concmd_ifpdistl:
case concmd_ifpdistg: case concmd_ifpdistg:
@ -1309,7 +1416,7 @@ int parsecommand()
case concmd_ifactorhealthl: case concmd_ifactorhealthl:
case concmd_ifsoundid: case concmd_ifsoundid:
case concmd_ifsounddist: case concmd_ifsounddist:
transnum(); transnum(tw == concmd_ifai? LABEL_AI : tw == concmd_ifaction? LABEL_ACTION : tw == concmd_ifmove? LABEL_MOVE : LABEL_DEFINE);
case concmd_ifonwater: case concmd_ifonwater:
case concmd_ifinwater: case concmd_ifinwater:
case concmd_ifactornotstayput: case concmd_ifactornotstayput:
@ -1377,7 +1484,7 @@ int parsecommand()
case concmd_definevolumename: case concmd_definevolumename:
popscriptvalue(); popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
j = popscriptvalue(); j = popscriptvalue();
while (*textptr == ' ' || *textptr == '\t') textptr++; while (*textptr == ' ' || *textptr == '\t') textptr++;
@ -1394,7 +1501,7 @@ int parsecommand()
return 0; return 0;
case concmd_defineskillname: case concmd_defineskillname:
popscriptvalue(); popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
j = popscriptvalue(); j = popscriptvalue();
while (*textptr == ' ') textptr++; while (*textptr == ' ') textptr++;
@ -1413,9 +1520,9 @@ int parsecommand()
case concmd_definelevelname: case concmd_definelevelname:
{ {
popscriptvalue(); popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
j = popscriptvalue(); j = popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
k = popscriptvalue(); k = popscriptvalue();
while (*textptr == ' ') textptr++; while (*textptr == ' ') textptr++;
@ -1464,7 +1571,7 @@ int parsecommand()
} }
case concmd_definequote: case concmd_definequote:
popscriptvalue(); popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
k = popscriptvalue(); k = popscriptvalue();
if (k >= MAXQUOTES) if (k >= MAXQUOTES)
{ {
@ -1488,7 +1595,7 @@ int parsecommand()
case concmd_definesound: case concmd_definesound:
{ {
popscriptvalue(); popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
k = popscriptvalue(); k = popscriptvalue();
i = 0; i = 0;
while (*textptr == ' ') while (*textptr == ' ')
@ -1502,15 +1609,15 @@ int parsecommand()
} }
parsebuffer.Push(0); parsebuffer.Push(0);
transnum(); transnum(LABEL_DEFINE);
int ps = popscriptvalue(); int ps = popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
int pe = popscriptvalue(); int pe = popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
int pr = popscriptvalue(); int pr = popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
int m = popscriptvalue(); int m = popscriptvalue();
transnum(); transnum(LABEL_DEFINE);
int vo = popscriptvalue(); int vo = popscriptvalue();
S_DefineSound(k, parsebuffer.Data(), ps, pe, pr, m, vo, 1.f); S_DefineSound(k, parsebuffer.Data(), ps, pe, pr, m, vo, 1.f);
return 0; return 0;
@ -1595,7 +1702,7 @@ int parsecommand()
case concmd_gamestartup: case concmd_gamestartup:
{ {
popscriptvalue(); popscriptvalue();
auto parseone = []() { transnum(); return popscriptvalue(); }; auto parseone = []() { transnum(LABEL_DEFINE); return popscriptvalue(); };
ud.const_visibility = parseone(); ud.const_visibility = parseone();
impact_damage = parseone(); impact_damage = parseone();
max_player_health = parseone(); max_player_health = parseone();
@ -1670,13 +1777,52 @@ void compilecon(const char *filenam)
} }
//==========================================================================
//
// Fallback in case nothing got defined.
//
//==========================================================================
static const char* ConFile(void)
{
if (userConfig.DefaultCon.IsNotEmpty()) return userConfig.DefaultCon.GetChars();
// WW2GI anf NAM special con names got introduced by EDuke32.
// Do we really need these?
if (g_gameType & GAMEFLAG_WW2GI)
{
if (fileSystem.FindFile("ww2gi.con") >= 0) return "ww2gi.con";
}
if (g_gameType & GAMEFLAG_NAM)
{
if (fileSystem.FindFile("nam.con") >= 0) return "nam.con";
if (fileSystem.FindFile("napalm.con") >= 0) return "napalm.con";
}
if (g_gameType & GAMEFLAG_NAPALM)
{
if (fileSystem.FindFile("napalm.con") >= 0) return "napalm.con";
if (fileSystem.FindFile("nam.con") >= 0) return "nam.con";
}
// This got introduced by EDuke 2.0.
if (g_gameType & GAMEFLAG_DUKE)
{
if (fileSystem.FindFile("eduke.con") >= 0) return "eduke.con";
}
// the other games only use game.con.
return "game.con";
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// why was this called loadefs? // why was this called loadefs?
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void loadcons(const char* filenam) void loadcons()
{ {
for (int i = 0; i < MAXTILES; i++) for (int i = 0; i < MAXTILES; i++)
{ {
@ -1684,8 +1830,7 @@ void loadcons(const char* filenam)
} }
ScriptCode.Clear(); ScriptCode.Clear();
labels.Clear();
labelcnt = 0;
SortCommands(); SortCommands();
@ -1696,25 +1841,27 @@ void loadcons(const char* filenam)
auto before = I_nsTime(); auto before = I_nsTime();
ScriptCode.Push(0); ScriptCode.Push(0);
compilecon(filenam); //Tokenize compilecon(ConFile()); //Tokenize
if (userConfig.AddCons) for (FString& m : *userConfig.AddCons.get()) if (userConfig.AddCons) for (FString& m : *userConfig.AddCons.get())
{ {
compilecon(filenam); compilecon(m);
} }
ScriptCode.ShrinkToFit();
labels.ShrinkToFit();
userConfig.AddCons.reset(); userConfig.AddCons.reset();
setscriptvalue(0, scriptpos()); setscriptvalue(0, scriptpos());
if (errorcount) if (errorcount)
{ {
I_FatalError("\nError in %s.", filenam); I_FatalError("Failed to compile CONs.");
} }
else else
{ {
auto after = I_nsTime(); auto after = I_nsTime();
Printf("Compilation time:%.2f ms, Code Size:%d bytes. %d labels. %d/%d Variables.\n", (after-before) / 1000000., Printf("Compilation time:%.2f ms, Code Size:%u bytes. %u labels. %d/%d Variables.\n", (after-before) / 1000000.,
(ScriptCode.Size() << 2) - 4, (ScriptCode.Size() << 2) - 4,
labelcnt, labels.Size(),
0,//iGameVarCount, 0,//iGameVarCount,
MAXGAMEVARS MAXGAMEVARS
); );
@ -1723,11 +1870,6 @@ void loadcons(const char* filenam)
// These can only be retrieved AFTER loading the scripts. // These can only be retrieved AFTER loading the scripts.
InitGameVarPointers(); InitGameVarPointers();
ResetSystemDefaults(); ResetSystemDefaults();
for (auto& tm : tempMusic)
{
auto map = FindMapByLevelNum(tm.levnum);
if (map) map->music = tm.music;
}
if (isRRRA()) if (isRRRA())
{ {
// RRRA goes directly to the second episode after E1L7 to continue the game. // RRRA goes directly to the second episode after E1L7 to continue the game.
@ -1756,6 +1898,11 @@ void loadcons(const char* filenam)
maprec->levelNumber = levelnum(1, 7); maprec->levelNumber = levelnum(1, 7);
} }
} }
for (auto& tm : tempMusic)
{
auto map = FindMapByLevelNum(tm.levnum);
if (map) map->music = tm.music;
}
tempMusic.Clear(); tempMusic.Clear();
} }

View file

@ -62,7 +62,7 @@ void C_DefineMusic(int volumeNum, int levelNum, const char *fileName);
void C_DefineVolumeFlags(int32_t vol, int32_t flags); void C_DefineVolumeFlags(int32_t vol, int32_t flags);
void ReportError(int32_t iError); void ReportError(int32_t iError);
void loadcons(const char *filenam); void loadcons();
extern int32_t g_errorLineNum; extern int32_t g_errorLineNum;
extern int32_t g_tw; extern int32_t g_tw;

View file

@ -85,7 +85,6 @@ enum
MAXLABELLEN = 64 MAXLABELLEN = 64
}; };
extern char *label;
G_EXTERN char g_loadFromGroupOnly; G_EXTERN char g_loadFromGroupOnly;
G_EXTERN char g_skillCnt; G_EXTERN char g_skillCnt;
G_EXTERN char pus,pub; G_EXTERN char pus,pub;
@ -126,7 +125,6 @@ G_EXTERN int32_t g_freezerSelfDamage;
G_EXTERN int32_t g_gameQuit; G_EXTERN int32_t g_gameQuit;
G_EXTERN int32_t global_random; G_EXTERN int32_t global_random;
G_EXTERN int32_t impact_damage; G_EXTERN int32_t impact_damage;
extern int32_t labelcnt;
G_EXTERN int32_t g_maxPlayerHealth; G_EXTERN int32_t g_maxPlayerHealth;
G_EXTERN int32_t mirrorcnt; G_EXTERN int32_t mirrorcnt;
G_EXTERN int32_t playerswhenstarted; G_EXTERN int32_t playerswhenstarted;
@ -159,10 +157,6 @@ G_EXTERN int16_t g_cyclers[MAXCYCLERS][6];
#define cyclers g_cyclers #define cyclers g_cyclers
G_EXTERN int16_t mirrorsector[64]; G_EXTERN int16_t mirrorsector[64];
G_EXTERN int16_t mirrorwall[64]; G_EXTERN int16_t mirrorwall[64];
G_EXTERN int32_t *labelcode;
#if 0
G_EXTERN int32_t *labeltype;
#endif
G_EXTERN ClockTicks lockclock; G_EXTERN ClockTicks lockclock;
G_EXTERN ClockTicks ototalclock; G_EXTERN ClockTicks ototalclock;

View file

@ -66,8 +66,6 @@ uint8_t shadedsector[MAXSECTORS];
int32_t cameradist = 0, cameraclock = 0; int32_t cameradist = 0, cameraclock = 0;
char boardfilename[BMAX_PATH] = {0};
int32_t g_Shareware = 0; int32_t g_Shareware = 0;
int32_t tempwallptr; int32_t tempwallptr;
@ -289,9 +287,6 @@ static void G_Cleanup(void)
{ {
Xfree(g_player[i].input); Xfree(g_player[i].input);
} }
if (label != (char *)&sprite[0]) Xfree(label);
if (labelcode != (int32_t *)&sector[0]) Xfree(labelcode);
} }
/* /*
@ -302,44 +297,6 @@ static void G_Cleanup(void)
=================== ===================
*/ */
static void G_CompileScripts(void)
{
label = (char *)&sprite[0]; // V8: 16384*44/64 = 11264 V7: 4096*44/64 = 2816
labelcode = (int32_t *)&sector[0]; // V8: 4096*40/4 = 40960 V7: 1024*40/4 = 10240
loadcons(G_ConFile());
fi.initactorflags();
if ((uint32_t)labelcnt > MAXSPRITES*sizeof(spritetype)/64) // see the arithmetic above for why
I_FatalError("Error: too many labels defined!");
{
char *newlabel;
int32_t *newlabelcode;
int32_t *newlabeltype;
newlabel = (char *)Xmalloc(labelcnt << 6);
newlabelcode = (int32_t *)Xmalloc(labelcnt * sizeof(int32_t));
newlabeltype = (int32_t *)Xmalloc(labelcnt * sizeof(int32_t));
Bmemcpy(newlabel, label, labelcnt*64);
Bmemcpy(newlabelcode, labelcode, labelcnt*sizeof(int32_t));
label = newlabel;
labelcode = newlabelcode;
}
Bmemset(sprite, 0, MAXSPRITES*sizeof(spritetype));
Bmemset(sector, 0, MAXSECTORS*sizeof(sectortype));
Bmemset(wall, 0, MAXWALLS*sizeof(walltype));
if (IsGameEvent(EVENT_INIT))
{
SetGameVarID(g_iReturnVarID, -1, -1, -1);
OnEvent(EVENT_INIT);
}
}
inline int G_CheckPlayerColor(int color) inline int G_CheckPlayerColor(int color)
{ {
static int32_t player_pals[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, }; static int32_t player_pals[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, };
@ -353,7 +310,14 @@ static void G_Startup(void)
timerInit(TICRATE); timerInit(TICRATE);
timerSetCallback(gameTimerHandler); timerSetCallback(gameTimerHandler);
G_CompileScripts(); loadcons();
fi.initactorflags();
if (IsGameEvent(EVENT_INIT))
{
SetGameVarID(g_iReturnVarID, -1, -1, -1);
OnEvent(EVENT_INIT);
}
enginecompatibility_mode = ENGINECOMPATIBILITY_19961112; enginecompatibility_mode = ENGINECOMPATIBILITY_19961112;
@ -366,30 +330,11 @@ static void G_Startup(void)
if (userConfig.CommandMap.IsNotEmpty()) if (userConfig.CommandMap.IsNotEmpty())
{ {
FString startupMap;
if (VOLUMEONE) if (VOLUMEONE)
{ {
Printf("The -map option is available in the registered version only!\n"); Printf("The -map option is available in the registered version only!\n");
userConfig.CommandMap = "";
} }
else
{
startupMap = userConfig.CommandMap;
if (startupMap.IndexOfAny("/\\") < 0) startupMap.Insert(0, "/");
DefaultExtension(startupMap, ".map");
startupMap.Substitute("\\", "/");
NormalizeFileName(startupMap);
if (fileSystem.FileExists(startupMap))
{
Printf("Using level: \"%s\".\n",startupMap.GetChars());
}
else
{
Printf("Level \"%s\" not found.\n",startupMap.GetChars());
boardfilename[0] = 0;
}
}
strncpy(boardfilename, startupMap, BMAX_PATH);
} }
if (numplayers > 1) if (numplayers > 1)
@ -445,7 +390,6 @@ void G_UpdatePlayerFromMenu(void)
void G_BackToMenu(void) void G_BackToMenu(void)
{ {
boardfilename[0] = 0;
ps[myconnectindex].gm = 0; ps[myconnectindex].gm = 0;
M_StartControlPanel(false); M_StartControlPanel(false);
M_SetMenu(NAME_Mainmenu); M_SetMenu(NAME_Mainmenu);
@ -658,9 +602,9 @@ MAIN_LOOP_RESTART:
//if (ud.warp_on == 0) //if (ud.warp_on == 0)
{ {
#if 0 // fixme once the game loop has been done. #if 0 // fixme once the game loop has been done.
if ((ud.multimode > 1) && boardfilename[0] != 0) if ((ud.multimode > 1) && startupMap.IsNotEmpty())
{ {
auto maprecord = FindMap(boardfilename); auto maprecord = FindMap(startupMap);
ud.m_respawn_monsters = ud.m_player_skill == 4; ud.m_respawn_monsters = ud.m_player_skill == 4;
for (int i = 0; i != -1; i = connectpoint2[i]) for (int i = 0; i != -1; i = connectpoint2[i])

View file

@ -164,9 +164,6 @@ int32_t G_LoadPlayer(const char *path)
ud.m_player_skill = h.skill; ud.m_player_skill = h.skill;
// NOTE: Bmemcpy needed for SAVEGAME_MUSIC.
strcpy(boardfilename, currentLevel->fileName);
char workbuffer[BMAX_PATH]; char workbuffer[BMAX_PATH];
Bstrcpy(workbuffer, currentLevel->fileName); Bstrcpy(workbuffer, currentLevel->fileName);