Merge remote-tracking branch 'gzdoom/master' into merge-gzdoom

This commit is contained in:
Magnus Norddahl 2023-10-19 21:05:17 +02:00
commit e75e5a387b
600 changed files with 40006 additions and 59374 deletions

View file

@ -122,6 +122,8 @@
#include "i_system.h" // for SHARE_DIR
#endif // __unix__
using namespace FileSys;
EXTERN_CVAR(Bool, hud_althud)
EXTERN_CVAR(Int, vr_mode)
EXTERN_CVAR(Bool, cl_customizeinvulmap)
@ -202,11 +204,6 @@ extern bool insave;
extern TDeletingArray<FLightDefaults *> LightDefaults;
extern FName MessageBoxClass;
static const char* iwad_folders[] = { "flats/", "textures/", "hires/", "sprites/", "voxels/", "colormaps/", "acs/", "maps/", "voices/", "patches/", "graphics/", "sounds/", "music/",
"materials/", "models/", "fonts/", "brightmaps/"};
static const char* iwad_reserved[] = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "maps/" };
CUSTOM_CVAR(Float, i_timescale, 1.0f, CVAR_NOINITCALL | CVAR_VIRTUAL)
{
if (netgame)
@ -280,7 +277,7 @@ CUSTOM_CVAR (String, vid_cursor, "None", CVAR_ARCHIVE | CVAR_NOINITCALL)
if (!stricmp(self, "None" ) && gameinfo.CursorPic.IsNotEmpty())
{
res = I_SetCursor(TexMan.GetGameTextureByName(gameinfo.CursorPic));
res = I_SetCursor(TexMan.GetGameTextureByName(gameinfo.CursorPic.GetChars()));
}
else
{
@ -1099,7 +1096,7 @@ void D_Display ()
}
if ( !skip )
{
auto tex = TexMan.GetGameTextureByName(gameinfo.PauseSign, true);
auto tex = TexMan.GetGameTextureByName(gameinfo.PauseSign.GetChars(), true);
double x = (SCREENWIDTH - tex->GetDisplayWidth() * CleanXfac)/2 +
tex->GetDisplayLeftOffset() * CleanXfac;
DrawTexture(twod, tex, x, 4, DTA_CleanNoMove, true, TAG_DONE);
@ -1110,7 +1107,7 @@ void D_Display ()
pstring.Substitute("%s", players[paused - 1].userinfo.GetName());
DrawText(twod, font, CR_RED,
(twod->GetWidth() - font->StringWidth(pstring)*CleanXfac) / 2,
(tex->GetDisplayHeight() * CleanYfac) + 4, pstring, DTA_CleanNoMove, true, TAG_DONE);
(tex->GetDisplayHeight() * CleanYfac) + 4, pstring.GetChars(), DTA_CleanNoMove, true, TAG_DONE);
}
}
}
@ -1247,7 +1244,7 @@ void D_DoomLoop ()
return;
}
}
catch (CRecoverableError &error)
catch (const CRecoverableError &error)
{
if (error.GetMessage ())
{
@ -1255,6 +1252,14 @@ void D_DoomLoop ()
}
D_ErrorCleanup ();
}
catch (const FileSystemException& error) // in case this propagates up to here it should be treated as a recoverable error.
{
if (error.what())
{
Printf(PRINT_NONOTIFY | PRINT_BOLD, "\n%s\n", error.what());
}
D_ErrorCleanup();
}
catch (CVMAbortException &error)
{
error.MaybePrintMessage();
@ -1524,7 +1529,7 @@ void D_DoAdvanceDemo (void)
gamestate = GS_DEMOSCREEN;
pagename = gameinfo.TitlePage;
pagetic = (int)(gameinfo.titleTime * TICRATE);
if (!playedtitlemusic) S_ChangeMusic (gameinfo.titleMusic, gameinfo.titleOrder, false);
if (!playedtitlemusic) S_ChangeMusic (gameinfo.titleMusic.GetChars(), gameinfo.titleOrder, false);
playedtitlemusic = true;
demosequence = 3;
pagecount = 0;
@ -1546,7 +1551,7 @@ void D_DoAdvanceDemo (void)
if (pagename.IsNotEmpty())
{
Page = TexMan.CheckForTexture(pagename, ETextureType::MiscPatch);
Page = TexMan.CheckForTexture(pagename.GetChars(), ETextureType::MiscPatch);
}
}
@ -1725,7 +1730,7 @@ void ParseCVarInfo()
}
}
// Now create the cvar.
cvar = customCVar ? C_CreateZSCustomCVar(cvarname, cvartype, cvarflags, customCVarClassName) : C_CreateCVar(cvarname, cvartype, cvarflags);
cvar = customCVar ? C_CreateZSCustomCVar(cvarname.GetChars(), cvartype, cvarflags, customCVarClassName) : C_CreateCVar(cvarname.GetChars(), cvartype, cvarflags);
if (cvardefault != NULL)
{
UCVarValue val;
@ -1741,7 +1746,7 @@ void ParseCVarInfo()
// clutter up the cvar space when not playing mods with custom cvars.
if (addedcvars)
{
GameConfig->DoModSetup (gameinfo.ConfigName);
GameConfig->DoModSetup (gameinfo.ConfigName.GetChars());
}
}
@ -1762,8 +1767,8 @@ bool ConsiderPatches (const char *arg)
argc = Args->CheckParmList(arg, &args);
for (i = 0; i < argc; ++i)
{
if ( (f = BaseFileSearch(args[i], ".deh", false, GameConfig)) ||
(f = BaseFileSearch(args[i], ".bex", false, GameConfig)) )
if ( (f = BaseFileSearch(args[i].GetChars(), ".deh", false, GameConfig)) ||
(f = BaseFileSearch(args[i].GetChars(), ".bex", false, GameConfig)) )
{
D_LoadDehFile(f);
}
@ -1786,7 +1791,7 @@ FExecList *D_MultiExec (FArgs *list, FExecList *exec)
return exec;
}
static void GetCmdLineFiles(TArray<FString> &wadfiles)
static void GetCmdLineFiles(std::vector<std::string>& wadfiles)
{
FString *args;
int i, argc;
@ -1794,12 +1799,12 @@ static void GetCmdLineFiles(TArray<FString> &wadfiles)
argc = Args->CheckParmList("-file", &args);
for (i = 0; i < argc; ++i)
{
D_AddWildFile(wadfiles, args[i], ".wad", GameConfig);
D_AddWildFile(wadfiles, args[i].GetChars(), ".wad", GameConfig);
}
}
static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char *data, int size)
static FString ParseGameInfo(std::vector<std::string> &pwads, const char *fn, const char *data, int size)
{
FScanner sc;
FString iwad;
@ -1807,6 +1812,8 @@ static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char
bool isDir;
const char *lastSlash = strrchr (fn, '/');
if (lastSlash == NULL)
lastSlash = strrchr (fn, ':');
sc.OpenMem("GAMEINFO", data, size);
while(sc.GetToken())
@ -1831,20 +1838,19 @@ static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char
FString checkpath;
if (lastSlash != NULL)
{
checkpath = FString(fn, (lastSlash - fn) + 1);
checkpath += sc.String;
checkpath = FString(fn, lastSlash - fn) + '/' + sc.String;
}
else
{
checkpath = sc.String;
}
if (!DirEntryExists(checkpath, &isDir))
if (!DirEntryExists(checkpath.GetChars(), &isDir))
{
pos += D_AddFile(pwads, sc.String, true, pos, GameConfig);
}
else
{
pos += D_AddFile(pwads, checkpath, true, pos, GameConfig);
pos += D_AddFile(pwads, checkpath.GetChars(), true, pos, GameConfig);
}
}
while (sc.CheckToken(','));
@ -1926,11 +1932,12 @@ static FString ParseGameInfo(TArray<FString> &pwads, const char *fn, const char
void GetReserved(LumpFilterInfo& lfi)
{
for (auto p : iwad_folders) lfi.reservedFolders.Push(p);
for (auto p : iwad_reserved) lfi.requiredPrefixes.Push(p);
lfi.reservedFolders = { "flats/", "textures/", "hires/", "sprites/", "voxels/", "colormaps/", "acs/", "maps/", "voices/", "patches/", "graphics/", "sounds/", "music/",
"materials/", "models/", "fonts/", "brightmaps/" };
lfi.requiredPrefixes = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "maps/" };
}
static FString CheckGameInfo(TArray<FString> & pwads)
static FString CheckGameInfo(std::vector<std::string> & pwads)
{
FileSystem check;
@ -1944,9 +1951,9 @@ static FString CheckGameInfo(TArray<FString> & pwads)
if (num >= 0)
{
// Found one!
auto data = check.GetFileData(num);
auto data = check.ReadFile(num);
auto wadname = check.GetResourceFileName(check.GetFileContainer(num));
return ParseGameInfo(pwads, wadname, (const char*)data.Data(), data.Size());
return ParseGameInfo(pwads, wadname, data.GetString(), (int)data.GetSize());
}
}
return "";
@ -1997,7 +2004,7 @@ static void D_DoomInit()
//
//==========================================================================
static void AddAutoloadFiles(const char *autoname, TArray<FString>& allwads)
static void AddAutoloadFiles(const char *autoname, std::vector<std::string>& allwads)
{
LumpFilterIWAD.Format("%s.", autoname); // The '.' is appened to simplify parsing the string
@ -2044,11 +2051,11 @@ static void AddAutoloadFiles(const char *autoname, TArray<FString>& allwads)
file = progdir;
#endif
file += "skins";
D_AddDirectory (allwads, file, "*.wad", GameConfig);
D_AddDirectory (allwads, file.GetChars(), "*.wad", GameConfig);
#ifdef __unix__
file = NicePath("$HOME/" GAME_DIR "/skins");
D_AddDirectory (allwads, file, "*.wad", GameConfig);
D_AddDirectory (allwads, file.GetChars(), "*.wad", GameConfig);
#endif
// Add common (global) wads
@ -2060,7 +2067,7 @@ static void AddAutoloadFiles(const char *autoname, TArray<FString>& allwads)
while ((len = LumpFilterIWAD.IndexOf('.', lastpos+1)) > 0)
{
file = LumpFilterIWAD.Left(len) + ".Autoload";
D_AddConfigFiles(allwads, file, "*.wad", GameConfig);
D_AddConfigFiles(allwads, file.GetChars(), "*.wad", GameConfig);
lastpos = len;
}
}
@ -2147,7 +2154,7 @@ static void CheckCmdLine()
FString mapvalue = Args->TakeValue("+map");
if (mapvalue.IsNotEmpty())
{
if (!P_CheckMapData(mapvalue))
if (!P_CheckMapData(mapvalue.GetChars()))
{
Printf ("Can't find map %s\n", mapvalue.GetChars());
}
@ -2199,9 +2206,8 @@ static void CheckCmdLine()
StartScreen->AppendStatusLine("Respawning...");
if (autostart)
{
FString temp;
temp.Format ("Warp to map %s, Skill %d ", startmap.GetChars(), gameskill + 1);
StartScreen->AppendStatusLine(temp);
FStringf temp("Warp to map %s, Skill %d ", startmap.GetChars(), gameskill + 1);
StartScreen->AppendStatusLine(temp.GetChars());
}
}
@ -2421,7 +2427,7 @@ void RenameNerve(FileSystem& fileSystem)
continue;
}
for (int icheck = 0; icheck < numnerveversions; icheck++)
if (fr->GetLength() == (long)nervesize[icheck])
if (fr->GetLength() == (ptrdiff_t)nervesize[icheck])
isizecheck = icheck;
if (isizecheck == -1)
{
@ -2482,9 +2488,9 @@ void FixMacHexen(FileSystem& fileSystem)
FileReader* reader = fileSystem.GetFileReader(fileSystem.GetIwadNum());
auto iwadSize = reader->GetLength();
static const long DEMO_SIZE = 13596228;
static const long BETA_SIZE = 13749984;
static const long FULL_SIZE = 21078584;
static const ptrdiff_t DEMO_SIZE = 13596228;
static const ptrdiff_t BETA_SIZE = 13749984;
static const ptrdiff_t FULL_SIZE = 21078584;
if (DEMO_SIZE != iwadSize
&& BETA_SIZE != iwadSize
@ -3044,6 +3050,26 @@ static FILE* D_GetHashFile()
return hashfile;
}
// checks if a file within a directory is allowed to be added to the file system.
static bool FileNameCheck(const char* base, const char* path)
{
// This one is courtesy of EDuke32. :(
// Putting cache files in the application directory is very bad style.
// Unfortunately, having a garbage file named "textures" present will cause serious problems down the line.
if (!strnicmp(base, "textures", 8))
{
// do not use fopen. The path may contain non-ASCII characters.
FileReader f;
if (f.OpenFile(path))
{
char check[3]{};
f.Read(check, 3);
if (!memcmp(check, "LZ4", 3)) return false;
}
}
return true;
}
static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...)
{
va_list arg;
@ -3079,7 +3105,7 @@ static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...)
//
//==========================================================================
static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArray<FString>& pwads)
static int D_InitGame(const FIWADInfo* iwad_info, std::vector<std::string>& allwads, std::vector<std::string>& pwads)
{
SavegameFolder = iwad_info->Autoname;
gameinfo.gametype = iwad_info->gametype;
@ -3104,15 +3130,15 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
FRandom::StaticClearRandom ();
FBaseCVar::DisableCallbacks();
GameConfig->DoGameSetup (gameinfo.ConfigName);
GameConfig->DoGameSetup (gameinfo.ConfigName.GetChars());
AddAutoloadFiles(iwad_info->Autoname, allwads);
AddAutoloadFiles(iwad_info->Autoname.GetChars(), allwads);
// Process automatically executed files
FExecList *exec;
FArgs *execFiles = new FArgs;
if (!(Args->CheckParm("-noautoexec")))
GameConfig->AddAutoexec(execFiles, gameinfo.ConfigName);
GameConfig->AddAutoexec(execFiles, gameinfo.ConfigName.GetChars());
exec = D_MultiExec(execFiles, NULL);
delete execFiles;
@ -3132,7 +3158,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
if (!batchrun) Printf ("W_Init: Init WADfiles.\n");
LumpFilterInfo lfi;
lfi.dotFilter = LumpFilterIWAD;
lfi.dotFilter = LumpFilterIWAD.GetChars();
static const struct { int match; const char* name; } blanket[] =
{
@ -3144,9 +3170,9 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
for (auto& inf : blanket)
{
if (gameinfo.gametype & inf.match) lfi.gameTypeFilter.Push(inf.name);
if (gameinfo.gametype & inf.match) lfi.gameTypeFilter.push_back(inf.name);
}
lfi.gameTypeFilter.Push(FStringf("game-%s", GameTypeName()));
lfi.gameTypeFilter.push_back(FStringf("game-%s", GameTypeName()).GetChars());
GetReserved(lfi);
@ -3157,7 +3183,11 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
FixMacHexen(fileSystem);
FindStrifeTeaserVoices(fileSystem);
};
allwads.Append(std::move(pwads));
allwads.insert(
allwads.end(),
std::make_move_iterator(pwads.begin()),
std::make_move_iterator(pwads.end())
);
bool allowduplicates = Args->CheckParm("-allowduplicates");
auto hashfile = D_GetHashFile();
@ -3165,8 +3195,8 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
{
I_FatalError("FileSystem: no files found");
}
allwads.Clear();
allwads.ShrinkToFit();
allwads.clear();
allwads.shrink_to_fit();
SetMapxxFlag();
D_GrabCVarDefaults(); //parse DEFCVARS
@ -3191,7 +3221,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
StartScreen = nostartscreen? nullptr : GetGameStartScreen(per_shader_progress > 0 ? max_progress * 10 / 9 : max_progress + 3);
GameConfig->DoKeySetup(gameinfo.ConfigName);
GameConfig->DoKeySetup(gameinfo.ConfigName.GetChars());
// Now that wads are loaded, define mod-specific cvars.
ParseCVarInfo();
@ -3295,7 +3325,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
}, CheckForHacks, InitBuildTiles);
PatchTextures();
TexAnim.Init();
C_InitConback(TexMan.CheckForTexture(gameinfo.BorderFlat, ETextureType::Flat), true, 0.25);
C_InitConback(TexMan.CheckForTexture(gameinfo.BorderFlat.GetChars(), ETextureType::Flat), true, 0.25);
FixWideStatusBar();
@ -3342,6 +3372,8 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
if (!batchrun) Printf ("DecalLibrary: Load decals.\n");
DecalLibrary.ReadAllDecals ();
auto numbasesounds = soundEngine->GetNumSounds();
// Load embedded Dehacked patches
D_LoadDehLumps(FromIWAD);
@ -3371,6 +3403,9 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
// Create replacements for dehacked pickups
FinishDehPatch();
auto numdehsounds = soundEngine->GetNumSounds();
if (numbasesounds < numdehsounds) S_LockLocalSndinfo(); // DSDHacked sounds are not compatible with map-local SNDINFOs.
if (!batchrun) Printf("M_Init: Init menus.\n");
SetDefaultMenuColors();
M_Init();
@ -3499,7 +3534,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
{
I_FatalError("Cannot find savegame %s", file.GetChars());
}
G_LoadGame(file);
G_LoadGame(file.GetChars());
}
v = Args->CheckValue("-playdemo");
@ -3528,11 +3563,11 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray<FString>& allwads, TArr
}
CheckWarpTransMap(startmap, true);
if (demorecording)
G_BeginRecording(startmap);
G_InitNew(startmap, false);
G_BeginRecording(startmap.GetChars());
G_InitNew(startmap.GetChars(), false);
if (StoredWarp.IsNotEmpty())
{
AddCommandString(StoredWarp);
AddCommandString(StoredWarp.GetChars());
StoredWarp = "";
}
}
@ -3648,7 +3683,7 @@ static int D_DoomMain_Internal (void)
FString logfile = Args->TakeValue("+logfile");
if (logfile.IsNotEmpty())
{
execLogfile(logfile);
execLogfile(logfile.GetChars());
}
else if (batchout != NULL && *batchout != 0)
{
@ -3672,7 +3707,7 @@ static int D_DoomMain_Internal (void)
FString optionalwad = BaseFileSearch(OPTIONALWAD, NULL, true, GameConfig);
iwad_man = new FIWadManager(basewad, optionalwad);
iwad_man = new FIWadManager(basewad.GetChars(), optionalwad.GetChars());
// Now that we have the IWADINFO, initialize the autoload ini sections.
GameConfig->DoAutoloadSetup(iwad_man);
@ -3692,13 +3727,13 @@ static int D_DoomMain_Internal (void)
if (iwad_man == NULL)
{
iwad_man = new FIWadManager(basewad, optionalwad);
iwad_man = new FIWadManager(basewad.GetChars(), optionalwad.GetChars());
}
// Load zdoom.pk3 alone so that we can get access to the internal gameinfos before
// the IWAD is known.
TArray<FString> pwads;
std::vector<std::string> pwads;
GetCmdLineFiles(pwads);
FString iwad = CheckGameInfo(pwads);
@ -3706,18 +3741,21 @@ static int D_DoomMain_Internal (void)
// restart is initiated without a defined IWAD assume for now that it's not going to change.
if (iwad.IsEmpty()) iwad = lastIWAD;
TArray<FString> allwads;
std::vector<std::string> allwads;
const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad, optionalwad);
const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad.GetChars(), basewad.GetChars(), optionalwad.GetChars());
if (!iwad_info) return 0; // user exited the selection popup via cancel button.
if ((iwad_info->flags & GI_SHAREWARE) && pwads.Size() > 0)
if ((iwad_info->flags & GI_SHAREWARE) && pwads.size() > 0)
{
I_FatalError ("You cannot -file with the shareware version. Register!");
}
lastIWAD = iwad;
int ret = D_InitGame(iwad_info, allwads, pwads);
allwads.Reset();
pwads.clear();
pwads.shrink_to_fit();
allwads.clear();
allwads.shrink_to_fit();
delete iwad_man; // now we won't need this anymore
iwad_man = NULL;
if (ret != 0) return ret;
@ -3930,7 +3968,7 @@ void I_UpdateWindowTitle()
// Strip out any color escape sequences before setting a window title
TArray<char> copy(titlestr.Len() + 1);
const char* srcp = titlestr;
const char* srcp = titlestr.GetChars();
char* dstp = copy.Data();
while (*srcp != 0)