From 4045be32b18fa4f61d5d28e9a93c86749ea0c98e Mon Sep 17 00:00:00 2001 From: Radegast Date: Wed, 21 May 2014 22:31:18 +0100 Subject: [PATCH 1/3] Replaced procfs dependent functions with native calls on OS X. #87 --- neo/CMakeLists.txt | 27 +- neo/framework/Licensee.h | 8 +- neo/idlib/Str.h | 5 - .../platform_linux.cpp} | 211 --------------- neo/sys/posix/posix_main.cpp | 241 ++++++++++++++---- neo/sys/posix/posix_public.h | 2 + 6 files changed, 211 insertions(+), 283 deletions(-) rename neo/sys/{linux/linux_main.cpp => posix/platform_linux.cpp} (75%) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index 0d7fcf40..ec8fdd15 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -827,7 +827,7 @@ set(WIN32_RESOURCES file(GLOB POSIX_INCLUDES sys/posix/*.h) -file(GLOB POSIX_SOURCES sys/posix/*.cpp) +file(GLOB POSIX_SOURCES sys/posix/*.cpp sys/posix/*.mm) file(GLOB COMMON_INCLUDES sys/common/*.h) file(GLOB COMMON_SOURCES sys/common/*.cpp) @@ -1342,11 +1342,16 @@ else() include_directories(${SDL_INCLUDE_DIR}) set(SDLx_LIBRARY ${SDL_LIBRARY}) 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.mm) + endif() + list(APPEND RBDOOM3_SOURCES ${POSIX_INCLUDES} ${POSIX_SOURCES} - ${SDL_INCLUDES} ${SDL_SOURCES} - sys/linux/linux_main.cpp) + ${SDL_INCLUDES} ${SDL_SOURCES}) if(OPENAL) find_package(OpenAL REQUIRED) @@ -1443,15 +1448,15 @@ else() add_dependencies(rm_precomp_header RBDoom3BFG) - IF(NOT "${CMAKE_SYSTEM}" MATCHES "Darwin") - set(RT_LIBRARY rt) - ENDIF() + if(NOT WIN32) + if(NOT "${CMAKE_SYSTEM}" MATCHES "Darwin") + set(RT_LIBRARY rt) + endif() - IF(NOT "${CMAKE_SYSTEM}" MATCHES "FreeBSD") - set(DL_LIBRARY dl) - ENDIF() + if(NOT "${CMAKE_SYSTEM}" MATCHES "FreeBSD") + set(DL_LIBRARY dl) + endif() - IF(NOT WIN32) target_link_libraries(RBDoom3BFG idlib ${OPENGL_LIBRARIES} diff --git a/neo/framework/Licensee.h b/neo/framework/Licensee.h index 106d0bed..3ce42e85 100644 --- a/neo/framework/Licensee.h +++ b/neo/framework/Licensee.h @@ -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" // RB begin -// Linux info -#define LINUX_DEFAULT_PATH "/usr/local/games/rbdoom3-bfg" +// Default base path (used only if none could be found) +#ifdef __APPLE__ +#define DEFAULT_BASEPATH "/Applications/rbdoom3-bfg.app/Contents/Resources" +#else +#define DEFAULT_BASEPATH "/usr/local/games/rbdoom3-bfg" +#endif // RB end diff --git a/neo/idlib/Str.h b/neo/idlib/Str.h index 331ad139..72bb40c1 100644 --- a/neo/idlib/Str.h +++ b/neo/idlib/Str.h @@ -83,11 +83,6 @@ enum utf8Encoding_t #define _strnicmp 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; #ifndef FILE_HASH_SIZE diff --git a/neo/sys/linux/linux_main.cpp b/neo/sys/posix/platform_linux.cpp similarity index 75% rename from neo/sys/linux/linux_main.cpp rename to neo/sys/posix/platform_linux.cpp index 65007432..9cd947dd 100644 --- a/neo/sys/linux/linux_main.cpp +++ b/neo/sys/posix/platform_linux.cpp @@ -45,18 +45,10 @@ static const char** cmdargv = NULL; static int cmdargc = 0; // DG end -#if defined(__APPLE__) -#include -#endif - #ifdef ID_MCHECK #include #endif -static idStr basepath; -static idStr savepath; - - /* ============== Sys_DefaultSavePath @@ -92,70 +84,6 @@ const char* Sys_EXEPath() 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 @@ -176,73 +104,6 @@ const char* Sys_GetProcessorString() 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 @@ -417,23 +278,6 @@ returns in megabytes int Sys_GetSystemRam() { 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; count = sysconf( _SC_PHYS_PAGES ); @@ -452,11 +296,8 @@ int Sys_GetSystemRam() // round to the nearest 16Mb mb = ( mb + 8 ) & ~15; return mb; -#endif } - - /* ================== Sys_DoStartProcess @@ -532,58 +373,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 diff --git a/neo/sys/posix/posix_main.cpp b/neo/sys/posix/posix_main.cpp index 71a6a7ca..21269096 100644 --- a/neo/sys/posix/posix_main.cpp +++ b/neo/sys/posix/posix_main.cpp @@ -49,12 +49,6 @@ If you have questions concerning this license or the applicable additional terms #include #endif -#if defined(__APPLE__) -#include -#include -#include -#endif - #include // RB end @@ -63,6 +57,9 @@ If you have questions concerning this license or the applicable additional terms #define MAX_OSPATH 256 #define COMMAND_HISTORY 64 +static idStr basepath; +static idStr savepath; + static int input_hide = 0; idEditField input_field; @@ -71,7 +68,7 @@ static char input_ret[256]; static idStr history[ COMMAND_HISTORY ]; // cycle buffer static int history_count = 0; // buffer fill up 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 // terminal support @@ -179,6 +176,85 @@ void Sys_Quit() 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 @@ -196,53 +272,6 @@ Sys_Milliseconds #define D3_CLOCK_TO_USE CLOCK_MONOTONIC #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 unsigned int sys_timeBase = 0; // RB end @@ -338,6 +367,56 @@ uint64 Sys_Microseconds() #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 @@ -1513,3 +1592,57 @@ void Sys_SetLanguageFromSystem() { 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 ); +} + + diff --git a/neo/sys/posix/posix_public.h b/neo/sys/posix/posix_public.h index 5c6911f5..c0a9a05e 100644 --- a/neo/sys/posix/posix_public.h +++ b/neo/sys/posix/posix_public.h @@ -59,6 +59,8 @@ void Sys_DoStartProcess( const char* exeName, bool dofork = true ); // if not f char* Posix_ConsoleInput(); +double MeasureClockTicks(); + #ifdef __APPLE__ enum clk_id_t { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW }; int clock_gettime( clk_id_t clock, struct timespec* tp ); From c76e9a26efe32f5ee2802bdd9a63624db61f88e9 Mon Sep 17 00:00:00 2001 From: Radegast Date: Thu, 22 May 2014 00:07:34 +0100 Subject: [PATCH 2/3] Removed objective-c++ code. #87 --- neo/CMakeLists.txt | 4 +- neo/sys/posix/platform_linux.cpp | 11 - neo/sys/posix/platform_osx.cpp | 493 +++++++++++++++++++++++++++++++ neo/sys/posix/posix_main.cpp | 16 + 4 files changed, 511 insertions(+), 13 deletions(-) create mode 100644 neo/sys/posix/platform_osx.cpp diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index ec8fdd15..fe76c9be 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -827,7 +827,7 @@ set(WIN32_RESOURCES file(GLOB POSIX_INCLUDES sys/posix/*.h) -file(GLOB POSIX_SOURCES sys/posix/*.cpp sys/posix/*.mm) +file(GLOB POSIX_SOURCES sys/posix/*.cpp) file(GLOB COMMON_INCLUDES sys/common/*.h) file(GLOB COMMON_SOURCES sys/common/*.cpp) @@ -1346,7 +1346,7 @@ else() 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.mm) + list(REMOVE_ITEM POSIX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sys/posix/platform_osx.cpp) endif() list(APPEND RBDOOM3_SOURCES diff --git a/neo/sys/posix/platform_linux.cpp b/neo/sys/posix/platform_linux.cpp index 9cd947dd..8342a00e 100644 --- a/neo/sys/posix/platform_linux.cpp +++ b/neo/sys/posix/platform_linux.cpp @@ -49,17 +49,6 @@ static int cmdargc = 0; #include #endif -/* - ============== - Sys_DefaultSavePath - ============== - */ -const char* Sys_DefaultSavePath() -{ - sprintf( savepath, "%s/.rbdoom3bfg", getenv( "HOME" ) ); - - return savepath.c_str(); -} /* ============== Sys_EXEPath diff --git a/neo/sys/posix/platform_osx.cpp b/neo/sys/posix/platform_osx.cpp new file mode 100644 index 00000000..dd484003 --- /dev/null +++ b/neo/sys/posix/platform_osx.cpp @@ -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 . + +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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +// DG: needed for Sys_ReLaunch() +#include + +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(); + } +} diff --git a/neo/sys/posix/posix_main.cpp b/neo/sys/posix/posix_main.cpp index 21269096..3ccb9c2c 100644 --- a/neo/sys/posix/posix_main.cpp +++ b/neo/sys/posix/posix_main.cpp @@ -85,6 +85,22 @@ idCVar com_pid( "com_pid", "0", CVAR_INTEGER | CVAR_INIT | CVAR_SYSTEM, "process static int set_exit = 0; static char exit_spawn[ 1024 ]; +/* + ============== + Sys_DefaultSavePath + ============== + */ +const char* Sys_DefaultSavePath() +{ +#ifdef __APPLE__ + sprintf( savepath, "%s/Library/Application Support/rbdoom3bfg", getenv( "HOME" ) ); +#else + sprintf( savepath, "%s/.rbdoom3bfg", getenv( "HOME" ) ); +#endif + + return savepath.c_str(); +} + /* ================ Posix_Exit From e1f8597360e7e7c483760060aea92e482ed97b4b Mon Sep 17 00:00:00 2001 From: Radegast Date: Thu, 22 May 2014 00:33:58 +0100 Subject: [PATCH 3/3] Use SDL to find Application Support path. #87 --- neo/sys/posix/posix_main.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/neo/sys/posix/posix_main.cpp b/neo/sys/posix/posix_main.cpp index 3ccb9c2c..502ab04c 100644 --- a/neo/sys/posix/posix_main.cpp +++ b/neo/sys/posix/posix_main.cpp @@ -49,6 +49,7 @@ If you have questions concerning this license or the applicable additional terms #include #endif +#include "SDL2/SDL.h" #include // RB end @@ -93,7 +94,12 @@ static char exit_spawn[ 1024 ]; const char* Sys_DefaultSavePath() { #ifdef __APPLE__ - sprintf( savepath, "%s/Library/Application Support/rbdoom3bfg", getenv( "HOME" ) ); + 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