mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
- added support for ZDoom-style GAMEINFO.
This commit is contained in:
parent
af80e64ecf
commit
3b955b7c94
6 changed files with 285 additions and 20 deletions
|
@ -51,6 +51,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "st_start.h"
|
||||
#include "s_music.h"
|
||||
#include "i_video.h"
|
||||
#include "v_text.h"
|
||||
#include "resourcefile.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "glbackend/glbackend.h"
|
||||
#ifndef NETCODE_DISABLE
|
||||
|
@ -62,6 +64,7 @@ MapRecord *currentLevel; // level that is currently played. (The real level, not
|
|||
MapRecord* lastLevel; // Same here, for the last level.
|
||||
MapRecord userMapRecord; // stand-in for the user map.
|
||||
|
||||
FStartupInfo RazeStartupInfo;
|
||||
FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown.
|
||||
|
||||
FString progdir;
|
||||
|
@ -70,7 +73,9 @@ void C_CON_SetAliases();
|
|||
InputState inputState;
|
||||
void SetClipshapes();
|
||||
int ShowStartupWindow(TArray<GrpEntry> &);
|
||||
FString GetGameFronUserFiles();
|
||||
void InitFileSystem(TArray<GrpEntry>&);
|
||||
void I_SetWindowTitle(const char* caption);
|
||||
bool gHaveNetworking;
|
||||
bool AppActive;
|
||||
|
||||
|
@ -86,6 +91,7 @@ CVAR(Bool, disableautoload, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALC
|
|||
//CVAR(Bool, autoloadbrightmaps, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG) // hopefully this is an option for later
|
||||
//CVAR(Bool, autoloadlights, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -443,6 +449,12 @@ static TArray<GrpEntry> SetupGame()
|
|||
|
||||
// If the user has specified a file name, let's see if we know it.
|
||||
//
|
||||
FString game = GetGameFronUserFiles();
|
||||
if (userConfig.gamegrp.IsEmpty())
|
||||
{
|
||||
userConfig.gamegrp = game;
|
||||
}
|
||||
|
||||
if (userConfig.gamegrp.Len())
|
||||
{
|
||||
FString gamegrplower = "/" + userConfig.gamegrp.MakeLower();
|
||||
|
@ -461,7 +473,6 @@ static TArray<GrpEntry> SetupGame()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (groupno == -1)
|
||||
{
|
||||
int pick = 0;
|
||||
|
@ -510,6 +521,9 @@ static TArray<GrpEntry> SetupGame()
|
|||
if (groupno == -1) return TArray<GrpEntry>();
|
||||
auto& group = groups[groupno];
|
||||
|
||||
if (RazeStartupInfo.Name.IsNotEmpty()) I_SetWindowTitle(RazeStartupInfo.Name);
|
||||
else I_SetWindowTitle(group.FileInfo.name);
|
||||
|
||||
// Now filter out the data we actually need and delete the rest.
|
||||
|
||||
usedgroups.Push(group);
|
||||
|
|
|
@ -157,3 +157,17 @@ void S_SetSoundPaused(int state);
|
|||
|
||||
void G_HandleMemErr(int32_t lineNum, const char* fileName, const char* funcName);
|
||||
void G_FatalEngineError(void);
|
||||
|
||||
|
||||
struct FStartupInfo
|
||||
{
|
||||
FString Name;
|
||||
uint32_t FgColor; // Foreground color for title banner
|
||||
uint32_t BkColor; // Background color for title banner
|
||||
//FString Song;
|
||||
//int Type;
|
||||
//int LoadLights = -1;
|
||||
//int LoadBrightmaps = -1;
|
||||
};
|
||||
|
||||
extern FStartupInfo RazeStartupInfo;
|
|
@ -42,6 +42,9 @@
|
|||
#include "printf.h"
|
||||
#include "m_argv.h"
|
||||
#include "version.h"
|
||||
#include "sc_man.h"
|
||||
#include "v_video.h"
|
||||
#include "v_text.h"
|
||||
#include "../platform/win32/i_findfile.h" // This is a temporary direct path. Needs to be fixed when stuff gets cleaned up.
|
||||
|
||||
#ifndef PATH_MAX
|
||||
|
@ -268,7 +271,7 @@ static void D_AddDirectory (TArray<FString> &wadfiles, const char *dir)
|
|||
{
|
||||
skindir[stuffstart++] = '/';
|
||||
int savedstart = stuffstart;
|
||||
static const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7", "*.dat" };
|
||||
static const char* validexts[] = { "*.grp", "*.zip", "*.pk3", "*.pk4", "*.7z", "*.pk7", "*.dat", "*.rff" };
|
||||
for (auto ext : validexts)
|
||||
{
|
||||
stuffstart = savedstart;
|
||||
|
@ -290,6 +293,186 @@ static void D_AddDirectory (TArray<FString> &wadfiles, const char *dir)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static FString ParseGameInfo(TArray<FString>& pwads, const char* fn, const char* data, int size)
|
||||
{
|
||||
FScanner sc;
|
||||
FString iwad;
|
||||
int pos = 0;
|
||||
|
||||
const char* lastSlash = strrchr(fn, '/');
|
||||
|
||||
sc.OpenMem("GAMEINFO", data, size);
|
||||
sc.SetCMode(true);
|
||||
while (sc.GetToken())
|
||||
{
|
||||
sc.TokenMustBe(TK_Identifier);
|
||||
FString nextKey = sc.String;
|
||||
sc.MustGetToken('=');
|
||||
if (!nextKey.CompareNoCase("GAME"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
iwad = sc.String;
|
||||
}
|
||||
else if (!nextKey.CompareNoCase("LOAD"))
|
||||
{
|
||||
do
|
||||
{
|
||||
sc.MustGetString();
|
||||
|
||||
// Try looking for the wad in the same directory as the .wad
|
||||
// before looking for it in the current directory.
|
||||
|
||||
FString checkpath;
|
||||
if (lastSlash != NULL)
|
||||
{
|
||||
checkpath = FString(fn, (lastSlash - fn) + 1);
|
||||
checkpath += sc.String;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkpath = sc.String;
|
||||
}
|
||||
if (!FileExists(checkpath))
|
||||
{
|
||||
pos += D_AddFile(pwads, sc.String, true, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos += D_AddFile(pwads, checkpath, true, pos);
|
||||
}
|
||||
} while (sc.CheckToken(','));
|
||||
}
|
||||
else if (!nextKey.CompareNoCase("STARTUPTITLE"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
RazeStartupInfo.Name = sc.String;
|
||||
}
|
||||
else if (!nextKey.CompareNoCase("STARTUPCOLORS"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
RazeStartupInfo.FgColor = V_GetColor(NULL, sc);
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetString();
|
||||
RazeStartupInfo.BkColor = V_GetColor(NULL, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Silently ignore unknown properties
|
||||
do
|
||||
{
|
||||
sc.MustGetAnyToken();
|
||||
} while (sc.CheckToken(','));
|
||||
}
|
||||
}
|
||||
return iwad;
|
||||
}
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static FString CheckGameInfo(TArray<FString>& pwads)
|
||||
{
|
||||
// scan the list of WADs backwards to find the last one that contains a GAMEINFO lump
|
||||
for (int i = pwads.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
bool isdir = false;
|
||||
FResourceFile* resfile;
|
||||
const char* filename = pwads[i];
|
||||
|
||||
// Does this exist? If so, is it a directory?
|
||||
if (!DirEntryExists(pwads[i], &isdir))
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "Could not find %s\n", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isdir)
|
||||
{
|
||||
FileReader fr;
|
||||
if (!fr.OpenFile(filename))
|
||||
{
|
||||
// Didn't find file
|
||||
continue;
|
||||
}
|
||||
resfile = FResourceFile::OpenResourceFile(filename, fr, true);
|
||||
}
|
||||
else
|
||||
resfile = FResourceFile::OpenDirectory(filename, true);
|
||||
|
||||
FName gameinfo = "GAMEINFO.TXT";
|
||||
if (resfile != NULL)
|
||||
{
|
||||
uint32_t cnt = resfile->LumpCount();
|
||||
for (int i = cnt - 1; i >= 0; i--)
|
||||
{
|
||||
FResourceLump* lmp = resfile->GetLump(i);
|
||||
|
||||
if (lmp->LumpName[0] == gameinfo)
|
||||
{
|
||||
// Found one!
|
||||
FString iwad = ParseGameInfo(pwads, resfile->FileName, (const char*)lmp->Lock(), lmp->LumpSize);
|
||||
delete resfile;
|
||||
return iwad;
|
||||
}
|
||||
}
|
||||
delete resfile;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString GetGameFronUserFiles()
|
||||
{
|
||||
TArray<FString> Files;
|
||||
|
||||
if (userConfig.AddFilesPre) for (auto& file : *userConfig.AddFilesPre)
|
||||
{
|
||||
D_AddFile(Files, file);
|
||||
}
|
||||
if (userConfig.AddFiles)
|
||||
{
|
||||
for (auto& file : *userConfig.AddFiles)
|
||||
{
|
||||
D_AddFile(Files, file);
|
||||
}
|
||||
|
||||
// Finally, if the last entry in the chain is a directory, it's being considered the mod directory, and all GRPs inside need to be loaded, too.
|
||||
if (userConfig.AddFiles->NumArgs() > 0)
|
||||
{
|
||||
auto fn = (*userConfig.AddFiles)[userConfig.AddFiles->NumArgs() - 1];
|
||||
bool isdir = false;
|
||||
if (DirEntryExists(fn, &isdir) && isdir)
|
||||
{
|
||||
// Insert the GRPs before this entry itself.
|
||||
FString lastfn;
|
||||
Files.Pop(lastfn);
|
||||
D_AddDirectory(Files, fn);
|
||||
Files.Push(lastfn);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CheckGameInfo(Files);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void InitFileSystem(TArray<GrpEntry>& groups)
|
||||
{
|
||||
|
@ -338,6 +521,20 @@ void InitFileSystem(TArray<GrpEntry>& groups)
|
|||
i--;
|
||||
}
|
||||
|
||||
const char* key;
|
||||
const char* value;
|
||||
if (GameConfig->SetSection("global.Autoload"))
|
||||
{
|
||||
while (GameConfig->NextInSection(key, value))
|
||||
{
|
||||
if (stricmp(key, "Path") == 0)
|
||||
{
|
||||
FString nice = NicePath(value);
|
||||
D_AddFile(Files, nice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!insertdirectoriesafter && userConfig.AddFilesPre) for (auto& file : *userConfig.AddFilesPre)
|
||||
{
|
||||
D_AddFile(Files, file);
|
||||
|
@ -364,19 +561,7 @@ void InitFileSystem(TArray<GrpEntry>& groups)
|
|||
}
|
||||
}
|
||||
}
|
||||
const char* key;
|
||||
const char* value;
|
||||
if (GameConfig->SetSection("global.Autoload"))
|
||||
{
|
||||
while (GameConfig->NextInSection(key, value))
|
||||
{
|
||||
if (stricmp(key, "Path") == 0)
|
||||
{
|
||||
FString nice = NicePath(value);
|
||||
D_AddFile(Files, nice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TArray<FString> todelete;
|
||||
for (auto& g : groups)
|
||||
|
|
|
@ -102,6 +102,7 @@ public:
|
|||
FString TakeValue(const char *check);
|
||||
int NumArgs() const;
|
||||
void FlushArgs();
|
||||
TArray<FString>& Array() { return Argv; }
|
||||
|
||||
private:
|
||||
TArray<FString> Argv;
|
||||
|
|
|
@ -336,17 +336,17 @@ void FConsoleWindow::SetTitleText()
|
|||
// It's used in graphical startup screen, with Hexen style in particular
|
||||
// Native OS X backend doesn't implement this yet
|
||||
|
||||
if (DoomStartupInfo.FgColor == DoomStartupInfo.BkColor)
|
||||
if (RazeStartupInfo.FgColor == RazeStartupInfo.BkColor)
|
||||
{
|
||||
DoomStartupInfo.FgColor = ~DoomStartupInfo.FgColor;
|
||||
RazeStartupInfo.FgColor = ~RazeStartupInfo.FgColor;
|
||||
}
|
||||
|
||||
NSTextField* titleText = [[NSTextField alloc] initWithFrame:titleTextRect];
|
||||
[titleText setStringValue:[NSString stringWithCString:DoomStartupInfo.Name
|
||||
[titleText setStringValue:[NSString stringWithCString:RazeStartupInfo.Name
|
||||
encoding:NSISOLatin1StringEncoding]];
|
||||
[titleText setAlignment:NSCenterTextAlignment];
|
||||
[titleText setTextColor:RGB(DoomStartupInfo.FgColor)];
|
||||
[titleText setBackgroundColor:RGB(DoomStartupInfo.BkColor)];
|
||||
[titleText setTextColor:RGB(RazeStartupInfo.FgColor)];
|
||||
[titleText setBackgroundColor:RGB(RazeStartupInfo.BkColor)];
|
||||
[titleText setFont:[NSFont fontWithName:@"Trebuchet MS Bold" size:18.0f]];
|
||||
[titleText setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
|
||||
[titleText setSelectable:NO];
|
||||
|
|
|
@ -426,6 +426,57 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
return 0;
|
||||
|
||||
case WM_DRAWITEM:
|
||||
// Draw title banner.
|
||||
if (wParam == IDC_STATIC_TITLE && RazeStartupInfo.Name.IsNotEmpty())
|
||||
{
|
||||
const PalEntry *c;
|
||||
|
||||
// Draw the game title strip at the top of the window.
|
||||
auto drawitem = (LPDRAWITEMSTRUCT)lParam;
|
||||
SIZE size;
|
||||
|
||||
// Draw the background.
|
||||
auto rect = drawitem->rcItem;
|
||||
rect.bottom -= 1;
|
||||
c = (const PalEntry *)&RazeStartupInfo.BkColor;
|
||||
auto hbr = CreateSolidBrush (RGB(c->r,c->g,c->b));
|
||||
FillRect (drawitem->hDC, &drawitem->rcItem, hbr);
|
||||
DeleteObject (hbr);
|
||||
|
||||
// Calculate width of the title string.
|
||||
SetTextAlign (drawitem->hDC, TA_TOP);
|
||||
oldfont = SelectObject (drawitem->hDC, GameTitleFont != NULL ? GameTitleFont : (HFONT)GetStockObject (DEFAULT_GUI_FONT));
|
||||
auto widename = RazeStartupInfo.Name.WideString();
|
||||
GetTextExtentPoint32W (drawitem->hDC, widename.c_str(), (int)widename.length(), &size);
|
||||
|
||||
// Draw the title.
|
||||
c = (const PalEntry *)&RazeStartupInfo.FgColor;
|
||||
SetTextColor (drawitem->hDC, RGB(c->r,c->g,c->b));
|
||||
SetBkMode (drawitem->hDC, TRANSPARENT);
|
||||
TextOutW (drawitem->hDC, rect.left + (rect.right - rect.left - size.cx) / 2, 2, widename.c_str(), (int)widename.length());
|
||||
SelectObject (drawitem->hDC, oldfont);
|
||||
return TRUE;
|
||||
}
|
||||
// Draw stop icon.
|
||||
else if (wParam == IDC_ICONPIC)
|
||||
{
|
||||
HICON icon;
|
||||
POINTL char_pos;
|
||||
auto drawitem = (LPDRAWITEMSTRUCT)lParam;
|
||||
|
||||
// This background color should match the edit control's.
|
||||
auto hbr = CreateSolidBrush (RGB(70,70,70));
|
||||
FillRect (drawitem->hDC, &drawitem->rcItem, hbr);
|
||||
DeleteObject (hbr);
|
||||
|
||||
// Draw the icon aligned with the first line of error text.
|
||||
SendMessage (ConWindow, EM_POSFROMCHAR, (WPARAM)&char_pos, ErrorIconChar);
|
||||
icon = (HICON)LoadImage (0, IDI_ERROR, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
|
||||
DrawIcon (drawitem->hDC, 6, char_pos.y, icon);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if (ErrorIcon != NULL && (HWND)lParam == ConWindow && HIWORD(wParam) == EN_UPDATE)
|
||||
|
|
Loading…
Reference in a new issue