mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-12-02 08:51:57 +00:00
Merge pull request #125 from JanSimek/objective-c
Replaced procfs dependent functions with native calls on OS X. #87
This commit is contained in:
commit
0f1f22de45
7 changed files with 725 additions and 293 deletions
|
@ -1343,10 +1343,15 @@ else()
|
||||||
set(SDLx_LIBRARY ${SDL_LIBRARY})
|
set(SDLx_LIBRARY ${SDL_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||||
|
list(REMOVE_ITEM POSIX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sys/posix/platform_linux.cpp)
|
||||||
|
else()
|
||||||
|
list(REMOVE_ITEM POSIX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sys/posix/platform_osx.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND RBDOOM3_SOURCES
|
list(APPEND RBDOOM3_SOURCES
|
||||||
${POSIX_INCLUDES} ${POSIX_SOURCES}
|
${POSIX_INCLUDES} ${POSIX_SOURCES}
|
||||||
${SDL_INCLUDES} ${SDL_SOURCES}
|
${SDL_INCLUDES} ${SDL_SOURCES})
|
||||||
sys/linux/linux_main.cpp)
|
|
||||||
|
|
||||||
if(OPENAL)
|
if(OPENAL)
|
||||||
find_package(OpenAL REQUIRED)
|
find_package(OpenAL REQUIRED)
|
||||||
|
@ -1443,15 +1448,15 @@ else()
|
||||||
add_dependencies(rm_precomp_header RBDoom3BFG)
|
add_dependencies(rm_precomp_header RBDoom3BFG)
|
||||||
|
|
||||||
|
|
||||||
IF(NOT "${CMAKE_SYSTEM}" MATCHES "Darwin")
|
if(NOT WIN32)
|
||||||
set(RT_LIBRARY rt)
|
if(NOT "${CMAKE_SYSTEM}" MATCHES "Darwin")
|
||||||
ENDIF()
|
set(RT_LIBRARY rt)
|
||||||
|
endif()
|
||||||
|
|
||||||
IF(NOT "${CMAKE_SYSTEM}" MATCHES "FreeBSD")
|
if(NOT "${CMAKE_SYSTEM}" MATCHES "FreeBSD")
|
||||||
set(DL_LIBRARY dl)
|
set(DL_LIBRARY dl)
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
IF(NOT WIN32)
|
|
||||||
target_link_libraries(RBDoom3BFG
|
target_link_libraries(RBDoom3BFG
|
||||||
idlib
|
idlib
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
|
|
|
@ -62,8 +62,12 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#define WIN32_FAKE_WINDOW_CLASS_NAME "D3BFG_WGL_FAKE"
|
#define WIN32_FAKE_WINDOW_CLASS_NAME "D3BFG_WGL_FAKE"
|
||||||
|
|
||||||
// RB begin
|
// RB begin
|
||||||
// Linux info
|
// Default base path (used only if none could be found)
|
||||||
#define LINUX_DEFAULT_PATH "/usr/local/games/rbdoom3-bfg"
|
#ifdef __APPLE__
|
||||||
|
#define DEFAULT_BASEPATH "/Applications/rbdoom3-bfg.app/Contents/Resources"
|
||||||
|
#else
|
||||||
|
#define DEFAULT_BASEPATH "/usr/local/games/rbdoom3-bfg"
|
||||||
|
#endif
|
||||||
// RB end
|
// RB end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -83,11 +83,6 @@ enum utf8Encoding_t
|
||||||
#define _strnicmp use_idStr_Icmpn
|
#define _strnicmp use_idStr_Icmpn
|
||||||
#define _memicmp use_idStr_Icmpn
|
#define _memicmp use_idStr_Icmpn
|
||||||
|
|
||||||
#define snprintf use_idStr_snPrintf
|
|
||||||
#define _snprintf use_idStr_snPrintf
|
|
||||||
#define vsnprintf use_idStr_vsnPrintf
|
|
||||||
#define _vsnprintf use_idStr_vsnPrintf
|
|
||||||
|
|
||||||
class idVec4;
|
class idVec4;
|
||||||
|
|
||||||
#ifndef FILE_HASH_SIZE
|
#ifndef FILE_HASH_SIZE
|
||||||
|
|
|
@ -45,29 +45,10 @@ static const char** cmdargv = NULL;
|
||||||
static int cmdargc = 0;
|
static int cmdargc = 0;
|
||||||
// DG end
|
// DG end
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <sys/sysctl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ID_MCHECK
|
#ifdef ID_MCHECK
|
||||||
#include <mcheck.h>
|
#include <mcheck.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static idStr basepath;
|
|
||||||
static idStr savepath;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
==============
|
|
||||||
Sys_DefaultSavePath
|
|
||||||
==============
|
|
||||||
*/
|
|
||||||
const char* Sys_DefaultSavePath()
|
|
||||||
{
|
|
||||||
sprintf( savepath, "%s/.rbdoom3bfg", getenv( "HOME" ) );
|
|
||||||
|
|
||||||
return savepath.c_str();
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
==============
|
==============
|
||||||
Sys_EXEPath
|
Sys_EXEPath
|
||||||
|
@ -92,70 +73,6 @@ const char* Sys_EXEPath()
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
Sys_DefaultBasePath
|
|
||||||
|
|
||||||
Get the default base path
|
|
||||||
- binary image path
|
|
||||||
- current directory
|
|
||||||
- hardcoded
|
|
||||||
Try to be intelligent: if there is no BASE_GAMEDIR, try the next path
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
const char* Sys_DefaultBasePath()
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
idStr testbase;
|
|
||||||
basepath = Sys_EXEPath();
|
|
||||||
if( basepath.Length() )
|
|
||||||
{
|
|
||||||
basepath.StripFilename();
|
|
||||||
testbase = basepath;
|
|
||||||
testbase += "/";
|
|
||||||
testbase += BASE_GAMEDIR;
|
|
||||||
if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) )
|
|
||||||
{
|
|
||||||
return basepath.c_str();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
common->Printf( "no '%s' directory in exe path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( basepath != Posix_Cwd() )
|
|
||||||
{
|
|
||||||
basepath = Posix_Cwd();
|
|
||||||
testbase = basepath;
|
|
||||||
testbase += "/";
|
|
||||||
testbase += BASE_GAMEDIR;
|
|
||||||
if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) )
|
|
||||||
{
|
|
||||||
return basepath.c_str();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
common->Printf( "no '%s' directory in cwd path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
common->Printf( "WARNING: using hardcoded default base path\n" );
|
|
||||||
return LINUX_DEFAULT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
Sys_Shutdown
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
void Sys_Shutdown()
|
|
||||||
{
|
|
||||||
basepath.Clear();
|
|
||||||
savepath.Clear();
|
|
||||||
Posix_Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
Sys_GetProcessorId
|
Sys_GetProcessorId
|
||||||
|
@ -176,73 +93,6 @@ const char* Sys_GetProcessorString()
|
||||||
return "generic";
|
return "generic";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
Sys_FPU_EnableExceptions
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
//void Sys_FPU_EnableExceptions( int exceptions )
|
|
||||||
//{
|
|
||||||
//}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
Sys_FPE_handler
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
void Sys_FPE_handler( int signum, siginfo_t* info, void* context )
|
|
||||||
{
|
|
||||||
assert( signum == SIGFPE );
|
|
||||||
Sys_Printf( "FPE\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
Sys_GetClockticks
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
double Sys_GetClockTicks()
|
|
||||||
{
|
|
||||||
#if defined( __i386__ )
|
|
||||||
unsigned long lo, hi;
|
|
||||||
|
|
||||||
__asm__ __volatile__(
|
|
||||||
"push %%ebx\n" \
|
|
||||||
"xor %%eax,%%eax\n" \
|
|
||||||
"cpuid\n" \
|
|
||||||
"rdtsc\n" \
|
|
||||||
"mov %%eax,%0\n" \
|
|
||||||
"mov %%edx,%1\n" \
|
|
||||||
"pop %%ebx\n"
|
|
||||||
: "=r"( lo ), "=r"( hi ) );
|
|
||||||
return ( double ) lo + ( double ) 0xFFFFFFFF * hi;
|
|
||||||
#else
|
|
||||||
//#error unsupported CPU
|
|
||||||
// RB begin
|
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
clock_gettime( CLOCK_MONOTONIC, &now );
|
|
||||||
|
|
||||||
return now.tv_sec * 1000000000LL + now.tv_nsec;
|
|
||||||
// RB end
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
===============
|
|
||||||
MeasureClockTicks
|
|
||||||
===============
|
|
||||||
*/
|
|
||||||
double MeasureClockTicks()
|
|
||||||
{
|
|
||||||
double t0, t1;
|
|
||||||
|
|
||||||
t0 = Sys_GetClockTicks( );
|
|
||||||
Sys_Sleep( 1000 );
|
|
||||||
t1 = Sys_GetClockTicks( );
|
|
||||||
return t1 - t0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
Sys_ClockTicksPerSecond
|
Sys_ClockTicksPerSecond
|
||||||
|
@ -417,23 +267,6 @@ returns in megabytes
|
||||||
int Sys_GetSystemRam()
|
int Sys_GetSystemRam()
|
||||||
{
|
{
|
||||||
int mb;
|
int mb;
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
int mib[2];
|
|
||||||
mib[0] = CTL_HW;
|
|
||||||
mib[1] = HW_MEMSIZE;
|
|
||||||
int64_t size = 0;
|
|
||||||
size_t len = sizeof( size );
|
|
||||||
if( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 )
|
|
||||||
{
|
|
||||||
mb = size / ( 1024 * 1024 );
|
|
||||||
mb = ( mb + 8 ) & ~15;
|
|
||||||
return mb;
|
|
||||||
}
|
|
||||||
|
|
||||||
common->Printf( "GetSystemRam: sysctl HW_MEMSIZE failed\n" );
|
|
||||||
return 512;
|
|
||||||
#else
|
|
||||||
long count, page_size;
|
long count, page_size;
|
||||||
|
|
||||||
count = sysconf( _SC_PHYS_PAGES );
|
count = sysconf( _SC_PHYS_PAGES );
|
||||||
|
@ -452,11 +285,8 @@ int Sys_GetSystemRam()
|
||||||
// round to the nearest 16Mb
|
// round to the nearest 16Mb
|
||||||
mb = ( mb + 8 ) & ~15;
|
mb = ( mb + 8 ) & ~15;
|
||||||
return mb;
|
return mb;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
Sys_DoStartProcess
|
Sys_DoStartProcess
|
||||||
|
@ -532,58 +362,6 @@ void Sys_DoStartProcess( const char* exeName, bool dofork )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
Sys_OpenURL
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void idSysLocal::OpenURL( const char* url, bool quit )
|
|
||||||
{
|
|
||||||
const char* script_path;
|
|
||||||
idFile* script_file;
|
|
||||||
char cmdline[ 1024 ];
|
|
||||||
|
|
||||||
static bool quit_spamguard = false;
|
|
||||||
|
|
||||||
if( quit_spamguard )
|
|
||||||
{
|
|
||||||
common->DPrintf( "Sys_OpenURL: already in a doexit sequence, ignoring %s\n", url );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
common->Printf( "Open URL: %s\n", url );
|
|
||||||
// opening an URL on *nix can mean a lot of things ..
|
|
||||||
// just spawn a script instead of deciding for the user :-)
|
|
||||||
|
|
||||||
// look in the savepath first, then in the basepath
|
|
||||||
script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_savepath" ), "", "openurl.sh" );
|
|
||||||
script_file = fileSystem->OpenExplicitFileRead( script_path );
|
|
||||||
if( !script_file )
|
|
||||||
{
|
|
||||||
script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_basepath" ), "", "openurl.sh" );
|
|
||||||
script_file = fileSystem->OpenExplicitFileRead( script_path );
|
|
||||||
}
|
|
||||||
if( !script_file )
|
|
||||||
{
|
|
||||||
common->Printf( "Can't find URL script 'openurl.sh' in either savepath or basepath\n" );
|
|
||||||
common->Printf( "OpenURL '%s' failed\n", url );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fileSystem->CloseFile( script_file );
|
|
||||||
|
|
||||||
// if we are going to quit, only accept a single URL before quitting and spawning the script
|
|
||||||
if( quit )
|
|
||||||
{
|
|
||||||
quit_spamguard = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
common->Printf( "URL script: %s\n", script_path );
|
|
||||||
|
|
||||||
// StartProcess is going to execute a system() call with that - hence the &
|
|
||||||
idStr::snPrintf( cmdline, 1024, "%s '%s' &", script_path, url );
|
|
||||||
sys->StartProcess( cmdline, quit );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
Sys_DoPreferences
|
Sys_DoPreferences
|
493
neo/sys/posix/platform_osx.cpp
Normal file
493
neo/sys/posix/platform_osx.cpp
Normal file
|
@ -0,0 +1,493 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 2012 Robert Beckebans
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
//#include "../../idlib/precompiled.h"
|
||||||
|
#include "../posix/posix_public.h"
|
||||||
|
//#include "../sys_local.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <mach/clock.h>
|
||||||
|
#include <mach/clock_types.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
|
||||||
|
// DG: needed for Sys_ReLaunch()
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
static const char** cmdargv = NULL;
|
||||||
|
static int cmdargc = 0;
|
||||||
|
// DG end
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
Sys_EXEPath
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
const char* Sys_EXEPath()
|
||||||
|
{
|
||||||
|
static char path[1024];
|
||||||
|
uint32_t size = sizeof( path );
|
||||||
|
|
||||||
|
if( _NSGetExecutablePath( path, &size ) != 0 )
|
||||||
|
{
|
||||||
|
Sys_Printf( "buffer too small to store exe path, need size %u\n", size );
|
||||||
|
path[0] = '\0';
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_GetProcessorId
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
cpuid_t Sys_GetProcessorId()
|
||||||
|
{
|
||||||
|
return CPUID_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_GetProcessorString
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
const char* Sys_GetProcessorString()
|
||||||
|
{
|
||||||
|
return "generic";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_ClockTicksPerSecond
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
double Sys_ClockTicksPerSecond()
|
||||||
|
{
|
||||||
|
static bool init = false;
|
||||||
|
static double ret;
|
||||||
|
size_t len = sizeof( ret );
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if( init )
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sysctlbyname( "hw.cpufrequency", &ret, &len, NULL, 0 );
|
||||||
|
|
||||||
|
if( status == -1 )
|
||||||
|
{
|
||||||
|
common->Printf( "couldn't read systclbyname\n" );
|
||||||
|
ret = MeasureClockTicks();
|
||||||
|
init = true;
|
||||||
|
common->Printf( "measured CPU frequency: %g MHz\n", ret / 1000000.0 );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "CPU frequency: %g MHz\n", ret / 1000000.0 );
|
||||||
|
init = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_CPUCount
|
||||||
|
|
||||||
|
numLogicalCPUCores - the number of logical CPU per core
|
||||||
|
numPhysicalCPUCores - the total number of cores per package
|
||||||
|
numCPUPackages - the total number of packages (physical processors)
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
// RB begin
|
||||||
|
void Sys_CPUCount( int& numLogicalCPUCores, int& numPhysicalCPUCores, int& numCPUPackages )
|
||||||
|
{
|
||||||
|
static bool init = false;
|
||||||
|
|
||||||
|
static int s_numLogicalCPUCores;
|
||||||
|
static int s_numPhysicalCPUCores;
|
||||||
|
static int s_numCPUPackages;
|
||||||
|
|
||||||
|
size_t len = sizeof( s_numPhysicalCPUCores );
|
||||||
|
|
||||||
|
if( init )
|
||||||
|
{
|
||||||
|
numPhysicalCPUCores = s_numPhysicalCPUCores;
|
||||||
|
numLogicalCPUCores = s_numLogicalCPUCores;
|
||||||
|
numCPUPackages = s_numCPUPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_numPhysicalCPUCores = 1;
|
||||||
|
s_numLogicalCPUCores = 1;
|
||||||
|
s_numCPUPackages = 1;
|
||||||
|
|
||||||
|
|
||||||
|
sysctlbyname( "hw.physicalcpu", &s_numPhysicalCPUCores, &len, NULL, 0 );
|
||||||
|
sysctlbyname( "hw.logicalcpu", &s_numLogicalCPUCores, &len, NULL, 0 );
|
||||||
|
|
||||||
|
common->Printf( "CPU processors: %d\n", s_numPhysicalCPUCores );
|
||||||
|
common->Printf( "CPU logical cores: %d\n", s_numLogicalCPUCores );
|
||||||
|
|
||||||
|
numPhysicalCPUCores = s_numPhysicalCPUCores;
|
||||||
|
numLogicalCPUCores = s_numLogicalCPUCores;
|
||||||
|
numCPUPackages = s_numCPUPackages;
|
||||||
|
}
|
||||||
|
// RB end
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_GetSystemRam
|
||||||
|
returns in megabytes
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
int Sys_GetSystemRam()
|
||||||
|
{
|
||||||
|
int mb, mib[2];
|
||||||
|
|
||||||
|
mib[0] = CTL_HW;
|
||||||
|
mib[1] = HW_MEMSIZE;
|
||||||
|
int64_t size = 0;
|
||||||
|
size_t len = sizeof( size );
|
||||||
|
if( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 )
|
||||||
|
{
|
||||||
|
mb = size / ( 1024 * 1024 );
|
||||||
|
mb = ( mb + 8 ) & ~15;
|
||||||
|
return mb;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "GetSystemRam: sysctl HW_MEMSIZE failed\n" );
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DoStartProcess
|
||||||
|
if we don't fork, this function never returns
|
||||||
|
the no-fork lets you keep the terminal when you're about to spawn an installer
|
||||||
|
|
||||||
|
if the command contains spaces, system() is used. Otherwise the more straightforward execl ( system() blows though )
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Sys_DoStartProcess( const char* exeName, bool dofork )
|
||||||
|
{
|
||||||
|
bool use_system = false;
|
||||||
|
if( strchr( exeName, ' ' ) )
|
||||||
|
{
|
||||||
|
use_system = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set exec rights when it's about a single file to execute
|
||||||
|
struct stat buf;
|
||||||
|
if( stat( exeName, &buf ) == -1 )
|
||||||
|
{
|
||||||
|
printf( "stat %s failed: %s\n", exeName, strerror( errno ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( chmod( exeName, buf.st_mode | S_IXUSR ) == -1 )
|
||||||
|
{
|
||||||
|
printf( "cmod +x %s failed: %s\n", exeName, strerror( errno ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( dofork )
|
||||||
|
{
|
||||||
|
switch( fork() )
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
// main thread
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
if( use_system )
|
||||||
|
{
|
||||||
|
printf( "system %s\n", exeName );
|
||||||
|
system( exeName );
|
||||||
|
_exit( 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf( "execl %s\n", exeName );
|
||||||
|
execl( exeName, exeName, NULL );
|
||||||
|
printf( "execl failed: %s\n", strerror( errno ) );
|
||||||
|
_exit( -1 );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( use_system )
|
||||||
|
{
|
||||||
|
printf( "system %s\n", exeName );
|
||||||
|
system( exeName );
|
||||||
|
sleep( 1 ); // on some systems I've seen that starting the new process and exiting this one should not be too close
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf( "execl %s\n", exeName );
|
||||||
|
execl( exeName, exeName, NULL );
|
||||||
|
printf( "execl failed: %s\n", strerror( errno ) );
|
||||||
|
}
|
||||||
|
// terminate
|
||||||
|
_exit( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DoPreferences
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Sys_DoPreferences() { }
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_FPU_SetDAZ
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_FPU_SetDAZ( bool enable )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
DWORD dwData;
|
||||||
|
|
||||||
|
_asm {
|
||||||
|
movzx ecx, byte ptr enable
|
||||||
|
and ecx, 1
|
||||||
|
shl ecx, 6
|
||||||
|
STMXCSR dword ptr dwData
|
||||||
|
mov eax, dwData
|
||||||
|
and eax, ~(1<<6) // clear DAX bit
|
||||||
|
or eax, ecx // set the DAZ bit
|
||||||
|
mov dwData, eax
|
||||||
|
LDMXCSR dword ptr dwData
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_FPU_SetFTZ
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_FPU_SetFTZ( bool enable )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
DWORD dwData;
|
||||||
|
|
||||||
|
_asm {
|
||||||
|
movzx ecx, byte ptr enable
|
||||||
|
and ecx, 1
|
||||||
|
shl ecx, 15
|
||||||
|
STMXCSR dword ptr dwData
|
||||||
|
mov eax, dwData
|
||||||
|
and eax, ~(1<<15) // clear FTZ bit
|
||||||
|
or eax, ecx // set the FTZ bit
|
||||||
|
mov dwData, eax
|
||||||
|
LDMXCSR dword ptr dwData
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_GetCmdLine
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
const char* Sys_GetCmdLine()
|
||||||
|
{
|
||||||
|
// DG: don't use this, use cmdargv and cmdargc instead!
|
||||||
|
return "TODO Sys_GetCmdLine";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_ReLaunch
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void Sys_ReLaunch()
|
||||||
|
{
|
||||||
|
// DG: implementing this... basic old fork() exec() (+ setsid()) routine..
|
||||||
|
// NOTE: this function used to have parameters: the commandline arguments, but as one string..
|
||||||
|
// for Linux/Unix we want one char* per argument so we'll just add the friggin'
|
||||||
|
// " +set com_skipIntroVideos 1" to the other commandline arguments in this function.
|
||||||
|
|
||||||
|
int ret = fork();
|
||||||
|
if( ret < 0 )
|
||||||
|
idLib::Error( "Sys_ReLaunch(): Couldn't fork(), reason: %s ", strerror( errno ) );
|
||||||
|
|
||||||
|
if( ret == 0 )
|
||||||
|
{
|
||||||
|
// child process
|
||||||
|
|
||||||
|
// get our own session so we don't depend on the (soon to be killed)
|
||||||
|
// parent process anymore - else we'll freeze
|
||||||
|
pid_t sId = setsid();
|
||||||
|
if( sId == ( pid_t ) - 1 )
|
||||||
|
{
|
||||||
|
idLib::Error( "Sys_ReLaunch(): setsid() failed! Reason: %s ", strerror( errno ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// close all FDs (except for stdin/out/err) so we don't leak FDs
|
||||||
|
DIR* devfd = opendir( "/dev/fd" );
|
||||||
|
if( devfd != NULL )
|
||||||
|
{
|
||||||
|
struct dirent entry;
|
||||||
|
struct dirent* result;
|
||||||
|
while( readdir_r( devfd, &entry, &result ) == 0 )
|
||||||
|
{
|
||||||
|
const char* filename = result->d_name;
|
||||||
|
char* endptr = NULL;
|
||||||
|
long int fd = strtol( filename, &endptr, 0 );
|
||||||
|
if( endptr != filename && fd > STDERR_FILENO )
|
||||||
|
close( fd );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idLib::Warning( "Sys_ReLaunch(): Couldn't open /dev/fd/ - will leak file descriptors. Reason: %s", strerror( errno ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// + 3 because "+set" "com_skipIntroVideos" "1" - and note that while we'll skip
|
||||||
|
// one (the first) cmdargv argument, we need one more pointer for NULL at the end.
|
||||||
|
int argc = cmdargc + 3;
|
||||||
|
const char** argv = ( const char** )calloc( argc, sizeof( char* ) );
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for( i = 0; i < cmdargc - 1; ++i )
|
||||||
|
argv[i] = cmdargv[i + 1]; // ignore cmdargv[0] == executable name
|
||||||
|
|
||||||
|
// add +set com_skipIntroVideos 1
|
||||||
|
argv[i++] = "+set";
|
||||||
|
argv[i++] = "com_skipIntroVideos";
|
||||||
|
argv[i++] = "1";
|
||||||
|
// execv expects NULL terminated array
|
||||||
|
argv[i] = NULL;
|
||||||
|
|
||||||
|
const char* exepath = Sys_EXEPath();
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
execv( exepath, ( char** )argv );
|
||||||
|
// we only get here if execv() fails, else the executable is restarted
|
||||||
|
idLib::Error( "Sys_ReLaunch(): WTF exec() failed! Reason: %s ", strerror( errno ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// original process
|
||||||
|
// just do a clean shutdown
|
||||||
|
cmdSystem->AppendCommandText( "quit\n" );
|
||||||
|
}
|
||||||
|
// DG end
|
||||||
|
}
|
||||||
|
|
||||||
|
// OS X doesn't have clock_gettime()
|
||||||
|
int clock_gettime( clk_id_t clock, struct timespec* tp )
|
||||||
|
{
|
||||||
|
switch( clock )
|
||||||
|
{
|
||||||
|
case CLOCK_MONOTONIC_RAW:
|
||||||
|
case CLOCK_MONOTONIC:
|
||||||
|
{
|
||||||
|
clock_serv_t clock_ref;
|
||||||
|
mach_timespec_t tm;
|
||||||
|
host_name_port_t self = mach_host_self();
|
||||||
|
memset( &tm, 0, sizeof( tm ) );
|
||||||
|
if( KERN_SUCCESS != host_get_clock_service( self, SYSTEM_CLOCK, &clock_ref ) )
|
||||||
|
{
|
||||||
|
mach_port_deallocate( mach_task_self(), self );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if( KERN_SUCCESS != clock_get_time( clock_ref, &tm ) )
|
||||||
|
{
|
||||||
|
mach_port_deallocate( mach_task_self(), self );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mach_port_deallocate( mach_task_self(), self );
|
||||||
|
mach_port_deallocate( mach_task_self(), clock_ref );
|
||||||
|
tp->tv_sec = tm.tv_sec;
|
||||||
|
tp->tv_nsec = tm.tv_nsec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CLOCK_REALTIME:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
if( KERN_SUCCESS != gettimeofday( &now, NULL ) )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
tp->tv_sec = now.tv_sec;
|
||||||
|
tp->tv_nsec = now.tv_usec * 1000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
main
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
int main( int argc, const char** argv )
|
||||||
|
{
|
||||||
|
// DG: needed for Sys_ReLaunch()
|
||||||
|
cmdargc = argc;
|
||||||
|
cmdargv = argv;
|
||||||
|
// DG end
|
||||||
|
|
||||||
|
Posix_EarlyInit( );
|
||||||
|
|
||||||
|
if( argc > 1 )
|
||||||
|
{
|
||||||
|
common->Init( argc - 1, &argv[1], NULL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Init( 0, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
Posix_LateInit( );
|
||||||
|
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
common->Frame();
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,12 +49,7 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#include "SDL2/SDL.h"
|
||||||
#include <mach/clock.h>
|
|
||||||
#include <mach/clock_types.h>
|
|
||||||
#include <mach/mach.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
// RB end
|
// RB end
|
||||||
|
|
||||||
|
@ -63,6 +58,9 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#define MAX_OSPATH 256
|
#define MAX_OSPATH 256
|
||||||
#define COMMAND_HISTORY 64
|
#define COMMAND_HISTORY 64
|
||||||
|
|
||||||
|
static idStr basepath;
|
||||||
|
static idStr savepath;
|
||||||
|
|
||||||
static int input_hide = 0;
|
static int input_hide = 0;
|
||||||
|
|
||||||
idEditField input_field;
|
idEditField input_field;
|
||||||
|
@ -71,7 +69,7 @@ static char input_ret[256];
|
||||||
static idStr history[ COMMAND_HISTORY ]; // cycle buffer
|
static idStr history[ COMMAND_HISTORY ]; // cycle buffer
|
||||||
static int history_count = 0; // buffer fill up
|
static int history_count = 0; // buffer fill up
|
||||||
static int history_start = 0; // current history start
|
static int history_start = 0; // current history start
|
||||||
static int history_current = 0; // goes back in history
|
static int history_current = 0; // goes back in history
|
||||||
idEditField history_backup; // the base edit line
|
idEditField history_backup; // the base edit line
|
||||||
|
|
||||||
// terminal support
|
// terminal support
|
||||||
|
@ -88,6 +86,27 @@ idCVar com_pid( "com_pid", "0", CVAR_INTEGER | CVAR_INIT | CVAR_SYSTEM, "process
|
||||||
static int set_exit = 0;
|
static int set_exit = 0;
|
||||||
static char exit_spawn[ 1024 ];
|
static char exit_spawn[ 1024 ];
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
Sys_DefaultSavePath
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
const char* Sys_DefaultSavePath()
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
char* base_path = SDL_GetPrefPath( "", "rbdoom3bfg" );
|
||||||
|
if( base_path )
|
||||||
|
{
|
||||||
|
savepath = SDL_strdup( base_path );
|
||||||
|
SDL_free( base_path );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
sprintf( savepath, "%s/.rbdoom3bfg", getenv( "HOME" ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return savepath.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Posix_Exit
|
Posix_Exit
|
||||||
|
@ -179,6 +198,85 @@ void Sys_Quit()
|
||||||
Posix_Exit( EXIT_SUCCESS );
|
Posix_Exit( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_Shutdown
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Sys_Shutdown()
|
||||||
|
{
|
||||||
|
basepath.Clear();
|
||||||
|
savepath.Clear();
|
||||||
|
Posix_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_FPU_EnableExceptions
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
//void Sys_FPU_EnableExceptions( int exceptions )
|
||||||
|
//{
|
||||||
|
//}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_FPE_handler
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Sys_FPE_handler( int signum, siginfo_t* info, void* context )
|
||||||
|
{
|
||||||
|
assert( signum == SIGFPE );
|
||||||
|
Sys_Printf( "FPE\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_GetClockticks
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
double Sys_GetClockTicks()
|
||||||
|
{
|
||||||
|
#if defined( __i386__ )
|
||||||
|
unsigned long lo, hi;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"push %%ebx\n" \
|
||||||
|
"xor %%eax,%%eax\n" \
|
||||||
|
"cpuid\n" \
|
||||||
|
"rdtsc\n" \
|
||||||
|
"mov %%eax,%0\n" \
|
||||||
|
"mov %%edx,%1\n" \
|
||||||
|
"pop %%ebx\n"
|
||||||
|
: "=r"( lo ), "=r"( hi ) );
|
||||||
|
return ( double ) lo + ( double ) 0xFFFFFFFF * hi;
|
||||||
|
#else
|
||||||
|
//#error unsupported CPU
|
||||||
|
// RB begin
|
||||||
|
struct timespec now;
|
||||||
|
|
||||||
|
clock_gettime( CLOCK_MONOTONIC, &now );
|
||||||
|
|
||||||
|
return now.tv_sec * 1000000000LL + now.tv_nsec;
|
||||||
|
// RB end
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
MeasureClockTicks
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
double MeasureClockTicks()
|
||||||
|
{
|
||||||
|
double t0, t1;
|
||||||
|
|
||||||
|
t0 = Sys_GetClockTicks( );
|
||||||
|
Sys_Sleep( 1000 );
|
||||||
|
t1 = Sys_GetClockTicks( );
|
||||||
|
return t1 - t0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_Milliseconds
|
Sys_Milliseconds
|
||||||
|
@ -196,53 +294,6 @@ Sys_Milliseconds
|
||||||
#define D3_CLOCK_TO_USE CLOCK_MONOTONIC
|
#define D3_CLOCK_TO_USE CLOCK_MONOTONIC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
// OS X doesn't have clock_gettime()
|
|
||||||
int clock_gettime( clk_id_t clock, struct timespec* tp )
|
|
||||||
{
|
|
||||||
switch( clock )
|
|
||||||
{
|
|
||||||
case CLOCK_MONOTONIC_RAW:
|
|
||||||
case CLOCK_MONOTONIC:
|
|
||||||
{
|
|
||||||
clock_serv_t clock_ref;
|
|
||||||
mach_timespec_t tm;
|
|
||||||
host_name_port_t self = mach_host_self();
|
|
||||||
memset( &tm, 0, sizeof( tm ) );
|
|
||||||
if( KERN_SUCCESS != host_get_clock_service( self, SYSTEM_CLOCK, &clock_ref ) )
|
|
||||||
{
|
|
||||||
mach_port_deallocate( mach_task_self(), self );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if( KERN_SUCCESS != clock_get_time( clock_ref, &tm ) )
|
|
||||||
{
|
|
||||||
mach_port_deallocate( mach_task_self(), self );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
mach_port_deallocate( mach_task_self(), self );
|
|
||||||
mach_port_deallocate( mach_task_self(), clock_ref );
|
|
||||||
tp->tv_sec = tm.tv_sec;
|
|
||||||
tp->tv_nsec = tm.tv_nsec;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CLOCK_REALTIME:
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
struct timeval now;
|
|
||||||
if( KERN_SUCCESS != gettimeofday( &now, NULL ) )
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
tp->tv_sec = now.tv_sec;
|
|
||||||
tp->tv_nsec = now.tv_usec * 1000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif // __APPLE__
|
|
||||||
|
|
||||||
// RB: changed long to int
|
// RB: changed long to int
|
||||||
unsigned int sys_timeBase = 0;
|
unsigned int sys_timeBase = 0;
|
||||||
// RB end
|
// RB end
|
||||||
|
@ -338,6 +389,56 @@ uint64 Sys_Microseconds()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_DefaultBasePath
|
||||||
|
|
||||||
|
Get the default base path
|
||||||
|
- binary image path
|
||||||
|
- current directory
|
||||||
|
- hardcoded
|
||||||
|
Try to be intelligent: if there is no BASE_GAMEDIR, try the next path
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
const char* Sys_DefaultBasePath()
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
idStr testbase;
|
||||||
|
basepath = Sys_EXEPath();
|
||||||
|
if( basepath.Length() )
|
||||||
|
{
|
||||||
|
basepath.StripFilename();
|
||||||
|
testbase = basepath;
|
||||||
|
testbase += "/";
|
||||||
|
testbase += BASE_GAMEDIR;
|
||||||
|
if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) )
|
||||||
|
{
|
||||||
|
return basepath.c_str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "no '%s' directory in exe path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( basepath != Posix_Cwd() )
|
||||||
|
{
|
||||||
|
basepath = Posix_Cwd();
|
||||||
|
testbase = basepath;
|
||||||
|
testbase += "/";
|
||||||
|
testbase += BASE_GAMEDIR;
|
||||||
|
if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) )
|
||||||
|
{
|
||||||
|
return basepath.c_str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "no '%s' directory in cwd path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
common->Printf( "WARNING: using hardcoded default base path %s\n", DEFAULT_BASEPATH );
|
||||||
|
return DEFAULT_BASEPATH;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_Mkdir
|
Sys_Mkdir
|
||||||
|
@ -1513,3 +1614,57 @@ void Sys_SetLanguageFromSystem()
|
||||||
{
|
{
|
||||||
sys_lang.SetString( Sys_DefaultLanguage() );
|
sys_lang.SetString( Sys_DefaultLanguage() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_OpenURL
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void idSysLocal::OpenURL( const char* url, bool quit )
|
||||||
|
{
|
||||||
|
const char* script_path;
|
||||||
|
idFile* script_file;
|
||||||
|
char cmdline[ 1024 ];
|
||||||
|
|
||||||
|
static bool quit_spamguard = false;
|
||||||
|
|
||||||
|
if( quit_spamguard )
|
||||||
|
{
|
||||||
|
common->DPrintf( "Sys_OpenURL: already in a doexit sequence, ignoring %s\n", url );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "Open URL: %s\n", url );
|
||||||
|
// opening an URL on *nix can mean a lot of things ..
|
||||||
|
// just spawn a script instead of deciding for the user :-)
|
||||||
|
|
||||||
|
// look in the savepath first, then in the basepath
|
||||||
|
script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_savepath" ), "", "openurl.sh" );
|
||||||
|
script_file = fileSystem->OpenExplicitFileRead( script_path );
|
||||||
|
if( !script_file )
|
||||||
|
{
|
||||||
|
script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_basepath" ), "", "openurl.sh" );
|
||||||
|
script_file = fileSystem->OpenExplicitFileRead( script_path );
|
||||||
|
}
|
||||||
|
if( !script_file )
|
||||||
|
{
|
||||||
|
common->Printf( "Can't find URL script 'openurl.sh' in either savepath or basepath\n" );
|
||||||
|
common->Printf( "OpenURL '%s' failed\n", url );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fileSystem->CloseFile( script_file );
|
||||||
|
|
||||||
|
// if we are going to quit, only accept a single URL before quitting and spawning the script
|
||||||
|
if( quit )
|
||||||
|
{
|
||||||
|
quit_spamguard = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "URL script: %s\n", script_path );
|
||||||
|
|
||||||
|
// StartProcess is going to execute a system() call with that - hence the &
|
||||||
|
idStr::snPrintf( cmdline, 1024, "%s '%s' &", script_path, url );
|
||||||
|
sys->StartProcess( cmdline, quit );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@ void Sys_DoStartProcess( const char* exeName, bool dofork = true ); // if not f
|
||||||
|
|
||||||
char* Posix_ConsoleInput();
|
char* Posix_ConsoleInput();
|
||||||
|
|
||||||
|
double MeasureClockTicks();
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
enum clk_id_t { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW };
|
enum clk_id_t { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW };
|
||||||
int clock_gettime( clk_id_t clock, struct timespec* tp );
|
int clock_gettime( clk_id_t clock, struct timespec* tp );
|
||||||
|
|
Loading…
Reference in a new issue