- all source compile now on macOS

This commit is contained in:
Christoph Oelckers 2020-01-08 01:00:57 +01:00
parent 8f455d8ffa
commit cfed7afd02
24 changed files with 219 additions and 597 deletions

View file

@ -522,7 +522,7 @@ if( WIN32 )
set( SYSTEM_SOURCES ${SYSTEM_SOURCES} platform/win32/gameres.rc )
elseif( APPLE )
if( OSX_COCOA_BACKEND )
set( SYSTEM_SOURCES_DIR posix/cocoa )
set( SYSTEM_SOURCES_DIR platform/posix/cocoa )
set( SYSTEM_SOURCES ${PLAT_COCOA_SOURCES} )
set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_SDL_SOURCES} ${PLAT_UNIX_SOURCES} )
else()

View file

@ -119,7 +119,4 @@ void COMMON_clearbackground(int32_t numcols, int32_t numrows);
int Paths_ReadRegistryValue(char const * const SubKey, char const * const Value, char * const Output, DWORD * OutputSize);
#endif
using SteamPathParseFunc = void(*)(const char *);
void Paths_ParseSteamKeyValuesForPaths(const char *vdf, SteamPathParseFunc func);
#endif

View file

@ -133,168 +133,3 @@ int Paths_ReadRegistryValue(char const * const SubKey, char const * const Value,
return 0;
}
#endif
// A bare-bones "parser" for Valve's KeyValues VDF format.
// There is no guarantee this will function properly with ill-formed files.
static void KeyValues_SkipWhitespace(char **vdfbuf, char * const vdfbufend)
{
while (((*vdfbuf)[0] == ' ' || (*vdfbuf)[0] == '\n' || (*vdfbuf)[0] == '\r' || (*vdfbuf)[0] == '\t' || (*vdfbuf)[0] == '\0') && *vdfbuf < vdfbufend)
(*vdfbuf)++;
// comments
if ((*vdfbuf) + 2 < vdfbufend && (*vdfbuf)[0] == '/' && (*vdfbuf)[1] == '/')
{
while ((*vdfbuf)[0] != '\n' && (*vdfbuf)[0] != '\r' && *vdfbuf < vdfbufend)
(*vdfbuf)++;
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
}
}
static void KeyValues_SkipToEndOfQuotedToken(char **vdfbuf, char * const vdfbufend)
{
(*vdfbuf)++;
while ((*vdfbuf)[0] != '\"' && (*vdfbuf)[-1] != '\\' && *vdfbuf < vdfbufend)
(*vdfbuf)++;
}
static void KeyValues_SkipToEndOfUnquotedToken(char **vdfbuf, char * const vdfbufend)
{
while ((*vdfbuf)[0] != ' ' && (*vdfbuf)[0] != '\n' && (*vdfbuf)[0] != '\r' && (*vdfbuf)[0] != '\t' && (*vdfbuf)[0] != '\0' && *vdfbuf < vdfbufend)
(*vdfbuf)++;
}
static void KeyValues_SkipNextWhatever(char **vdfbuf, char * const vdfbufend)
{
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
if (*vdfbuf == vdfbufend)
return;
if ((*vdfbuf)[0] == '{')
{
(*vdfbuf)++;
do
{
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
}
while ((*vdfbuf)[0] != '}');
(*vdfbuf)++;
}
else if ((*vdfbuf)[0] == '\"')
KeyValues_SkipToEndOfQuotedToken(vdfbuf, vdfbufend);
else if ((*vdfbuf)[0] != '}')
KeyValues_SkipToEndOfUnquotedToken(vdfbuf, vdfbufend);
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
}
static char* KeyValues_NormalizeToken(char **vdfbuf, char * const vdfbufend)
{
char *token = *vdfbuf;
if ((*vdfbuf)[0] == '\"' && *vdfbuf < vdfbufend)
{
token++;
KeyValues_SkipToEndOfQuotedToken(vdfbuf, vdfbufend);
(*vdfbuf)[0] = '\0';
// account for escape sequences
char *writeseeker = token, *readseeker = token;
while (readseeker <= *vdfbuf)
{
if (readseeker[0] == '\\')
readseeker++;
writeseeker[0] = readseeker[0];
writeseeker++;
readseeker++;
}
return token;
}
KeyValues_SkipToEndOfUnquotedToken(vdfbuf, vdfbufend);
(*vdfbuf)[0] = '\0';
return token;
}
static void KeyValues_FindKey(char **vdfbuf, char * const vdfbufend, const char *token)
{
char *ParentKey = KeyValues_NormalizeToken(vdfbuf, vdfbufend);
if (token != NULL) // pass in NULL to find the next key instead of a specific one
while (Bstrcmp(ParentKey, token) != 0 && *vdfbuf < vdfbufend)
{
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
ParentKey = KeyValues_NormalizeToken(vdfbuf, vdfbufend);
}
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
}
static int32_t KeyValues_FindParentKey(char **vdfbuf, char * const vdfbufend, const char *token)
{
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
// end of scope
if ((*vdfbuf)[0] == '}')
return 0;
KeyValues_FindKey(vdfbuf, vdfbufend, token);
// ignore the wrong type
while ((*vdfbuf)[0] != '{' && *vdfbuf < vdfbufend)
{
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
KeyValues_FindKey(vdfbuf, vdfbufend, token);
}
if (*vdfbuf == vdfbufend)
return 0;
return 1;
}
static char* KeyValues_FindKeyValue(char **vdfbuf, char * const vdfbufend, const char *token)
{
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
// end of scope
if ((*vdfbuf)[0] == '}')
return NULL;
KeyValues_FindKey(vdfbuf, vdfbufend, token);
// ignore the wrong type
while ((*vdfbuf)[0] == '{' && *vdfbuf < vdfbufend)
{
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
KeyValues_FindKey(vdfbuf, vdfbufend, token);
}
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
if (*vdfbuf == vdfbufend)
return NULL;
return KeyValues_NormalizeToken(vdfbuf, vdfbufend);
}
void Paths_ParseSteamKeyValuesForPaths(const char *vdf, SteamPathParseFunc func)
{
FileReader fr;
if (!fr.OpenFile(vdf)) return;
auto size = fr.GetLength();
char *vdfbuf, *vdfbufend;
if (size == 0)
return;
auto vdfbuffer = fr.ReadPadded(1);
vdfbuf = (char*)vdfbuffer.Data();
vdfbufend = vdfbuf + size;
if (KeyValues_FindParentKey(&vdfbuf, vdfbufend, "LibraryFolders"))
{
char *result;
vdfbuf++;
while ((result = KeyValues_FindKeyValue(&vdfbuf, vdfbufend, NULL)) != NULL)
func(result);
}
}

View file

@ -301,7 +301,6 @@ static int32_t defsparser(scriptfile *script)
iter = 0;
}
#endif
handleevents();
tokn = getatoken(script,basetokens,ARRAY_SIZE(basetokens));
cmdtokptr = script->ltextptr;
switch (tokn)

View file

@ -166,7 +166,6 @@ void C_ClearDelayedCommands()
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static long ParseCommandLine (const char *args, int *argc, char **argv, bool no_escapes);
static FConsoleCommand *FindNameInHashTable (FConsoleCommand **table, const char *name, size_t namelen);
static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *name, size_t namelen, FConsoleCommand **prev);

View file

@ -64,6 +64,7 @@ MapRecord userMapRecord; // stand-in for the user map.
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;
void C_CON_SetAliases();
InputState inputState;
@ -71,7 +72,7 @@ void SetClipshapes();
int ShowStartupWindow(TArray<GrpEntry> &);
void InitFileSystem(TArray<GrpEntry>&);
bool gHaveNetworking;
bool AppActive;
FString currentGame;
FString LumpFilter;
@ -85,6 +86,27 @@ 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)
//==========================================================================
//
//
//
//==========================================================================
static bool grab_mouse;
void mouseGrabInput(bool grab)
{
grab_mouse = grab;
if (grab) GUICapture &= ~1;
else GUICapture |= 1;
}
//==========================================================================
//
//
//
//==========================================================================
UserConfig userConfig;
void UserConfig::ProcessOptions()

View file

@ -532,7 +532,7 @@ CUSTOM_CVAR(Int, playergender, 0, CVAR_USERINFO|CVAR_ARCHIVE)
}
// Internal settings for demo recording and the multiplayer menu. These won't get saved and only are CVARs so that the menu code can use them.
CVAR(Bool, m_recstat, false, CVAR_NOSET)
CVAR(Int, m_recstat, false, CVAR_NOSET)
CVAR(Int, m_coop, 0, CVAR_NOSET)
CVAR(Int, m_ffire, 1, CVAR_NOSET)
CVAR(Int, m_monsters, 1, CVAR_NOSET)

View file

@ -86,7 +86,6 @@ EXTERN_CVAR(Int, gl_multisample)
EXTERN_CVAR(Int, gl_ssao)
EXTERN_CVAR(Bool, in_joystick)
EXTERN_CVAR(Int, in_mouse)
EXTERN_CVAR(Int, in_mousebias)
EXTERN_CVAR(Int, in_mousedeadzone)
EXTERN_CVAR(Bool, in_mouseflip)
@ -106,7 +105,7 @@ EXTERN_CVAR(String, playername)
EXTERN_CVAR(String, rtsname)
EXTERN_CVAR(String, usermapfolder)
EXTERN_CVAR(Bool, m_recstat)
EXTERN_CVAR(Int, m_recstat)
EXTERN_CVAR(Int, m_coop)
EXTERN_CVAR(Int, m_marker)
EXTERN_CVAR(Int, m_level_number)

View file

@ -135,9 +135,15 @@ void InputState::AddEvent(const event_t *ev)
//==========================================================================
void I_StartTic();
bool ToggleFullscreen;
int32_t handleevents(void)
{
if (ToggleFullscreen)
{
vid_fullscreen = !vid_fullscreen;
ToggleFullscreen = false;
}
// fullscreen toggle has been requested
if (setmodeneeded)
{
@ -192,7 +198,6 @@ void CONTROL_GetInput(ControlInfo* info)
{
memset(info, 0, sizeof(ControlInfo));
if (in_mouse >= 0)
inputState.GetMouseDelta(info);
if (in_joystick)

View file

@ -180,11 +180,13 @@ static void tim_printfunc(int type, int verbosity_level, const char* fmt, ...)
}
}
#if 0
static void wm_printfunc(const char* wmfmt, va_list args)
{
Printf(TEXTCOLOR_RED);
VPrintf(PRINT_HIGH, wmfmt, args);
}
#endif
//==========================================================================
//

View file

@ -51,7 +51,7 @@ public:
void Swap();
bool IsHWGammaActive() const { return HWGammaActive; }
void SetVSync(bool vsync);
void SetVSync(bool vsync) override;
//void Draw2D() override;
void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) override;

View file

@ -1,28 +1,36 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2019 EDuke32 developers and contributors
Copyright (C) 2019 Nuke.YKT
Copyright (C) 2019 Christoph Oelckers
This is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
** searchpaths.cpp
**
**---------------------------------------------------------------------------
** Copyright 2019 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
**
*/
//-------------------------------------------------------------------------
//
// Search path management. Scan all directories for potential game content and return a list with all proper matches
//
#include "m_crc32.h"
#include "i_specialpaths.h"
@ -57,161 +65,14 @@ void AddSearchPath(TArray<FString>& searchpaths, const char* path)
}
#ifndef _WIN32
//-------------------------------------------------------------------------
//
//
//
//-------------------------------------------------------------------------
static void G_AddSteamPaths(TArray<FString> &searchpaths, const char *basepath)
{
FString path;
// Duke Nukem 3D: Megaton Edition (Steam)
path.Format("%s/steamapps/common/Duke Nukem 3D/gameroot", basepath);
AddSearchPath(searchpaths, path);
path.Format("%s/steamapps/common/Duke Nukem 3D/gameroot/addons/dc", basepath);
AddSearchPath(searchpaths, path);
path.Format("%s/steamapps/common/Duke Nukem 3D/gameroot/addons/nw", basepath);
AddSearchPath(searchpaths, path);
path.Format("%s/steamapps/common/Duke Nukem 3D/gameroot/addons/vacation", basepath);
AddSearchPath(searchpaths, path);
// Duke Nukem 3D (3D Realms Anthology (Steam) / Kill-A-Ton Collection 2015)
#ifdef __APPLE__
path.Format("%s/steamapps/common/Duke Nukem 3D/Duke Nukem 3D.app/drive_c/Program Files/Duke Nukem 3D", basepath);
AddSearchPath(searchpaths, path);
#endif
// NAM (Steam)
#ifdef __APPLE__
path.Format("%s/steamapps/common/Nam/Nam.app/Contents/Resources/Nam.boxer/C.harddisk/NAM", basepath);
#else
path.Format("%s/steamapps/common/Nam/NAM", basepath);
#endif
AddSearchPath(searchpaths, path);
// WWII GI (Steam)
path.Format("%s/steamapps/common/World War II GI/WW2GI", basepath);
AddSearchPath(searchpaths, path);
// Shadow Warrior Classic Redux - Steam
static char const s_SWCR_Steam[] = "steamapps/common/Shadow Warrior Classic/gameroot";
path.Format("%s/%s", basepath, s_SWCR_Steam);
AddSearchPath(searchpaths, path);
//path.Format("%s/%s/addons", basepath, s_SWCR_Steam);
//AddSearchPath(searchpaths, path);
//path.Format("%s/%s/classic/MUSIC", basepath, s_SWCR_Steam);
//AddSearchPath(searchpaths, path);
// Shadow Warrior Classic (1997) - Steam
static char const s_SWC_Steam[] = "steamapps/common/Shadow Warrior Original/gameroot";
path.Format("%s/%s", basepath, s_SWC_Steam);
AddSearchPath(searchpaths, path);
//path.Format("%s/%s/MUSIC", basepath, s_SWC_Steam);
//AddSearchPath(searchpaths, path);
// Shadow Warrior (Classic) - 3D Realms Anthology - Steam
#if defined EDUKE32_OSX
path.Format("%s/steamapps/common/Shadow Warrior DOS/Shadow Warrior.app/Contents/Resources/sw", basepath);
AddSearchPath(searchpaths, path);
#endif
path.Format("%s/steamapps/common/Blood", basepath);
AddSearchPath(searchpaths, path);
// Blood: One Unit Whole Blood
path.Format("%s/steamapps/common/One Unit Whole Blood", basepath);
AddSearchPath(searchpaths, path);
}
static TArray<FString>* g_searchpaths;
static void AddAnItem(const char* item)
{
AddSearchPath(*g_searchpaths, item);
}
#ifndef __APPLE__
//-------------------------------------------------------------------------
//
//
//
//-------------------------------------------------------------------------
void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
{
FString path;
char *homepath = getenv("HOME");
path.Format("%s/.steam/steam", homepath);
G_AddSteamPaths(searchpaths, buf);
path.Format("%s/.steam/steam/steamapps/libraryfolders.vdf", homepath);
g_searchpaths = &searchpaths;
G_ParseSteamKeyValuesForPaths(searchpaths, buf, AddAnItem);
searchpaths.Append(I_GetSteamPath());
searchpaths.Append(I_GetGogPaths());
}
#else
//-------------------------------------------------------------------------
//
//
//
//-------------------------------------------------------------------------
void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
{
char *applications[] = { osx_getapplicationsdir(0), osx_getapplicationsdir(1) };
char *support[] = { osx_getsupportdir(0), osx_getsupportdir(1) };
FString path;
char buf[BMAX_PATH];
int32_t i;
g_searchpaths = &searchpaths;
for (i = 0; i < 2; i++)
{
path.Format("%s/Steam", support[i]);
G_AddSteamPaths(searchpaths, buf);
path.Format("%s/Steam/steamapps/libraryfolders.vdf", support[i]);
G_ParseSteamKeyValuesForPaths(searchpaths, buf, AddAnItem);
// Duke Nukem 3D: Atomic Edition (GOG.com)
path.Format("%s/Duke Nukem 3D.app/Contents/Resources/Duke Nukem 3D.boxer/C.harddisk", applications[i]);
AddSearchPath(searchpaths, path);
// Shadow Warrior Classic Complete - GOG.com
static char const s_SWC_GOG[] = "Shadow Warrior Complete/Shadow Warrior.app/Contents/Resources/Shadow Warrior.boxer/C swarrior_files.harddisk";
path.Format("%s/%s", applications[i], s_SWC_GOG);
AddSearchPath(searchpaths, path);
//path.Format("%s/%s/MUSIC", applications[i], s_SWC_GOG);
//addsearchpath(buf);
// Shadow Warrior Classic Redux - GOG.com
static char const s_SWCR_GOG[] = "Shadow Warrior Classic Redux/Shadow Warrior Classic Redux.app/Contents/Resources/gameroot";
path.Format("%s/%s", applications[i], s_SWCR_GOG);
AddSearchPath(searchpaths, path);
//path.Format("%s/%s/music", applications[i], s_SWCR_GOG);
//addsearchpath(buf);
}
for (i = 0; i < 2; i++)
{
Xfree(applications[i]);
Xfree(support[i]);
}
}
#endif
#else
//-------------------------------------------------------------------------
//
@ -219,211 +80,69 @@ void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
//
//-------------------------------------------------------------------------
struct RegistryPathInfo
{
const char *regPath;
const char *regKey;
const char **subpaths;
};
static const char * gameroot[] = { "/gameroot", nullptr};
static const char * dukeaddons[] = { "/gameroot", "/gameroot/addons/dc", "/gameroot/addons/nw", "/gameroot/addons/vacation", nullptr};
static const char * dn3d[] = { "/Duke Nukem 3D", nullptr};
static const char * nam[] = { "/NAM", nullptr};
static const char * ww2gi[] = { "/WW2GI", nullptr};
static const char * bloodfs[] = { "", R"(\addons\Cryptic Passage)", nullptr};
static const char * sw[] = { "/Shadow Warrior", nullptr};
static const RegistryPathInfo paths[] = {
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 434050)", "InstallLocation", nullptr },
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 225140)", "InstallLocation", dukeaddons },
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 359850)", "InstallLocation", dn3d },
{ "SOFTWARE\\GOG.com\\GOGDUKE3D", "PATH", nullptr },
{ "SOFTWARE\\3DRealms\\Duke Nukem 3D", nullptr, dn3d },
{ "SOFTWARE\\3DRealms\\Anthology", nullptr, dn3d },
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 329650)", "InstallLocation", nam },
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 376750)", "InstallLocation", ww2gi },
{ "SOFTWARE\\GOG.com\\GOGREDNECKRAMPAGE", "PATH", nullptr },
{ "SOFTWARE\\GOG.com\\GOGCREDNECKRIDESAGAIN", "PATH", nullptr },
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 299030)", "InstallLocation", nullptr }, // Blood: One Unit Whole Blood (Steam)
{ "SOFTWARE\\GOG.com\\GOGONEUNITONEBLOOD", "PATH", nullptr},
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1010750)", "InstallLocation", bloodfs},
{ R"(SOFTWARE\Wow6432Node\GOG.com\Games\1374469660)", "path", bloodfs},
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 225160)", "InstallLocation", gameroot },
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 238070)", "InstallLocation", gameroot}, // Shadow Warrior Classic (1997) - Steam
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 358400)", "InstallLocation", sw},
{ "SOFTWARE\\GOG.com\\GOGSHADOWARRIOR", "PATH", nullptr},
{ "SOFTWARE\\3DRealms\\Shadow Warrior", nullptr, sw},
{ "SOFTWARE\\3DRealms\\Anthology", nullptr, sw},
{ R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 562860)", "InstallLocation", nullptr}, // Ion Fury (Steam)
{ R"(SOFTWARE\GOG.com\Games\1740836875)", "path", nullptr},
{ nullptr}
};
void G_AddExternalSearchPaths(TArray<FString> &searchpaths)
{
char buf[BMAX_PATH] = {0};
DWORD bufsize;
// Duke Nukem 3D: 20th Anniversary World Tour (Steam)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 434050)", "InstallLocation", buf, &bufsize))
for (auto &entry : paths)
{
AddSearchPath(searchpaths, buf);
}
// Duke Nukem 3D: Megaton Edition (Steam)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 225140)", "InstallLocation", buf, &bufsize))
{
char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/gameroot", remaining);
AddSearchPath(searchpaths, buf);
strncpy(suffix, "/gameroot/addons/dc", remaining);
AddSearchPath(searchpaths, buf);
strncpy(suffix, "/gameroot/addons/nw", remaining);
AddSearchPath(searchpaths, buf);
strncpy(suffix, "/gameroot/addons/vacation", remaining);
AddSearchPath(searchpaths, buf);
}
// Duke Nukem 3D (3D Realms Anthology (Steam) / Kill-A-Ton Collection 2015)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 359850)", "InstallLocation", buf, &bufsize))
{
char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/Duke Nukem 3D", remaining);
AddSearchPath(searchpaths, buf);
}
// Duke Nukem 3D: Atomic Edition (GOG.com)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGDUKE3D", "PATH", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
}
// Duke Nukem 3D (3D Realms Anthology)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\3DRealms\\Duke Nukem 3D", NULL, buf, &bufsize))
{
char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/Duke Nukem 3D", remaining);
AddSearchPath(searchpaths, buf);
}
// 3D Realms Anthology
char buf[PATH_MAX];
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\3DRealms\\Anthology", NULL, buf, &bufsize))
if (Paths_ReadRegistryValue(entry.regPath, entry.regKey, buf, &bufsize))
{
char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/Duke Nukem 3D", remaining);
AddSearchPath(searchpaths, buf);
}
// NAM (Steam)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 329650)", "InstallLocation", buf, &bufsize))
if (!entry.subpaths) AddSearchPath(buf);
else
{
char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/NAM", remaining);
AddSearchPath(searchpaths, buf);
}
// WWII GI (Steam)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 376750)", "InstallLocation", buf, &bufsize))
FString path;
for (int i = 0; entry.subpaths[i]; i++)
{
char * const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/WW2GI", remaining);
AddSearchPath(searchpaths, buf);
path.Format("%s%s", buf, entry.subpaths[i]);
AddSearchPath(searchpaths, path);
}
// Redneck Rampage (GOG.com)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGREDNECKRAMPAGE", "PATH", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
}
// Redneck Rampage Rides Again (GOG.com)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGCREDNECKRIDESAGAIN", "PATH", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
}
// Blood: One Unit Whole Blood (Steam)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 299030)", "InstallLocation", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
}
// Blood: One Unit Whole Blood (GOG.com)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGONEUNITONEBLOOD", "PATH", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
}
// Blood: Fresh Supply (Steam)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 1010750)", "InstallLocation", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
strncat(buf, R"(\addons\Cryptic Passage)", 23);
AddSearchPath(searchpaths, buf);
}
// Blood: Fresh Supply (GOG.com)
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Wow6432Node\GOG.com\Games\1374469660)", "path", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
strncat(buf, R"(\addons\Cryptic Passage)", 23);
AddSearchPath(searchpaths, buf);
}
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 225160)", "InstallLocation", buf, &bufsize))
{
char* const suffix = buf + bufsize - 1;
size_t const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/gameroot", remaining);
AddSearchPath(searchpaths, buf);
//strncpy(suffix, "/gameroot/addons", remaining);
//addsearchpath_user(buf, SEARCHPATH_REMOVE);
//strncpy(suffix, "/gameroot/classic/MUSIC", remaining);
//addsearchpath(buf);
}
// Shadow Warrior Classic (1997) - Steam
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 238070)", "InstallLocation", buf, &bufsize))
{
char* const suffix = buf + bufsize - 1;
DWORD const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/gameroot", remaining);
AddSearchPath(searchpaths, buf);
//strncpy(suffix, "/gameroot/MUSIC", remaining);
//addsearchpath(buf);
}
// Shadow Warrior (Classic) - 3D Realms Anthology - Steam
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue(R"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 358400)", "InstallLocation", buf, &bufsize))
{
char* const suffix = buf + bufsize - 1;
DWORD const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/Shadow Warrior", remaining);
AddSearchPath(searchpaths, buf);
}
// Shadow Warrior Classic Complete - GOG.com
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\GOG.com\\GOGSHADOWARRIOR", "PATH", buf, &bufsize))
{
AddSearchPath(searchpaths, buf);
}
// Shadow Warrior - 3D Realms Anthology
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\3DRealms\\Shadow Warrior", NULL, buf, &bufsize))
{
char* const suffix = buf + bufsize - 1;
DWORD const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/Shadow Warrior", remaining);
AddSearchPath(searchpaths, buf);
}
// 3D Realms Anthology
bufsize = sizeof(buf);
if (Paths_ReadRegistryValue("SOFTWARE\\3DRealms\\Anthology", NULL, buf, &bufsize))
{
char* const suffix = buf + bufsize - 1;
DWORD const remaining = sizeof(buf) - bufsize;
strncpy(suffix, "/Shadow Warrior", remaining);
AddSearchPath(searchpaths, buf);
}
}
#endif

View file

@ -53,11 +53,6 @@ static uint64_t GetClockTimeNS()
return (uint64_t)((duration_cast<microseconds>(steady_clock::now().time_since_epoch()).count()) * (uint64_t)(TimeScale * 1000));
}
static uint64_t MSToNS(unsigned int ms)
{
return static_cast<uint64_t>(ms) * 1'000'000;
}
static uint64_t NSToMS(uint64_t ns)
{
return static_cast<uint64_t>(ns / 1'000'000);

View file

@ -175,7 +175,7 @@ int seq_ReadSequence(const char *seqName)
short tag;
hFile.Read(&tag, sizeof(tag));
if (tag < 'HI' || (tag > 'HI' && tag != 'SD'))
if (tag < MAKE_ID('I', 'H', 0, 0) || (tag > MAKE_ID('I', 'H', 0, 0) && tag != MAKE_ID('D', 'S', 0, 0)))
{
initprintf("Unsupported sequence version!\n");
return 0;
@ -267,7 +267,7 @@ int seq_ReadSequence(const char *seqName)
SeqBase[sequences] = frames;
chunks += nChunks;
if (tag == 'SD')
if (tag == MAKE_ID('D', 'S', 0, 0))
{
short var_20;
hFile.Read(&var_20, sizeof(var_20));

View file

@ -69,6 +69,7 @@ CUSTOM_CVAR(Int, mouse_capturemode, 1, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
extern int paused, chatmodeon;
extern constate_e ConsoleState;
extern bool ToggleFullscreen;
namespace
{
@ -165,7 +166,7 @@ void CheckNativeMouse()
else
{
wantNative = (!m_use_mouse || MENU_WaitKey != menuactive)
&& (!IsInGame() || GUICapture || paused);
&& (!IsInGame() || GUICapture /*|| paused*/);
}
}
else

View file

@ -57,6 +57,7 @@
//#include "vulkan/system/vk_framebuffer.h"
//#include "rendering/polyrenderer/backend/poly_framebuffer.h"
extern bool ToggleFullscreen;
@implementation NSWindow(ExitAppOnClose)
@ -150,7 +151,7 @@ namespace
{
if (nil == m_title)
{
m_title = [NSString stringWithFormat:@"%s %s", GAMESIG, GetVersionString()];
m_title = [NSString stringWithFormat:@"%s %s", GAMENAME, GetVersionString()];
}
[super setTitle:m_title];
@ -432,35 +433,40 @@ public:
}
else
#endif
#if 0
if (vid_preferbackend == 2)
{
SetupOpenGLView(ms_window, OpenGLProfile::Legacy);
fb = new PolyFrameBuffer(nullptr, fullscreen);
fb = new PolyFrameBuffer(nullptr, vid_fullscreen);
}
else
#endif
{
SetupOpenGLView(ms_window, OpenGLProfile::Core);
}
if (fb == nullptr)
{
fb = new OpenGLRenderer::OpenGLFrameBuffer(0, fullscreen);
fb = new OpenGLRenderer::OpenGLFrameBuffer(0, vid_fullscreen);
}
fb->SetWindow(ms_window);
fb->SetMode(fullscreen, vid_hidpi);
fb->SetMode(vid_fullscreen, vid_hidpi);
fb->SetSize(fb->GetClientWidth(), fb->GetClientHeight());
#ifdef HAVE_VULKAN
// This lame hack is a temporary workaround for strange performance issues
// with fullscreen window and Core Animation's Metal layer
// It is somehow related to initial window level and flags
// Toggling fullscreen -> window -> fullscreen mysteriously solves the problem
if (ms_isVulkanEnabled && fullscreen)
if (ms_isVulkanEnabled && vid_fullscreen)
{
fb->SetMode(false, vid_hidpi);
fb->SetMode(true, vid_hidpi);
}
#endif
return fb;
}
@ -471,8 +477,9 @@ public:
}
private:
#ifdef HAVE_VULKAN
VulkanDevice *m_vulkanDevice = nullptr;
#endif
static CocoaWindow* ms_window;
static bool ms_isVulkanEnabled;
@ -533,10 +540,10 @@ void SystemBaseFrameBuffer::SetWindowSize(int width, int height)
return;
}
if (fullscreen)
if (vid_fullscreen)
{
// Enter windowed mode in order to calculate title bar height
fullscreen = false;
vid_fullscreen = false;
SetMode(false, m_hiDPI);
}
@ -794,7 +801,7 @@ bool I_SetCursor(FTexture *cursorpic)
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSCursor* cursor = nil;
if (NULL != cursorpic && cursorpic->isValid())
if (NULL != cursorpic)
{
// Create bitmap image representation

View file

@ -36,6 +36,7 @@
#include "sc_man.h"
#include "cmdlib.h"
#include "i_specialpaths.h"
static void PSR_FindEndBlock(FScanner &sc)
{
@ -142,20 +143,28 @@ static TArray<FString> ParseSteamRegistry(const char* path)
return dirs;
}
static struct SteamAppInfo
const char *AppInfo[] =
{
const char* const BasePath;
const int AppID;
} AppInfo[] =
{
{"Doom 2/base", 2300},
{"Final Doom/base", 2290},
{"Heretic Shadow of the Serpent Riders/base", 2390},
{"Hexen/base", 2360},
{"Hexen Deathkings of the Dark Citadel/base", 2370},
{"Ultimate Doom/base", 2280},
{"DOOM 3 BFG Edition/base/wads", 208200},
{"Strife", 317040}
"Duke Nukem 3D/gameroot",
"Duke Nukem 3D/gameroot/addons/dc",
"Duke Nukem 3D/gameroot/addons/nw",
"Duke Nukem 3D/gameroot/addons/vacation",
"World War II GI/WW2GI",
"Shadow Warrior Classic/gameroot",
"Shadow Warrior Original/gameroot",
"Ion Fury",
#ifdef __APPLE
"Duke Nukem 3D/Duke Nukem 3D.app/drive_c/Program Files/Duke Nukem 3D",
"Nam/Nam.app/Contents/Resources/Nam.boxer/C.harddisk/NAM",
"Shadow Warrior DOS/Shadow Warrior.app/Contents/Resources/sw",
"Blood",
"One Unit Whole Blood",
#else
"Nam/NAM",
#endif
};
TArray<FString> I_GetSteamPath()
@ -212,7 +221,7 @@ TArray<FString> I_GetSteamPath()
for(unsigned int app = 0;app < countof(AppInfo);++app)
{
struct stat st;
FString candidate(SteamInstallFolders[i] + "/" + AppInfo[app].BasePath);
FString candidate(SteamInstallFolders[i] + "/" + AppInfo[app]);
if(DirExists(candidate))
result.Push(candidate);
}
@ -220,3 +229,4 @@ TArray<FString> I_GetSteamPath()
return result;
}

View file

@ -27,6 +27,7 @@ void I_Init (void);
// Return a seed value for the RNG.
unsigned int I_MakeRNGSeed();
void I_ShowFatalError(const char* msg);
void I_DetectOS (void);
void I_StartFrame (void);

View file

@ -37,6 +37,7 @@
#include "cmdlib.h"
#include "version.h" // for GAMENAME
#include "i_specialpaths.h"
FString M_GetMacAppSupportPath(const bool create);
@ -177,7 +178,7 @@ FString M_GetScreenshotsPath()
{
path += "/" GAME_DIR "/Screenshots/";
}
CreatePath(path);
return path;
}
@ -198,6 +199,7 @@ FString M_GetSavegamesPath()
path += "/" GAME_DIR "/Savegames/";
}
CreatePath(path);
return path;
}
@ -218,9 +220,29 @@ FString M_GetDocumentsPath()
path += "/" GAME_DIR "/";
}
CreatePath(path);
return path;
}
//===========================================================================
//
// M_GetDemoPath macOS
//
// Returns the path to the default demo directory.
//
//===========================================================================
FString M_GetDemoPath()
{
FString path = GetSpecialPath(NSDocumentDirectory);
if (path.IsNotEmpty())
{
path += "/" GAME_DIR "/Demos/";
}
CreatePath(path);
return path;
}
//===========================================================================
//

View file

@ -37,7 +37,6 @@
#include "version.h"
#include "c_cvars.h"
#include "m_argv.h"
#include "m_misc.h"
#include "gameconfigfile.h"
#include "printf.h"
#include "gamecontrol.h"
@ -385,8 +384,10 @@ static void RestartWithParameters(const WadStuff& wad, NSString* parameters)
defaultiwad = wad.Name;
GameConfig->DoGameSetup("Doom");
M_SaveDefaults(NULL);
GameConfig->ArchiveGlobalData();
GameConfig->WriteConfigFile();
delete GameConfig;
GameConfig = nullptr;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

View file

@ -185,3 +185,18 @@ FString M_GetDocumentsPath()
{
return NicePath("$HOME/" GAME_DIR);
}
//===========================================================================
//
// M_GetDemoPath Unix
//
// Returns the path to the default demo directory.
//
//===========================================================================
FString M_GetDemoPath()
{
return M_GetDocumentsPath() + "/demo/";
}

View file

@ -110,7 +110,7 @@ static HMODULE DInputDLL;
extern FMouse *Mouse;
extern FKeyboard *Keyboard;
bool ToggleFullscreen;
extern bool ToggleFullscreen;
bool VidResizing;
@ -131,7 +131,7 @@ static bool noidle = false;
LPDIRECTINPUT8 g_pdi;
LPDIRECTINPUT g_pdi3;
bool AppActive;
extern bool AppActive;
int SessionState = 0;
int BlockMouseMove;

View file

@ -275,14 +275,7 @@ static bool CaptureMode_InGame()
//
//==========================================================================
static bool grab_mouse;
void mouseGrabInput(bool grab)
{
grab_mouse = grab;
if (grab) GUICapture &= ~1;
else GUICapture |= 1;
}
extern bool grab_mouse;
void I_CheckNativeMouse(bool preferNative, bool eventhandlerresult)
{

View file

@ -47,7 +47,7 @@
#include "version.h" // for GAMENAME
// Stuff that needs to be set up later.
FString progdir;
extern FString progdir;
static bool batchrun;
// Vanilla MinGW does not have folder ids