- 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)
{
char buffer[64];
char buffer2[16];
levelInitINI(G_ConFile()); // This doubles for the INI in the global code.
levelInitINI(DefFile());
memset(gEpisodeInfo, 0, sizeof(gEpisodeInfo));
quoteMgr.InitializeQuote(MUS_INTRO, "PESTIS.MID");
int i;

View file

@ -541,7 +541,7 @@ DEFINE_ACTION_FUNCTION(_CVar, FindCVar)
//
//
//=============================================================================
#if 0
DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind)
{
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
@ -606,7 +606,7 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand)
C_DoCommand(cmd);
return 0;
}
#endif
DEFINE_ACTION_FUNCTION(_Console, MidPrint)
{
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;
}
CheckUserMap();
GPalette.Init(MAXPALOOKUPS + 2); // one slot for each translation, plus a separate one for the base palettes and the internal one
TexMan.Init([]() {}, [](BuildInfo &) {});
V_InitFonts();
@ -811,7 +838,6 @@ int RunGame()
LoadScripts();
M_Init();
SetDefaultStrings();
if (g_gameType & (GAMEFLAG_RR)) InitRREndMap(); // this needs to be done better later
if (Args->CheckParm("-sounddebug"))
C_DoCommand("stat sounddebug");

View file

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

View file

@ -134,13 +134,3 @@ MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic)
map->music = G_SetupFilenameBasedMusic(boardfilename, defaultmusic);
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;
bool SetMusicForMap(const char* mapname, const char* music, bool namehack = false);
void InitRREndMap();
MapRecord *FindMapByName(const char *nm);
MapRecord *FindMapByLevelNum(int num);

View file

@ -58,6 +58,7 @@ FSavegameManager savegameManager;
void FSavegameManager::LoadGame(FSaveGameNode* node)
{
inputState.ClearAllInput();
if (gi->CleanupForLoad())
{
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
// Should this be added to the game data collector?
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)
{
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) };
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;
}
int getlabelvalue(const char* text);
static int ccmd_spawn(CCmdFuncPtr parm)
{
int x = 0, y = 0, z = 0;
@ -191,20 +193,8 @@ static int ccmd_spawn(CCmdFuncPtr parm)
picnum = (unsigned short)atol(parm->parms[0]);
}
else {
int i, j;
for (j = 0; j < 2; j++) {
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) {
picnum = getlabelvalue(parm->parms[0]);
if (picnum < 0) {
Printf("spawn: Invalid tile label given\n");
return CCMD_OK;
}

View file

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

View file

@ -46,11 +46,10 @@ into many sub-files.
BEGIN_DUKE_NS
// parser state: todo: turn into a class
char* textptr;
char* label;
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 g_currentSourceFile;
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.
extern char tempbuf[];
extern int* labelcode;
TArray<int> ScriptCode;
@ -111,6 +109,62 @@ void SortCommands()
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:
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;
case ERROR_PARMUNDEFINED:
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Parameter '%s' is undefined.\n",
@ -146,23 +200,23 @@ void ReportError(int iError)
break;
case WARNING_DUPLICATEDEFINITION:
Printf(TEXTCOLOR_YELLOW " * WARNING.(%s, line %d) Duplicate definition '%s' ignored.\n",
fn, line_number, label + (labelcnt << 6));
fn, line_number, parselabel.GetChars());
break;
case ERROR_COULDNOTFIND:
Printf(TEXTCOLOR_RED " * ERROR!(%s, line %d) Could not find '%s'.\n",
fn, line_number, label + (labelcnt << 6));
fn, line_number, parselabel.GetChars());
break;
case ERROR_VARREADONLY:
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;
case ERROR_NOTAGAMEDEF:
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;
case ERROR_NOTAGAMEVAR:
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;
case ERROR_OPENBRACKET:
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;
}
}
if (ignorecase)
{
for (unsigned j = 0; j < labels.Size(); j++)
{
if (labels[j].name.comparei(text) == 0)
{
return j;
}
}
}
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;
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 appendlabeladdress(int offset = 0)
void appendlabelvalue(labeltypes type, int value)
{
labelcode[labelcnt++] = ScriptCode.Size() + offset;
labelcnt++;
labels.Reserve(1);
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;
labelcnt++;
appendlabelvalue(type, ScriptCode.Size() + offset);
}
//---------------------------------------------------------------------------
//
//
@ -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)
{
@ -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;
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.
int64_t value;
char *outp;
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);
else value = strtoull(textptr, &outp, ishex ? 16 : 10);
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? 0 : 10);
else value = strtoull(textptr, &outp, ishex ? 0 : 10);
if (*outp != 0)
{
// conversion was not successful.
}
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;
return int(value);
}
@ -574,7 +676,7 @@ int transnum(void)
void checkforkeyword()
{
if (getkeyword(label + (labelcnt << 6)) >= 0)
if (getkeyword(parselabel) >= 0)
{
errorcount++;
ReportError(ERROR_ISAKEYWORD);
@ -614,7 +716,7 @@ int parsecommand()
{
getlabel();
popscriptvalue();
appendlabeladdress();
appendlabeladdress(LABEL_STATE);
parsing_state = 1;
@ -624,14 +726,14 @@ int parsecommand()
getlabel();
checkforkeyword();
lnum = findlabel(label + (labelcnt << 6));
lnum = findlabel(parselabel);
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++;
}
appendscriptvalue(labelcode[lnum]);
appendscriptvalue(labels[lnum].value);
return 0;
case concmd_ends:
@ -665,25 +767,25 @@ int parsecommand()
// Check to see it's already defined
popscriptvalue();
if (getkeyword(label + (labelcnt << 6)) >= 0)
if (getkeyword(parselabel) >= 0)
{
errorcount++;
ReportError(ERROR_ISAKEYWORD);
return 0;
}
transnum(); // get initial value
transnum(LABEL_DEFINE); // get initial value
j = popscriptvalue();
transnum(); // get flags
transnum(LABEL_DEFINE); // get flags
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;
case concmd_define:
getlabel();
checkforkeyword();
lnum = findlabel(label + (labelcnt << 6));
lnum = findlabel(parselabel);
if (lnum >= 0)
{
warningcount++;
@ -691,11 +793,11 @@ int parsecommand()
break;
}
transnum();
transnum(LABEL_DEFINE);
i = popscriptvalue();
if (lnum < 0)
{
appendlabelvalue(i);
appendlabelvalue(LABEL_DEFINE, i);
}
popscriptvalue();
return 0;
@ -705,7 +807,7 @@ int parsecommand()
for (j = 0; j < 4; j++)
{
if (keyword() == -1)
transnum();
transnum(LABEL_DEFINE);
else break;
}
@ -719,12 +821,12 @@ int parsecommand()
case concmd_move:
if (parsing_actor || parsing_state)
{
transnum();
transnum(LABEL_MOVE);
j = 0;
while (keyword() == -1)
{
transnum();
transnum(LABEL_DEFINE);
j |= popscriptvalue();
}
appendscriptvalue(j);
@ -737,19 +839,19 @@ int parsecommand()
checkforkeyword();
for (i = 0; i < labelcnt; i++)
if (strcmp(label + (labelcnt << 6), label + (i << 6)) == 0)
for (i = 0; i < (int)labels.Size(); i++)
if (labels[i].compare(parselabel) == 0)
{
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;
}
if (i == labelcnt)
appendlabeladdress();
if (i == labels.Size())
appendlabeladdress(LABEL_MOVE);
for (j = 0; j < 2; j++)
{
if (keyword() >= 0) break;
transnum();
transnum(LABEL_DEFINE);
}
for (k = j; k < 2; k++)
{
@ -761,7 +863,7 @@ int parsecommand()
case concmd_music:
{
popscriptvalue();
transnum(); // Volume Number (0/4)
transnum(LABEL_DEFINE); // Volume Number (0/4)
k = popscriptvalue() - 1;
if (k < 0) specialmusic.Clear();
@ -856,20 +958,20 @@ int parsecommand()
case concmd_ai:
if (parsing_actor || parsing_state)
transnum();
transnum(LABEL_AI);
else
{
popscriptvalue();
getlabel();
checkforkeyword();
lnum = findlabel(label + (labelcnt << 6));
lnum = findlabel(parselabel);
if (lnum >= 0)
{
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++)
{
@ -879,13 +981,13 @@ int parsecommand()
k = 0;
while (keyword() == -1)
{
transnum();
transnum(LABEL_DEFINE);
k |= popscriptvalue();
}
appendscriptvalue(k);
return 0;
}
else transnum();
else transnum(j==0? LABEL_ACTION : LABEL_MOVE);
}
for (k = j; k < 3; k++)
{
@ -896,25 +998,25 @@ int parsecommand()
case concmd_action:
if (parsing_actor || parsing_state)
transnum();
transnum(LABEL_ACTION);
else
{
popscriptvalue();
getlabel();
checkforkeyword();
lnum = findlabel(label + (labelcnt << 6));
lnum = findlabel(parselabel);
if (lnum >= 0)
{
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++)
{
if (keyword() >= 0) break;
transnum();
transnum(LABEL_DEFINE);
}
for (k = j; k < 5; k++)
{
@ -944,11 +1046,11 @@ int parsecommand()
if (tw == concmd_useractor)
{
transnum();
transnum(LABEL_DEFINE);
j = popscriptvalue();
}
transnum();
transnum(LABEL_DEFINE);
lnum = popscriptvalue();
actorinfo[lnum].scriptaddress = parsing_actor; // TRANSITIONAL should only store an index
@ -969,7 +1071,7 @@ int parsecommand()
j = 0;
while (keyword() == -1)
{
transnum();
transnum(LABEL_DEFINE);
j |= popscriptvalue();
}
@ -983,7 +1085,12 @@ int parsecommand()
reservescriptspace(4 - j);
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.
//*(parsing_actor + j) = *(scriptaddress - 1);
}
@ -1011,7 +1118,7 @@ int parsecommand()
popscriptvalue();
parsing_event = parsing_actor = scriptpos();
transnum();
transnum(LABEL_DEFINE);
j = popscriptvalue();
if (j< 0 || j> EVENT_MAXEVENT)
{
@ -1027,7 +1134,7 @@ int parsecommand()
case concmd_cstat:
transnum();
transnum(LABEL_DEFINE);
#if 0
// 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.
@ -1076,7 +1183,7 @@ int parsecommand()
case concmd_isdrunk:
case concmd_iseat:
case concmd_newpic:
transnum();
transnum(LABEL_DEFINE);
return 0;
case concmd_addammo:
@ -1086,16 +1193,16 @@ int parsecommand()
case concmd_debris:
case concmd_addinventory:
case concmd_guts:
transnum();
transnum();
transnum(LABEL_DEFINE);
transnum(LABEL_DEFINE);
return 0;
case concmd_hitradius:
transnum();
transnum();
transnum();
transnum();
transnum();
transnum(LABEL_DEFINE);
transnum(LABEL_DEFINE);
transnum(LABEL_DEFINE);
transnum(LABEL_DEFINE);
transnum(LABEL_DEFINE);
break;
case concmd_else:
@ -1127,7 +1234,7 @@ int parsecommand()
// Check to see if it's a keyword
checkforkeyword();
i = GetDefID(label + (labelcnt << 6));
i = GetDefID(parselabel);
if (i < 0)
{ // not a defined DEF
errorcount++;
@ -1143,7 +1250,7 @@ int parsecommand()
}
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;
case concmd_setvarvar:
@ -1157,7 +1264,7 @@ int parsecommand()
checkforkeyword();
i = GetDefID(label + (labelcnt << 6));
i = GetDefID(parselabel);
if (i < 0)
{ // not a defined DEF
errorcount++;
@ -1177,7 +1284,7 @@ int parsecommand()
getlabel(); //GetGameVarLabel();
checkforkeyword();
i = GetDefID(label + (labelcnt << 6));
i = GetDefID(parselabel);
if (i < 0)
{ // not a defined DEF
errorcount++;
@ -1197,7 +1304,7 @@ int parsecommand()
checkforkeyword();
i = GetDefID(label + (labelcnt << 6));
i = GetDefID(parselabel);
if (i < 0)
{ // not a defined DEF
errorcount++;
@ -1211,7 +1318,7 @@ int parsecommand()
checkforkeyword();
i = GetDefID(label + (labelcnt << 6));
i = GetDefID(parselabel);
if (i < 0)
{ // not a defined DEF
errorcount++;
@ -1229,7 +1336,7 @@ int parsecommand()
getlabel(); //GetGameVarLabel();
checkforkeyword();
i = GetDefID(label + (labelcnt << 6));
i = GetDefID(parselabel);
if (i < 0)
{ // not a defined DEF
errorcount++;
@ -1238,7 +1345,7 @@ int parsecommand()
}
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;
case concmd_addlogvar:
@ -1252,7 +1359,7 @@ int parsecommand()
checkforkeyword();
i = GetDefID(label + (labelcnt << 6));
i = GetDefID(parselabel);
if (i < 0)
{ // not a defined DEF
errorcount++;
@ -1277,14 +1384,14 @@ int parsecommand()
j = 0;
do
{
transnum();
transnum(LABEL_DEFINE);
j |= popscriptvalue();
} while (keyword() == -1);
appendscriptvalue(j);
goto if_common;
case concmd_ifpinventory:
transnum();
transnum(LABEL_DEFINE);
case concmd_ifrnd:
case concmd_ifpdistl:
case concmd_ifpdistg:
@ -1309,7 +1416,7 @@ int parsecommand()
case concmd_ifactorhealthl:
case concmd_ifsoundid:
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_ifinwater:
case concmd_ifactornotstayput:
@ -1377,7 +1484,7 @@ int parsecommand()
case concmd_definevolumename:
popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
j = popscriptvalue();
while (*textptr == ' ' || *textptr == '\t') textptr++;
@ -1394,7 +1501,7 @@ int parsecommand()
return 0;
case concmd_defineskillname:
popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
j = popscriptvalue();
while (*textptr == ' ') textptr++;
@ -1413,9 +1520,9 @@ int parsecommand()
case concmd_definelevelname:
{
popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
j = popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
k = popscriptvalue();
while (*textptr == ' ') textptr++;
@ -1464,7 +1571,7 @@ int parsecommand()
}
case concmd_definequote:
popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
k = popscriptvalue();
if (k >= MAXQUOTES)
{
@ -1488,7 +1595,7 @@ int parsecommand()
case concmd_definesound:
{
popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
k = popscriptvalue();
i = 0;
while (*textptr == ' ')
@ -1502,15 +1609,15 @@ int parsecommand()
}
parsebuffer.Push(0);
transnum();
transnum(LABEL_DEFINE);
int ps = popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
int pe = popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
int pr = popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
int m = popscriptvalue();
transnum();
transnum(LABEL_DEFINE);
int vo = popscriptvalue();
S_DefineSound(k, parsebuffer.Data(), ps, pe, pr, m, vo, 1.f);
return 0;
@ -1595,7 +1702,7 @@ int parsecommand()
case concmd_gamestartup:
{
popscriptvalue();
auto parseone = []() { transnum(); return popscriptvalue(); };
auto parseone = []() { transnum(LABEL_DEFINE); return popscriptvalue(); };
ud.const_visibility = parseone();
impact_damage = 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?
//
//---------------------------------------------------------------------------
void loadcons(const char* filenam)
void loadcons()
{
for (int i = 0; i < MAXTILES; i++)
{
@ -1684,8 +1830,7 @@ void loadcons(const char* filenam)
}
ScriptCode.Clear();
labelcnt = 0;
labels.Clear();
SortCommands();
@ -1696,25 +1841,27 @@ void loadcons(const char* filenam)
auto before = I_nsTime();
ScriptCode.Push(0);
compilecon(filenam); //Tokenize
compilecon(ConFile()); //Tokenize
if (userConfig.AddCons) for (FString& m : *userConfig.AddCons.get())
{
compilecon(filenam);
compilecon(m);
}
ScriptCode.ShrinkToFit();
labels.ShrinkToFit();
userConfig.AddCons.reset();
setscriptvalue(0, scriptpos());
if (errorcount)
{
I_FatalError("\nError in %s.", filenam);
I_FatalError("Failed to compile CONs.");
}
else
{
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,
labelcnt,
labels.Size(),
0,//iGameVarCount,
MAXGAMEVARS
);
@ -1723,11 +1870,6 @@ void loadcons(const char* filenam)
// These can only be retrieved AFTER loading the scripts.
InitGameVarPointers();
ResetSystemDefaults();
for (auto& tm : tempMusic)
{
auto map = FindMapByLevelNum(tm.levnum);
if (map) map->music = tm.music;
}
if (isRRRA())
{
// 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);
}
}
for (auto& tm : tempMusic)
{
auto map = FindMapByLevelNum(tm.levnum);
if (map) map->music = tm.music;
}
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 ReportError(int32_t iError);
void loadcons(const char *filenam);
void loadcons();
extern int32_t g_errorLineNum;
extern int32_t g_tw;

View file

@ -85,7 +85,6 @@ enum
MAXLABELLEN = 64
};
extern char *label;
G_EXTERN char g_loadFromGroupOnly;
G_EXTERN char g_skillCnt;
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 global_random;
G_EXTERN int32_t impact_damage;
extern int32_t labelcnt;
G_EXTERN int32_t g_maxPlayerHealth;
G_EXTERN int32_t mirrorcnt;
G_EXTERN int32_t playerswhenstarted;
@ -159,10 +157,6 @@ G_EXTERN int16_t g_cyclers[MAXCYCLERS][6];
#define cyclers g_cyclers
G_EXTERN int16_t mirrorsector[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 ototalclock;

View file

@ -66,8 +66,6 @@ uint8_t shadedsector[MAXSECTORS];
int32_t cameradist = 0, cameraclock = 0;
char boardfilename[BMAX_PATH] = {0};
int32_t g_Shareware = 0;
int32_t tempwallptr;
@ -289,9 +287,6 @@ static void G_Cleanup(void)
{
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)
{
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);
timerSetCallback(gameTimerHandler);
G_CompileScripts();
loadcons();
fi.initactorflags();
if (IsGameEvent(EVENT_INIT))
{
SetGameVarID(g_iReturnVarID, -1, -1, -1);
OnEvent(EVENT_INIT);
}
enginecompatibility_mode = ENGINECOMPATIBILITY_19961112;
@ -366,30 +330,11 @@ static void G_Startup(void)
if (userConfig.CommandMap.IsNotEmpty())
{
FString startupMap;
if (VOLUMEONE)
{
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)
@ -445,7 +390,6 @@ void G_UpdatePlayerFromMenu(void)
void G_BackToMenu(void)
{
boardfilename[0] = 0;
ps[myconnectindex].gm = 0;
M_StartControlPanel(false);
M_SetMenu(NAME_Mainmenu);
@ -658,9 +602,9 @@ MAIN_LOOP_RESTART:
//if (ud.warp_on == 0)
{
#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;
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;
// NOTE: Bmemcpy needed for SAVEGAME_MUSIC.
strcpy(boardfilename, currentLevel->fileName);
char workbuffer[BMAX_PATH];
Bstrcpy(workbuffer, currentLevel->fileName);