mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Updated platform files to ioq3 codebase
This commit is contained in:
parent
0d074c09e8
commit
dc36511b5a
16 changed files with 2248 additions and 884 deletions
|
@ -106,6 +106,10 @@ set(SOURCES_COMMON
|
|||
"code/qcommon/tiki_main.cpp"
|
||||
"code/qcommon/tiki_script.cpp"
|
||||
"code/qcommon/unzip.c"
|
||||
# Main stuff
|
||||
"code/sys/sys_main.c"
|
||||
"code/sys/sys_autoupdater.c"
|
||||
"code/sys/con_log.c"
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SOURCES_SKEL "code/tiki/*.cpp" "code/skeletor/*.cpp")
|
||||
|
@ -124,7 +128,7 @@ set(SOURCES_APP ${SOURCES_SHARED} ${SOURCES_COMMON} ${SOURCES_SKEL})
|
|||
file(GLOB_RECURSE SOURCES_SERVER "code/server/*.c" "code/server/*.cpp")
|
||||
set(SOURCES_SERVER_APP ${SOURCES_APP} ${SOURCES_SERVER})
|
||||
|
||||
add_executable(omohaaded ${SOURCES_SERVER_APP} ${SOURCES_PLATFORM_SPECIFIC} "code/null/null_client.c" "code/null/null_input.c" "code/null/null_snddma.c" "code/sys/sys_main.c" "code/sys/con_log.c")
|
||||
add_executable(omohaaded ${SOURCES_SERVER_APP} ${SOURCES_PLATFORM_SPECIFIC} "code/null/null_client.c" "code/null/null_input.c" "code/null/null_snddma.c")
|
||||
set_property(TARGET omohaaded PROPERTY CXX_STANDARD 11)
|
||||
target_compile_features(omohaaded PUBLIC cxx_constexpr)
|
||||
target_compile_definitions(omohaaded PRIVATE NO_SCRIPTENGINE DEDICATED TARGET_GAME_TYPE=${TARGET_GAME_TYPE})
|
||||
|
|
|
@ -83,7 +83,8 @@ int Sys_Milliseconds (void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Sys_Mkdir (char *path) {
|
||||
qboolean Sys_Mkdir (const char *path) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
char *Sys_FindFirst (char *path, unsigned musthave, unsigned canthave) {
|
||||
|
|
|
@ -99,6 +99,7 @@ cvar_t *com_cameraMode;
|
|||
cvar_t *com_ansiColor;
|
||||
cvar_t *com_unfocused;
|
||||
cvar_t *com_minimized;
|
||||
cvar_t *com_homepath;
|
||||
cvar_t *precache;
|
||||
|
||||
// com_speeds times
|
||||
|
@ -291,7 +292,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
|
|||
lastErrorTime = currentTime;
|
||||
|
||||
if ( com_errorEntered ) {
|
||||
SyScriptError( "recursive error after: %s", com_errorMessage );
|
||||
Sys_Error( "recursive error after: %s", com_errorMessage );
|
||||
}
|
||||
com_errorEntered = qtrue;
|
||||
|
||||
|
@ -336,7 +337,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
|
|||
|
||||
Com_Shutdown ();
|
||||
|
||||
SyScriptError ("%s", com_errorMessage);
|
||||
Sys_Error("%s", com_errorMessage);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1266,7 +1267,7 @@ void Com_Init( char *commandLine ) {
|
|||
Com_Printf( "%s %s %s\n", PRODUCT_VERSION_FULL, PLATFORM_STRING, __DATE__ );
|
||||
|
||||
if ( setjmp (abortframe) ) {
|
||||
SyScriptError ("Error during initialization");
|
||||
Sys_Error("Error during initialization");
|
||||
}
|
||||
|
||||
// prepare enough of the subsystems to handle
|
||||
|
@ -1291,6 +1292,8 @@ void Com_Init( char *commandLine ) {
|
|||
// done early so bind command exists
|
||||
CL_InitKeyCommands();
|
||||
|
||||
com_homepath = Cvar_Get("com_homepath", "", CVAR_INIT|CVAR_ROM);
|
||||
|
||||
FS_InitFilesystem ();
|
||||
|
||||
Com_InitJournaling();
|
||||
|
@ -1404,7 +1407,7 @@ void Com_Init( char *commandLine ) {
|
|||
}
|
||||
}
|
||||
|
||||
s = va( "%s %s %s", PRODUCT_VERSION_FULL, PLATFORM_STRING, __DATE__ );
|
||||
s = va( "%s %s %s", PRODUCT_VERSION_FULL, PLATFORM_STRING, PRODUCT_DATE );
|
||||
com_version = Cvar_Get( "version", s, CVAR_ROM | CVAR_SERVERINFO );
|
||||
com_shortversion = Cvar_Get( "shortversion", TARGET_GAME_VERSION, CVAR_ROM );
|
||||
|
||||
|
|
|
@ -245,8 +245,7 @@ cvar_t *fs_basepath;
|
|||
static cvar_t *fs_basegame;
|
||||
static cvar_t *fs_gamedirvar;
|
||||
static cvar_t *fs_restrict;
|
||||
static cvar_t *fs_userpath;
|
||||
static cvar_t *fs_outputpath;
|
||||
static cvar_t *fs_homepath;
|
||||
static cvar_t *fs_copyfiles;
|
||||
static cvar_t *fs_filedir;
|
||||
static searchpath_t *fs_searchpaths;
|
||||
|
@ -671,7 +670,7 @@ qboolean FS_FileExists( const char *file )
|
|||
FILE *f;
|
||||
char *testpath;
|
||||
|
||||
testpath = FS_BuildOSPath( fs_outputpath->string, fs_gamedir, file );
|
||||
testpath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, file );
|
||||
|
||||
f = fopen( testpath, "rb" );
|
||||
if (f) {
|
||||
|
@ -693,7 +692,7 @@ qboolean FS_SV_FileExists( const char *file )
|
|||
FILE *f;
|
||||
char *testpath;
|
||||
|
||||
testpath = FS_BuildOSPath( fs_outputpath->string, file, "");
|
||||
testpath = FS_BuildOSPath( fs_homepath->string, file, "");
|
||||
testpath[strlen(testpath)-1] = '\0';
|
||||
|
||||
f = fopen( testpath, "rb" );
|
||||
|
@ -718,7 +717,7 @@ fileHandle_t FS_SV_FOpenFileWrite( const char *filename ) {
|
|||
Com_Error( ERR_FATAL, "Filesystem call made without initialization\n" );
|
||||
}
|
||||
|
||||
ospath = FS_BuildOSPath( fs_outputpath->string, filename, "" );
|
||||
ospath = FS_BuildOSPath( fs_homepath->string, filename, "" );
|
||||
ospath[strlen(ospath)-1] = '\0';
|
||||
|
||||
f = FS_HandleForFile();
|
||||
|
@ -769,20 +768,20 @@ int FS_SV_FOpenFileRead( const char *filename, fileHandle_t *fp ) {
|
|||
S_ClearSoundBuffer();
|
||||
|
||||
// search homepath
|
||||
ospath = FS_BuildOSPath( fs_outputpath->string, filename, "" );
|
||||
ospath = FS_BuildOSPath( fs_homepath->string, filename, "" );
|
||||
// remove trailing slash
|
||||
ospath[strlen(ospath)-1] = '\0';
|
||||
|
||||
if ( fs_debug->integer ) {
|
||||
Com_Printf( "FS_SV_FOpenFileRead (fs_outputpath): %s\n", ospath );
|
||||
Com_Printf( "FS_SV_FOpenFileRead (fs_homepath): %s\n", ospath );
|
||||
}
|
||||
|
||||
fsh[f].handleFiles.file.o = fopen( ospath, "rb" );
|
||||
fsh[f].handleSync = qfalse;
|
||||
if (!fsh[f].handleFiles.file.o)
|
||||
{
|
||||
// If fs_outputpath == fs_basepath, don't bother
|
||||
if (Q_stricmp(fs_outputpath->string,fs_basepath->string))
|
||||
// If fs_homepath == fs_basepath, don't bother
|
||||
if (Q_stricmp(fs_homepath->string,fs_basepath->string))
|
||||
{
|
||||
// search basepath
|
||||
ospath = FS_BuildOSPath( fs_basepath->string, filename, "" );
|
||||
|
@ -827,8 +826,8 @@ void FS_SV_Rename( const char *from, const char *to ) {
|
|||
// don't let sound stutter
|
||||
S_ClearSoundBuffer();
|
||||
|
||||
from_ospath = FS_BuildOSPath( fs_outputpath->string, from, "" );
|
||||
to_ospath = FS_BuildOSPath( fs_outputpath->string, to, "" );
|
||||
from_ospath = FS_BuildOSPath( fs_homepath->string, from, "" );
|
||||
to_ospath = FS_BuildOSPath( fs_homepath->string, to, "" );
|
||||
from_ospath[strlen(from_ospath)-1] = '\0';
|
||||
to_ospath[strlen(to_ospath)-1] = '\0';
|
||||
|
||||
|
@ -861,8 +860,8 @@ void FS_Rename( const char *from, const char *to ) {
|
|||
// don't let sound stutter
|
||||
S_ClearSoundBuffer();
|
||||
|
||||
from_ospath = FS_BuildOSPath( fs_outputpath->string, fs_gamedir, from );
|
||||
to_ospath = FS_BuildOSPath( fs_outputpath->string, fs_gamedir, to );
|
||||
from_ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, from );
|
||||
to_ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, to );
|
||||
|
||||
if ( fs_debug->integer ) {
|
||||
Com_Printf( "FS_Rename: %s --> %s\n", from_ospath, to_ospath );
|
||||
|
@ -923,7 +922,7 @@ fileHandle_t FS_FOpenFileWrite( const char *filename ) {
|
|||
f = FS_HandleForFile();
|
||||
fsh[f].zipFile = qfalse;
|
||||
|
||||
ospath = FS_BuildOSPath( fs_outputpath->string, fs_gamedir, filename );
|
||||
ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename );
|
||||
|
||||
if ( fs_debug->integer ) {
|
||||
Com_Printf( "FS_FOpenFileWrite: %s\n", ospath );
|
||||
|
@ -962,7 +961,7 @@ fileHandle_t FS_FOpenTextFileWrite( const char *filename ) {
|
|||
|
||||
Q_strncpyz( fsh[f].name, filename, sizeof( fsh[f].name ) );
|
||||
|
||||
ospath = FS_BuildOSPath( fs_outputpath->string, fs_gamedir, filename );
|
||||
ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename );
|
||||
|
||||
if ( fs_debug->integer ) {
|
||||
Com_Printf( "FS_FOpenFileWrite: %s\n", ospath );
|
||||
|
@ -1002,7 +1001,7 @@ fileHandle_t FS_FOpenFileAppend( const char *filename ) {
|
|||
// don't let sound stutter
|
||||
S_ClearSoundBuffer();
|
||||
|
||||
ospath = FS_BuildOSPath( fs_outputpath->string, fs_gamedir, filename );
|
||||
ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename );
|
||||
|
||||
if ( fs_debug->integer ) {
|
||||
Com_Printf( "FS_FOpenFileAppend: %s\n", ospath );
|
||||
|
@ -1084,7 +1083,7 @@ void FS_DeleteFile( const char *filename )
|
|||
Com_Error( 0, "Filesystem call made without initialization\n" );
|
||||
}
|
||||
|
||||
ospath = FS_BuildOSPath( fs_outputpath->string, fs_gamedir, filename );
|
||||
ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename );
|
||||
|
||||
if( fs_debug->integer ) {
|
||||
Com_Printf( "FS_DeleteFile: %s\n", ospath );
|
||||
|
@ -1130,7 +1129,6 @@ Used for streaming data out of either a
|
|||
separate file or a ZIP file.
|
||||
===========
|
||||
*/
|
||||
extern "C" qboolean com_fullyInitialized;
|
||||
|
||||
int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueFILE, qboolean quiet ) {
|
||||
searchpath_t *search;
|
||||
|
@ -1288,7 +1286,7 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dir = search->dir;
|
||||
|
||||
netpath = FS_BuildOSPath( dir->path, dir->gamedir, filename );
|
||||
|
@ -2397,7 +2395,7 @@ int FS_GetModList( char *listbuf, int bufsize ) {
|
|||
nMods = 0;
|
||||
nPotential = nTotal = 0;
|
||||
|
||||
pFiles0 = Sys_ListFiles( fs_outputpath->string, NULL, NULL, &dummy, qtrue );
|
||||
pFiles0 = Sys_ListFiles( fs_homepath->string, NULL, NULL, &dummy, qtrue );
|
||||
pFiles1 = Sys_ListFiles( fs_basepath->string, NULL, NULL, &dummy, qtrue );
|
||||
// we searched for mods in the three paths
|
||||
// it is likely that we have duplicate names now, which we will cleanup below
|
||||
|
@ -2437,7 +2435,7 @@ int FS_GetModList( char *listbuf, int bufsize ) {
|
|||
/* try on home path */
|
||||
if ( nPaks <= 0 )
|
||||
{
|
||||
path = FS_BuildOSPath( fs_outputpath->string, name, "" );
|
||||
path = FS_BuildOSPath( fs_homepath->string, name, "" );
|
||||
nPaks = 0;
|
||||
pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
|
||||
Sys_FreeFileList( pPaks );
|
||||
|
@ -3072,13 +3070,20 @@ FS_Startup
|
|||
*/
|
||||
static void FS_Startup( const char *gameName )
|
||||
{
|
||||
const char* homePath;
|
||||
|
||||
if( !silentStart ) {
|
||||
Com_Printf( "----- FS_Startup -----\n" );
|
||||
}
|
||||
|
||||
fs_debug = Cvar_Get( "fs_debug", "0", 0 );
|
||||
fs_copyfiles = Cvar_Get( "fs_copyfiles", "0", CVAR_INIT );
|
||||
fs_basepath = Cvar_Get ("fs_basepath", Sys_DefaultBasePath(), CVAR_INIT );
|
||||
fs_basepath = Cvar_Get("fs_basepath", Sys_DefaultInstallPath(), CVAR_INIT);
|
||||
homePath = Sys_DefaultHomePath();
|
||||
if (!homePath || !homePath[0]) {
|
||||
homePath = fs_basepath->string;
|
||||
}
|
||||
fs_homepath = Cvar_Get("fs_homepath", homePath, CVAR_INIT | CVAR_ROM);
|
||||
fs_gamedirvar = Cvar_Get( "fs_game", "", CVAR_INIT | CVAR_SYSTEMINFO );
|
||||
fs_restrict = Cvar_Get( "fs_restrict", "", CVAR_INIT );
|
||||
|
||||
|
@ -3097,14 +3102,7 @@ static void FS_Startup( const char *gameName )
|
|||
Cmd_AddCommand ("fdir", FS_NewDir_f );
|
||||
Cmd_AddCommand ("touchFile", FS_TouchFile_f );
|
||||
|
||||
fs_userpath = Cvar_Get( "fs_userpath", Sys_DefaultUserPath(), CVAR_INIT );
|
||||
fs_outputpath = Cvar_Get( "fs_outputpath", Sys_DefaultOutputPath(), CVAR_INIT );
|
||||
|
||||
Sys_Mkdir( fs_userpath->string );
|
||||
Sys_Mkdir( fs_outputpath->string );
|
||||
|
||||
FS_AddGameDirectory( fs_userpath->string, gameName );
|
||||
|
||||
Sys_Mkdir(fs_homepath->string);
|
||||
|
||||
if( !silentStart ) {
|
||||
// print the current search paths
|
||||
|
@ -3593,8 +3591,7 @@ void FS_InitFilesystem( void ) {
|
|||
Com_StartupVariable( "fs_game" );
|
||||
Com_StartupVariable( "fs_copyfiles" );
|
||||
Com_StartupVariable( "fs_restrict" );
|
||||
Com_StartupVariable( "fs_userpath" );
|
||||
Com_StartupVariable( "fs_outputpath" );
|
||||
Com_StartupVariable( "fs_homepath" );
|
||||
|
||||
// try to start up normally
|
||||
FS_Startup( BASEGAME );
|
||||
|
@ -3893,3 +3890,8 @@ void FS_GetRelativeFilename( const char *currentDirectory, const char *absoluteF
|
|||
// copy the rest of the filename into the result string
|
||||
strcpy( &out[ rfMarker ], &absoluteFilename[ afMarker ] );
|
||||
}
|
||||
|
||||
const char* FS_GetCurrentGameDir()
|
||||
{
|
||||
return fs_gamedirvar->string;
|
||||
}
|
||||
|
|
|
@ -220,6 +220,30 @@ void COM_StripExtension( const char *in, char *out, int destsize ) {
|
|||
out[length] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
COM_CompareExtension
|
||||
|
||||
string compare the end of the strings and return qtrue if strings match
|
||||
============
|
||||
*/
|
||||
qboolean COM_CompareExtension(const char* in, const char* ext)
|
||||
{
|
||||
int inlen, extlen;
|
||||
|
||||
inlen = strlen(in);
|
||||
extlen = strlen(ext);
|
||||
|
||||
if (extlen <= inlen)
|
||||
{
|
||||
in += inlen - extlen;
|
||||
|
||||
if (!Q_stricmp(in, ext))
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -1040,34 +1064,86 @@ int Com_HexStrToInt( const char *str )
|
|||
============================================================================
|
||||
*/
|
||||
|
||||
int Q_isprint( int c )
|
||||
int Q_isprint(int c)
|
||||
{
|
||||
if ( c >= 0x20 && c <= 0x7E )
|
||||
return ( 1 );
|
||||
return ( 0 );
|
||||
if (c >= 0x20 && c <= 0x7E)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int Q_islower( int c )
|
||||
int Q_islower(int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return ( 1 );
|
||||
return ( 0 );
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int Q_isupper( int c )
|
||||
int Q_isupper(int c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return ( 1 );
|
||||
return ( 0 );
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int Q_isalpha( int c )
|
||||
int Q_isalpha(int c)
|
||||
{
|
||||
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
|
||||
return ( 1 );
|
||||
return ( 0 );
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
qboolean Q_isanumber(const char* s)
|
||||
{
|
||||
char* p;
|
||||
double d;
|
||||
|
||||
if (*s == '\0')
|
||||
return qfalse;
|
||||
|
||||
d = strtod(s, &p);
|
||||
|
||||
return *p == '\0';
|
||||
}
|
||||
|
||||
qboolean Q_isintegral(float f)
|
||||
{
|
||||
return (int)f == f;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
=============
|
||||
Q_vsnprintf
|
||||
|
||||
Special wrapper function for Microsoft's broken _vsnprintf() function.
|
||||
MinGW comes with its own vsnprintf() which is not broken. mingw-w64
|
||||
however, uses Microsoft's broken _vsnprintf() function.
|
||||
=============
|
||||
*/
|
||||
|
||||
int Q_vsnprintf(char* str, size_t size, const char* format, va_list ap)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = _vsnprintf(str, size, format, ap);
|
||||
|
||||
if (retval < 0 || retval == size)
|
||||
{
|
||||
// Microsoft doesn't adhere to the C99 standard of vsnprintf,
|
||||
// which states that the return value must be the number of
|
||||
// bytes written if the output string had sufficient length.
|
||||
//
|
||||
// Obviously we cannot determine that value from Microsoft's
|
||||
// implementation, so we have no choice but to return size.
|
||||
|
||||
str[size - 1] = '\0';
|
||||
return size;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
char* Q_strrchr( const char* string, int c )
|
||||
{
|
||||
char cc = c;
|
||||
|
@ -1325,24 +1401,18 @@ char *Q_CleanStr( char *string ) {
|
|||
}
|
||||
|
||||
|
||||
void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) {
|
||||
size_t len;
|
||||
int QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) {
|
||||
int len;
|
||||
va_list argptr;
|
||||
char bigbuffer[32000]; // big, but small enough to fit in PPC stack
|
||||
|
||||
va_start (argptr,fmt);
|
||||
len = vsprintf (bigbuffer,fmt,argptr);
|
||||
va_end (argptr);
|
||||
if ( len >= sizeof( bigbuffer ) ) {
|
||||
Com_Error( ERR_FATAL, "Com_sprintf: overflowed bigbuffer" );
|
||||
}
|
||||
if (len >= size) {
|
||||
Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size);
|
||||
#ifdef _DEBUG
|
||||
__debugbreak();
|
||||
#endif
|
||||
}
|
||||
Q_strncpyz (dest, bigbuffer, size );
|
||||
va_start(argptr, fmt);
|
||||
len = Q_vsnprintf(dest, size, fmt, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if (len >= size)
|
||||
Com_Printf("Com_sprintf: Output length %d too short, require %d bytes.\n", size, len + 1);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void Com_BackslashToSlash( char *str )
|
||||
|
|
|
@ -31,6 +31,7 @@ extern "C" {
|
|||
|
||||
#define PRODUCT_NAME "OpenMoHAA"
|
||||
#define PRODUCT_VERSION "0.49-alpha"
|
||||
#define PRODUCT_DATE __DATE__
|
||||
|
||||
#if TARGET_GAME_TYPE == 1
|
||||
// Team Assault
|
||||
|
@ -39,6 +40,10 @@ extern "C" {
|
|||
// The version string must be equal or above 2.0 to be able to connect to spearhead servers
|
||||
#define TARGET_GAME_VERSION "2.41"
|
||||
#define TARGET_GAME_PROTOCOL 17
|
||||
|
||||
#define HOMEPATH_NAME_UNIX ".mohta"
|
||||
#define HOMEPATH_NAME_WIN "mohta"
|
||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
||||
#elif TARGET_GAME_TYPE == 2
|
||||
// Team Tactics
|
||||
#define BASEGAME "maintt"
|
||||
|
@ -46,6 +51,10 @@ extern "C" {
|
|||
// The version string must be equal or above 2.0 to be able to connect to breakthrough servers
|
||||
#define TARGET_GAME_VERSION "2.41"
|
||||
#define TARGET_GAME_PROTOCOL 17
|
||||
|
||||
#define HOMEPATH_NAME_UNIX ".mohtt"
|
||||
#define HOMEPATH_NAME_WIN "mohtt"
|
||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
||||
#else
|
||||
// The default: the base game (no expansion)
|
||||
|
||||
|
@ -54,6 +63,10 @@ extern "C" {
|
|||
// The version string must be below 1.12, otherwise it's not possible to connect
|
||||
#define TARGET_GAME_VERSION "1.12"
|
||||
#define TARGET_GAME_PROTOCOL 8
|
||||
|
||||
#define HOMEPATH_NAME_UNIX ".moh"
|
||||
#define HOMEPATH_NAME_WIN "moh"
|
||||
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
|
||||
#endif
|
||||
|
||||
#define PRODUCT_NAME_FULL PRODUCT_NAME ": " PRODUCT_EXTENSION
|
||||
|
@ -141,28 +154,25 @@ extern "C" {
|
|||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
|
||||
#ifndef _STDINT
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
#endif
|
||||
|
||||
// vsnprintf is ISO/IEC 9899:1999
|
||||
// abstracting this to make it portable
|
||||
int Q_vsnprintf( char *str, size_t size, const char *format, va_list ap );
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
#define Q_vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
#define HAVE_STDINT_H
|
||||
#define _HAVE_STDINT_H 1
|
||||
#ifdef _WIN32
|
||||
// vsnprintf is ISO/IEC 9899:1999
|
||||
// abstracting this to make it portable
|
||||
int Q_vsnprintf(char* str, size_t size, const char* format, va_list ap);
|
||||
#else
|
||||
#define Q_vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1097,6 +1107,7 @@ float Com_Clamp( float min, float max, float value );
|
|||
const char *COM_SkipPath( const char *pathname );
|
||||
const char *COM_GetExtension( const char *name );
|
||||
void COM_StripExtension(const char *in, char *out, int destsize);
|
||||
qboolean COM_CompareExtension(const char* in, const char* ext);
|
||||
void COM_DefaultExtension( char *path, int maxSize, const char *extension );
|
||||
|
||||
void COM_BeginParseSession( const char *name );
|
||||
|
@ -1147,7 +1158,7 @@ void Parse3DMatrix (char **buf_p, int z, int y, int x, float *m);
|
|||
|
||||
int Com_HexStrToInt( const char *str );
|
||||
|
||||
void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
int QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
char *Com_SkipTokens( char *s, int numTokens, char *sep );
|
||||
char *Com_SkipCharset( char *s, char *sep );
|
||||
|
|
|
@ -647,7 +647,7 @@ qboolean FS_FileExists( const char *file );
|
|||
|
||||
char *FS_BuildOSPath( const char *base, const char *game, const char *qpath );
|
||||
|
||||
qboolean FS_CreatePath( char *OSPath );
|
||||
qboolean FS_CreatePath(char *OSPath);
|
||||
|
||||
int FS_LoadStack( void );
|
||||
|
||||
|
@ -767,6 +767,7 @@ void FS_Remove( const char *osPath );
|
|||
void FS_FilenameCompletion( const char *dir, const char *ext,
|
||||
qboolean stripExt, void(*callback)(const char *s) );
|
||||
|
||||
const char* FS_GetCurrentGameDir();
|
||||
void FS_GetRelativeFilename( const char *currentDirectory, const char *absoluteFilename, char *out, size_t destlen );
|
||||
|
||||
extern char fs_gamedir[];
|
||||
|
@ -1098,6 +1099,7 @@ extern cvar_t *com_cameraMode;
|
|||
extern cvar_t *com_ansiColor;
|
||||
extern cvar_t *com_unfocused;
|
||||
extern cvar_t *com_minimized;
|
||||
extern cvar_t *com_homepath;
|
||||
extern cvar_t *com_altivec;
|
||||
|
||||
// both client and server must agree to pause
|
||||
|
@ -1116,6 +1118,7 @@ extern int com_frameTime;
|
|||
extern int com_frameMsec;
|
||||
|
||||
extern qboolean com_errorEntered;
|
||||
extern qboolean com_fullyInitialized;
|
||||
|
||||
extern fileHandle_t com_journalFile;
|
||||
extern fileHandle_t com_journalDataFile;
|
||||
|
@ -1299,6 +1302,14 @@ void SV_Frame( int msec );
|
|||
void SV_PacketEvent( netadr_t from, msg_t *msg );
|
||||
qboolean SV_GameCommand( void );
|
||||
|
||||
//
|
||||
// input interface
|
||||
//
|
||||
void IN_Init(void* windowData);
|
||||
void IN_Frame(void);
|
||||
void IN_Shutdown(void);
|
||||
void IN_Restart(void);
|
||||
|
||||
void Com_Pause();
|
||||
void Com_Unpause();
|
||||
void Com_FakePause();
|
||||
|
@ -1350,10 +1361,10 @@ sysEvent_t Com_GetSystemEvent( void );
|
|||
void Sys_Init (void);
|
||||
|
||||
// general development dll loading for virtual machine testing
|
||||
void * QDECL Sys_LoadDll( const char *name, char *fqpath , intptr_t (QDECL **entryPoint)(int, ...),
|
||||
intptr_t (QDECL *systemcalls)(intptr_t, ...) );
|
||||
void Sys_UnloadDll( void *dllHandle );
|
||||
|
||||
qboolean Sys_DllExtension(const char* name);
|
||||
|
||||
void Sys_UnloadGame( void );
|
||||
void *Sys_GetGameAPI( void *parms );
|
||||
|
||||
|
@ -1369,7 +1380,7 @@ void *Sys_GetBotLibAPI( void *parms );
|
|||
|
||||
char *Sys_GetCurrentUser( void );
|
||||
|
||||
void QDECL SyScriptError( const char *error, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void QDECL Sys_Error( const char *error, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void Sys_Quit (void);
|
||||
char *Sys_GetClipboardData( void ); // note that this isn't journaled...
|
||||
|
||||
|
@ -1399,7 +1410,7 @@ qboolean Sys_StringToAdr( const char *s, netadr_t *a );
|
|||
qboolean Sys_IsLANAddress (netadr_t adr);
|
||||
void Sys_ShowIP(void);
|
||||
|
||||
void Sys_Mkdir( const char *path );
|
||||
qboolean Sys_Mkdir( const char *path );
|
||||
char *Sys_Cwd( void );
|
||||
void Sys_SetDefaultInstallPath(const char *path);
|
||||
char *Sys_DefaultInstallPath( void );
|
||||
|
|
|
@ -26,16 +26,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define MAX_LOG 32768
|
||||
|
||||
static char consoleLog[ MAX_LOG ];
|
||||
static size_t writePos = 0;
|
||||
static size_t readPos = 0;
|
||||
static char consoleLog[ MAX_LOG ];
|
||||
static unsigned int writePos = 0;
|
||||
static unsigned int readPos = 0;
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_LogSize
|
||||
==================
|
||||
*/
|
||||
size_t CON_LogSize( void )
|
||||
unsigned int CON_LogSize( void )
|
||||
{
|
||||
if( readPos <= writePos )
|
||||
return writePos - readPos;
|
||||
|
@ -48,7 +48,7 @@ size_t CON_LogSize( void )
|
|||
CON_LogFree
|
||||
==================
|
||||
*/
|
||||
static size_t CON_LogFree( void )
|
||||
static unsigned int CON_LogFree( void )
|
||||
{
|
||||
return MAX_LOG - CON_LogSize( ) - 1;
|
||||
}
|
||||
|
@ -58,11 +58,11 @@ static size_t CON_LogFree( void )
|
|||
CON_LogWrite
|
||||
==================
|
||||
*/
|
||||
size_t CON_LogWrite( const char *in )
|
||||
unsigned int CON_LogWrite( const char *in )
|
||||
{
|
||||
size_t length = strlen( in );
|
||||
size_t firstChunk;
|
||||
size_t secondChunk;
|
||||
unsigned int length = (unsigned int)strlen( in );
|
||||
unsigned int firstChunk;
|
||||
unsigned int secondChunk;
|
||||
|
||||
while( CON_LogFree( ) < length && CON_LogSize( ) > 0 )
|
||||
{
|
||||
|
@ -101,10 +101,10 @@ size_t CON_LogWrite( const char *in )
|
|||
CON_LogRead
|
||||
==================
|
||||
*/
|
||||
size_t CON_LogRead( char *out, size_t outSize )
|
||||
unsigned int CON_LogRead( char *out, unsigned int outSize )
|
||||
{
|
||||
size_t firstChunk;
|
||||
size_t secondChunk;
|
||||
unsigned int firstChunk;
|
||||
unsigned int secondChunk;
|
||||
|
||||
if( CON_LogSize( ) < outSize )
|
||||
outSize = CON_LogSize( );
|
||||
|
@ -121,7 +121,7 @@ size_t CON_LogRead( char *out, size_t outSize )
|
|||
}
|
||||
|
||||
Com_Memcpy( out, consoleLog + readPos, firstChunk );
|
||||
Com_Memcpy( out + firstChunk, out, secondChunk );
|
||||
Com_Memcpy( out + firstChunk, consoleLog, secondChunk );
|
||||
|
||||
readPos = ( readPos + outSize ) % MAX_LOG;
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/qcommon.h"
|
||||
#include "sys_local.h"
|
||||
|
||||
#ifndef DEDICATED
|
||||
#include "../client/client.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
|
@ -40,9 +44,12 @@ called before and after a stdout or stderr output
|
|||
=============================================================
|
||||
*/
|
||||
|
||||
extern qboolean stdinIsATTY;
|
||||
static qboolean stdin_active;
|
||||
// general flag to tell about tty console mode
|
||||
static qboolean ttycon_on = qfalse;
|
||||
static int ttycon_hide = 0;
|
||||
static int ttycon_show_overdue = 0;
|
||||
|
||||
// some key codes that the terminal may be using, initialised on start up
|
||||
static int TTY_erase;
|
||||
|
@ -58,19 +65,13 @@ static field_t TTY_con;
|
|||
static field_t ttyEditLines[ CON_HISTORY ];
|
||||
static int hist_current = -1, hist_count = 0;
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_FlushIn
|
||||
|
||||
Flush stdin, I suspect some terminals are sending a LOT of shit
|
||||
FIXME relevant?
|
||||
==================
|
||||
*/
|
||||
static void CON_FlushIn( void )
|
||||
{
|
||||
char key;
|
||||
while (read(0, &key, 1)!=-1);
|
||||
}
|
||||
#ifndef DEDICATED
|
||||
// Don't use "]" as it would be the same as in-game console,
|
||||
// this makes it clear where input came from.
|
||||
#define TTY_CONSOLE_PROMPT "tty]"
|
||||
#else
|
||||
#define TTY_CONSOLE_PROMPT "]"
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -86,12 +87,14 @@ send "\b \b"
|
|||
static void CON_Back( void )
|
||||
{
|
||||
char key;
|
||||
size_t UNUSED_VAR size;
|
||||
|
||||
key = '\b';
|
||||
write(1, &key, 1);
|
||||
size = write(STDOUT_FILENO, &key, 1);
|
||||
key = ' ';
|
||||
write(1, &key, 1);
|
||||
size = write(STDOUT_FILENO, &key, 1);
|
||||
key = '\b';
|
||||
write(1, &key, 1);
|
||||
size = write(STDOUT_FILENO, &key, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -119,7 +122,10 @@ static void CON_Hide( void )
|
|||
CON_Back();
|
||||
}
|
||||
}
|
||||
CON_Back(); // Delete "]"
|
||||
// Delete prompt
|
||||
for (i = strlen(TTY_CONSOLE_PROMPT); i > 0; i--) {
|
||||
CON_Back();
|
||||
}
|
||||
ttycon_hide++;
|
||||
}
|
||||
}
|
||||
|
@ -142,12 +148,13 @@ static void CON_Show( void )
|
|||
ttycon_hide--;
|
||||
if (ttycon_hide == 0)
|
||||
{
|
||||
write( 1, "]", 1 );
|
||||
size_t UNUSED_VAR size;
|
||||
size = write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT));
|
||||
if (TTY_con.cursor)
|
||||
{
|
||||
for (i=0; i<TTY_con.cursor; i++)
|
||||
{
|
||||
write(1, TTY_con.buffer+i, 1);
|
||||
size = write(STDOUT_FILENO, TTY_con.buffer+i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,12 +172,12 @@ void CON_Shutdown( void )
|
|||
{
|
||||
if (ttycon_on)
|
||||
{
|
||||
CON_Back(); // Delete "]"
|
||||
tcsetattr (0, TCSADRAIN, &TTY_tc);
|
||||
CON_Hide();
|
||||
tcsetattr (STDIN_FILENO, TCSADRAIN, &TTY_tc);
|
||||
}
|
||||
|
||||
// Restore blocking to stdin reads
|
||||
fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) & ~O_NONBLOCK );
|
||||
// Restore blocking to stdin reads
|
||||
fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) & ~O_NONBLOCK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -181,6 +188,11 @@ Hist_Add
|
|||
void Hist_Add(field_t *field)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Don't save blank lines in history.
|
||||
if (!field->cursor)
|
||||
return;
|
||||
|
||||
assert(hist_count <= CON_HISTORY);
|
||||
assert(hist_count >= 0);
|
||||
assert(hist_current >= -1);
|
||||
|
@ -241,6 +253,19 @@ field_t *Hist_Next( void )
|
|||
return &(ttyEditLines[hist_current]);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_SigCont
|
||||
Reinitialize console input after receiving SIGCONT, as on Linux the terminal seems to lose all
|
||||
set attributes if user did CTRL+Z and then does fg again.
|
||||
==================
|
||||
*/
|
||||
|
||||
void CON_SigCont(int signum)
|
||||
{
|
||||
CON_Init();
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Init
|
||||
|
@ -257,18 +282,22 @@ void CON_Init( void )
|
|||
signal(SIGTTIN, SIG_IGN);
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
|
||||
// Make stdin reads non-blocking
|
||||
fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) | O_NONBLOCK );
|
||||
// If SIGCONT is received, reinitialize console
|
||||
signal(SIGCONT, CON_SigCont);
|
||||
|
||||
if (isatty(STDIN_FILENO)!=1)
|
||||
// Make stdin reads non-blocking
|
||||
fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK );
|
||||
|
||||
if (!stdinIsATTY)
|
||||
{
|
||||
Com_Printf( "stdin is not a tty, tty console mode disabled\n");
|
||||
Com_Printf("tty console mode disabled\n");
|
||||
ttycon_on = qfalse;
|
||||
stdin_active = qtrue;
|
||||
return;
|
||||
}
|
||||
|
||||
Field_Clear(&TTY_con);
|
||||
tcgetattr (0, &TTY_tc);
|
||||
tcgetattr (STDIN_FILENO, &TTY_tc);
|
||||
TTY_erase = TTY_tc.c_cc[VERASE];
|
||||
TTY_eof = TTY_tc.c_cc[VEOF];
|
||||
tc = TTY_tc;
|
||||
|
@ -279,8 +308,7 @@ void CON_Init( void )
|
|||
characters EOF, EOL, EOL2, ERASE, KILL, REPRINT,
|
||||
STATUS, and WERASE, and buffers by lines.
|
||||
ISIG: when any of the characters INTR, QUIT, SUSP, or
|
||||
DSUSP are received, generate the corresponding sig
|
||||
nal
|
||||
DSUSP are received, generate the corresponding signal
|
||||
*/
|
||||
tc.c_lflag &= ~(ECHO | ICANON);
|
||||
|
||||
|
@ -291,8 +319,10 @@ void CON_Init( void )
|
|||
tc.c_iflag &= ~(ISTRIP | INPCK);
|
||||
tc.c_cc[VMIN] = 1;
|
||||
tc.c_cc[VTIME] = 0;
|
||||
tcsetattr (0, TCSADRAIN, &tc);
|
||||
tcsetattr (STDIN_FILENO, TCSADRAIN, &tc);
|
||||
ttycon_on = qtrue;
|
||||
ttycon_hide = 1; // Mark as hidden, so prompt is shown in CON_Show
|
||||
CON_Show();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -303,14 +333,15 @@ CON_Input
|
|||
char *CON_Input( void )
|
||||
{
|
||||
// we use this when sending back commands
|
||||
static char text[256];
|
||||
static char text[MAX_EDIT_LINE];
|
||||
int avail;
|
||||
char key;
|
||||
field_t *history;
|
||||
size_t UNUSED_VAR size;
|
||||
|
||||
if( ttycon_on )
|
||||
if(ttycon_on)
|
||||
{
|
||||
avail = read(0, &key, 1);
|
||||
avail = read(STDIN_FILENO, &key, 1);
|
||||
if (avail != -1)
|
||||
{
|
||||
// we have something
|
||||
|
@ -331,13 +362,43 @@ char *CON_Input( void )
|
|||
{
|
||||
if (key == '\n')
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
// if not in the game explicitly prepend a slash if needed
|
||||
if (clc.state != CA_ACTIVE && con_autochat->integer && TTY_con.cursor &&
|
||||
TTY_con.buffer[0] != '/' && TTY_con.buffer[0] != '\\')
|
||||
{
|
||||
memmove(TTY_con.buffer + 1, TTY_con.buffer, sizeof(TTY_con.buffer) - 1);
|
||||
TTY_con.buffer[0] = '\\';
|
||||
TTY_con.cursor++;
|
||||
}
|
||||
|
||||
if (TTY_con.buffer[0] == '/' || TTY_con.buffer[0] == '\\') {
|
||||
Q_strncpyz(text, TTY_con.buffer + 1, sizeof(text));
|
||||
} else if (TTY_con.cursor) {
|
||||
if (con_autochat->integer) {
|
||||
Com_sprintf(text, sizeof(text), "cmd say %s", TTY_con.buffer);
|
||||
} else {
|
||||
Q_strncpyz(text, TTY_con.buffer, sizeof(text));
|
||||
}
|
||||
} else {
|
||||
text[0] = '\0';
|
||||
}
|
||||
|
||||
// push it in history
|
||||
Hist_Add(&TTY_con);
|
||||
strcpy(text, TTY_con.buffer);
|
||||
CON_Hide();
|
||||
Com_Printf("%s%s\n", TTY_CONSOLE_PROMPT, TTY_con.buffer);
|
||||
Field_Clear(&TTY_con);
|
||||
CON_Show();
|
||||
#else
|
||||
// push it in history
|
||||
Hist_Add(&TTY_con);
|
||||
Q_strncpyz(text, TTY_con.buffer, sizeof(text));
|
||||
Field_Clear(&TTY_con);
|
||||
key = '\n';
|
||||
write(1, &key, 1);
|
||||
write( 1, "]", 1 );
|
||||
size = write(STDOUT_FILENO, &key, 1);
|
||||
size = write(STDOUT_FILENO, TTY_CONSOLE_PROMPT, strlen(TTY_CONSOLE_PROMPT));
|
||||
#endif
|
||||
return text;
|
||||
}
|
||||
if (key == '\t')
|
||||
|
@ -347,13 +408,13 @@ char *CON_Input( void )
|
|||
CON_Show();
|
||||
return NULL;
|
||||
}
|
||||
avail = read(0, &key, 1);
|
||||
avail = read(STDIN_FILENO, &key, 1);
|
||||
if (avail != -1)
|
||||
{
|
||||
// VT 100 keys
|
||||
if (key == '[' || key == 'O')
|
||||
{
|
||||
avail = read(0, &key, 1);
|
||||
avail = read(STDIN_FILENO, &key, 1);
|
||||
if (avail != -1)
|
||||
{
|
||||
switch (key)
|
||||
|
@ -366,7 +427,7 @@ char *CON_Input( void )
|
|||
TTY_con = *history;
|
||||
CON_Show();
|
||||
}
|
||||
CON_FlushIn();
|
||||
tcflush(STDIN_FILENO, TCIFLUSH);
|
||||
return NULL;
|
||||
break;
|
||||
case 'B':
|
||||
|
@ -380,7 +441,7 @@ char *CON_Input( void )
|
|||
Field_Clear(&TTY_con);
|
||||
}
|
||||
CON_Show();
|
||||
CON_FlushIn();
|
||||
tcflush(STDIN_FILENO, TCIFLUSH);
|
||||
return NULL;
|
||||
break;
|
||||
case 'C':
|
||||
|
@ -392,41 +453,34 @@ char *CON_Input( void )
|
|||
}
|
||||
}
|
||||
Com_DPrintf("droping ISCTL sequence: %d, TTY_erase: %d\n", key, TTY_erase);
|
||||
CON_FlushIn();
|
||||
tcflush(STDIN_FILENO, TCIFLUSH);
|
||||
return NULL;
|
||||
}
|
||||
if (TTY_con.cursor >= sizeof(text) - 1)
|
||||
return NULL;
|
||||
// push regular character
|
||||
TTY_con.buffer[TTY_con.cursor] = key;
|
||||
TTY_con.cursor++;
|
||||
TTY_con.cursor++; // next char will always be '\0'
|
||||
// print the current line (this is differential)
|
||||
write(1, &key, 1);
|
||||
size = write(STDOUT_FILENO, &key, 1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
else if (stdin_active)
|
||||
{
|
||||
int len;
|
||||
fd_set fdset;
|
||||
struct timeval timeout;
|
||||
static qboolean stdin_active;
|
||||
|
||||
if (!com_dedicated || !com_dedicated->value)
|
||||
return NULL;
|
||||
|
||||
if (!stdin_active)
|
||||
return NULL;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(0, &fdset); // stdin
|
||||
FD_SET(STDIN_FILENO, &fdset); // stdin
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
|
||||
{
|
||||
if(select (STDIN_FILENO + 1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(STDIN_FILENO, &fdset))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = read (0, text, sizeof(text));
|
||||
len = read(STDIN_FILENO, text, sizeof(text));
|
||||
if (len == 0)
|
||||
{ // eof!
|
||||
stdin_active = qfalse;
|
||||
|
@ -439,6 +493,7 @@ char *CON_Input( void )
|
|||
|
||||
return text;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -448,6 +503,9 @@ CON_Print
|
|||
*/
|
||||
void CON_Print( const char *msg )
|
||||
{
|
||||
if (!msg[0])
|
||||
return;
|
||||
|
||||
CON_Hide( );
|
||||
|
||||
if( com_ansiColor && com_ansiColor->integer )
|
||||
|
@ -455,5 +513,25 @@ void CON_Print( const char *msg )
|
|||
else
|
||||
fputs( msg, stderr );
|
||||
|
||||
CON_Show( );
|
||||
if (!ttycon_on) {
|
||||
// CON_Hide didn't do anything.
|
||||
return;
|
||||
}
|
||||
|
||||
// Only print prompt when msg ends with a newline, otherwise the console
|
||||
// might get garbled when output does not fit on one line.
|
||||
if (msg[strlen(msg) - 1] == '\n') {
|
||||
CON_Show();
|
||||
|
||||
// Run CON_Show the number of times it was deferred.
|
||||
while (ttycon_show_overdue > 0) {
|
||||
CON_Show();
|
||||
ttycon_show_overdue--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Defer calling CON_Show
|
||||
ttycon_show_overdue++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define QCONSOLE_HISTORY 32
|
||||
|
||||
static WORD qconsole_attrib;
|
||||
static WORD qconsole_backgroundAttrib;
|
||||
|
||||
// saved console status
|
||||
static DWORD qconsole_orig_mode;
|
||||
|
@ -36,15 +37,50 @@ static CONSOLE_CURSOR_INFO qconsole_orig_cursorinfo;
|
|||
// cmd history
|
||||
static char qconsole_history[ QCONSOLE_HISTORY ][ MAX_EDIT_LINE ];
|
||||
static int qconsole_history_pos = -1;
|
||||
static int qconsole_history_lines = 0;
|
||||
static int qconsole_history_oldest = 0;
|
||||
|
||||
// current edit buffer
|
||||
static char qconsole_line[ MAX_EDIT_LINE ];
|
||||
static size_t qconsole_linelen = 0;
|
||||
static int qconsole_linelen = 0;
|
||||
static qboolean qconsole_drawinput = qtrue;
|
||||
static int qconsole_cursor;
|
||||
|
||||
static HANDLE qconsole_hout;
|
||||
static HANDLE qconsole_hin;
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_ColorCharToAttrib
|
||||
|
||||
Convert Quake color character to Windows text attrib
|
||||
==================
|
||||
*/
|
||||
static WORD CON_ColorCharToAttrib( char color ) {
|
||||
WORD attrib;
|
||||
|
||||
if ( color == COLOR_WHITE )
|
||||
{
|
||||
// use console's foreground and background colors
|
||||
attrib = qconsole_attrib;
|
||||
}
|
||||
else
|
||||
{
|
||||
float *rgba = g_color_table[ ColorIndex( color ) ];
|
||||
|
||||
// set foreground color
|
||||
attrib = ( rgba[0] >= 0.5 ? FOREGROUND_RED : 0 ) |
|
||||
( rgba[1] >= 0.5 ? FOREGROUND_GREEN : 0 ) |
|
||||
( rgba[2] >= 0.5 ? FOREGROUND_BLUE : 0 ) |
|
||||
( rgba[3] >= 0.5 ? FOREGROUND_INTENSITY : 0 );
|
||||
|
||||
// use console's background color
|
||||
attrib |= qconsole_backgroundAttrib;
|
||||
}
|
||||
|
||||
return attrib;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_CtrlHandler
|
||||
|
@ -73,6 +109,9 @@ static void CON_HistAdd( void )
|
|||
Q_strncpyz( qconsole_history[ qconsole_history_oldest ], qconsole_line,
|
||||
sizeof( qconsole_history[ qconsole_history_oldest ] ) );
|
||||
|
||||
if( qconsole_history_lines < QCONSOLE_HISTORY )
|
||||
qconsole_history_lines++;
|
||||
|
||||
if( qconsole_history_oldest >= QCONSOLE_HISTORY - 1 )
|
||||
qconsole_history_oldest = 0;
|
||||
else
|
||||
|
@ -94,13 +133,14 @@ static void CON_HistPrev( void )
|
|||
( QCONSOLE_HISTORY - 1 ) : ( qconsole_history_pos - 1 );
|
||||
|
||||
// don' t allow looping through history
|
||||
if( pos == qconsole_history_oldest )
|
||||
if( pos == qconsole_history_oldest || pos >= qconsole_history_lines )
|
||||
return;
|
||||
|
||||
qconsole_history_pos = pos;
|
||||
Q_strncpyz( qconsole_line, qconsole_history[ qconsole_history_pos ],
|
||||
sizeof( qconsole_line ) );
|
||||
qconsole_linelen = strlen( qconsole_line );
|
||||
qconsole_cursor = qconsole_linelen;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -112,14 +152,20 @@ static void CON_HistNext( void )
|
|||
{
|
||||
int pos;
|
||||
|
||||
// don' t allow looping through history
|
||||
if( qconsole_history_pos == qconsole_history_oldest )
|
||||
return;
|
||||
|
||||
pos = ( qconsole_history_pos >= QCONSOLE_HISTORY - 1 ) ?
|
||||
0 : ( qconsole_history_pos + 1 );
|
||||
|
||||
// clear the edit buffer if they try to advance to a future command
|
||||
if( pos == qconsole_history_oldest )
|
||||
{
|
||||
qconsole_history_pos = pos;
|
||||
qconsole_line[ 0 ] = '\0';
|
||||
qconsole_linelen = 0;
|
||||
qconsole_cursor = qconsole_linelen;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -127,6 +173,7 @@ static void CON_HistNext( void )
|
|||
Q_strncpyz( qconsole_line, qconsole_history[ qconsole_history_pos ],
|
||||
sizeof( qconsole_line ) );
|
||||
qconsole_linelen = strlen( qconsole_line );
|
||||
qconsole_cursor = qconsole_linelen;
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,13 +188,15 @@ static void CON_Show( void )
|
|||
COORD writeSize = { MAX_EDIT_LINE, 1 };
|
||||
COORD writePos = { 0, 0 };
|
||||
SMALL_RECT writeArea = { 0, 0, 0, 0 };
|
||||
COORD cursorPos;
|
||||
int i;
|
||||
CHAR_INFO line[ MAX_EDIT_LINE ];
|
||||
WORD attrib;
|
||||
|
||||
GetConsoleScreenBufferInfo( qconsole_hout, &binfo );
|
||||
|
||||
// if we're in the middle of printf, don't bother writing the buffer
|
||||
if( binfo.dwCursorPosition.X != 0 )
|
||||
if( !qconsole_drawinput )
|
||||
return;
|
||||
|
||||
writeArea.Left = 0;
|
||||
|
@ -155,15 +204,23 @@ static void CON_Show( void )
|
|||
writeArea.Bottom = binfo.dwCursorPosition.Y;
|
||||
writeArea.Right = MAX_EDIT_LINE;
|
||||
|
||||
// set color to white
|
||||
attrib = CON_ColorCharToAttrib( COLOR_WHITE );
|
||||
|
||||
// build a space-padded CHAR_INFO array
|
||||
for( i = 0; i < MAX_EDIT_LINE; i++ )
|
||||
{
|
||||
if( i < qconsole_linelen )
|
||||
{
|
||||
if( i + 1 < qconsole_linelen && Q_IsColorString( qconsole_line + i ) )
|
||||
attrib = CON_ColorCharToAttrib( *( qconsole_line + i + 1 ) );
|
||||
|
||||
line[ i ].Char.AsciiChar = qconsole_line[ i ];
|
||||
}
|
||||
else
|
||||
line[ i ].Char.AsciiChar = ' ';
|
||||
|
||||
line[ i ].Attributes = qconsole_attrib;
|
||||
line[ i ].Attributes = attrib;
|
||||
}
|
||||
|
||||
if( qconsole_linelen > binfo.srWindow.Right )
|
||||
|
@ -177,8 +234,37 @@ static void CON_Show( void )
|
|||
WriteConsoleOutput( qconsole_hout, line, writeSize,
|
||||
writePos, &writeArea );
|
||||
}
|
||||
|
||||
// set curor position
|
||||
cursorPos.Y = binfo.dwCursorPosition.Y;
|
||||
cursorPos.X = qconsole_cursor < qconsole_linelen
|
||||
? qconsole_cursor
|
||||
: qconsole_linelen > binfo.srWindow.Right
|
||||
? binfo.srWindow.Right
|
||||
: qconsole_linelen;
|
||||
|
||||
SetConsoleCursorPosition( qconsole_hout, cursorPos );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Hide
|
||||
==================
|
||||
*/
|
||||
static void CON_Hide( void )
|
||||
{
|
||||
int realLen;
|
||||
|
||||
realLen = qconsole_linelen;
|
||||
|
||||
// remove input line from console output buffer
|
||||
qconsole_linelen = 0;
|
||||
CON_Show( );
|
||||
|
||||
qconsole_linelen = realLen;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Shutdown
|
||||
|
@ -186,8 +272,10 @@ CON_Shutdown
|
|||
*/
|
||||
void CON_Shutdown( void )
|
||||
{
|
||||
CON_Hide( );
|
||||
SetConsoleMode( qconsole_hin, qconsole_orig_mode );
|
||||
SetConsoleCursorInfo( qconsole_hout, &qconsole_orig_cursorinfo );
|
||||
SetConsoleTextAttribute( qconsole_hout, qconsole_attrib );
|
||||
CloseHandle( qconsole_hout );
|
||||
CloseHandle( qconsole_hin );
|
||||
}
|
||||
|
@ -199,7 +287,6 @@ CON_Init
|
|||
*/
|
||||
void CON_Init( void )
|
||||
{
|
||||
CONSOLE_CURSOR_INFO curs;
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
int i;
|
||||
|
||||
|
@ -224,18 +311,16 @@ void CON_Init( void )
|
|||
|
||||
GetConsoleScreenBufferInfo( qconsole_hout, &info );
|
||||
qconsole_attrib = info.wAttributes;
|
||||
qconsole_backgroundAttrib = qconsole_attrib & (BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_INTENSITY);
|
||||
|
||||
SetConsoleTitle(CLIENT_WINDOW_TITLE " Dedicated Server Console");
|
||||
|
||||
// make cursor invisible
|
||||
GetConsoleCursorInfo( qconsole_hout, &qconsole_orig_cursorinfo );
|
||||
curs.dwSize = 1;
|
||||
curs.bVisible = FALSE;
|
||||
SetConsoleCursorInfo( qconsole_hout, &curs );
|
||||
|
||||
// initialize history
|
||||
for( i = 0; i < QCONSOLE_HISTORY; i++ )
|
||||
qconsole_history[ i ][ 0 ] = '\0';
|
||||
|
||||
// set text color to white
|
||||
SetConsoleTextAttribute( qconsole_hout, CON_ColorCharToAttrib( COLOR_WHITE ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -281,6 +366,7 @@ char *CON_Input( void )
|
|||
if( key == VK_RETURN )
|
||||
{
|
||||
newlinepos = i;
|
||||
qconsole_cursor = 0;
|
||||
break;
|
||||
}
|
||||
else if( key == VK_UP )
|
||||
|
@ -293,6 +379,34 @@ char *CON_Input( void )
|
|||
CON_HistNext();
|
||||
break;
|
||||
}
|
||||
else if( key == VK_LEFT )
|
||||
{
|
||||
qconsole_cursor--;
|
||||
if ( qconsole_cursor < 0 )
|
||||
{
|
||||
qconsole_cursor = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if( key == VK_RIGHT )
|
||||
{
|
||||
qconsole_cursor++;
|
||||
if ( qconsole_cursor > qconsole_linelen )
|
||||
{
|
||||
qconsole_cursor = qconsole_linelen;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if( key == VK_HOME )
|
||||
{
|
||||
qconsole_cursor = 0;
|
||||
break;
|
||||
}
|
||||
else if( key == VK_END )
|
||||
{
|
||||
qconsole_cursor = qconsole_linelen;
|
||||
break;
|
||||
}
|
||||
else if( key == VK_TAB )
|
||||
{
|
||||
field_t f;
|
||||
|
@ -303,6 +417,7 @@ char *CON_Input( void )
|
|||
Q_strncpyz( qconsole_line, f.buffer,
|
||||
sizeof( qconsole_line ) );
|
||||
qconsole_linelen = strlen( qconsole_line );
|
||||
qconsole_cursor = qconsole_linelen;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -312,15 +427,33 @@ char *CON_Input( void )
|
|||
|
||||
if( key == VK_BACK )
|
||||
{
|
||||
size_t pos = ( qconsole_linelen > 0 ) ?
|
||||
qconsole_linelen - 1 : 0;
|
||||
if ( qconsole_cursor > 0 )
|
||||
{
|
||||
int newlen = ( qconsole_linelen > 0 ) ? qconsole_linelen - 1 : 0;
|
||||
if ( qconsole_cursor < qconsole_linelen )
|
||||
{
|
||||
memmove( qconsole_line + qconsole_cursor - 1,
|
||||
qconsole_line + qconsole_cursor,
|
||||
qconsole_linelen - qconsole_cursor );
|
||||
}
|
||||
|
||||
qconsole_line[ pos ] = '\0';
|
||||
qconsole_linelen = pos;
|
||||
qconsole_line[ newlen ] = '\0';
|
||||
qconsole_linelen = newlen;
|
||||
qconsole_cursor--;
|
||||
}
|
||||
}
|
||||
else if( c )
|
||||
{
|
||||
qconsole_line[ qconsole_linelen++ ] = c;
|
||||
if ( qconsole_linelen > qconsole_cursor )
|
||||
{
|
||||
memmove( qconsole_line + qconsole_cursor + 1,
|
||||
qconsole_line + qconsole_cursor,
|
||||
qconsole_linelen - qconsole_cursor );
|
||||
}
|
||||
|
||||
qconsole_line[ qconsole_cursor++ ] = c;
|
||||
|
||||
qconsole_linelen++;
|
||||
qconsole_line[ qconsole_linelen ] = '\0';
|
||||
}
|
||||
}
|
||||
|
@ -338,15 +471,74 @@ char *CON_Input( void )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
CON_HistAdd();
|
||||
Com_Printf( "%s\n", qconsole_line );
|
||||
|
||||
qconsole_linelen = 0;
|
||||
CON_Show();
|
||||
|
||||
CON_HistAdd();
|
||||
Com_Printf( "%s\n", qconsole_line );
|
||||
|
||||
return qconsole_line;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CON_WindowsColorPrint
|
||||
|
||||
Set text colors based on Q3 color codes
|
||||
=================
|
||||
*/
|
||||
void CON_WindowsColorPrint( const char *msg )
|
||||
{
|
||||
static char buffer[ MAXPRINTMSG ];
|
||||
int length = 0;
|
||||
|
||||
while( *msg )
|
||||
{
|
||||
qconsole_drawinput = ( *msg == '\n' );
|
||||
|
||||
if( Q_IsColorString( msg ) || *msg == '\n' )
|
||||
{
|
||||
// First empty the buffer
|
||||
if( length > 0 )
|
||||
{
|
||||
buffer[ length ] = '\0';
|
||||
fputs( buffer, stderr );
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if( *msg == '\n' )
|
||||
{
|
||||
// Reset color and then add the newline
|
||||
SetConsoleTextAttribute( qconsole_hout, CON_ColorCharToAttrib( COLOR_WHITE ) );
|
||||
fputs( "\n", stderr );
|
||||
msg++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the color
|
||||
SetConsoleTextAttribute( qconsole_hout, CON_ColorCharToAttrib( *( msg + 1 ) ) );
|
||||
msg += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( length >= MAXPRINTMSG - 1 )
|
||||
break;
|
||||
|
||||
buffer[ length ] = *msg;
|
||||
length++;
|
||||
msg++;
|
||||
}
|
||||
}
|
||||
|
||||
// Empty anything still left in the buffer
|
||||
if( length > 0 )
|
||||
{
|
||||
buffer[ length ] = '\0';
|
||||
fputs( buffer, stderr );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CON_Print
|
||||
|
@ -354,7 +546,9 @@ CON_Print
|
|||
*/
|
||||
void CON_Print( const char *msg )
|
||||
{
|
||||
fputs( msg, stderr );
|
||||
CON_Hide( );
|
||||
|
||||
CON_WindowsColorPrint( msg );
|
||||
|
||||
CON_Show( );
|
||||
}
|
||||
|
|
86
code/sys/sys_autoupdater.c
Normal file
86
code/sys/sys_autoupdater.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
The code in this file is in the public domain. The rest of ioquake3
|
||||
is licensed under the GPLv2. Do not mingle code, please!
|
||||
*/
|
||||
|
||||
#ifdef USE_AUTOUPDATER
|
||||
# ifndef AUTOUPDATER_BIN
|
||||
# error The build system should have defined AUTOUPDATER_BIN
|
||||
# endif
|
||||
|
||||
# ifdef _WIN32
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# include <windows.h>
|
||||
# else
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
void Sys_LaunchAutoupdater(int argc, char **argv)
|
||||
{
|
||||
#ifdef USE_AUTOUPDATER
|
||||
#ifdef _WIN32
|
||||
{
|
||||
/* We don't need the Unix pipe() tapdance here because Windows lets children wait on parent processes. */
|
||||
PROCESS_INFORMATION procinfo;
|
||||
STARTUPINFO startinfo;
|
||||
char cmdline[128];
|
||||
memset(&procinfo, '\0', sizeof (procinfo));
|
||||
memset(&startinfo, '\0', sizeof (startinfo));
|
||||
startinfo.cb = sizeof (startinfo);
|
||||
sprintf(cmdline, "" AUTOUPDATER_BIN " --waitpid %u", (unsigned int) GetCurrentProcessId());
|
||||
|
||||
if (CreateProcessA(AUTOUPDATER_BIN, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startinfo, &procinfo))
|
||||
{
|
||||
/* close handles now so child cleans up immediately if nothing to do */
|
||||
CloseHandle(procinfo.hProcess);
|
||||
CloseHandle(procinfo.hThread);
|
||||
}
|
||||
}
|
||||
#else
|
||||
int updater_pipes[2];
|
||||
if (pipe(updater_pipes) == 0)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) /* failure, oh well. */
|
||||
{
|
||||
close(updater_pipes[0]);
|
||||
close(updater_pipes[1]);
|
||||
}
|
||||
else if (pid == 0) /* child process */
|
||||
{
|
||||
close(updater_pipes[1]); /* don't need write end. */
|
||||
if (dup2(updater_pipes[0], 3) != -1)
|
||||
{
|
||||
char pidstr[64];
|
||||
char *ptr = strrchr(argv[0], '/');
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
if (chdir(argv[0]) == -1) {
|
||||
_exit(1); /* oh well. */
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
if (chdir("../..") == -1) { /* put this at base of app bundle so paths make sense later. */
|
||||
_exit(1); /* oh well. */
|
||||
}
|
||||
#endif
|
||||
snprintf(pidstr, sizeof (pidstr), "%lld", (long long) getppid());
|
||||
execl(AUTOUPDATER_BIN, AUTOUPDATER_BIN, "--waitpid", pidstr, NULL);
|
||||
}
|
||||
_exit(0); /* oh well. */
|
||||
}
|
||||
else /* parent process */
|
||||
{
|
||||
/* leave the write end open until we terminate so updater can block on it. */
|
||||
close(updater_pipes[0]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
(void) argc; (void) argv; /* possibly unused. Pacify compilers. */
|
||||
}
|
||||
|
|
@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef DEDICATED
|
||||
# ifdef _WIN32
|
||||
# include <windows.h>
|
||||
|
@ -33,12 +35,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
# define Sys_UnloadLibrary(h) dlclose(h)
|
||||
# define Sys_LoadFunction(h,fn) dlsym(h,fn)
|
||||
# define Sys_LibraryError() dlerror()
|
||||
#endif
|
||||
# endif
|
||||
#else
|
||||
# include "SDL.h"
|
||||
# include "SDL_loadso.h"
|
||||
# ifdef USE_LOCAL_HEADERS
|
||||
# include "SDL.h"
|
||||
# include "SDL_loadso.h"
|
||||
# else
|
||||
# include <SDL.h>
|
||||
# include <SDL_loadso.h>
|
||||
# endif
|
||||
# define Sys_LoadLibrary(f) SDL_LoadObject(f)
|
||||
# define Sys_UnloadLibrary(h) SDL_UnloadObject(h)
|
||||
# define Sys_LoadFunction(h,fn) SDL_LoadFunction(h,fn)
|
||||
# define Sys_LibraryError() SDL_GetError()
|
||||
#endif
|
||||
|
||||
void * QDECL Sys_LoadDll(const char *name, qboolean useSystemLib);
|
||||
|
|
|
@ -23,20 +23,22 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/q_shared.h"
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#ifndef DEDICATED
|
||||
#ifdef USE_LOCAL_HEADERS
|
||||
# include "SDL_version.h"
|
||||
#else
|
||||
# include <SDL_version.h>
|
||||
#endif
|
||||
|
||||
// Require a minimum version of SDL
|
||||
#define MINSDL_MAJOR 1
|
||||
#define MINSDL_MINOR 2
|
||||
#define MINSDL_PATCH 7
|
||||
|
||||
// Input subsystem
|
||||
void IN_Init( void *windowData );
|
||||
void IN_Frame( void );
|
||||
void IN_Shutdown( void );
|
||||
void IN_Restart( void );
|
||||
#define MINSDL_MAJOR 2
|
||||
#define MINSDL_MINOR 0
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 5 )
|
||||
#define MINSDL_PATCH 5
|
||||
#else
|
||||
#define MINSDL_PATCH 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Console
|
||||
void CON_Shutdown( void );
|
||||
|
@ -44,18 +46,21 @@ void CON_Init( void );
|
|||
char *CON_Input( void );
|
||||
void CON_Print( const char *message );
|
||||
|
||||
size_t CON_LogSize( void );
|
||||
size_t CON_LogWrite( const char *in );
|
||||
size_t CON_LogRead( char *out, size_t outSize );
|
||||
unsigned int CON_LogSize( void );
|
||||
unsigned int CON_LogWrite( const char *in );
|
||||
unsigned int CON_LogRead( char *out, unsigned int outSize );
|
||||
|
||||
#ifdef MACOS_X
|
||||
#ifdef __APPLE__
|
||||
char *Sys_StripAppBundle( char *pwd );
|
||||
#endif
|
||||
|
||||
void Sys_SigHandler( int signal );
|
||||
void Sys_GLimpSafeInit( void );
|
||||
void Sys_GLimpInit( void );
|
||||
void Sys_PlatformInit( void );
|
||||
void Sys_PlatformExit( void );
|
||||
void Sys_SigHandler( int signal ) __attribute__ ((noreturn));
|
||||
void Sys_ErrorDialog( const char *error );
|
||||
void Sys_AnsiColorPrint( const char *msg );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
int Sys_PID( void );
|
||||
qboolean Sys_PIDIsRunning( int pid );
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/qcommon.h"
|
||||
#include "sys_local.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
@ -34,10 +35,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include <sys/time.h>
|
||||
#include <pwd.h>
|
||||
#include <libgen.h>
|
||||
#include <fcntl.h>
|
||||
#include <fenv.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
qboolean stdinIsATTY;
|
||||
|
||||
// Used to determine where to store user-specific files
|
||||
static char homePath[ MAX_OSPATH ] = { 0 };
|
||||
|
||||
// Used to store the Steam Quake 3 installation path
|
||||
static char steamPath[ MAX_OSPATH ] = { 0 };
|
||||
|
||||
// Used to store the GOG Quake 3 installation path
|
||||
static char gogPath[ MAX_OSPATH ] = { 0 };
|
||||
|
||||
// Used to store the Microsoft Store Quake 3 installation path
|
||||
static char microsoftStorePath[MAX_OSPATH] = { 0 };
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_DefaultHomePath
|
||||
|
@ -47,30 +62,79 @@ char *Sys_DefaultHomePath(void)
|
|||
{
|
||||
char *p;
|
||||
|
||||
if( !*homePath )
|
||||
if( !*homePath && com_homepath != NULL )
|
||||
{
|
||||
if( ( p = getenv( "HOME" ) ) != NULL )
|
||||
{
|
||||
Q_strncpyz( homePath, p, sizeof( homePath ) );
|
||||
#ifdef MACOS_X
|
||||
Q_strcat( homePath, sizeof( homePath ), "/Library/Application Support/OpenMoHAA" );
|
||||
Com_sprintf(homePath, sizeof(homePath), "%s%c", p, PATH_SEP);
|
||||
#ifdef __APPLE__
|
||||
Q_strcat(homePath, sizeof(homePath),
|
||||
"Library/Application Support/");
|
||||
|
||||
if(com_homepath->string[0])
|
||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||
else
|
||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
|
||||
#else
|
||||
Q_strcat( homePath, sizeof( homePath ), "/.openmohaa" );
|
||||
if(com_homepath->string[0])
|
||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||
else
|
||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_UNIX);
|
||||
#endif
|
||||
if( mkdir( homePath, 0777 ) )
|
||||
{
|
||||
if( errno != EEXIST )
|
||||
{
|
||||
Com_Error( "Unable to create directory \"%s\", error is %s(%d)\n",
|
||||
homePath, strerror( errno ), errno );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return homePath;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_SteamPath
|
||||
================
|
||||
*/
|
||||
char *Sys_SteamPath( void )
|
||||
{
|
||||
// Disabled since Steam doesn't let you install Quake 3 on Mac/Linux
|
||||
#if 0 //#ifdef STEAMPATH_NAME
|
||||
char *p;
|
||||
|
||||
if( ( p = getenv( "HOME" ) ) != NULL )
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
char *steamPathEnd = "/Library/Application Support/Steam/SteamApps/common/" STEAMPATH_NAME;
|
||||
#else
|
||||
char *steamPathEnd = "/.steam/steam/SteamApps/common/" STEAMPATH_NAME;
|
||||
#endif
|
||||
Com_sprintf(steamPath, sizeof(steamPath), "%s%s", p, steamPathEnd);
|
||||
}
|
||||
#endif
|
||||
|
||||
return steamPath;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_GogPath
|
||||
================
|
||||
*/
|
||||
char *Sys_GogPath( void )
|
||||
{
|
||||
// GOG also doesn't let you install Quake 3 on Mac/Linux
|
||||
return gogPath;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_MicrosoftStorePath
|
||||
================
|
||||
*/
|
||||
char* Sys_MicrosoftStorePath(void)
|
||||
{
|
||||
// Microsoft Store doesn't exist on Mac/Linux
|
||||
return microsoftStorePath;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Milliseconds
|
||||
|
@ -78,8 +142,7 @@ Sys_Milliseconds
|
|||
*/
|
||||
/* base time in seconds, that's our origin
|
||||
timeval:tv_sec is an int:
|
||||
assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038
|
||||
using unsigned long data type to work right with Sys_XTimeToSysTime */
|
||||
assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038 */
|
||||
unsigned long sys_timeBase = 0;
|
||||
/* current time in ms, using sys_timeBase as origin
|
||||
NOTE: sys_timeBase*1000 + curtime -> ms since the Epoch
|
||||
|
@ -104,31 +167,6 @@ int Sys_Milliseconds (void)
|
|||
return curtime;
|
||||
}
|
||||
|
||||
#if !id386
|
||||
/*
|
||||
==================
|
||||
fastftol
|
||||
==================
|
||||
*/
|
||||
long fastftol( float f )
|
||||
{
|
||||
return (long)f;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_SnapVector
|
||||
==================
|
||||
*/
|
||||
void Sys_SnapVector( float *v )
|
||||
{
|
||||
v[0] = rint(v[0]);
|
||||
v[1] = rint(v[1]);
|
||||
v[2] = rint(v[2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_RandomBytes
|
||||
|
@ -142,7 +180,9 @@ qboolean Sys_RandomBytes( byte *string, int len )
|
|||
if( !fp )
|
||||
return qfalse;
|
||||
|
||||
if( !fread( string, sizeof( byte ), len, fp ) )
|
||||
setvbuf( fp, NULL, _IONBF, 0 ); // don't buffer reads from /dev/urandom
|
||||
|
||||
if( fread( string, sizeof( byte ), len, fp ) != len )
|
||||
{
|
||||
fclose( fp );
|
||||
return qfalse;
|
||||
|
@ -167,16 +207,6 @@ char *Sys_GetCurrentUser( void )
|
|||
return p->pw_name;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_GetClipboardData
|
||||
==================
|
||||
*/
|
||||
char *Sys_GetClipboardData(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MEM_THRESHOLD 96*1024*1024
|
||||
|
||||
/*
|
||||
|
@ -211,14 +241,64 @@ const char *Sys_Dirname( char *path )
|
|||
return dirname( path );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_FOpen
|
||||
==============
|
||||
*/
|
||||
FILE *Sys_FOpen( const char *ospath, const char *mode ) {
|
||||
struct stat buf;
|
||||
|
||||
// check if path exists and is a directory
|
||||
if ( !stat( ospath, &buf ) && S_ISDIR( buf.st_mode ) )
|
||||
return NULL;
|
||||
|
||||
return fopen( ospath, mode );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_Mkdir
|
||||
==================
|
||||
*/
|
||||
void Sys_Mkdir( const char *path )
|
||||
qboolean Sys_Mkdir( const char *path )
|
||||
{
|
||||
mkdir( path, 0777 );
|
||||
int result = mkdir( path, 0750 );
|
||||
|
||||
if( result != 0 )
|
||||
return errno == EEXIST;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_Mkfifo
|
||||
==================
|
||||
*/
|
||||
FILE *Sys_Mkfifo( const char *ospath )
|
||||
{
|
||||
FILE *fifo;
|
||||
int result;
|
||||
int fn;
|
||||
struct stat buf;
|
||||
|
||||
// if file already exists AND is a pipefile, remove it
|
||||
if( !stat( ospath, &buf ) && S_ISFIFO( buf.st_mode ) )
|
||||
FS_Remove( ospath );
|
||||
|
||||
result = mkfifo( ospath, 0600 );
|
||||
if( result != 0 )
|
||||
return NULL;
|
||||
|
||||
fifo = fopen( ospath, "w+" );
|
||||
if( fifo )
|
||||
{
|
||||
fn = fileno( fifo );
|
||||
fcntl( fn, F_SETFL, O_NONBLOCK );
|
||||
}
|
||||
|
||||
return fifo;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -230,7 +310,10 @@ char *Sys_Cwd( void )
|
|||
{
|
||||
static char cwd[MAX_OSPATH];
|
||||
|
||||
getcwd( cwd, sizeof( cwd ) - 1 );
|
||||
char *result = getcwd( cwd, sizeof( cwd ) - 1 );
|
||||
if( result != cwd )
|
||||
return NULL;
|
||||
|
||||
cwd[MAX_OSPATH-1] = 0;
|
||||
|
||||
return cwd;
|
||||
|
@ -369,9 +452,9 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter
|
|||
continue;
|
||||
|
||||
if (*extension) {
|
||||
if ( strlen( d->d_name ) < strlen( extension ) ||
|
||||
if ( strlen( d->d_name ) < extLen ||
|
||||
Q_stricmp(
|
||||
d->d_name + strlen( d->d_name ) - strlen( extension ),
|
||||
d->d_name + strlen( d->d_name ) - extLen,
|
||||
extension ) ) {
|
||||
continue; // didn't match
|
||||
}
|
||||
|
@ -423,59 +506,44 @@ void Sys_FreeFileList( char **list )
|
|||
Z_Free( list );
|
||||
}
|
||||
|
||||
#ifdef MACOS_X
|
||||
/*
|
||||
=================
|
||||
Sys_StripAppBundle
|
||||
|
||||
Discovers if passed dir is suffixed with the directory structure of a Mac OS X
|
||||
.app bundle. If it is, the .app directory structure is stripped off the end and
|
||||
the result is returned. If not, dir is returned untouched.
|
||||
=================
|
||||
*/
|
||||
char *Sys_StripAppBundle( char *dir )
|
||||
{
|
||||
static char cwd[MAX_OSPATH];
|
||||
|
||||
Q_strncpyz(cwd, dir, sizeof(cwd));
|
||||
if(strcmp(Sys_Basename(cwd), "MacOS"))
|
||||
return dir;
|
||||
Q_strncpyz(cwd, Sys_Dirname(cwd), sizeof(cwd));
|
||||
if(strcmp(Sys_Basename(cwd), "Contents"))
|
||||
return dir;
|
||||
Q_strncpyz(cwd, Sys_Dirname(cwd), sizeof(cwd));
|
||||
if(!strstr(Sys_Basename(cwd), ".app"))
|
||||
return dir;
|
||||
Q_strncpyz(cwd, Sys_Dirname(cwd), sizeof(cwd));
|
||||
return cwd;
|
||||
}
|
||||
#endif // MACOS_X
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_Sleep
|
||||
|
||||
Block execution for msec or until input is recieved.
|
||||
Block execution for msec or until input is received.
|
||||
==================
|
||||
*/
|
||||
void Sys_Sleep( int msec )
|
||||
{
|
||||
fd_set fdset;
|
||||
if( msec == 0 )
|
||||
return;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(fileno(stdin), &fdset);
|
||||
if( msec < 0 )
|
||||
if( stdinIsATTY )
|
||||
{
|
||||
select((fileno(stdin) + 1), &fdset, NULL, NULL, NULL);
|
||||
fd_set fdset;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(STDIN_FILENO, &fdset);
|
||||
if( msec < 0 )
|
||||
{
|
||||
select(STDIN_FILENO + 1, &fdset, NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timeval timeout;
|
||||
|
||||
timeout.tv_sec = msec/1000;
|
||||
timeout.tv_usec = (msec%1000)*1000;
|
||||
select(STDIN_FILENO + 1, &fdset, NULL, NULL, &timeout);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timeval timeout;
|
||||
// With nothing to select() on, we can't wait indefinitely
|
||||
if( msec < 0 )
|
||||
msec = 10;
|
||||
|
||||
timeout.tv_sec = msec/1000;
|
||||
timeout.tv_usec = (msec%1000)*1000;
|
||||
select((fileno(stdin) + 1), &fdset, NULL, NULL, &timeout);
|
||||
usleep( msec * 1000 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,21 +558,421 @@ void Sys_ErrorDialog( const char *error )
|
|||
{
|
||||
char buffer[ 1024 ];
|
||||
unsigned int size;
|
||||
fileHandle_t f;
|
||||
int f = -1;
|
||||
const char *homepath = Cvar_VariableString( "fs_homepath" );
|
||||
const char *gamedir = Cvar_VariableString( "fs_game" );
|
||||
const char *fileName = "crashlog.txt";
|
||||
char *dirpath = FS_BuildOSPath( homepath, gamedir, "");
|
||||
char *ospath = FS_BuildOSPath( homepath, gamedir, fileName );
|
||||
|
||||
Sys_Print( va( "%s\n", error ) );
|
||||
|
||||
// Write console log to file
|
||||
f = FS_FOpenFileWrite( fileName );
|
||||
if( !f )
|
||||
#ifndef DEDICATED
|
||||
Sys_Dialog( DT_ERROR, va( "%s. See \"%s\" for details.", error, ospath ), "Error" );
|
||||
#endif
|
||||
|
||||
// Make sure the write path for the crashlog exists...
|
||||
|
||||
if(!Sys_Mkdir(homepath))
|
||||
{
|
||||
Com_Printf("ERROR: couldn't create path '%s' for crash log.\n", homepath);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Sys_Mkdir(dirpath))
|
||||
{
|
||||
Com_Printf("ERROR: couldn't create path '%s' for crash log.\n", dirpath);
|
||||
return;
|
||||
}
|
||||
|
||||
// We might be crashing because we maxed out the Quake MAX_FILE_HANDLES,
|
||||
// which will come through here, so we don't want to recurse forever by
|
||||
// calling FS_FOpenFileWrite()...use the Unix system APIs instead.
|
||||
f = open( ospath, O_CREAT | O_TRUNC | O_WRONLY, 0640 );
|
||||
if( f == -1 )
|
||||
{
|
||||
Com_Printf( "ERROR: couldn't open %s\n", fileName );
|
||||
return;
|
||||
}
|
||||
|
||||
while( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 )
|
||||
FS_Write( buffer, size, f );
|
||||
// We're crashing, so we don't care much if write() or close() fails.
|
||||
while( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 ) {
|
||||
if( write( f, buffer, size ) != size ) {
|
||||
Com_Printf( "ERROR: couldn't fully write to %s\n", fileName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FS_FCloseFile( f );
|
||||
close( f );
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
static char execBuffer[ 1024 ];
|
||||
static char *execBufferPointer;
|
||||
static char *execArgv[ 16 ];
|
||||
static int execArgc;
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_ClearExecBuffer
|
||||
==============
|
||||
*/
|
||||
static void Sys_ClearExecBuffer( void )
|
||||
{
|
||||
execBufferPointer = execBuffer;
|
||||
Com_Memset( execArgv, 0, sizeof( execArgv ) );
|
||||
execArgc = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_AppendToExecBuffer
|
||||
==============
|
||||
*/
|
||||
static void Sys_AppendToExecBuffer( const char *text )
|
||||
{
|
||||
size_t size = sizeof( execBuffer ) - ( execBufferPointer - execBuffer );
|
||||
int length = strlen( text ) + 1;
|
||||
|
||||
if( length > size || execArgc >= ARRAY_LEN( execArgv ) )
|
||||
return;
|
||||
|
||||
Q_strncpyz( execBufferPointer, text, size );
|
||||
execArgv[ execArgc++ ] = execBufferPointer;
|
||||
|
||||
execBufferPointer += length;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_Exec
|
||||
==============
|
||||
*/
|
||||
static int Sys_Exec( void )
|
||||
{
|
||||
pid_t pid = fork( );
|
||||
|
||||
if( pid < 0 )
|
||||
return -1;
|
||||
|
||||
if( pid )
|
||||
{
|
||||
// Parent
|
||||
int exitCode;
|
||||
|
||||
wait( &exitCode );
|
||||
|
||||
return WEXITSTATUS( exitCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Child
|
||||
execvp( execArgv[ 0 ], execArgv );
|
||||
|
||||
// Failed to execute
|
||||
exit( -1 );
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_ZenityCommand
|
||||
==============
|
||||
*/
|
||||
static void Sys_ZenityCommand( dialogType_t type, const char *message, const char *title )
|
||||
{
|
||||
Sys_ClearExecBuffer( );
|
||||
Sys_AppendToExecBuffer( "zenity" );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
default:
|
||||
case DT_INFO: Sys_AppendToExecBuffer( "--info" ); break;
|
||||
case DT_WARNING: Sys_AppendToExecBuffer( "--warning" ); break;
|
||||
case DT_ERROR: Sys_AppendToExecBuffer( "--error" ); break;
|
||||
case DT_YES_NO:
|
||||
Sys_AppendToExecBuffer( "--question" );
|
||||
Sys_AppendToExecBuffer( "--ok-label=Yes" );
|
||||
Sys_AppendToExecBuffer( "--cancel-label=No" );
|
||||
break;
|
||||
|
||||
case DT_OK_CANCEL:
|
||||
Sys_AppendToExecBuffer( "--question" );
|
||||
Sys_AppendToExecBuffer( "--ok-label=OK" );
|
||||
Sys_AppendToExecBuffer( "--cancel-label=Cancel" );
|
||||
break;
|
||||
}
|
||||
|
||||
Sys_AppendToExecBuffer( va( "--text=%s", message ) );
|
||||
Sys_AppendToExecBuffer( va( "--title=%s", title ) );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_KdialogCommand
|
||||
==============
|
||||
*/
|
||||
static void Sys_KdialogCommand( dialogType_t type, const char *message, const char *title )
|
||||
{
|
||||
Sys_ClearExecBuffer( );
|
||||
Sys_AppendToExecBuffer( "kdialog" );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
default:
|
||||
case DT_INFO: Sys_AppendToExecBuffer( "--msgbox" ); break;
|
||||
case DT_WARNING: Sys_AppendToExecBuffer( "--sorry" ); break;
|
||||
case DT_ERROR: Sys_AppendToExecBuffer( "--error" ); break;
|
||||
case DT_YES_NO: Sys_AppendToExecBuffer( "--warningyesno" ); break;
|
||||
case DT_OK_CANCEL: Sys_AppendToExecBuffer( "--warningcontinuecancel" ); break;
|
||||
}
|
||||
|
||||
Sys_AppendToExecBuffer( message );
|
||||
Sys_AppendToExecBuffer( va( "--title=%s", title ) );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_XmessageCommand
|
||||
==============
|
||||
*/
|
||||
static void Sys_XmessageCommand( dialogType_t type, const char *message, const char *title )
|
||||
{
|
||||
Sys_ClearExecBuffer( );
|
||||
Sys_AppendToExecBuffer( "xmessage" );
|
||||
Sys_AppendToExecBuffer( "-buttons" );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
default: Sys_AppendToExecBuffer( "OK:0" ); break;
|
||||
case DT_YES_NO: Sys_AppendToExecBuffer( "Yes:0,No:1" ); break;
|
||||
case DT_OK_CANCEL: Sys_AppendToExecBuffer( "OK:0,Cancel:1" ); break;
|
||||
}
|
||||
|
||||
Sys_AppendToExecBuffer( "-center" );
|
||||
Sys_AppendToExecBuffer( message );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_Dialog
|
||||
|
||||
Display a *nix dialog box
|
||||
==============
|
||||
*/
|
||||
dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title )
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
NONE = 0,
|
||||
ZENITY,
|
||||
KDIALOG,
|
||||
XMESSAGE,
|
||||
NUM_DIALOG_PROGRAMS
|
||||
} dialogCommandType_t;
|
||||
typedef void (*dialogCommandBuilder_t)( dialogType_t, const char *, const char * );
|
||||
|
||||
const char *session = getenv( "DESKTOP_SESSION" );
|
||||
qboolean tried[ NUM_DIALOG_PROGRAMS ] = { qfalse };
|
||||
dialogCommandBuilder_t commands[ NUM_DIALOG_PROGRAMS ] = { NULL };
|
||||
dialogCommandType_t preferredCommandType = NONE;
|
||||
int i;
|
||||
|
||||
commands[ ZENITY ] = &Sys_ZenityCommand;
|
||||
commands[ KDIALOG ] = &Sys_KdialogCommand;
|
||||
commands[ XMESSAGE ] = &Sys_XmessageCommand;
|
||||
|
||||
// This may not be the best way
|
||||
if( !Q_stricmp( session, "gnome" ) )
|
||||
preferredCommandType = ZENITY;
|
||||
else if( !Q_stricmp( session, "kde" ) )
|
||||
preferredCommandType = KDIALOG;
|
||||
|
||||
for( i = NONE + 1; i < NUM_DIALOG_PROGRAMS; i++ )
|
||||
{
|
||||
if( preferredCommandType != NONE && preferredCommandType != i )
|
||||
continue;
|
||||
|
||||
if( !tried[ i ] )
|
||||
{
|
||||
int exitCode;
|
||||
|
||||
commands[ i ]( type, message, title );
|
||||
exitCode = Sys_Exec( );
|
||||
|
||||
if( exitCode >= 0 )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case DT_YES_NO: return exitCode ? DR_NO : DR_YES;
|
||||
case DT_OK_CANCEL: return exitCode ? DR_CANCEL : DR_OK;
|
||||
default: return DR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
tried[ i ] = qtrue;
|
||||
|
||||
// The preference failed, so start again in order
|
||||
if( preferredCommandType != NONE )
|
||||
{
|
||||
preferredCommandType = NONE;
|
||||
i = NONE + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Com_DPrintf( S_COLOR_YELLOW "WARNING: failed to show a dialog\n" );
|
||||
return DR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_GLimpSafeInit
|
||||
|
||||
Unix specific "safe" GL implementation initialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_GLimpSafeInit( void )
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_GLimpInit
|
||||
|
||||
Unix specific GL implementation initialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_GLimpInit( void )
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
void Sys_SetFloatEnv(void)
|
||||
{
|
||||
// rounding toward nearest
|
||||
fesetround(FE_TONEAREST);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PlatformInit
|
||||
|
||||
Unix specific initialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_PlatformInit( void )
|
||||
{
|
||||
const char* term = getenv( "TERM" );
|
||||
|
||||
signal( SIGHUP, Sys_SigHandler );
|
||||
signal( SIGQUIT, Sys_SigHandler );
|
||||
signal( SIGTRAP, Sys_SigHandler );
|
||||
signal( SIGABRT, Sys_SigHandler );
|
||||
signal( SIGBUS, Sys_SigHandler );
|
||||
|
||||
Sys_SetFloatEnv();
|
||||
|
||||
stdinIsATTY = isatty( STDIN_FILENO ) &&
|
||||
!( term && ( !strcmp( term, "raw" ) || !strcmp( term, "dumb" ) ) );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PlatformExit
|
||||
|
||||
Unix specific deinitialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_PlatformExit( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_SetEnv
|
||||
|
||||
set/unset environment variables (empty value removes it)
|
||||
==============
|
||||
*/
|
||||
|
||||
void Sys_SetEnv(const char *name, const char *value)
|
||||
{
|
||||
if(value && *value)
|
||||
setenv(name, value, 1);
|
||||
else
|
||||
unsetenv(name);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PID
|
||||
==============
|
||||
*/
|
||||
int Sys_PID( void )
|
||||
{
|
||||
return getpid( );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PIDIsRunning
|
||||
==============
|
||||
*/
|
||||
qboolean Sys_PIDIsRunning( size_t pid )
|
||||
{
|
||||
return kill( pid, 0 ) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_DllExtension
|
||||
|
||||
Check if filename should be allowed to be loaded as a DLL.
|
||||
=================
|
||||
*/
|
||||
qboolean Sys_DllExtension( const char *name ) {
|
||||
const char *p;
|
||||
char c = 0;
|
||||
|
||||
if ( COM_CompareExtension( name, DLL_EXT ) ) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Allow system frameworks without dylib extensions
|
||||
// i.e., /System/Library/Frameworks/OpenAL.framework/OpenAL
|
||||
if ( strncmp( name, "/System/Library/Frameworks/", 27 ) == 0 ) {
|
||||
return qtrue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check for format of filename.so.1.2.3
|
||||
p = strstr( name, DLL_EXT "." );
|
||||
|
||||
if ( p ) {
|
||||
p += strlen( DLL_EXT );
|
||||
|
||||
// Check if .so is only followed for periods and numbers.
|
||||
while ( *p ) {
|
||||
c = *p;
|
||||
|
||||
if ( !isdigit( c ) && c != '.' ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
// Don't allow filename to end in a period. file.so., file.so.0., etc
|
||||
if ( c != '.' ) {
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
|
|
@ -36,19 +36,60 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include <conio.h>
|
||||
#include <wincrypt.h>
|
||||
#include <shlobj.h>
|
||||
#include <psapi.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifndef KEY_WOW64_32KEY
|
||||
#define KEY_WOW64_32KEY 0x0200
|
||||
#endif
|
||||
|
||||
// Used to determine where to store user-specific files
|
||||
static char homePath[ MAX_OSPATH ] = { 0 };
|
||||
static char programpath[ MAX_OSPATH ] = { 0 };
|
||||
|
||||
// Used to store the Steam Quake 3 installation path
|
||||
static char steamPath[ MAX_OSPATH ] = { 0 };
|
||||
|
||||
// Used to store the GOG Quake 3 installation path
|
||||
static char gogPath[ MAX_OSPATH ] = { 0 };
|
||||
|
||||
// Used to store the Microsoft Store Quake 3 installation path
|
||||
static char microsoftStorePath[MAX_OSPATH] = { 0 };
|
||||
|
||||
#ifndef DEDICATED
|
||||
static UINT timerResolution = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
RecoverLostAutodialData
|
||||
Sys_SetFPUCW
|
||||
Set FPU control word to default value
|
||||
================
|
||||
*/
|
||||
void RecoverLostAutodialData( void )
|
||||
|
||||
#ifndef _RC_CHOP
|
||||
// mingw doesn't seem to have these defined :(
|
||||
|
||||
#define _MCW_EM 0x0008001fU
|
||||
#define _MCW_RC 0x00000300U
|
||||
#define _MCW_PC 0x00030000U
|
||||
#define _RC_NEAR 0x00000000U
|
||||
#define _PC_53 0x00010000U
|
||||
|
||||
unsigned int _controlfp(unsigned int new, unsigned int mask);
|
||||
#endif
|
||||
|
||||
#define FPUCWMASK1 (_MCW_RC | _MCW_EM)
|
||||
#define FPUCW (_RC_NEAR | _MCW_EM | _PC_53)
|
||||
|
||||
#if idx64
|
||||
#define FPUCWMASK (FPUCWMASK1)
|
||||
#else
|
||||
#define FPUCWMASK (FPUCWMASK1 | _MCW_PC)
|
||||
#endif
|
||||
|
||||
void Sys_SetFloatEnv(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
_controlfp(FPUCW, FPUCWMASK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,19 +101,16 @@ char *Sys_DefaultHomePath( void )
|
|||
{
|
||||
TCHAR szPath[MAX_PATH];
|
||||
FARPROC qSHGetFolderPath;
|
||||
HMODULE shfolder;
|
||||
HMODULE shfolder = LoadLibrary("shfolder.dll");
|
||||
|
||||
return NULL;
|
||||
shfolder = LoadLibrary("shfolder.dll");
|
||||
|
||||
if( !*homePath )
|
||||
if(shfolder == NULL)
|
||||
{
|
||||
if(shfolder == NULL)
|
||||
{
|
||||
Com_Printf("Unable to load SHFolder.dll\n");
|
||||
return NULL;
|
||||
}
|
||||
Com_Printf("Unable to load SHFolder.dll\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!*homePath && com_homepath)
|
||||
{
|
||||
qSHGetFolderPath = GetProcAddress(shfolder, "SHGetFolderPathA");
|
||||
if(qSHGetFolderPath == NULL)
|
||||
{
|
||||
|
@ -88,70 +126,148 @@ char *Sys_DefaultHomePath( void )
|
|||
FreeLibrary(shfolder);
|
||||
return NULL;
|
||||
}
|
||||
Q_strncpyz( homePath, szPath, sizeof( homePath ) );
|
||||
Q_strcat( homePath, sizeof( homePath ), "\\OpenMoHAA" );
|
||||
FreeLibrary(shfolder);
|
||||
if( !CreateDirectory( homePath, NULL ) )
|
||||
{
|
||||
if( GetLastError() != ERROR_ALREADY_EXISTS )
|
||||
{
|
||||
Com_Printf("Unable to create directory \"%s\"\n", homePath );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Com_sprintf(homePath, sizeof(homePath), "%s%c", szPath, PATH_SEP);
|
||||
|
||||
if(com_homepath->string[0])
|
||||
Q_strcat(homePath, sizeof(homePath), com_homepath->string);
|
||||
else
|
||||
Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_WIN);
|
||||
}
|
||||
|
||||
FreeLibrary(shfolder);
|
||||
return homePath;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SetProgramPath
|
||||
Sys_SteamPath
|
||||
================
|
||||
*/
|
||||
void SetProgramPath( const char *path )
|
||||
char *Sys_SteamPath( void )
|
||||
{
|
||||
char *p;
|
||||
#if defined(STEAMPATH_NAME) || defined(STEAMPATH_APPID)
|
||||
HKEY steamRegKey;
|
||||
DWORD pathLen = MAX_OSPATH;
|
||||
qboolean finishPath = qfalse;
|
||||
|
||||
Q_strncpyz( programpath, path, sizeof( programpath ) );
|
||||
#ifdef STEAMPATH_APPID
|
||||
// Assuming Steam is a 32-bit app
|
||||
if (!steamPath[0] && !RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App " STEAMPATH_APPID, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &steamRegKey))
|
||||
{
|
||||
pathLen = MAX_OSPATH;
|
||||
if (RegQueryValueEx(steamRegKey, "InstallLocation", NULL, NULL, (LPBYTE)steamPath, &pathLen))
|
||||
steamPath[0] = '\0';
|
||||
|
||||
p = strrchr( programpath, '/' );
|
||||
if( p ) {
|
||||
*p = 0;
|
||||
RegCloseKey(steamRegKey);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef STEAMPATH_NAME
|
||||
if (!steamPath[0] && !RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Valve\\Steam", 0, KEY_QUERY_VALUE, &steamRegKey))
|
||||
{
|
||||
pathLen = MAX_OSPATH;
|
||||
if (RegQueryValueEx(steamRegKey, "SteamPath", NULL, NULL, (LPBYTE)steamPath, &pathLen))
|
||||
if (RegQueryValueEx(steamRegKey, "InstallPath", NULL, NULL, (LPBYTE)steamPath, &pathLen))
|
||||
steamPath[0] = '\0';
|
||||
|
||||
if (steamPath[0])
|
||||
finishPath = qtrue;
|
||||
|
||||
RegCloseKey(steamRegKey);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (steamPath[0])
|
||||
{
|
||||
if (pathLen == MAX_OSPATH)
|
||||
pathLen--;
|
||||
|
||||
steamPath[pathLen] = '\0';
|
||||
|
||||
if (finishPath)
|
||||
Q_strcat(steamPath, MAX_OSPATH, "\\SteamApps\\common\\" STEAMPATH_NAME );
|
||||
}
|
||||
#endif
|
||||
|
||||
return steamPath;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_DefaultBasePath
|
||||
Sys_GogPath
|
||||
================
|
||||
*/
|
||||
char *Sys_DefaultBasePath( void )
|
||||
char *Sys_GogPath( void )
|
||||
{
|
||||
static char basepath[ 256 ];
|
||||
#ifdef GOGPATH_ID
|
||||
HKEY gogRegKey;
|
||||
DWORD pathLen = MAX_OSPATH;
|
||||
|
||||
Q_strncpyz( basepath, programpath, sizeof( basepath ) );
|
||||
return basepath;
|
||||
if (!gogPath[0] && !RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\GOG.com\\Games\\" GOGPATH_ID, 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &gogRegKey))
|
||||
{
|
||||
pathLen = MAX_OSPATH;
|
||||
if (RegQueryValueEx(gogRegKey, "PATH", NULL, NULL, (LPBYTE)gogPath, &pathLen))
|
||||
gogPath[0] = '\0';
|
||||
|
||||
RegCloseKey(gogRegKey);
|
||||
}
|
||||
|
||||
if (gogPath[0])
|
||||
{
|
||||
if (pathLen == MAX_OSPATH)
|
||||
pathLen--;
|
||||
|
||||
gogPath[pathLen] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
return gogPath;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_DefaultUserPath
|
||||
Sys_MicrosoftStorePath
|
||||
================
|
||||
*/
|
||||
char *Sys_DefaultUserPath( void )
|
||||
char* Sys_MicrosoftStorePath(void)
|
||||
{
|
||||
return Sys_DefaultBasePath();
|
||||
}
|
||||
#ifdef MSSTORE_PATH
|
||||
if (!microsoftStorePath[0])
|
||||
{
|
||||
TCHAR szPath[MAX_PATH];
|
||||
FARPROC qSHGetFolderPath;
|
||||
HMODULE shfolder = LoadLibrary("shfolder.dll");
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_DefaultUserPath
|
||||
================
|
||||
*/
|
||||
char *Sys_DefaultOutputPath( void )
|
||||
{
|
||||
return Sys_DefaultUserPath();
|
||||
if(shfolder == NULL)
|
||||
{
|
||||
Com_Printf("Unable to load SHFolder.dll\n");
|
||||
return microsoftStorePath;
|
||||
}
|
||||
|
||||
qSHGetFolderPath = GetProcAddress(shfolder, "SHGetFolderPathA");
|
||||
if(qSHGetFolderPath == NULL)
|
||||
{
|
||||
Com_Printf("Unable to find SHGetFolderPath in SHFolder.dll\n");
|
||||
FreeLibrary(shfolder);
|
||||
return microsoftStorePath;
|
||||
}
|
||||
|
||||
if( !SUCCEEDED( qSHGetFolderPath( NULL, CSIDL_PROGRAM_FILES,
|
||||
NULL, 0, szPath ) ) )
|
||||
{
|
||||
Com_Printf("Unable to detect CSIDL_PROGRAM_FILES\n");
|
||||
FreeLibrary(shfolder);
|
||||
return microsoftStorePath;
|
||||
}
|
||||
|
||||
FreeLibrary(shfolder);
|
||||
|
||||
// default: C:\Program Files\ModifiableWindowsApps\Quake 3\EN
|
||||
Com_sprintf(microsoftStorePath, sizeof(microsoftStorePath), "%s%cModifiableWindowsApps%c%s%cEN", szPath, PATH_SEP, PATH_SEP, MSSTORE_PATH, PATH_SEP);
|
||||
}
|
||||
#endif
|
||||
return microsoftStorePath;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -174,40 +290,6 @@ int Sys_Milliseconds (void)
|
|||
return sys_curtime;
|
||||
}
|
||||
|
||||
#ifndef __GNUC__ //see snapvectora.s
|
||||
/*
|
||||
================
|
||||
Sys_SnapVector
|
||||
================
|
||||
*/
|
||||
void Sys_SnapVector( float *v )
|
||||
{
|
||||
#ifndef _WIN64
|
||||
int i;
|
||||
float f;
|
||||
|
||||
f = *v;
|
||||
__asm fld f;
|
||||
__asm fistp i;
|
||||
*v = i;
|
||||
v++;
|
||||
f = *v;
|
||||
__asm fld f;
|
||||
__asm fistp i;
|
||||
*v = i;
|
||||
v++;
|
||||
f = *v;
|
||||
__asm fld f;
|
||||
__asm fistp i;
|
||||
*v = i;
|
||||
#else
|
||||
v[ 0 ] = rint( v[ 0 ] );
|
||||
v[ 1 ] = rint( v[ 1 ] );
|
||||
v[ 2 ] = rint( v[ 2 ] );
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_RandomBytes
|
||||
|
@ -252,33 +334,6 @@ char *Sys_GetCurrentUser( void )
|
|||
return s_userName;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_GetClipboardData
|
||||
================
|
||||
*/
|
||||
char *Sys_GetClipboardData( void )
|
||||
{
|
||||
char *data = NULL;
|
||||
char *cliptext;
|
||||
|
||||
if ( OpenClipboard( NULL ) != 0 ) {
|
||||
HANDLE hClipboardData;
|
||||
|
||||
if ( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) {
|
||||
if ( ( cliptext = GlobalLock( hClipboardData ) ) != 0 ) {
|
||||
data = Z_Malloc( GlobalSize( hClipboardData ) + 1 );
|
||||
Q_strncpyz( data, cliptext, GlobalSize( hClipboardData ) );
|
||||
GlobalUnlock( hClipboardData );
|
||||
|
||||
strtok( data, "\n\r\b" );
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
#define MEM_THRESHOLD 96*1024*1024
|
||||
|
||||
/*
|
||||
|
@ -293,26 +348,6 @@ qboolean Sys_LowPhysicalMemory( void )
|
|||
return (stat.dwTotalPhys <= MEM_THRESHOLD) ? qtrue : qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SetNormalThreadPriority
|
||||
==================
|
||||
*/
|
||||
void SetNormalThreadPriority( void )
|
||||
{
|
||||
SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SetBelowNormalThreadPriority
|
||||
==================
|
||||
*/
|
||||
void SetBelowNormalThreadPriority( void )
|
||||
{
|
||||
SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_Basename
|
||||
|
@ -321,7 +356,7 @@ Sys_Basename
|
|||
const char *Sys_Basename( char *path )
|
||||
{
|
||||
static char base[ MAX_OSPATH ] = { 0 };
|
||||
intptr_t length;
|
||||
int length;
|
||||
|
||||
length = strlen( path ) - 1;
|
||||
|
||||
|
@ -351,7 +386,7 @@ Sys_Dirname
|
|||
const char *Sys_Dirname( char *path )
|
||||
{
|
||||
static char dir[ MAX_OSPATH ] = { 0 };
|
||||
intptr_t length;
|
||||
int length;
|
||||
|
||||
Q_strncpyz( dir, path, sizeof( dir ) );
|
||||
length = strlen( dir ) - 1;
|
||||
|
@ -364,14 +399,48 @@ const char *Sys_Dirname( char *path )
|
|||
return dir;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_FOpen
|
||||
==============
|
||||
*/
|
||||
FILE *Sys_FOpen( const char *ospath, const char *mode ) {
|
||||
size_t length;
|
||||
|
||||
// Windows API ignores all trailing spaces and periods which can get around Quake 3 file system restrictions.
|
||||
length = strlen( ospath );
|
||||
if ( length == 0 || ospath[length-1] == ' ' || ospath[length-1] == '.' ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fopen( ospath, mode );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_Mkdir
|
||||
==============
|
||||
*/
|
||||
void Sys_Mkdir( const char *path )
|
||||
qboolean Sys_Mkdir( const char *path )
|
||||
{
|
||||
_mkdir (path);
|
||||
if( !CreateDirectory( path, NULL ) )
|
||||
{
|
||||
if( GetLastError( ) != ERROR_ALREADY_EXISTS )
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Sys_Mkfifo
|
||||
Noop on windows because named pipes do not function the same way
|
||||
==================
|
||||
*/
|
||||
FILE *Sys_Mkfifo( const char *ospath )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -403,7 +472,7 @@ DIRECTORY SCANNING
|
|||
Sys_ListFilteredFiles
|
||||
==============
|
||||
*/
|
||||
void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, const char **list, int *numfiles )
|
||||
void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles )
|
||||
{
|
||||
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
|
||||
char filename[MAX_OSPATH];
|
||||
|
@ -490,9 +559,10 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter
|
|||
char **listCopy;
|
||||
char *list[MAX_FOUND_FILES];
|
||||
struct _finddata_t findinfo;
|
||||
intptr_t findhandle;
|
||||
intptr_t findhandle;
|
||||
int flag;
|
||||
int i;
|
||||
int extLen;
|
||||
|
||||
if (filter) {
|
||||
|
||||
|
@ -526,6 +596,8 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter
|
|||
flag = _A_SUBDIR;
|
||||
}
|
||||
|
||||
extLen = strlen( extension );
|
||||
|
||||
Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension );
|
||||
|
||||
// search
|
||||
|
@ -539,6 +611,14 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter
|
|||
|
||||
do {
|
||||
if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) ) {
|
||||
if (*extension) {
|
||||
if ( strlen( findinfo.name ) < extLen ||
|
||||
Q_stricmp(
|
||||
findinfo.name + strlen( findinfo.name ) - extLen,
|
||||
extension ) ) {
|
||||
continue; // didn't match
|
||||
}
|
||||
}
|
||||
if ( nfiles == MAX_FOUND_FILES - 1 ) {
|
||||
break;
|
||||
}
|
||||
|
@ -604,28 +684,39 @@ void Sys_FreeFileList( char **list )
|
|||
==============
|
||||
Sys_Sleep
|
||||
|
||||
Block execution for msec or until input is recieved.
|
||||
Block execution for msec or until input is received.
|
||||
==============
|
||||
*/
|
||||
void Sys_Sleep( int msec )
|
||||
{
|
||||
if( msec == 0 )
|
||||
return;
|
||||
|
||||
#ifdef DEDICATED
|
||||
if( msec < 0 )
|
||||
WaitForSingleObject( GetStdHandle( STD_INPUT_HANDLE ), INFINITE );
|
||||
else
|
||||
WaitForSingleObject( GetStdHandle( STD_INPUT_HANDLE ), msec );
|
||||
#else
|
||||
// Client Sys_Sleep doesn't support waiting on stdin
|
||||
if( msec < 0 )
|
||||
return;
|
||||
|
||||
Sleep( msec );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SyScriptErrorDialog
|
||||
Sys_ErrorDialog
|
||||
|
||||
Display an error message
|
||||
==============
|
||||
*/
|
||||
void SyScriptErrorDialog( const char *error )
|
||||
void Sys_ErrorDialog( const char *error )
|
||||
{
|
||||
if( MessageBox( NULL, va( "%s. Copy console log to clipboard?", error ),
|
||||
NULL, MB_YESNO|MB_ICONERROR ) == IDYES )
|
||||
if( Sys_Dialog( DT_YES_NO, va( "%s. Copy console log to clipboard?", error ),
|
||||
"Error" ) == DR_YES )
|
||||
{
|
||||
HGLOBAL memoryHandle;
|
||||
char *clipMemory;
|
||||
|
@ -637,7 +728,7 @@ void SyScriptErrorDialog( const char *error )
|
|||
{
|
||||
char *p = clipMemory;
|
||||
char buffer[ 1024 ];
|
||||
size_t size;
|
||||
unsigned int size;
|
||||
|
||||
while( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 )
|
||||
{
|
||||
|
@ -656,39 +747,10 @@ void SyScriptErrorDialog( const char *error )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_CloseMutex
|
||||
==============
|
||||
*/
|
||||
void Sys_CloseMutex( void )
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_ShowConsole
|
||||
==============
|
||||
*/
|
||||
void Sys_ShowConsole( int visLevel, qboolean quitOnClose )
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PumpMessageLoop
|
||||
==============
|
||||
*/
|
||||
void Sys_PumpMessageLoop( void )
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_Dialog
|
||||
|
||||
Display a win32 dialog box
|
||||
==============
|
||||
*/
|
||||
|
@ -716,14 +778,185 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_GLimpSafeInit
|
||||
|
||||
Windows specific "safe" GL implementation initialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_GLimpSafeInit( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_GLimpInit
|
||||
|
||||
Windows specific GL implementation initialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_GLimpInit( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PlatformInit
|
||||
|
||||
Windows specific initialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_PlatformInit( void )
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
TIMECAPS ptc;
|
||||
#endif
|
||||
|
||||
Sys_SetFloatEnv();
|
||||
|
||||
#ifndef DEDICATED
|
||||
if(timeGetDevCaps(&ptc, sizeof(ptc)) == MMSYSERR_NOERROR)
|
||||
{
|
||||
timerResolution = ptc.wPeriodMin;
|
||||
|
||||
if(timerResolution > 1)
|
||||
{
|
||||
Com_Printf("Warning: Minimum supported timer resolution is %ums "
|
||||
"on this system, recommended resolution 1ms\n", timerResolution);
|
||||
}
|
||||
|
||||
timeBeginPeriod(timerResolution);
|
||||
}
|
||||
else
|
||||
timerResolution = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PlatformExit
|
||||
|
||||
Windows specific initialisation
|
||||
==============
|
||||
*/
|
||||
void Sys_PlatformExit( void )
|
||||
{
|
||||
#ifndef DEDICATED
|
||||
if(timerResolution)
|
||||
timeEndPeriod(timerResolution);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_SetEnv
|
||||
|
||||
set/unset environment variables (empty value removes it)
|
||||
==============
|
||||
*/
|
||||
void Sys_SetEnv(const char *name, const char *value)
|
||||
{
|
||||
if(value)
|
||||
_putenv(va("%s=%s", name, value));
|
||||
else
|
||||
_putenv(va("%s=", name));
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PID
|
||||
==============
|
||||
*/
|
||||
int Sys_PID( void )
|
||||
{
|
||||
return GetCurrentProcessId( );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PIDIsRunning
|
||||
==============
|
||||
*/
|
||||
qboolean Sys_PIDIsRunning( int pid )
|
||||
{
|
||||
DWORD processes[ 1024 ];
|
||||
DWORD numBytes, numProcesses;
|
||||
int i;
|
||||
|
||||
if( !EnumProcesses( processes, sizeof( processes ), &numBytes ) )
|
||||
return qfalse; // Assume it's not running
|
||||
|
||||
numProcesses = numBytes / sizeof( DWORD );
|
||||
|
||||
// Search for the pid
|
||||
for( i = 0; i < numProcesses; i++ )
|
||||
{
|
||||
if( processes[ i ] == pid )
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_DllExtension
|
||||
|
||||
Check if filename should be allowed to be loaded as a DLL.
|
||||
=================
|
||||
*/
|
||||
qboolean Sys_DllExtension( const char *name ) {
|
||||
return COM_CompareExtension( name, DLL_EXT );
|
||||
}
|
||||
/*
|
||||
================
|
||||
RecoverLostAutodialData
|
||||
================
|
||||
*/
|
||||
void RecoverLostAutodialData(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_CloseMutex
|
||||
==============
|
||||
*/
|
||||
void Sys_CloseMutex(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_ShowConsole
|
||||
==============
|
||||
*/
|
||||
void Sys_ShowConsole(int visLevel, qboolean quitOnClose)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
Sys_PumpMessageLoop
|
||||
==============
|
||||
*/
|
||||
void Sys_PumpMessageLoop(void)
|
||||
{
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SaveRegistryInfo
|
||||
==============
|
||||
*/
|
||||
qboolean SaveRegistryInfo( qboolean user, const char *pszName, void *pvBuf, long lSize )
|
||||
qboolean SaveRegistryInfo(qboolean user, const char* pszName, void* pvBuf, long lSize)
|
||||
{
|
||||
STUB_DESC( "not implemented" );
|
||||
STUB_DESC("not implemented");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -732,9 +965,9 @@ qboolean SaveRegistryInfo( qboolean user, const char *pszName, void *pvBuf, long
|
|||
LoadRegistryInfo
|
||||
==============
|
||||
*/
|
||||
qboolean LoadRegistryInfo( qboolean user, const char *pszName, void *pvBuf, long *plSize )
|
||||
qboolean LoadRegistryInfo(qboolean user, const char* pszName, void* pvBuf, long* plSize)
|
||||
{
|
||||
STUB_DESC( "not implemented" );
|
||||
STUB_DESC("not implemented");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -743,9 +976,9 @@ qboolean LoadRegistryInfo( qboolean user, const char *pszName, void *pvBuf, long
|
|||
IsFirstRun
|
||||
==============
|
||||
*/
|
||||
qboolean IsFirstRun( void )
|
||||
qboolean IsFirstRun(void)
|
||||
{
|
||||
STUB_DESC( "wtf" );
|
||||
STUB_DESC("wtf");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -754,9 +987,9 @@ qboolean IsFirstRun( void )
|
|||
IsNewConfig
|
||||
==============
|
||||
*/
|
||||
qboolean IsNewConfig( void )
|
||||
qboolean IsNewConfig(void)
|
||||
{
|
||||
STUB_DESC( "wtf" );
|
||||
STUB_DESC("wtf");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -765,9 +998,9 @@ qboolean IsNewConfig( void )
|
|||
IsSafeMode
|
||||
==============
|
||||
*/
|
||||
qboolean IsSafeMode( void )
|
||||
qboolean IsSafeMode(void)
|
||||
{
|
||||
STUB_DESC( "wtf" );
|
||||
STUB_DESC("wtf");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -776,7 +1009,7 @@ qboolean IsSafeMode( void )
|
|||
ClearNewConfigFlag
|
||||
==============
|
||||
*/
|
||||
void ClearNewConfigFlag( void )
|
||||
void ClearNewConfigFlag(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -785,7 +1018,7 @@ void ClearNewConfigFlag( void )
|
|||
Sys_GetWholeClipboard
|
||||
==============
|
||||
*/
|
||||
const char *Sys_GetWholeClipboard( void )
|
||||
const char* Sys_GetWholeClipboard(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -795,6 +1028,26 @@ const char *Sys_GetWholeClipboard( void )
|
|||
Sys_SetClipboard
|
||||
==============
|
||||
*/
|
||||
void Sys_SetClipboard( const char *contents )
|
||||
void Sys_SetClipboard(const char* contents)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SetNormalThreadPriority
|
||||
==================
|
||||
*/
|
||||
void SetNormalThreadPriority(void)
|
||||
{
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SetBelowNormalThreadPriority
|
||||
==================
|
||||
*/
|
||||
void SetBelowNormalThreadPriority(void)
|
||||
{
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue