diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index bd625e074..1d9044dc9 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -770,6 +770,7 @@ set (PCH_SOURCES common/gamecontrol.cpp common/inputstate.cpp common/searchpaths.cpp + common/initfs.cpp common/2d/v_2ddrawer.cpp common/2d/v_draw.cpp diff --git a/source/blood/src/blood.cpp b/source/blood/src/blood.cpp index fffc4746c..94e05fc18 100644 --- a/source/blood/src/blood.cpp +++ b/source/blood/src/blood.cpp @@ -69,6 +69,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "warp.h" #include "weapon.h" #include "gameconfigfile.h" +#include "gamecontrol.h" +#include "m_argv.h" #ifdef _WIN32 # include @@ -83,9 +85,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -extern const char* G_DefaultDefFile(void); -extern const char* G_DefFile(void); - int32_t gNoSetup = 0, gCommandSetup = 0; INPUT_MODE gInputMode; @@ -164,11 +163,6 @@ enum gametokens int blood_globalflags; -void app_crashhandler(void) -{ - // NUKE-TODO: -} - void G_Polymer_UnInit(void) { // NUKE-TODO: @@ -1262,8 +1256,6 @@ int app_main() ScanINIFiles(); - G_LoadGroups(); - initprintf("Initializing OSD...\n"); OSD_SetVersion("Blood", 10, 0); @@ -2116,7 +2108,7 @@ int loaddefinitions_game(const char *fileName, int32_t firstPass) if (pScript) parsedefinitions_game(pScript, firstPass); - for (char const * m : g_defModules) + for (auto & m : *userConfig.AddDefs) parsedefinitions_game_include(m, NULL, "null", firstPass); if (pScript) @@ -2254,22 +2246,17 @@ void sndPlaySpecialMusicOrNothing(int nMusic) extern void faketimerhandler(); extern int app_main(); -extern void app_crashhandler(void); bool validate_hud(int layout); void set_hud_layout(int layout); void set_hud_scale(int scale); int32_t GetTime(); GameInterface Interface = { - TICRATE, faketimerhandler, app_main, validate_hud, set_hud_layout, set_hud_scale, - app_crashhandler, - G_DefaultDefFile, - G_DefFile, }; END_BLD_NS diff --git a/source/blood/src/common.cpp b/source/blood/src/common.cpp index 217786b60..06449b4d2 100644 --- a/source/blood/src/common.cpp +++ b/source/blood/src/common.cpp @@ -53,36 +53,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_BLD_NS -// g_grpNamePtr can ONLY point to a malloc'd block (length BMAX_PATH) -char *g_grpNamePtr = NULL; - -void clearGrpNamePtr(void) -{ - Bfree(g_grpNamePtr); - // g_grpNamePtr assumed to be assigned to right after -} - -const char *G_DefaultGrpFile(void) -{ - return "blood.rff"; -} - -const char *G_DefaultDefFile(void) -{ - return "blood.def"; -} - -const char *G_GrpFile(void) -{ - return (g_grpNamePtr == NULL) ? G_DefaultGrpFile() : g_grpNamePtr; -} - -const char *G_DefFile(void) -{ - return (g_defNamePtr == NULL) ? G_DefaultDefFile() : g_defNamePtr; -} - - void G_SetupGlobalPsky(void) { int skyIdx = 0; @@ -103,109 +73,6 @@ void G_SetupGlobalPsky(void) } -int32_t g_groupFileHandle; -struct strllist* CommandGrps; - - -static int32_t G_TryLoadingGrp(char const * const grpfile) -{ - int32_t i; - - if ((i = initgroupfile(grpfile)) == -1) - initprintf("Warning: could not find main data file \"%s\"!\n", grpfile); - else - initprintf("Using \"%s\" as main game data file.\n", grpfile); - - return i; -} - -void G_LoadGroups() -{ - if (g_modDir[0] != '/') - { - char cwd[BMAX_PATH]; - - FString g_rootDir = progdir + g_modDir; - addsearchpath(g_rootDir); - // addsearchpath(mod_dir); - - char path[BMAX_PATH]; - - if (getcwd(cwd, BMAX_PATH)) - { - Bsnprintf(path, sizeof(path), "%s/%s", cwd, g_modDir); - if (!Bstrcmp(g_rootDir, path)) - { - if (addsearchpath(path) == -2) - if (Bmkdir(path, S_IRWXU) == 0) - addsearchpath(path); - } - } - - } - const char *grpfile = G_GrpFile(); - G_TryLoadingGrp(grpfile); - - if (G_AllowAutoload()) - { - G_LoadGroupsInDir("autoload"); - - //if (i != -1) - // G_DoAutoload(grpfile); - } - - if (g_modDir[0] != '/') - G_LoadGroupsInDir(g_modDir); - - if (g_defNamePtr == NULL) - { - const char *tmpptr = getenv("BLOODDEF"); - if (tmpptr) - { - clearDefNamePtr(); - g_defNamePtr = dup_filename(tmpptr); - initprintf("Using \"%s\" as definitions file\n", g_defNamePtr); - } - } - - loaddefinitions_game(BLOODWIDESCREENDEF, TRUE); - loaddefinitions_game(G_DefFile(), TRUE); -} - -////////// - -// loads all group (grp, zip, pk3/4) files in the given directory -void G_LoadGroupsInDir(const char *dirname) -{ - static const char *extensions[] = { "*.grp", "*.zip", "*.ssi", "*.pk3", "*.pk4" }; - char buf[BMAX_PATH]; - fnlist_t fnlist = FNLIST_INITIALIZER; - - for (auto & extension : extensions) - { - BUILDVFS_FIND_REC *rec; - - fnlist_getnames(&fnlist, dirname, extension, -1, 0); - - for (rec=fnlist.findfiles; rec; rec=rec->next) - { - Bsnprintf(buf, sizeof(buf), "%s/%s", dirname, rec->name); - initprintf("Using group file \"%s\".\n", buf); - initgroupfile(buf); - } - - fnlist_clearnames(&fnlist); - } -} - -void G_DoAutoload(const char *dirname) -{ - char buf[BMAX_PATH]; - - Bsnprintf(buf, sizeof(buf), "autoload/%s", dirname); - G_LoadGroupsInDir(buf); -} - ////////// #ifdef FORMAT_UPGRADE_ELIGIBLE diff --git a/source/blood/src/common_game.h b/source/blood/src/common_game.h index 8d637dc99..1a5e46008 100644 --- a/source/blood/src/common_game.h +++ b/source/blood/src/common_game.h @@ -509,18 +509,10 @@ enum searchpathtypes_t { if (alpha < 0) { blend = -alpha; alpha = 0; orientation |= RS_TRANS1; } \ } while (0) -extern char *g_grpNamePtr; - extern int loaddefinitions_game(const char *fn, int32_t preload); -extern void G_AddSearchPaths(void); - extern void G_ExtInit(void); -void G_LoadGroupsInDir(const char *dirname); -void G_DoAutoload(const char *dirname); -extern void G_LoadGroups(); - extern void G_SetupGlobalPsky(void); #define G_ModDirSnprintf(buf, size, basename, ...) \ diff --git a/source/build/include/baselayer.h b/source/build/include/baselayer.h index a737a7c42..ff52fb808 100644 --- a/source/build/include/baselayer.h +++ b/source/build/include/baselayer.h @@ -228,18 +228,11 @@ int32_t baselayer_init(); struct GameInterface { - int TicRate; void (*faketimerhandler)(); int (*app_main)(); bool (*validate_hud)(int); void (*set_hud_layout)(int size); void (*set_hud_scale)(int size); - - // These will later be removed. - void (*app_crashhandler)(); - const char* (*DefaultDefFile)(); - const char* (*DefFile)(); - }; extern GameInterface* gi; diff --git a/source/build/include/build.h b/source/build/include/build.h index 0f4d5ee20..00ef486a0 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -1332,10 +1332,6 @@ int32_t md_loadmodel(const char *fn); int32_t md_setmisc(int32_t modelid, float scale, int32_t shadeoff, float zadd, float yoffset, int32_t flags); // int32_t md_tilehasmodel(int32_t tilenume, int32_t pal); -extern char *g_defNamePtr; - -extern GrowArray g_defModules; - #ifdef HAVE_CLIPSHAPE_FEATURE extern GrowArray g_clipMapFiles; #endif diff --git a/source/build/include/common.h b/source/build/include/common.h index 591f90171..5e98894fc 100644 --- a/source/build/include/common.h +++ b/source/build/include/common.h @@ -52,7 +52,6 @@ extern const char *s_buildRev; extern const char *s_buildTimestamp; //// FUNCTIONS -extern void clearDefNamePtr(void); void G_AddDef(const char *buffer); void G_AddDefModule(const char *buffer); diff --git a/source/build/src/common.cpp b/source/build/src/common.cpp index 0ba6a2451..8a37cb792 100644 --- a/source/build/src/common.cpp +++ b/source/build/src/common.cpp @@ -11,19 +11,8 @@ #include "vfs.h" #include "../../glbackend/glbackend.h" -GrowArray g_defModules; - // def/clipmap handling -// g_defNamePtr can ONLY point to a malloc'd block (length BMAX_PATH) -char *g_defNamePtr = NULL; - -void clearDefNamePtr(void) -{ - Xfree(g_defNamePtr); - // g_defNamePtr assumed to be assigned to right after -} - #ifdef HAVE_CLIPSHAPE_FEATURE GrowArray g_clipMapFiles; #endif @@ -42,18 +31,6 @@ void SetClipshapes() #endif } -void G_AddDef(const char *buffer) -{ - clearDefNamePtr(); - g_defNamePtr = dup_filename(buffer); - initprintf("Using DEF file \"%s\".\n",g_defNamePtr); -} - -void G_AddDefModule(const char *buffer) -{ - g_defModules.append(Xstrdup(buffer)); -} - #ifdef HAVE_CLIPSHAPE_FEATURE void G_AddClipMap(const char *buffer) { diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index beea87493..abe59c9ed 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -18,6 +18,8 @@ #include "colmatch.h" #include "textures.h" #include "bitmap.h" +#include "m_argv.h" +#include "gamecontrol.h" #ifdef USE_OPENGL # include "hightile.h" @@ -327,7 +329,7 @@ static int32_t defsparser(scriptfile *script) } case T_INCLUDEDEFAULT: { - defsparser_include(gi->DefaultDefFile(), script, cmdtokptr); + defsparser_include(G_DefaultDefFile(), script, cmdtokptr); break; } case T_DEFINE: @@ -3414,7 +3416,7 @@ int32_t loaddefinitionsfile(const char *fn) defsparser(script); } - for (char const * m : g_defModules) + for (auto& m : *userConfig.AddDefs) defsparser_include(m, NULL, NULL); g_logFlushWindow = f; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 1969659b4..7833f0c02 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -8277,8 +8277,6 @@ void engineUnInit(void) DO_FREE_AND_NULL(multipsky); DO_FREE_AND_NULL(multipskytile); pskynummultis = 0; - - DO_FREE_AND_NULL(g_defNamePtr); } diff --git a/source/build/src/sdlayer.cpp b/source/build/src/sdlayer.cpp index 9d9536e84..ab5b33133 100644 --- a/source/build/src/sdlayer.cpp +++ b/source/build/src/sdlayer.cpp @@ -380,9 +380,11 @@ static void sighandler(int signum) // usleep(15000000); #endif attach_debugger_here(); - gi->app_crashhandler(); - uninitsystem(); - Bexit(EXIT_FAILURE); + std::terminate(); + // NOTE: It is not safe to call any of this from a signal handler! + //gi->app_crashhandler(); + //uninitsystem(); + //Bexit(EXIT_FAILURE); } } #endif diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index a372d2b79..14ecb706b 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -125,7 +125,7 @@ int FileSystem::InitMultipleFiles (TArray &filenames, const TArrayLumpName[l]) % NumEntries; } - else if (lump->ResourceId > 0) + else if (l == (int)ELookupMode::IdWithType && lump->ResourceId > 0) { hash = int(lump->ResourceId) % NumEntries; } + else continue; NextFileIndex[l][hash] = FirstFileIndex[l][hash]; FirstFileIndex[l][hash] = i; } diff --git a/source/common/filesystem/resourcefile.cpp b/source/common/filesystem/resourcefile.cpp index 3b895be3d..3fed881f8 100644 --- a/source/common/filesystem/resourcefile.cpp +++ b/source/common/filesystem/resourcefile.cpp @@ -219,7 +219,7 @@ FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReade for(size_t i = 0; i < countof(funcs) - containeronly; i++) { FResourceFile *resfile = funcs[i](filename, file, quiet); - if (resfile != NULL && resfile->Open(quiet)) return resfile; + if (resfile != NULL) return resfile; } return NULL; } diff --git a/source/common/gamecontrol.cpp b/source/common/gamecontrol.cpp index 3a35b0df2..988db9082 100644 --- a/source/common/gamecontrol.cpp +++ b/source/common/gamecontrol.cpp @@ -1,3 +1,4 @@ +#include #include "gamecontrol.h" #include "tarray.h" #include "zstring.h" @@ -14,10 +15,12 @@ #include "control.h" #include "m_argv.h" #include "rts.h" +#include "printf.h" InputState inputState; void SetClipshapes(); int ShowStartupWindow(TArray &); +void InitFileSystem(TArray&); int globalShadeDiv; struct GameFuncNameDesc @@ -194,7 +197,7 @@ void UserConfig::ProcessOptions() gamegrp = "WW2GI.GRP"; } - v = Args->CheckValue("-gamegrp"); // Although it says 'grp', this will take a directory as well + v = Args->CheckValue("-gamegrp"); if (v) { gamegrp = v; @@ -267,9 +270,9 @@ void UserConfig::ProcessOptions() } else { - // Trying to emulate Build. This means to treat RFF special as lowest priority, then all GRPs and then all directories. + // Trying to emulate Build. This means to treat RFF files as lowest priority, then all GRPs and then all directories. // This is only for people depending on lauchers. Since the semantics are so crappy it is strongly recommended to - // use -file instead which gives the user full control about the order in which things are added. + // use -file instead which gives the user full control over the order in which things are added. // For single mods this is no problem but don't even think about loading more stuff consistently... static const char* grps[] = { "-g", "-grp", nullptr }; @@ -354,7 +357,7 @@ int CONFIG_Init() SetClipshapes(); // This must be done before initializing any data, so doing it late in the startup process won't work. - if (CONTROL_Startup(controltype_keyboardandmouse, BGetTime, gi->TicRate)) + if (CONTROL_Startup(controltype_keyboardandmouse, BGetTime, 120)) { return 1; } @@ -365,27 +368,84 @@ int CONFIG_Init() // Startup dialog must be presented here so that everything can be set up before reading the keybinds. auto groups = GrpScan(); - int groupno = ShowStartupWindow(groups); - if (groupno == -1) return 0; - auto &group = groups[groupno]; - GrpEntry* dependency = nullptr; - if (group.FileInfo.dependencyCRC != 0) + if (groups.Size() == 0) { - for (auto& dep : groups) - { - if (dep.FileInfo.CRC == group.FileInfo.dependencyCRC) - { - dependency = &dep; - break; - } - } + // Abort if no game data found. + I_Error("Unable to find any game data. Please verify your settings."); + } + + decltype(groups) usedgroups; + + int groupno = -1; + + // If the user has specified a file name, let's see if we know it. + // + if (userConfig.gamegrp) + { + std::filesystem::path gpath = std::filesystem::u8path(userConfig.gamegrp.GetChars()); + + int g = 0; + for (auto& grp : groups) + { + std::filesystem::path fpath = std::filesystem::u8path(grp.FileName.GetChars()); + std::error_code err; + if (std::filesystem::equivalent(gpath, fpath, err)) + { + break; + } + g++; + } + groupno = g; + } + if (groupno == -1 || userConfig.setupstate == 1) + groupno = ShowStartupWindow(groups); + + if (groupno == -1) return 0; + auto &group = groups[groupno]; + + // Now filter out the data we actually need and delete the rest. + + usedgroups.Push(group); + + auto crc = group.FileInfo.dependencyCRC; + for (auto& dep : groups) + { + if (dep.FileInfo.CRC == crc) + { + usedgroups.Insert(0, dep); // Order from least dependent to most dependent, which is the loading order of data. + } + } + groups.Reset(); + + FString selectedScript; + FString selectedDef; + for (auto& ugroup : usedgroups) + { + // For CONs the command line has priority, aside from that, the last one wins. For Blood this handles INIs - the rules are the same. + if (ugroup.FileInfo.scriptname.IsNotEmpty()) selectedScript = ugroup.FileInfo.scriptname; + if (ugroup.FileInfo.defname.IsNotEmpty()) selectedDef = ugroup.FileInfo.defname; + + // CVAR has priority. This also overwrites the global variable each time. Init here is lazy so this is ok. + if (ugroup.FileInfo.rtsname.IsNotEmpty() && **rtsname == 0) RTS_Init(ugroup.FileInfo.rtsname); + + // For the game filter the last non-empty one wins. + if (ugroup.FileInfo.gamefilter.IsNotEmpty()) LumpFilter = ugroup.FileInfo.gamefilter; + g_gameType |= ugroup.FileInfo.flags; + } + if (userConfig.DefaultCon.IsEmpty()) userConfig.DefaultCon = selectedScript; + if (userConfig.DefaultDef.IsEmpty()) userConfig.DefaultDef = selectedDef; + + // This can only happen with a custom game that does not define any filter. + // In this case take the display name and strip all whitespace and invaliid path characters from it. + if (LumpFilter.IsEmpty()) + { + LumpFilter = usedgroups.Last().FileInfo.name; + LumpFilter.StripChars(".:/\\<>?\"*| \t\r\n"); } - LumpFilter = group.FileInfo.gamefilter; - if (LumpFilter.IsEmpty() && dependency) LumpFilter = dependency->FileInfo.gamefilter; currentGame = LumpFilter; currentGame.Truncate(currentGame.IndexOf(".")); - CheckFrontend(group.FileInfo.flags); + CheckFrontend(g_gameType); G_ReadConfig(currentGame); if (!GameConfig->IsInitialized()) @@ -418,6 +478,7 @@ int CONFIG_Init() CONTROL_ClearAssignments(); CONFIG_InitMouseAndController(); CONFIG_SetGameControllerDefaultsStandard(); + InitFileSystem(usedgroups); return gi->app_main(); } @@ -1599,3 +1660,4 @@ int osdcmd_unbind(osdcmdptr_t parm) return OSDCMD_SHOWHELP; } + diff --git a/source/common/gamecontrol.h b/source/common/gamecontrol.h index b85a5e4c6..68cf9bfbb 100644 --- a/source/common/gamecontrol.h +++ b/source/common/gamecontrol.h @@ -140,7 +140,6 @@ struct GrpInfo { FString name; FString scriptname; - FString dirname; FString defname; FString rtsname; FString gamefilter; @@ -148,6 +147,8 @@ struct GrpInfo uint32_t dependencyCRC = 0; size_t size = 0; int flags = 0; + bool loaddirectory = false; + TArray mustcontain; TArray loadfiles; TArray loadart; }; @@ -160,5 +161,10 @@ struct GrpEntry GrpInfo FileInfo; uint32_t FileIndex; }; +extern int g_gameType; +const char* G_DefaultDefFile(void); +const char* G_DefFile(void); +const char* G_DefaultConFile(void); +const char* G_ConFile(void); TArray GrpScan(); diff --git a/source/common/gamecvars.cpp b/source/common/gamecvars.cpp index fb36815f1..b56ee6fc0 100644 --- a/source/common/gamecvars.cpp +++ b/source/common/gamecvars.cpp @@ -465,7 +465,6 @@ CUSTOM_CVAR(String, rtsname, "", CVAR_ARCHIVE | CVAR_USERINFO) #if 0 // These will be redone once the resource management has been swapped out. -//GameConfig->SetValueForKey("Setup", "SelectedGRP", g_grpNamePtr); //GameConfig->SetValueForKey("Setup", "ModDir", &g_modDir[0]); #endif diff --git a/source/common/searchpaths.cpp b/source/common/searchpaths.cpp index f42fc639d..d8d64282f 100644 --- a/source/common/searchpaths.cpp +++ b/source/common/searchpaths.cpp @@ -36,10 +36,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "printf.h" #include "common.h" #include "gamecontrol.h" +#include "filesystem/filesystem.h" namespace fs = std::filesystem; +int g_gameType; fs::path AbsolutePath(const char* path) @@ -534,9 +536,21 @@ struct FileEntry TArray CollectAllFilesInSearchPath() { + uint32_t index = 0; TArray filelist; + + if (userConfig.gamegrp.IsNotEmpty()) + { + // If the user specified a file on the command line, insert that first, if found. + FileReader fr; + if (fr.OpenFile(userConfig.gamegrp)) + { + FileEntry fe = { userConfig.gamegrp, (uintmax_t)fr.GetLength(), 0, 0, index++ }; + filelist.Push(fe); + } + } + auto paths = CollectSearchPaths(); - int index = 0; for(auto &path : paths) { auto fpath = fs::u8path(path.GetChars()); @@ -682,8 +696,8 @@ static TArray ParseGrpInfo(const char *fn, FileReader &fr, TMap ParseGrpInfo(const char *fn, FileReader &fr, TMap GrpScan() } return foundGames; } + + +//========================================================================== +// +// Fallback in case nothing got defined. +// Also used by 'includedefault' which forces this to be statically defined +// (and which shouldn't be used to begin with because there are no default DEFs!) +// +//========================================================================== + +const char* G_DefaultDefFile(void) +{ + if (g_gameType & GAMEFLAG_BLOOD) + return "blood.def"; + + if (g_gameType & GAMEFLAG_DUKE) + return "duke3d.def"; + + if (g_gameType & GAMEFLAG_RRRA) + return "rrra.def"; + + if (g_gameType & GAMEFLAG_RR) + return "rr.def"; + + if (g_gameType & GAMEFLAG_WW2GI) + return "ww2gi.def"; + + if (g_gameType & GAMEFLAG_SW) + return "sw.def"; + + if (g_gameType & GAMEFLAG_NAM) + return fileSystem.FindFile("nam.def") ? "nam.def" : "napalm.def"; + + if (g_gameType & GAMEFLAG_NAPALM) + return fileSystem.FindFile("napalm.def") ? "napalm.def" : "nam.def"; + + return "duke3d.def"; +} + +const char* G_DefFile(void) +{ + return userConfig.DefaultDef.IsNotEmpty() ? userConfig.DefaultDef.GetChars() : G_DefaultDefFile(); +} + + +//========================================================================== +// +// 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")) return "ww2gi.con"; + } + + if (g_gameType & GAMEFLAG_SW) + return nullptr; // SW has no scripts of any kind (todo: Make Blood's INI files usable here for map definitions) + + if (g_gameType & GAMEFLAG_NAM) + { + if (fileSystem.FindFile("nam.def")) return "nam.def"; + if (fileSystem.FindFile("napalm.def")) return "napalm.def"; + } + + if (g_gameType & GAMEFLAG_NAPALM) + { + if (fileSystem.FindFile("napalm.def")) return "napalm.def"; + if (fileSystem.FindFile("nam.def")) return "nam.def"; + } + + // the other games only use game.con. + return "game.con"; +} + +const char* G_ConFile(void) +{ + return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : G_DefaultConFile(); +} + + diff --git a/source/common/utility/m_argv.h b/source/common/utility/m_argv.h index 26df5b587..2e822dee7 100644 --- a/source/common/utility/m_argv.h +++ b/source/common/utility/m_argv.h @@ -81,6 +81,7 @@ public: FArgs(int argc, FString *argv); FArgs &operator=(const FArgs &other); + const FString& operator[](size_t index) { return Argv[index]; } void AppendArg(FString arg); void AppendArgs(int argc, const FString *argv); diff --git a/source/duke3d/src/common.cpp b/source/duke3d/src/common.cpp index 864f06392..1c69e2333 100644 --- a/source/duke3d/src/common.cpp +++ b/source/duke3d/src/common.cpp @@ -23,83 +23,6 @@ BEGIN_DUKE_NS -struct grpfile_t const *g_selectedGrp; - -int32_t g_gameType = GAMEFLAG_DUKE; -int g_addonNum = 0; - -// g_gameNamePtr can point to one of: grpfiles[].name (string literal), string -// literal, malloc'd block (XXX: possible leak) -const char *g_gameNamePtr = NULL; - -// grp/con handling - -static const char *defaultconfilename = "GAME.CON"; -#ifndef EDUKE32_STANDALONE -static const char *defaultgamegrp[GAMECOUNT] = { "DUKE3D.GRP", "NAM.GRP", "NAPALM.GRP", "WW2GI.GRP" }; -static const char *defaultdeffilename[GAMECOUNT] = { "duke3d.def", "nam.def", "napalm.def", "ww2gi.def" }; -static const char *defaultgameconfilename[GAMECOUNT] = { "EDUKE.CON", "NAM.CON", "NAPALM.CON", "WW2GI.CON" }; -#endif - -const char *G_DefaultGrpFile(void) -{ - return "(none)"; // must be define in GRPINFO. -} - -const char *G_DefaultDefFile(void) -{ - // Todo: Get from the selected game record. - return "DUKE3D.DEF"; -} -const char *G_DefaultConFile(void) -{ - // Todo: Get from the selected game record. -#ifndef EDUKE32_STANDALONE - if (DUKE && testkopen(defaultgameconfilename[GAME_DUKE],0)) - return defaultgameconfilename[GAME_DUKE]; - else if (WW2GI && testkopen(defaultgameconfilename[GAME_WW2GI],0)) - return defaultgameconfilename[GAME_WW2GI]; - else if (NAPALM) - { - if (!testkopen(defaultgameconfilename[GAME_NAPALM],0)) - { - if (testkopen(defaultgameconfilename[GAME_NAM],0)) - return defaultgameconfilename[GAME_NAM]; // NAM/NAPALM Sharing - } - else - return defaultgameconfilename[GAME_NAPALM]; - } - else if (NAM) - { - if (!testkopen(defaultgameconfilename[GAME_NAM],0)) - { - if (testkopen(defaultgameconfilename[GAME_NAPALM],0)) - return defaultgameconfilename[GAME_NAPALM]; // NAM/NAPALM Sharing - } - else - return defaultgameconfilename[GAME_NAM]; - } -#endif - return defaultconfilename; -} - -const char* G_GrpFile(void) -{ - return userConfig.gamegrp.IsNotEmpty() ? userConfig.gamegrp.GetChars() : G_DefaultGrpFile(); -} - -const char* G_DefFile(void) -{ - return userConfig.DefaultDef.IsNotEmpty() ? userConfig.DefaultDef.GetChars() : G_DefaultDefFile(); -} - -const char* G_ConFile(void) -{ - return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : G_DefaultConFile(); -} - -////////// - // Set up new-style multi-psky handling. void G_InitMultiPsky(int CLOUDYOCEAN__DYN, int MOONSKY1__DYN, int BIGORBIT1__DYN, int LA__DYN) { @@ -179,177 +102,6 @@ void G_SetupGlobalPsky(void) g_pskyidx = skyIdx; } -////////// - -//char g_modDir[BMAX_PATH] = "/"; - - -static void G_LoadAddon(void); -int32_t g_groupFileHandle; -struct strllist* CommandGrps; - -static int32_t G_TryLoadingGrp(char const * const grpfile) -{ - int32_t i; - - if ((i = initgroupfile(grpfile)) == -1) - initprintf("Warning: could not find main data file \"%s\"!\n", grpfile); - else - initprintf("Using \"%s\" as main game data file.\n", grpfile); - - return i; -} - -static int32_t G_LoadGrpDependencyChain(grpfile_t const * const grp) -{ - if (!grp) - return -1; - - if (grp->type->dependency && grp->type->dependency != grp->type->crcval) - G_LoadGrpDependencyChain(FindGroup(grp->type->dependency)); - - int32_t const i = G_TryLoadingGrp(grp->filename); - - if (grp->type->postprocessing) - grp->type->postprocessing(i); - - return i; -} - -void G_LoadGroups() -{ - if (g_modDir[0] != '/') - { - char cwd[BMAX_PATH]; - - FString g_rootDir = progdir + g_modDir; - addsearchpath(g_rootDir); - // addsearchpath(mod_dir); - - char path[BMAX_PATH]; - - if (buildvfs_getcwd(cwd, BMAX_PATH)) - { - Bsnprintf(path, sizeof(path), "%s/%s", cwd, g_modDir); - if (!Bstrcmp(g_rootDir, path)) - { - addsearchpath(path); - } - } - - } - - if (g_addonNum) - G_LoadAddon(); - - const char *grpfile; - int32_t i; - - if ((i = G_LoadGrpDependencyChain(g_selectedGrp)) != -1) - { - grpfile = g_selectedGrp->filename; - - //clearGrpNamePtr(); - //g_grpNamePtr = dup_filename(grpfile); - - grpinfo_t const * const type = g_selectedGrp->type; - - g_gameType = type->game; - g_gameNamePtr = type->name; - - //if (type->scriptname && g_scriptNamePtr == NULL) - // g_scriptNamePtr = dup_filename(type->scriptname); - - if (type->defname && g_defNamePtr == NULL) - g_defNamePtr = dup_filename(type->defname); - - if (type->rtsname) - RTS_Init(type->rtsname); - } - else - { - grpfile = G_GrpFile(); - i = G_TryLoadingGrp(grpfile); - } - - if (G_AllowAutoload()) - { - G_LoadGroupsInDir("autoload"); - - if (i != -1) - G_DoAutoload(grpfile); - } - - if (g_modDir[0] != '/') - G_LoadGroupsInDir(g_modDir); - - - loaddefinitions_game(G_DefFile(), TRUE); -} - - - -static void G_LoadAddon(void) -{ -#ifndef EDUKE32_STANDALONE - int32_t crc = 0; // compiler-happy - - switch (g_addonNum) - { - case ADDON_DUKEDC: - crc = DUKEDC_CRC; - break; - case ADDON_NWINTER: - crc = DUKENW_CRC; - break; - case ADDON_CARIBBEAN: - crc = DUKECB_CRC; - break; - } - - if (!crc) return; - - grpfile_t const * const grp = FindGroup(crc); - - if (grp) - g_selectedGrp = grp; -#endif -} - - -////////// - -// loads all group (grp, zip, pk3/4) files in the given directory -void G_LoadGroupsInDir(const char *dirname) -{ - static const char *extensions[] = { "*.grp", "*.zip", "*.ssi", "*.pk3", "*.pk4" }; - char buf[BMAX_PATH]; - fnlist_t fnlist = FNLIST_INITIALIZER; - - for (auto & extension : extensions) - { - CACHE1D_FIND_REC *rec; - - fnlist_getnames(&fnlist, dirname, extension, -1, 0); - - for (rec=fnlist.findfiles; rec; rec=rec->next) - { - Bsnprintf(buf, sizeof(buf), "%s/%s", dirname, rec->name); - initprintf("Using group file \"%s\".\n", buf); - initgroupfile(buf); - } - - fnlist_clearnames(&fnlist); - } -} - -void G_DoAutoload(const char *dirname) -{ - char buf[BMAX_PATH]; - - Bsnprintf(buf, sizeof(buf), "autoload/%s", dirname); - G_LoadGroupsInDir(buf); -} ////////// diff --git a/source/duke3d/src/common_game.h b/source/duke3d/src/common_game.h index 27d1a505f..f8594ee73 100644 --- a/source/duke3d/src/common_game.h +++ b/source/duke3d/src/common_game.h @@ -16,11 +16,6 @@ BEGIN_DUKE_NS -extern struct grpfile_t const *g_selectedGrp; - -extern int32_t g_gameType; -extern int g_addonNum; - #define DUKE (g_gameType & GAMEFLAG_DUKE) #define NAM (g_gameType & GAMEFLAG_NAM) #define NAPALM (g_gameType & GAMEFLAG_NAPALM) @@ -38,12 +33,6 @@ enum Games_t { GAMECOUNT }; -enum searchpathtypes_t { - SEARCHPATH_REMOVE = 1<<0, - SEARCHPATH_NAM = 1<<1, - SEARCHPATH_WW2GI = 1<<2, -}; - typedef enum basepal_ { BASEPAL = 0, WATERPAL, @@ -65,16 +54,7 @@ typedef enum basepal_ { #define OSD_ERROR OSDTEXT_DARKRED OSDTEXT_BRIGHT -extern const char *g_gameNamePtr; - -extern const char *G_DefaultGrpFile(void); -extern const char *G_GrpFile(void); - -extern const char *G_DefaultConFile(void); -extern const char *G_ConFile(void); - extern int loaddefinitions_game(const char *fn, int32_t preload); -extern int32_t g_groupFileHandle; ////////// @@ -83,19 +63,6 @@ extern void G_SetupGlobalPsky(void); ////////// -extern void G_AddSearchPaths(void); - -extern void G_LoadGroups(); - -extern const char * G_GetInstallPath(int32_t insttype); - -////////// - -void G_LoadGroupsInDir(const char *dirname); -void G_DoAutoload(const char *dirname); - -////////// - extern void G_LoadLookups(void); ////////// diff --git a/source/duke3d/src/game.cpp b/source/duke3d/src/game.cpp index 43c175d5d..c7a47f690 100644 --- a/source/duke3d/src/game.cpp +++ b/source/duke3d/src/game.cpp @@ -45,6 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecvars.h" #include "gameconfigfile.h" #include "printf.h" +#include "m_argv.h" #include "filesystem/filesystem.h" #include "vfs.h" @@ -73,17 +74,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_DUKE_NS -extern const char* G_DefaultDefFile(void); -extern const char* G_DefFile(void); - - int32_t g_quitDeadline = 0; -#ifdef LUNATIC -camera_t g_camera; -#else int32_t g_cameraDistance = 0, g_cameraClock = 0; -#endif static int32_t g_quickExit; char boardfilename[BMAX_PATH] = {0}, currentboardfilename[BMAX_PATH] = {0}; @@ -5656,7 +5649,7 @@ int loaddefinitions_game(const char *fileName, int32_t firstPass) if (pScript) parsedefinitions_game(pScript, firstPass); - for (char const * m : g_defModules) + for (auto& m : *userConfig.AddDefs) parsedefinitions_game_include(m, NULL, "null", firstPass); if (pScript) @@ -6146,16 +6139,6 @@ static int G_EndOfLevel(void) return 1; } -void app_crashhandler(void) -{ - G_CloseDemoWrite(); -#if !defined LUNATIC - VM_ScriptInfo(insptr, 64); -#endif - G_GameQuit(); -} - - void G_MaybeAllocPlayer(int32_t pnum) { if (g_player[pnum].ps == NULL) @@ -6199,8 +6182,6 @@ int app_main() g_logFlushWindow = 0; - G_LoadGroups(); -// flushlogwindow = 1; #ifndef EDUKE32_STANDALONE G_SetupCheats(); @@ -6284,9 +6265,7 @@ int app_main() } loaddefinitions_game(defsfile, FALSE); - for (char * m : g_defModules) - free(m); - g_defModules.clear(); + userConfig.AddDefs.reset(); if (enginePostInit()) G_FatalEngineError(); @@ -6966,18 +6945,13 @@ void A_SpawnRandomGlass(int spriteNum, int wallNum, int glassCnt) #endif extern void faketimerhandler(); -extern void app_crashhandler(void); GameInterface Interface = { - TICRATE, faketimerhandler, app_main, validate_hud, set_hud_layout, set_hud_scale, - app_crashhandler, - G_DefaultDefFile, - G_DefFile, }; END_DUKE_NS diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index 71853eadc..a67a069c2 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "ns.h" // Must come before everything else! +#include #include "gamedef.h" #include "cheats.h" @@ -2100,11 +2101,6 @@ void C_UndefineLevel(int32_t vol, int32_t lev) LUNATIC_EXTERN int32_t C_SetDefName(const char *name) { - clearDefNamePtr(); - g_defNamePtr = dup_filename(name); - if (g_defNamePtr) - initprintf("Using DEF file: %s.\n", g_defNamePtr); - return (g_defNamePtr==NULL); } defaultprojectile_t DefaultProjectile; @@ -4603,8 +4599,8 @@ ifvar: if (n != i) { - std::swap(&tempscrptr[i], &tempscrptr[n]); - std::swap(&tempscrptr[i+1], &tempscrptr[n+1]); + std::swap(tempscrptr[i], tempscrptr[n]); + std::swap(tempscrptr[i+1], tempscrptr[n+1]); } } // for (j=3;j<3+tempscrptr[1]*2;j+=2)initprintf("%5d %8x\n",tempscrptr[j],tempscrptr[j+1]); @@ -5193,7 +5189,7 @@ repeatcase: } } gamename[i] = '\0'; - g_gameNamePtr = Xstrdup(gamename); + //g_gameName = gamename; never used. // G_UpdateAppTitle(); } continue; @@ -5211,7 +5207,7 @@ repeatcase: } tempbuf[j] = '\0'; - C_SetDefName(tempbuf); + //C_SetDefName(tempbuf); Uh, what? We're inside the DEF here! } continue; diff --git a/source/platform/win32/i_findfile.h b/source/platform/win32/i_findfile.h new file mode 100644 index 000000000..650972b8a --- /dev/null +++ b/source/platform/win32/i_findfile.h @@ -0,0 +1,42 @@ +#pragma once + +// Directory searching routines + +// Mirror WIN32_FIND_DATAW in + +struct findstate_t +{ +private: + struct WinData + { + uint32_t Attribs; + uint32_t Times[3 * 2]; + uint32_t Size[2]; + uint32_t Reserved[2]; + wchar_t Name[260]; + wchar_t AltName[14]; + }; + WinData FindData; + FString UTF8Name; + + friend void *I_FindFirst(const char *filespec, findstate_t *fileinfo); + friend int I_FindNext(void *handle, findstate_t *fileinfo); + friend const char *I_FindName(findstate_t *fileinfo); + friend int I_FindAttr(findstate_t *fileinfo); +}; + +void *I_FindFirst (const char *filespec, findstate_t *fileinfo); +int I_FindNext (void *handle, findstate_t *fileinfo); +int I_FindClose (void *handle); + +const char *I_FindName(findstate_t *fileinfo); +inline int I_FindAttr(findstate_t *fileinfo) +{ + return fileinfo->FindData.Attribs; +} + +#define FA_RDONLY 0x00000001 +#define FA_HIDDEN 0x00000002 +#define FA_SYSTEM 0x00000004 +#define FA_DIREC 0x00000010 +#define FA_ARCH 0x00000020 \ No newline at end of file diff --git a/source/platform/win32/i_specialpaths.cpp b/source/platform/win32/i_specialpaths.cpp index cd8a88569..f520ed207 100644 --- a/source/platform/win32/i_specialpaths.cpp +++ b/source/platform/win32/i_specialpaths.cpp @@ -41,6 +41,7 @@ #include "i_specialpaths.h" #include "printf.h" #include "cmdlib.h" +#include "i_findfile.h" //#include "version.h" // for GAMENAME // Stuff that needs to be set up later. @@ -336,3 +337,61 @@ FString M_GetDocumentsPath() return path; } +//========================================================================== +// +// I_FindFirst +// +// Start a pattern matching sequence. +// +//========================================================================== + + +void *I_FindFirst(const char *filespec, findstate_t *fileinfo) +{ + static_assert(sizeof(WIN32_FIND_DATAW) == sizeof(fileinfo->FindData), "Findata size mismatch"); + auto widespec = WideString(filespec); + fileinfo->UTF8Name = ""; + return FindFirstFileW(widespec.c_str(), (LPWIN32_FIND_DATAW)&fileinfo->FindData); +} + +//========================================================================== +// +// I_FindNext +// +// Return the next file in a pattern matching sequence. +// +//========================================================================== + +int I_FindNext(void *handle, findstate_t *fileinfo) +{ + fileinfo->UTF8Name = ""; + return !FindNextFileW((HANDLE)handle, (LPWIN32_FIND_DATAW)&fileinfo->FindData); +} + +//========================================================================== +// +// I_FindClose +// +// Finish a pattern matching sequence. +// +//========================================================================== + +int I_FindClose(void *handle) +{ + return FindClose((HANDLE)handle); +} + +//========================================================================== +// +// I_FindName +// +// Returns the name for an entry +// +//========================================================================== + +const char *I_FindName(findstate_t *fileinfo) +{ + if (fileinfo->UTF8Name.IsEmpty()) fileinfo->UTF8Name = fileinfo->FindData.Name; + return fileinfo->UTF8Name.GetChars(); +} + \ No newline at end of file diff --git a/source/rr/src/common.cpp b/source/rr/src/common.cpp index 0030b6564..d6dd514e9 100644 --- a/source/rr/src/common.cpp +++ b/source/rr/src/common.cpp @@ -19,87 +19,6 @@ BEGIN_RR_NS -struct grpfile_t const *g_selectedGrp; - -int32_t g_gameType = GAMEFLAG_DUKE; -int g_addonNum = 0; - -// g_gameNamePtr can point to one of: grpfiles[].name (string literal), string -// literal, malloc'd block (XXX: possible leak) -const char *g_gameNamePtr = NULL; - -// grp/con handling - -static const char *defaultconfilename = "GAME.CON"; -static const char *defaultgamegrp[GAMECOUNT] = { "DUKE3D.GRP", "REDNECK.GRP", "REDNECK.GRP", "NAM.GRP", "NAPALM.GRP" }; -static const char *defaultdeffilename[GAMECOUNT] = { "duke3d.def", "rr.def", "rrra.def", "nam.def", "napalm.grp" }; -static const char *defaultgameconfilename[GAMECOUNT] = { "GAME.CON", "GAME.CON", "GAME.CON", "NAM.CON", "NAPALM.CON" }; - -const char* G_DefaultGrpFile(void) -{ - if (DUKE) - return defaultgamegrp[GAME_DUKE]; - else if (RR) - return defaultgamegrp[GAME_RR]; - - return defaultgamegrp[0]; -} - -const char* G_DefaultDefFile(void) -{ - if (DUKE) - return defaultdeffilename[GAME_DUKE]; - else if (RRRA) - return defaultdeffilename[GAME_RRRA]; - else if (RR) - return defaultdeffilename[GAME_RR]; - - return defaultdeffilename[0]; -} -const char *G_DefaultConFile(void) -{ - /*if (DUKE && testkopen(defaultgameconfilename[GAME_DUKE],0)) - return defaultgameconfilename[GAME_DUKE]; - else if (WW2GI && testkopen(defaultgameconfilename[GAME_WW2GI],0)) - return defaultgameconfilename[GAME_WW2GI]; - else */if (NAPALM) - { - if (!testkopen(defaultgameconfilename[GAME_NAPALM],0)) - { - if (testkopen(defaultgameconfilename[GAME_NAM],0)) - return defaultgameconfilename[GAME_NAM]; // NAM/NAPALM Sharing - } - else - return defaultgameconfilename[GAME_NAPALM]; - } - else if (NAM) - { - if (!testkopen(defaultgameconfilename[GAME_NAM],0)) - { - if (testkopen(defaultgameconfilename[GAME_NAPALM],0)) - return defaultgameconfilename[GAME_NAPALM]; // NAM/NAPALM Sharing - } - else - return defaultgameconfilename[GAME_NAM]; - } - return defaultconfilename; -} - -const char *G_GrpFile(void) -{ - return userConfig.gamegrp.IsNotEmpty()? userConfig.gamegrp.GetChars() : G_DefaultGrpFile(); -} - -const char *G_DefFile(void) -{ - return userConfig.DefaultDef.IsNotEmpty() ? userConfig.DefaultDef.GetChars() : G_DefaultDefFile(); -} - -const char *G_ConFile(void) -{ - return userConfig.DefaultCon.IsNotEmpty() ? userConfig.DefaultCon.GetChars() : G_DefaultConFile(); -} - ////////// // Set up new-style multi-psky handling. @@ -183,187 +102,6 @@ void G_SetupGlobalPsky(void) ////////// -static void G_LoadAddon(void); -int32_t g_groupFileHandle; -struct strllist* CommandGrps; - -static int32_t G_TryLoadingGrp(char const * const grpfile) -{ - int32_t i; - - if ((i = initgroupfile(grpfile)) == -1) - initprintf("Warning: could not find main data file \"%s\"!\n", grpfile); - else - initprintf("Using \"%s\" as main game data file.\n", grpfile); - - return i; -} - -static int32_t G_LoadGrpDependencyChain(grpfile_t const * const grp) -{ - if (!grp) - return -1; - - if (grp->type->dependency && grp->type->dependency != grp->type->crcval) - G_LoadGrpDependencyChain(FindGroup(grp->type->dependency)); - - int32_t const i = G_TryLoadingGrp(grp->filename); - - if (grp->type->postprocessing) - grp->type->postprocessing(i); - - return i; -} - -void G_LoadGroups() -{ - if (g_modDir[0] != '/') - { - char cwd[BMAX_PATH]; - - FString g_rootDir = progdir + g_modDir; - addsearchpath(g_rootDir); - // addsearchpath(mod_dir); - - char path[BMAX_PATH]; - - if (getcwd(cwd, BMAX_PATH)) - { - Bsnprintf(path, sizeof(path), "%s/%s", cwd, g_modDir); - if (!Bstrcmp(g_rootDir, path)) - { - if (addsearchpath(path) == -2) - if (Bmkdir(path, S_IRWXU) == 0) - addsearchpath(path); - } - } - - } - - if (g_addonNum) - G_LoadAddon(); - - const char *grpfile; - int32_t i; - - if ((i = G_LoadGrpDependencyChain(g_selectedGrp)) != -1) - { - grpfile = g_selectedGrp->filename; - - //clearGrpNamePtr(); - //g_grpNamePtr = dup_filename(grpfile); - - grpinfo_t const * const type = g_selectedGrp->type; - - g_gameType = type->game; - g_gameNamePtr = type->name; - - //if (type->scriptname && g_scriptNamePtr == NULL) - // g_scriptNamePtr = dup_filename(type->scriptname); - - if (type->defname && g_defNamePtr == NULL) - g_defNamePtr = dup_filename(type->defname); - - if (type->rtsname) - RTS_Init(type->rtsname); - } - else - { - grpfile = G_GrpFile(); - i = G_TryLoadingGrp(grpfile); - } - - if (G_AllowAutoload()) - { - G_LoadGroupsInDir("autoload"); - - if (i != -1) - G_DoAutoload(grpfile); - } - - if (g_modDir[0] != '/') - G_LoadGroupsInDir(g_modDir); - - if (g_defNamePtr == NULL) - { - const char *tmpptr = getenv("DUKE3DDEF"); - if (tmpptr) - { - clearDefNamePtr(); - g_defNamePtr = dup_filename(tmpptr); - initprintf("Using \"%s\" as definitions file\n", g_defNamePtr); - } - } - - loaddefinitions_game(G_DefFile(), TRUE); -} - - -static void G_LoadAddon(void) -{ - int32_t crc = 0; // compiler-happy - - switch (g_addonNum) - { - case ADDON_DUKEDC: - crc = DUKEDC_CRC; - break; - case ADDON_NWINTER: - crc = DUKENW_CRC; - break; - case ADDON_CARIBBEAN: - crc = DUKECB_CRC; - break; - } - - if (!crc) return; - - grpfile_t const * const grp = FindGroup(crc); - - if (grp) - g_selectedGrp = grp; -} - - - - -////////// - - -// loads all group (grp, zip, pk3/4) files in the given directory -void G_LoadGroupsInDir(const char *dirname) -{ - static const char *extensions[] = { "*.grp", "*.zip", "*.ssi", "*.pk3", "*.pk4" }; - char buf[BMAX_PATH]; - fnlist_t fnlist = FNLIST_INITIALIZER; - - for (auto & extension : extensions) - { - CACHE1D_FIND_REC *rec; - - fnlist_getnames(&fnlist, dirname, extension, -1, 0); - - for (rec=fnlist.findfiles; rec; rec=rec->next) - { - Bsnprintf(buf, sizeof(buf), "%s/%s", dirname, rec->name); - initprintf("Using group file \"%s\".\n", buf); - initgroupfile(buf); - } - - fnlist_clearnames(&fnlist); - } -} - -void G_DoAutoload(const char *dirname) -{ - char buf[BMAX_PATH]; - - Bsnprintf(buf, sizeof(buf), "autoload/%s", dirname); - G_LoadGroupsInDir(buf); -} - -////////// - void G_LoadLookups(void) { int32_t j; diff --git a/source/rr/src/common_game.h b/source/rr/src/common_game.h index feba48ea8..b7b3e057e 100644 --- a/source/rr/src/common_game.h +++ b/source/rr/src/common_game.h @@ -14,11 +14,6 @@ BEGIN_RR_NS -extern struct grpfile_t const *g_selectedGrp; - -extern int32_t g_gameType; -extern int g_addonNum; - #define DUKE (g_gameType & GAMEFLAG_DUKE) #define RR (g_gameType & GAMEFLAG_RR) #define RRRA (g_gameType & GAMEFLAG_RRRA) @@ -40,26 +35,6 @@ enum Games_t { GAMECOUNT }; -enum instpath_t { - INSTPATH_STEAM_DUKE3D_MEGATON, - INSTPATH_STEAM_DUKE3D_3DR, - INSTPATH_GOG_DUKE3D, - INSTPATH_3DR_DUKE3D, - INSTPATH_3DR_ANTH, - //INSTPATH_STEAM_NAM, - //INSTPATH_STEAM_WW2GI, - INSTPATH_GOG_RR, - INSTPATH_GOG_RRRA, - NUMINSTPATHS -}; - -enum searchpathtypes_t { - SEARCHPATH_REMOVE = 1<<0, - SEARCHPATH_NAM = 1<<1, - SEARCHPATH_RR = 1<<2, - SEARCHPATH_RRRA = 1<<3, -}; - typedef enum basepal_ { BASEPAL = 0, WATERPAL, @@ -82,16 +57,7 @@ typedef enum basepal_ { #define OSD_ERROR OSDTEXT_DARKRED OSDTEXT_BRIGHT -extern const char *g_gameNamePtr; - -extern const char *G_DefaultGrpFile(void); -extern const char *G_GrpFile(void); - -extern const char *G_DefaultConFile(void); -extern const char *G_ConFile(void); - extern int loaddefinitions_game(const char *fn, int32_t preload); -extern int32_t g_groupFileHandle; ////////// @@ -100,19 +66,6 @@ extern void G_SetupGlobalPsky(void); ////////// -extern void G_AddSearchPaths(void); - -extern void G_LoadGroups(); - -extern const char * G_GetInstallPath(int32_t insttype); - -////////// - -void G_LoadGroupsInDir(const char *dirname); -void G_DoAutoload(const char *dirname); - -////////// - extern void G_LoadLookups(void); ////////// diff --git a/source/rr/src/game.cpp b/source/rr/src/game.cpp index 1388a4f35..f55f6fa5a 100644 --- a/source/rr/src/game.cpp +++ b/source/rr/src/game.cpp @@ -45,6 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "gamecvars.h" #include "gameconfigfile.h" #include "printf.h" +#include "m_argv.h" #include "filesystem/filesystem.h" // Uncomment to prevent anything except mirrors from drawing. It is sensible to @@ -72,10 +73,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_RR_NS -extern const char* G_DefaultDefFile(void); -extern const char* G_DefFile(void); - - int32_t g_quitDeadline = 0; int32_t g_cameraDistance = 0, g_cameraClock = 0; @@ -7022,7 +7019,7 @@ int loaddefinitions_game(const char *fileName, int32_t firstPass) if (pScript) parsedefinitions_game(pScript, firstPass); - for (char const * m : g_defModules) + for (auto& m : *userConfig.AddDefs) parsedefinitions_game_include(m, NULL, "null", firstPass); if (pScript) @@ -7148,8 +7145,6 @@ static void G_CompileScripts(void) Bmemset(sprite, 0, MAXSPRITES*sizeof(spritetype)); Bmemset(sector, 0, MAXSECTORS*sizeof(sectortype)); Bmemset(wall, 0, MAXWALLS*sizeof(walltype)); - - pathsearchmode = psm; } static inline void G_CheckGametype(void) @@ -7539,12 +7534,6 @@ static int G_EndOfLevel(void) return 1; } -void app_crashhandler(void) -{ - G_CloseDemoWrite(); - G_GameQuit(); -} - #if defined(_WIN32) && defined(DEBUGGINGAIDS) // See FILENAME_CASE_CHECK in cache1d.c static int32_t check_filename_casing(void) @@ -7603,8 +7592,6 @@ int app_main() g_logFlushWindow = 0; - G_LoadGroups(); -// flushlogwindow = 1; if (RR) { @@ -7693,9 +7680,7 @@ int app_main() } loaddefinitions_game(defsfile, FALSE); - for (char * m : g_defModules) - free(m); - g_defModules.clear(); + userConfig.AddDefs.reset(); if (enginePostInit()) G_FatalEngineError(); @@ -8442,18 +8427,12 @@ void A_SpawnRandomGlass(int spriteNum, int wallNum, int glassCnt) extern void faketimerhandler(); extern int app_main(); -extern void app_crashhandler(void); GameInterface Interface = { - TICRATE, faketimerhandler, app_main, validate_hud, set_hud_layout, set_hud_scale, - app_crashhandler, - G_DefaultDefFile, - G_DefFile, - }; END_RR_NS diff --git a/source/sw/src/common.cpp b/source/sw/src/common.cpp index fc8a469a2..6674ce4b9 100644 --- a/source/sw/src/common.cpp +++ b/source/sw/src/common.cpp @@ -13,43 +13,6 @@ BEGIN_SW_NS -static const char *defaultgrpfilename = "SW.GRP"; -static const char *defaultdeffilename = "sw.def"; - -// g_grpNamePtr can ONLY point to a malloc'd block (length BMAX_PATH) -char *g_grpNamePtr = NULL; - -void clearGrpNamePtr(void) -{ - Bfree(g_grpNamePtr); - // g_grpNamePtr assumed to be assigned to right after -} - -const char *G_DefaultGrpFile(void) -{ - return defaultgrpfilename; -} -const char *G_GrpFile(void) -{ - if (g_grpNamePtr == NULL) - return G_DefaultGrpFile(); - else - return g_grpNamePtr; -} - -const char *G_DefaultDefFile(void) -{ - return defaultdeffilename; -} -const char *G_DefFile(void) -{ - if (g_defNamePtr == NULL) - return G_DefaultDefFile(); - else - return g_defNamePtr; -} - - void SW_InitMultiPsky(void) { // default @@ -58,8 +21,6 @@ void SW_InitMultiPsky(void) defaultsky->horizfrac = 8192; } - - void SW_CleanupSearchPaths() { } diff --git a/source/sw/src/common_game.h b/source/sw/src/common_game.h index 21a99e032..c7c0248b0 100644 --- a/source/sw/src/common_game.h +++ b/source/sw/src/common_game.h @@ -129,13 +129,6 @@ BEGIN_SW_NS extern int g_useCwd; -extern char *g_grpNamePtr; - -const char *G_DefaultGrpFile(void); -const char *G_GrpFile(void); - -void clearGrpNamePtr(void); - void SW_InitMultiPsky(void); void SW_ExtPreInit(int32_t argc, char const * const * argv); diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 3d7e80322..52098e8fe 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -92,6 +92,7 @@ Things required to make savegames work: #include "common_game.h" #include "gameconfigfile.h" #include "printf.h" +#include "m_argv.h" //#include "crc32.h" @@ -103,8 +104,6 @@ signed char MNU_InputString(char*, short); SWBOOL IsCommand(char* str); SWBOOL MNU_StartNetGame(void); -const char* G_DefFile(void); - const char* AppProperName = "VoidSW"; const char* AppTechnicalName = "voidsw"; @@ -862,7 +861,6 @@ InitGame() if (engineInit()) SW_FatalEngineError(); - //initgroupfile(G_GrpFile()); // JBF: moving this close to start of program to detect shareware InitAutoNet(); timerInit(120); @@ -976,9 +974,7 @@ InitGame() if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n"); - for (char * m : g_defModules) - free(m); - g_defModules.clear(); + userConfig.AddDefs.reset(); if (enginePostInit()) SW_FatalEngineError(); @@ -3350,7 +3346,6 @@ int32_t app_main() I_Error("There was a problem initialising the Build engine: %s", engineerrstr); } - initgroupfile(G_GrpFile()); if (!DetectShareware()) { if (SW_SHAREWARE) buildputs("Detected shareware GRP\n"); @@ -3375,468 +3370,6 @@ int32_t app_main() UserMapName[0] = '\0'; - //LocationInfo = TRUE; - -#if 0 - //#if DEBUG && SYNC_TEST - // automatically record a demo - DemoRecording = TRUE; - DemoPlaying = FALSE; - PreCaching = TRUE; - DemoRecCnt = 0; - strcpy(DemoFileName, "DMOTEST.DMO"); - //DemoSyncRecord = TRUE; -#endif - -#if DEBUG - { - FILE *fout; - if ((fout = fopen("dbg.foo", "wb")) != NULL) - { - fprintf(fout, "Whoo-oo-ooooo wants some wang?\n"); - fclose(fout); - } - } -#endif - -#if 0 - for (cnt = 1; cnt < argc; cnt++) - { - char const *arg = argv[cnt]; - - if (*arg != '/' && *arg != '-') continue; - - if (firstnet > 0) - { - arg++; - switch (arg[0]) - { - case 'n': - case 'N': - if (arg[1] == '0') - { - NetBroadcastMode = FALSE; - buildputs("Network mode: master/slave\n"); - wm_msgbox("Multiplayer Option Error", - "This release unfortunately does not support a master-slave networking " - "mode because of certain bugs we have not been able to locate and fix " - "at this time. However, peer-to-peer networking has been found to be " - "playable, so we suggest attempting to use that for now. Details can be " - "found in the release notes. Sorry for the inconvenience."); - return 0; - } - else if (arg[1] == '1') - { - NetBroadcastMode = TRUE; - buildputs("Network mode: peer-to-peer\n"); - } - break; - default: - break; - } - continue; - } - - // Store arg in command line array! - CON_StoreArg(arg); - arg++; - - if (Bstrncasecmp(arg, "autonet",7) == 0) - { - AutoNet = TRUE; - cnt++; - sscanf(argv[cnt],"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",&Auto.Rules,&Auto.Level,&Auto.Enemy,&Auto.Markers, - &Auto.Team,&Auto.HurtTeam,&Auto.Kill,&Auto.Time,&Auto.Color,&Auto.Nuke); - } - else if (Bstrncasecmp(arg, "turnscale",9) == 0) - { - if (cnt <= argc-2) - { - cnt++; - sscanf(argv[cnt], "%d",&turn_scale); - } - } - else if (Bstrncasecmp(arg, "movescale",9) == 0) - { - if (cnt <= argc-2) - { - cnt++; - sscanf(argv[cnt], "%d",&move_scale); - } - } - else if (Bstrncasecmp(arg, "extcompat",9) == 0) - { - move_scale *= 5; - turn_scale *= 5; - } - else if (Bstrncasecmp(arg, "setupfile",8) == 0) - { - // Passed by setup.exe - // skip setupfile name - cnt++; - } - else if (Bstrncasecmp(arg, "net",3) == 0) - { - if (cnt+1 < argc) - { - firstnet = cnt+1; - } - } -#if DEBUG - else if (Bstrncasecmp(arg, "debug",5) == 0) - { -#ifdef RENDERTYPEWIN - char *str; - int strl; - - strl = 24 + 70; - for (i=0; i < (int)SIZ(cli_dbg_arg); i++) - strl += strlen(cli_dbg_arg[i].arg_fmt) + 1 + strlen(cli_dbg_arg[i].arg_descr) + 1; - - str = (char *)malloc(strl); - if (str) - { - strcpy(str, - "Usage: sw [options]\n" - "options: ('/' may be used instead of '-', <> text is optional)\n\n" - ); - for (i=0; i < (int)SIZ(cli_dbg_arg); i++) - { - strcat(str, cli_dbg_arg[i].arg_fmt); - strcat(str, "\t"); - strcat(str, cli_dbg_arg[i].arg_descr); - strcat(str, "\n"); - } - wm_msgbox("Shadow Warrior Debug Help",str); - free(str); - } -#else - printf("Usage: %s [options]\n", argv[0]); - printf("options: ('/' may be used instead of '-', <> text is optional)\n\n"); - for (i = 0; i < (int)SIZ(cli_dbg_arg); i++) - { - if (cli_dbg_arg[i].arg_fmt) - { - printf(" %-20s %-30s\n",cli_dbg_arg[i].arg_fmt, cli_dbg_arg[i].arg_descr); - } - } -#endif - swexit(0); - } -#endif - else if (Bstrncasecmp(arg, "short",5) == 0) - { - ShortGameMode = TRUE; - } - else if (Bstrncasecmp(arg, "nodemo",6) == 0) - { - NoDemoStartup = TRUE; - } - else if (Bstrncasecmp(arg, "allsync",3) == 0) - { - NumSyncBytes = 8; - } - else if (Bstrncasecmp(arg, "name",4) == 0) - { - if (cnt <= argc-2) - { - strncpy(PlayerNameArg, argv[++cnt], SIZ(PlayerNameArg)-1); - PlayerNameArg[SIZ(PlayerNameArg)-1] = '\0'; - } - } - else if (Bstrncasecmp(arg, "f8",2) == 0) - { - MovesPerPacket = 8; - } - else if (Bstrncasecmp(arg, "f4",2) == 0) - { - MovesPerPacket = 4; - } - else if (Bstrncasecmp(arg, "f2",2) == 0) - { - MovesPerPacket = 2; - } - else if (Bstrncasecmp(arg, "monst", 5) == 0) - { - DebugActor = TRUE; - } - else if (Bstrncasecmp(arg, "nopredict",6) == 0) - { - extern SWBOOL PredictionOn; - PredictionOn = FALSE; - } - else if (Bstrncasecmp(arg, "col", 3) == 0) - // provides a way to force the player color for joiners - // since -autonet does not seem to work for them - { - int temp; - cnt++; - sscanf(argv[cnt],"%d",&temp); - AutoColor = temp; - HasAutoColor = TRUE; - } - else if (Bstrncasecmp(arg, "level", 5) == 0) - { - if (strlen(arg) > 5) - { - strcpy(UserMapName,LevelInfo[atoi(&arg[5])].LevelName); - } - } - else if (Bstrncasecmp(arg, "s", 1) == 0) - { - if (strlen(arg) > 1) - Skill = atoi(&arg[1])-1; - - Skill = max(Skill,short(0)); - Skill = min(Skill,short(3)); - } - else if (Bstrncasecmp(arg, "commbat", 7) == 0) - { - if (strlen(arg) > 7) - { - FakeMultiNumPlayers = atoi(&arg[7]); - gNet.MultiGameType = MULTI_GAME_COMMBAT; - } - } - else - /* bots suck, bye bye! - #ifndef SW_SHAREWARE - if (memcmp(argv[cnt], "-bots", 5) == 0) - { - if (strlen(argv[cnt]) > 5) - { - FakeMultiNumPlayers = atoi(&argv[cnt][5]); - printf("Adding %d BOT(s) to the game!\n",FakeMultiNumPlayers); - gNet.MultiGameType = MULTI_GAME_AI_BOTS; - BotMode = TRUE; - } - } - else - #endif - */ - if (Bstrncasecmp(arg, "nometers", 8) == 0) - { - NoMeters = TRUE; - } - else if (Bstrncasecmp(arg, "coop", 4) == 0) - { - if (strlen(arg) > 4) - { - FakeMultiNumPlayers = atoi(&arg[4]); - gNet.MultiGameType = MULTI_GAME_COOPERATIVE; - } - } - else if (FALSE && Bstrncasecmp(arg, "ddr", 3) == 0) - { - //NumSyncBytes = 8; - DemoRecording = TRUE; - DemoPlaying = FALSE; - DemoRecCnt = 0; - DemoDebugMode = TRUE; - - if (strlen(arg) > 3) - { - strcpy(DemoFileName, &arg[2]); - if (strchr(DemoFileName, '.') == 0) - strcat(DemoFileName, ".dmo"); - } - } - else if (FALSE && Bstrncasecmp(arg, "dr", 2) == 0) - { - //NumSyncBytes = 8; - DemoRecording = TRUE; - DemoPlaying = FALSE; - DemoRecCnt = 0; - - if (strlen(arg) > 2) - { - strcpy(DemoFileName, &arg[2]); - if (strchr(DemoFileName, '.') == 0) - strcat(DemoFileName, ".dmo"); - } - } - else if (FALSE && Bstrncasecmp(arg, "dp", 2) == 0) - { - DemoPlaying = TRUE; - DemoRecording = FALSE; - PreCaching = TRUE; - - if (strlen(arg) > 2) - { - strcpy(DemoFileName, &arg[2]); - if (strchr(DemoFileName, '.') == 0) - strcat(DemoFileName, ".dmo"); - } - } - -#if 0 //def NET_MODE_MASTER_SLAVE - else if (Bstrncasecmp(arg, "masterslave",6) == 0) - { - NetModeOverride = TRUE; - NetBroadcastMode = FALSE; - } - else if (Bstrncasecmp(arg, "broadcast",5) == 0) - { - NetModeOverride = TRUE; - NetBroadcastMode = TRUE; - } -#endif - - else if (Bstrncasecmp(arg, "cheat",5) == 0) - { - ArgCheat = TRUE; - } - else if (Bstrncasecmp(arg, "demosynctest",12) == 0) - { - NumSyncBytes = 8; - DemoSyncTest = TRUE; - DemoSyncRecord = FALSE; - } - else if (Bstrncasecmp(arg, "demosyncrecord",12) == 0) - { - NumSyncBytes = 8; - DemoSyncTest = FALSE; - DemoSyncRecord = TRUE; - } - else if (Bstrncasecmp(arg, "cam",3) == 0) - { - CameraTestMode = TRUE; - } - -#if DEBUG - else if (FALSE && Bstrncasecmp(arg, "de", 2) == 0) - { -#if DEMO_FILE_TYPE == DEMO_FILE_GROUP - DemoPlaying = TRUE; - DemoRecording = FALSE; - - if (strlen(arg) > 2) - { - strcpy(DemoFileName, &arg[2]); - if (strchr(DemoFileName, '.') == 0) - strcat(DemoFileName, ".dmo"); - } -#else - DemoEdit = TRUE; - DemoPlaying = TRUE; - DemoRecording = FALSE; - - if (strlen(arg) > 2) - { - strcpy(DemoFileName, &arg[2]); - if (strchr(DemoFileName, '.') == 0) - strcat(DemoFileName, ".dmo"); - } -#endif - } - else if (Bstrncasecmp(arg, "randprint",5) == 0) - { - RandomPrint = TRUE; - } - else if (Bstrncasecmp(arg, "level", 5) == 0) - { - if (strlen(arg) > 5) - { - strcpy(UserMapName,LevelInfo[atoi(&arg[5])].LevelName); - } - } - else if (Bstrncasecmp(arg, "debugsecret", 10) == 0) - { - extern SWBOOL DebugSecret; - DebugSecret = TRUE; - } - else if (Bstrncasecmp(arg, "debugactor", 10) == 0) - { - DebugActor = TRUE; - } - else if (Bstrncasecmp(arg, "mono", 4) == 0) - { - DispMono = TRUE; - } - else if (Bstrncasecmp(arg, "debugso", 7) == 0) - { - DebugSO = TRUE; - } - else if (Bstrncasecmp(arg, "nosyncprint",10) == 0) - { - extern SWBOOL SyncPrintMode; - SyncPrintMode = FALSE; - } - else if (Bstrncasecmp(arg, "debuganim", 9) == 0) - { - DebugAnim = TRUE; - } - else if (Bstrncasecmp(arg, "debugsector", 11) == 0) - { - DebugSector = TRUE; - } - else if (Bstrncasecmp(arg, "debugpanel", 10) == 0) - { - DebugPanel = TRUE; - } - else if (FALSE && Bstrncasecmp(arg, "dt", 2) == 0) - { - if (strlen(arg) > 2) - { - strcpy(DemoTmpName, &arg[2]); - if (strchr(DemoFileName, '.') == 0) - strcat(DemoFileName, ".dmo"); - } - } - else if (Bstrncasecmp(arg, "nodemo", 6) == 0) - { - DemoRecording = FALSE; - DemoPlaying = FALSE; - PreCaching = TRUE; - DemoRecCnt = 0; - - DemoSyncTest = FALSE; - DemoSyncRecord = FALSE; - } - -#endif - - else if (Bstrncasecmp(arg, "map", 3) == 0 && !SW_SHAREWARE) - { - int fil; - - strcpy(UserMapName, argv[++cnt]); - if (strchr(UserMapName, '.') == 0) - strcat(UserMapName, ".map"); - - if (!testkopen(UserMapName,0)) - { -#ifdef RENDERTYPEWIN - char msg[256]; - Bsnprintf(msg, 256, "ERROR: Could not find user map %s!",UserMapName); - wm_msgbox(apptitle, msg); -#else - printf("ERROR: Could not find user map %s!\n\n",UserMapName); -#endif - swexit(0); - } - } - - else if (Bstrncasecmp(arg, "g", 1) == 0 && !SW_SHAREWARE) - { - if (strlen(arg) > 1) - { - if (initgroupfile(arg+1) >= 0) - buildprintf("Added %s\n", arg+1); - } - } - else if (Bstrncasecmp(arg, "h", 1) == 0 && !SW_SHAREWARE) - { - if (strlen(arg) > 1) - G_AddDef(arg+1); - } - else if (Bstrncasecmp(arg, "mh", 1) == 0 && !SW_SHAREWARE) - { - if (strlen(arg) > 1) - G_AddDefModule(arg+1); - } - } -#endif Control(); return 0; @@ -5502,7 +5035,6 @@ StdRandomRange(int range) // [JM] Probably will need some doing over. !CHECKME! void M32RunScript(const char *s) { UNREFERENCED_PARAMETER(s); } void G_Polymer_UnInit(void) { } -void app_crashhandler(void) { } int osdcmd_restartvid(const osdfuncparm_t *parm) { @@ -5537,20 +5069,15 @@ saveable_module saveable_build = extern void faketimerhandler(); extern int app_main(); -extern void app_crashhandler(void); /*extern*/ bool validate_hud(int requested_size) { return requested_size; } /*extern*/ void set_hud(int requested_size) { /* the relevant setting is gs.BorderNum */} GameInterface Interface = { - 140, // Huh? faketimerhandler, app_main, validate_hud, set_hud, set_hud, - app_crashhandler, - G_DefFile, - G_DefFile, }; // vim:ts=4:sw=4:expandtab: