mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-01-18 23:41:42 +00:00
Supplemented Linux backend with missing functions. -> [100%] Built target RBDoom3 on Kubuntu 12.10
This commit is contained in:
parent
f7279b850c
commit
a1730fa430
28 changed files with 5378 additions and 741 deletions
|
@ -1053,7 +1053,8 @@ else()
|
||||||
|
|
||||||
list(APPEND RBDOOM3_SOURCES
|
list(APPEND RBDOOM3_SOURCES
|
||||||
${POSIX_INCLUDES} ${POSIX_SOURCES}
|
${POSIX_INCLUDES} ${POSIX_SOURCES}
|
||||||
${SDL_INCLUDES} ${SDL_SOURCES})
|
${SDL_INCLUDES} ${SDL_SOURCES}
|
||||||
|
sys/linux/linux_main.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(REMOVE_DUPLICATES RBDOOM3_SOURCES)
|
list(REMOVE_DUPLICATES RBDOOM3_SOURCES)
|
||||||
|
|
|
@ -320,8 +320,6 @@ public:
|
||||||
|
|
||||||
virtual int GetGameFrame() = 0;
|
virtual int GetGameFrame() = 0;
|
||||||
|
|
||||||
virtual void LaunchExternalTitle( int titleIndex, int device, const lobbyConnectInfo_t* const connectInfo ) = 0;
|
|
||||||
|
|
||||||
virtual void InitializeMPMapsModes() = 0;
|
virtual void InitializeMPMapsModes() = 0;
|
||||||
virtual const idStrList& GetModeList() const = 0;
|
virtual const idStrList& GetModeList() const = 0;
|
||||||
virtual const idStrList& GetModeDisplayList() const = 0;
|
virtual const idStrList& GetModeDisplayList() const = 0;
|
||||||
|
|
|
@ -48,60 +48,7 @@ extern idCVar g_demoMode;
|
||||||
// This is for the dirty hack to get a dialog to show up before we capture the screen for autorender.
|
// This is for the dirty hack to get a dialog to show up before we capture the screen for autorender.
|
||||||
const int NumScreenUpdatesToShowDialog = 25;
|
const int NumScreenUpdatesToShowDialog = 25;
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
|
||||||
idCommonLocal::LaunchExternalTitle
|
|
||||||
|
|
||||||
Launches an external title ( Doom 1, or 2 ) based on title index.
|
|
||||||
for PS3, a device number is sent in, for the game to register as a local
|
|
||||||
user by default, when title initializes.
|
|
||||||
================
|
|
||||||
*/
|
|
||||||
void idCommonLocal::LaunchExternalTitle( int titleIndex, int device, const lobbyConnectInfo_t* const connectInfo )
|
|
||||||
{
|
|
||||||
|
|
||||||
idStr deviceString( device );
|
|
||||||
|
|
||||||
// We want to pass in the current executable, so that the launching title knows which title to return to.
|
|
||||||
// as of right now, this feature is TBD.
|
|
||||||
const char* currentExecutablePath = "ImNotSureYet";
|
|
||||||
idStr launchingExecutablePath;
|
|
||||||
|
|
||||||
idCmdArgs cmdArgs;
|
|
||||||
cmdArgs.AppendArg( currentExecutablePath );
|
|
||||||
|
|
||||||
if( titleIndex == LAUNCH_TITLE_DOOM )
|
|
||||||
{
|
|
||||||
launchingExecutablePath.Format( "%s%s", Sys_DefaultBasePath(), LAUNCH_TITLE_DOOM_EXECUTABLE );
|
|
||||||
cmdArgs.AppendArg( "d1bfg" );
|
|
||||||
}
|
|
||||||
else if( titleIndex == LAUNCH_TITLE_DOOM2 )
|
|
||||||
{
|
|
||||||
launchingExecutablePath.Format( "%s%s", Sys_DefaultBasePath(), LAUNCH_TITLE_DOOM2_EXECUTABLE );
|
|
||||||
cmdArgs.AppendArg( "d2bfg" );
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
idLib::Warning( "Unhandled Launch Title %d \n", titleIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdArgs.AppendArg( deviceString.c_str() );
|
|
||||||
|
|
||||||
// Add an argument so that the new process knows whether or not to read exitspawn data.
|
|
||||||
if( connectInfo != NULL )
|
|
||||||
{
|
|
||||||
cmdArgs.AppendArg( "exitspawnInvite" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add arguments so that the new process will know which command line to invoke to relaunch this process
|
|
||||||
// if necessary.
|
|
||||||
|
|
||||||
const int launchDataSize = ( connectInfo == NULL ) ? 0 : sizeof( *connectInfo );
|
|
||||||
|
|
||||||
Sys_Launch( launchingExecutablePath.c_str() , cmdArgs, const_cast< lobbyConnectInfo_t* const >( connectInfo ), launchDataSize );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
|
|
|
@ -244,10 +244,6 @@ public:
|
||||||
return gameFrame;
|
return gameFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void LaunchExternalTitle( int titleIndex,
|
|
||||||
int device,
|
|
||||||
const lobbyConnectInfo_t* const connectInfo ); // For handling invitations. NULL if no invitation used.
|
|
||||||
|
|
||||||
virtual void InitializeMPMapsModes();
|
virtual void InitializeMPMapsModes();
|
||||||
virtual const idStrList& GetModeList() const
|
virtual const idStrList& GetModeList() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
Doom 3 BFG Edition GPL Source Code
|
Doom 3 BFG Edition GPL Source Code
|
||||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 2012 Robert Beckebans
|
||||||
|
|
||||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#define GAME_NAME "DOOM 3: BFG Edition" // appears on window titles and errors
|
#define GAME_NAME "DOOM 3: BFG Edition" // appears on window titles and errors
|
||||||
#define SAVE_PATH "\\id Software\\DOOM 3 BFG"
|
#define SAVE_PATH "\\id Software\\DOOM 3 BFG"
|
||||||
|
|
||||||
#define ENGINE_VERSION "D3BFG 1" // printed in console
|
#define ENGINE_VERSION "RBD3BFG 1" // printed in console
|
||||||
|
|
||||||
#define BASE_GAMEDIR "base"
|
#define BASE_GAMEDIR "base"
|
||||||
|
|
||||||
|
@ -56,3 +57,14 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#define WIN32_CONSOLE_CLASS "D3BFG_WinConsole"
|
#define WIN32_CONSOLE_CLASS "D3BFG_WinConsole"
|
||||||
#define WIN32_WINDOW_CLASS_NAME "D3BFG"
|
#define WIN32_WINDOW_CLASS_NAME "D3BFG"
|
||||||
#define WIN32_FAKE_WINDOW_CLASS_NAME "D3BFG_WGL_FAKE"
|
#define WIN32_FAKE_WINDOW_CLASS_NAME "D3BFG_WGL_FAKE"
|
||||||
|
|
||||||
|
// RB begin
|
||||||
|
// Linux info
|
||||||
|
#ifdef ID_DEMO_BUILD
|
||||||
|
#define LINUX_DEFAULT_PATH "/usr/local/games/rbdoom3-bfg-demo"
|
||||||
|
#else
|
||||||
|
#define LINUX_DEFAULT_PATH "/usr/local/games/rbdoom3-bfg"
|
||||||
|
#endif
|
||||||
|
// RB end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,11 +61,13 @@ uintptr_t Sys_CreateThread( xthread_t function, void* parms, xthreadPriority pri
|
||||||
pthread_attr_destroy( &attr );
|
pthread_attr_destroy( &attr );
|
||||||
|
|
||||||
// RB: TODO pthread_setname_np is different on Linux, MacOSX and other systems
|
// RB: TODO pthread_setname_np is different on Linux, MacOSX and other systems
|
||||||
|
#if 0
|
||||||
if( pthread_setname_np( handle, name ) != 0 )
|
if( pthread_setname_np( handle, name ) != 0 )
|
||||||
{
|
{
|
||||||
idLib::common->FatalError( "ERROR: pthread_setname_np %s failed\n", name );
|
idLib::common->FatalError( "ERROR: pthread_setname_np %s failed\n", name );
|
||||||
return ( uintptr_t )0;
|
return ( uintptr_t )0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO RB: support thread priorities?
|
TODO RB: support thread priorities?
|
||||||
|
|
|
@ -1,322 +0,0 @@
|
||||||
/* minigzip.c -- simulate gzip using the zlib compression library
|
|
||||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* minigzip is a minimal implementation of the gzip utility. This is
|
|
||||||
* only an example of using zlib and isn't meant to replace the
|
|
||||||
* full-featured gzip. No attempt is made to deal with file systems
|
|
||||||
* limiting names to 14 or 8+3 characters, etc... Error checking is
|
|
||||||
* very limited. So use minigzip only for testing; use gzip for the
|
|
||||||
* real thing. On MSDOS, use only on file names without extension
|
|
||||||
* or in pipe mode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* @(#) $Id$ */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "zlib.h"
|
|
||||||
|
|
||||||
#ifdef STDC
|
|
||||||
# include <string.h>
|
|
||||||
# include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_MMAP
|
|
||||||
# include <sys/types.h>
|
|
||||||
# include <sys/mman.h>
|
|
||||||
# include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
|
|
||||||
# include <fcntl.h>
|
|
||||||
# include <io.h>
|
|
||||||
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
|
|
||||||
#else
|
|
||||||
# define SET_BINARY_MODE(file)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VMS
|
|
||||||
# define unlink delete
|
|
||||||
# define GZ_SUFFIX "-gz"
|
|
||||||
#endif
|
|
||||||
#ifdef RISCOS
|
|
||||||
# define unlink remove
|
|
||||||
# define GZ_SUFFIX "-gz"
|
|
||||||
# define fileno(file) file->__file
|
|
||||||
#endif
|
|
||||||
#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
|
||||||
# include <unix.h> /* for fileno */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
|
|
||||||
extern int unlink OF((const char *));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GZ_SUFFIX
|
|
||||||
# define GZ_SUFFIX ".gz"
|
|
||||||
#endif
|
|
||||||
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
|
|
||||||
|
|
||||||
#define BUFLEN 16384
|
|
||||||
#define MAX_NAME_LEN 1024
|
|
||||||
|
|
||||||
#ifdef MAXSEG_64K
|
|
||||||
# define local static
|
|
||||||
/* Needed for systems with limitation on stack size. */
|
|
||||||
#else
|
|
||||||
# define local
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *prog;
|
|
||||||
|
|
||||||
void error OF((const char *msg));
|
|
||||||
void gz_compress OF((FILE *in, gzFile out));
|
|
||||||
#ifdef USE_MMAP
|
|
||||||
int gz_compress_mmap OF((FILE *in, gzFile out));
|
|
||||||
#endif
|
|
||||||
void gz_uncompress OF((gzFile in, FILE *out));
|
|
||||||
void file_compress OF((char *file, char *mode));
|
|
||||||
void file_uncompress OF((char *file));
|
|
||||||
int main OF((int argc, char *argv[]));
|
|
||||||
|
|
||||||
/* ===========================================================================
|
|
||||||
* Display error message and exit
|
|
||||||
*/
|
|
||||||
void error(msg)
|
|
||||||
const char *msg;
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: %s\n", prog, msg);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===========================================================================
|
|
||||||
* Compress input to output then close both files.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void gz_compress(in, out)
|
|
||||||
FILE *in;
|
|
||||||
gzFile out;
|
|
||||||
{
|
|
||||||
local char buf[BUFLEN];
|
|
||||||
int len;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
#ifdef USE_MMAP
|
|
||||||
/* Try first compressing with mmap. If mmap fails (minigzip used in a
|
|
||||||
* pipe), use the normal fread loop.
|
|
||||||
*/
|
|
||||||
if (gz_compress_mmap(in, out) == Z_OK) return;
|
|
||||||
#endif
|
|
||||||
for (;;) {
|
|
||||||
len = (int)fread(buf, 1, sizeof(buf), in);
|
|
||||||
if (ferror(in)) {
|
|
||||||
perror("fread");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if (len == 0) break;
|
|
||||||
|
|
||||||
if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
|
|
||||||
}
|
|
||||||
fclose(in);
|
|
||||||
if (gzclose(out) != Z_OK) error("failed gzclose");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
|
|
||||||
|
|
||||||
/* Try compressing the input file at once using mmap. Return Z_OK if
|
|
||||||
* if success, Z_ERRNO otherwise.
|
|
||||||
*/
|
|
||||||
int gz_compress_mmap(in, out)
|
|
||||||
FILE *in;
|
|
||||||
gzFile out;
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
int err;
|
|
||||||
int ifd = fileno(in);
|
|
||||||
caddr_t buf; /* mmap'ed buffer for the entire input file */
|
|
||||||
off_t buf_len; /* length of the input file */
|
|
||||||
struct stat sb;
|
|
||||||
|
|
||||||
/* Determine the size of the file, needed for mmap: */
|
|
||||||
if (fstat(ifd, &sb) < 0) return Z_ERRNO;
|
|
||||||
buf_len = sb.st_size;
|
|
||||||
if (buf_len <= 0) return Z_ERRNO;
|
|
||||||
|
|
||||||
/* Now do the actual mmap: */
|
|
||||||
buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
|
|
||||||
if (buf == (caddr_t)(-1)) return Z_ERRNO;
|
|
||||||
|
|
||||||
/* Compress the whole file at once: */
|
|
||||||
len = gzwrite(out, (char *)buf, (unsigned)buf_len);
|
|
||||||
|
|
||||||
if (len != (int)buf_len) error(gzerror(out, &err));
|
|
||||||
|
|
||||||
munmap(buf, buf_len);
|
|
||||||
fclose(in);
|
|
||||||
if (gzclose(out) != Z_OK) error("failed gzclose");
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
#endif /* USE_MMAP */
|
|
||||||
|
|
||||||
/* ===========================================================================
|
|
||||||
* Uncompress input to output then close both files.
|
|
||||||
*/
|
|
||||||
void gz_uncompress(in, out)
|
|
||||||
gzFile in;
|
|
||||||
FILE *out;
|
|
||||||
{
|
|
||||||
local char buf[BUFLEN];
|
|
||||||
int len;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
len = gzread(in, buf, sizeof(buf));
|
|
||||||
if (len < 0) error (gzerror(in, &err));
|
|
||||||
if (len == 0) break;
|
|
||||||
|
|
||||||
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
|
|
||||||
error("failed fwrite");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fclose(out)) error("failed fclose");
|
|
||||||
|
|
||||||
if (gzclose(in) != Z_OK) error("failed gzclose");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
|
||||||
* Compress the given file: create a corresponding .gz file and remove the
|
|
||||||
* original.
|
|
||||||
*/
|
|
||||||
void file_compress(file, mode)
|
|
||||||
char *file;
|
|
||||||
char *mode;
|
|
||||||
{
|
|
||||||
local char outfile[MAX_NAME_LEN];
|
|
||||||
FILE *in;
|
|
||||||
gzFile out;
|
|
||||||
|
|
||||||
strcpy(outfile, file);
|
|
||||||
strcat(outfile, GZ_SUFFIX);
|
|
||||||
|
|
||||||
in = fopen(file, "rb");
|
|
||||||
if (in == NULL) {
|
|
||||||
perror(file);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
out = gzopen(outfile, mode);
|
|
||||||
if (out == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
gz_compress(in, out);
|
|
||||||
|
|
||||||
unlink(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
|
||||||
* Uncompress the given file and remove the original.
|
|
||||||
*/
|
|
||||||
void file_uncompress(file)
|
|
||||||
char *file;
|
|
||||||
{
|
|
||||||
local char buf[MAX_NAME_LEN];
|
|
||||||
char *infile, *outfile;
|
|
||||||
FILE *out;
|
|
||||||
gzFile in;
|
|
||||||
uInt len = (uInt)strlen(file);
|
|
||||||
|
|
||||||
strcpy(buf, file);
|
|
||||||
|
|
||||||
if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
|
|
||||||
infile = file;
|
|
||||||
outfile = buf;
|
|
||||||
outfile[len-3] = '\0';
|
|
||||||
} else {
|
|
||||||
outfile = file;
|
|
||||||
infile = buf;
|
|
||||||
strcat(infile, GZ_SUFFIX);
|
|
||||||
}
|
|
||||||
in = gzopen(infile, "rb");
|
|
||||||
if (in == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
out = fopen(outfile, "wb");
|
|
||||||
if (out == NULL) {
|
|
||||||
perror(file);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
gz_uncompress(in, out);
|
|
||||||
|
|
||||||
unlink(infile);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
|
||||||
* Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
|
|
||||||
* -d : decompress
|
|
||||||
* -f : compress with Z_FILTERED
|
|
||||||
* -h : compress with Z_HUFFMAN_ONLY
|
|
||||||
* -r : compress with Z_RLE
|
|
||||||
* -1 to -9 : compression level
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main(argc, argv)
|
|
||||||
int argc;
|
|
||||||
char *argv[];
|
|
||||||
{
|
|
||||||
int uncompr = 0;
|
|
||||||
gzFile file;
|
|
||||||
char outmode[20];
|
|
||||||
|
|
||||||
strcpy(outmode, "wb6 ");
|
|
||||||
|
|
||||||
prog = argv[0];
|
|
||||||
argc--, argv++;
|
|
||||||
|
|
||||||
while (argc > 0) {
|
|
||||||
if (strcmp(*argv, "-d") == 0)
|
|
||||||
uncompr = 1;
|
|
||||||
else if (strcmp(*argv, "-f") == 0)
|
|
||||||
outmode[3] = 'f';
|
|
||||||
else if (strcmp(*argv, "-h") == 0)
|
|
||||||
outmode[3] = 'h';
|
|
||||||
else if (strcmp(*argv, "-r") == 0)
|
|
||||||
outmode[3] = 'R';
|
|
||||||
else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
|
|
||||||
(*argv)[2] == 0)
|
|
||||||
outmode[2] = (*argv)[1];
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
argc--, argv++;
|
|
||||||
}
|
|
||||||
if (outmode[3] == ' ')
|
|
||||||
outmode[3] = 0;
|
|
||||||
if (argc == 0) {
|
|
||||||
SET_BINARY_MODE(stdin);
|
|
||||||
SET_BINARY_MODE(stdout);
|
|
||||||
if (uncompr) {
|
|
||||||
file = gzdopen(fileno(stdin), "rb");
|
|
||||||
if (file == NULL) error("can't gzdopen stdin");
|
|
||||||
gz_uncompress(file, stdout);
|
|
||||||
} else {
|
|
||||||
file = gzdopen(fileno(stdout), outmode);
|
|
||||||
if (file == NULL) error("can't gzdopen stdout");
|
|
||||||
gz_compress(stdin, file);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
do {
|
|
||||||
if (uncompr) {
|
|
||||||
file_uncompress(*argv);
|
|
||||||
} else {
|
|
||||||
file_compress(*argv, outmode);
|
|
||||||
}
|
|
||||||
} while (argv++, --argc);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -97,7 +97,9 @@ idCVar r_skipDynamicTextures( "r_skipDynamicTextures", "0", CVAR_RENDERER | CVAR
|
||||||
idCVar r_skipCopyTexture( "r_skipCopyTexture", "0", CVAR_RENDERER | CVAR_BOOL, "do all rendering, but don't actually copyTexSubImage2D" );
|
idCVar r_skipCopyTexture( "r_skipCopyTexture", "0", CVAR_RENDERER | CVAR_BOOL, "do all rendering, but don't actually copyTexSubImage2D" );
|
||||||
idCVar r_skipBackEnd( "r_skipBackEnd", "0", CVAR_RENDERER | CVAR_BOOL, "don't draw anything" );
|
idCVar r_skipBackEnd( "r_skipBackEnd", "0", CVAR_RENDERER | CVAR_BOOL, "don't draw anything" );
|
||||||
idCVar r_skipRender( "r_skipRender", "0", CVAR_RENDERER | CVAR_BOOL, "skip 3D rendering, but pass 2D" );
|
idCVar r_skipRender( "r_skipRender", "0", CVAR_RENDERER | CVAR_BOOL, "skip 3D rendering, but pass 2D" );
|
||||||
idCVar r_skipRenderContext( "r_skipRenderContext", "0", CVAR_RENDERER | CVAR_BOOL, "NULL the rendering context during backend 3D rendering" );
|
// RB begin
|
||||||
|
idCVar r_skipRenderContext( "r_skipRenderContext", "0", CVAR_RENDERER | CVAR_BOOL, "DISABLED: NULL the rendering context during backend 3D rendering" );
|
||||||
|
// RB end
|
||||||
idCVar r_skipTranslucent( "r_skipTranslucent", "0", CVAR_RENDERER | CVAR_BOOL, "skip the translucent interaction rendering" );
|
idCVar r_skipTranslucent( "r_skipTranslucent", "0", CVAR_RENDERER | CVAR_BOOL, "skip the translucent interaction rendering" );
|
||||||
idCVar r_skipAmbient( "r_skipAmbient", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all non-interaction drawing" );
|
idCVar r_skipAmbient( "r_skipAmbient", "0", CVAR_RENDERER | CVAR_BOOL, "bypasses all non-interaction drawing" );
|
||||||
idCVar r_skipNewAmbient( "r_skipNewAmbient", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "bypasses all vertex/fragment program ambient drawing" );
|
idCVar r_skipNewAmbient( "r_skipNewAmbient", "0", CVAR_RENDERER | CVAR_BOOL | CVAR_ARCHIVE, "bypasses all vertex/fragment program ambient drawing" );
|
||||||
|
|
|
@ -3150,10 +3150,13 @@ void RB_DrawView( const void* data, const int stereoEye )
|
||||||
// skip render context sets the wgl context to NULL,
|
// skip render context sets the wgl context to NULL,
|
||||||
// which should factor out the API cost, under the assumption
|
// which should factor out the API cost, under the assumption
|
||||||
// that all gl calls just return if the context isn't valid
|
// that all gl calls just return if the context isn't valid
|
||||||
if( r_skipRenderContext.GetBool() && backEnd.viewDef->viewEntitys )
|
|
||||||
{
|
// RB: not really needed
|
||||||
GLimp_DeactivateContext();
|
//if( r_skipRenderContext.GetBool() && backEnd.viewDef->viewEntitys )
|
||||||
}
|
//{
|
||||||
|
// GLimp_DeactivateContext();
|
||||||
|
//}
|
||||||
|
// RB end
|
||||||
|
|
||||||
backEnd.pc.c_surfaces += backEnd.viewDef->numDrawSurfs;
|
backEnd.pc.c_surfaces += backEnd.viewDef->numDrawSurfs;
|
||||||
|
|
||||||
|
@ -3165,11 +3168,13 @@ void RB_DrawView( const void* data, const int stereoEye )
|
||||||
RB_MotionBlur();
|
RB_MotionBlur();
|
||||||
|
|
||||||
// restore the context for 2D drawing if we were stubbing it out
|
// restore the context for 2D drawing if we were stubbing it out
|
||||||
if( r_skipRenderContext.GetBool() && backEnd.viewDef->viewEntitys )
|
// RB: not really needed
|
||||||
{
|
//if( r_skipRenderContext.GetBool() && backEnd.viewDef->viewEntitys )
|
||||||
GLimp_ActivateContext();
|
//{
|
||||||
GL_SetDefaultState();
|
// GLimp_ActivateContext();
|
||||||
}
|
// GL_SetDefaultState();
|
||||||
|
//}
|
||||||
|
// RB end
|
||||||
|
|
||||||
// optionally draw a box colored based on the eye number
|
// optionally draw a box colored based on the eye number
|
||||||
if( r_drawEyeColor.GetBool() )
|
if( r_drawEyeColor.GetBool() )
|
||||||
|
|
688
neo/sys/linux/linux_main.cpp
Normal file
688
neo/sys/linux/linux_main.cpp
Normal file
|
@ -0,0 +1,688 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 GPL Source Code
|
||||||
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 2012 Robert Beckebans
|
||||||
|
|
||||||
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||||
|
|
||||||
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
#include "../../idlib/precompiled.h"
|
||||||
|
#include "../posix/posix_public.h"
|
||||||
|
#include "../sys_local.h"
|
||||||
|
//#include "local.h"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef ID_MCHECK
|
||||||
|
#include <mcheck.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static idStr basepath;
|
||||||
|
static idStr savepath;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
Sys_DefaultSavePath
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
const char* Sys_DefaultSavePath()
|
||||||
|
{
|
||||||
|
#if defined( ID_DEMO_BUILD )
|
||||||
|
sprintf( savepath, "%s/.rbdoom3-demo", getenv( "HOME" ) );
|
||||||
|
#else
|
||||||
|
sprintf( savepath, "%s/.rbdoom3", getenv( "HOME" ) );
|
||||||
|
#endif
|
||||||
|
return savepath.c_str();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
Sys_EXEPath
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
const char* Sys_EXEPath()
|
||||||
|
{
|
||||||
|
static char buf[ 1024 ];
|
||||||
|
idStr linkpath;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
buf[ 0 ] = '\0';
|
||||||
|
sprintf( linkpath, "/proc/%d/exe", getpid() );
|
||||||
|
len = readlink( linkpath.c_str(), buf, sizeof( buf ) );
|
||||||
|
if( len == -1 )
|
||||||
|
{
|
||||||
|
Sys_Printf( "couldn't stat exe path link %s\n", linkpath.c_str() );
|
||||||
|
// RB: fixed array subscript is below array bounds
|
||||||
|
buf[ 0 ] = '\0';
|
||||||
|
// RB end
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_DefaultBasePath
|
||||||
|
|
||||||
|
Get the default base path
|
||||||
|
- binary image path
|
||||||
|
- current directory
|
||||||
|
- hardcoded
|
||||||
|
Try to be intelligent: if there is no BASE_GAMEDIR, try the next path
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
const char* Sys_DefaultBasePath()
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
idStr testbase;
|
||||||
|
basepath = Sys_EXEPath();
|
||||||
|
if( basepath.Length() )
|
||||||
|
{
|
||||||
|
basepath.StripFilename();
|
||||||
|
testbase = basepath;
|
||||||
|
testbase += "/";
|
||||||
|
testbase += BASE_GAMEDIR;
|
||||||
|
if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) )
|
||||||
|
{
|
||||||
|
return basepath.c_str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "no '%s' directory in exe path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( basepath != Posix_Cwd() )
|
||||||
|
{
|
||||||
|
basepath = Posix_Cwd();
|
||||||
|
testbase = basepath;
|
||||||
|
testbase += "/";
|
||||||
|
testbase += BASE_GAMEDIR;
|
||||||
|
if( stat( testbase.c_str(), &st ) != -1 && S_ISDIR( st.st_mode ) )
|
||||||
|
{
|
||||||
|
return basepath.c_str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "no '%s' directory in cwd path %s, skipping\n", BASE_GAMEDIR, basepath.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
common->Printf( "WARNING: using hardcoded default base path\n" );
|
||||||
|
return LINUX_DEFAULT_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_Shutdown
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Sys_Shutdown()
|
||||||
|
{
|
||||||
|
basepath.Clear();
|
||||||
|
savepath.Clear();
|
||||||
|
Posix_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_GetProcessorId
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
cpuid_t Sys_GetProcessorId()
|
||||||
|
{
|
||||||
|
return CPUID_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_GetProcessorString
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
const char* Sys_GetProcessorString()
|
||||||
|
{
|
||||||
|
return "generic";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_FPU_EnableExceptions
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
//void Sys_FPU_EnableExceptions( int exceptions )
|
||||||
|
//{
|
||||||
|
//}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_FPE_handler
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
void Sys_FPE_handler( int signum, siginfo_t* info, void* context )
|
||||||
|
{
|
||||||
|
assert( signum == SIGFPE );
|
||||||
|
Sys_Printf( "FPE\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_GetClockticks
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
double Sys_GetClockTicks()
|
||||||
|
{
|
||||||
|
#if defined( __i386__ )
|
||||||
|
unsigned long lo, hi;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"push %%ebx\n" \
|
||||||
|
"xor %%eax,%%eax\n" \
|
||||||
|
"cpuid\n" \
|
||||||
|
"rdtsc\n" \
|
||||||
|
"mov %%eax,%0\n" \
|
||||||
|
"mov %%edx,%1\n" \
|
||||||
|
"pop %%ebx\n"
|
||||||
|
: "=r"( lo ), "=r"( hi ) );
|
||||||
|
return ( double ) lo + ( double ) 0xFFFFFFFF * hi;
|
||||||
|
#else
|
||||||
|
//#error unsupported CPU
|
||||||
|
// RB begin
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime( CLOCK_MONOTONIC, &now );
|
||||||
|
return now.tv_sec * 1000000000LL + now.tv_nsec;
|
||||||
|
// RB end
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
MeasureClockTicks
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
double MeasureClockTicks()
|
||||||
|
{
|
||||||
|
double t0, t1;
|
||||||
|
|
||||||
|
t0 = Sys_GetClockTicks( );
|
||||||
|
Sys_Sleep( 1000 );
|
||||||
|
t1 = Sys_GetClockTicks( );
|
||||||
|
return t1 - t0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
Sys_ClockTicksPerSecond
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
double Sys_ClockTicksPerSecond()
|
||||||
|
{
|
||||||
|
static bool init = false;
|
||||||
|
static double ret;
|
||||||
|
|
||||||
|
int fd, len, pos, end;
|
||||||
|
char buf[ 4096 ];
|
||||||
|
|
||||||
|
if( init )
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open( "/proc/cpuinfo", O_RDONLY );
|
||||||
|
if( fd == -1 )
|
||||||
|
{
|
||||||
|
common->Printf( "couldn't read /proc/cpuinfo\n" );
|
||||||
|
ret = MeasureClockTicks();
|
||||||
|
init = true;
|
||||||
|
common->Printf( "measured CPU frequency: %g MHz\n", ret / 1000000.0 );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
len = read( fd, buf, 4096 );
|
||||||
|
close( fd );
|
||||||
|
pos = 0;
|
||||||
|
while( pos < len )
|
||||||
|
{
|
||||||
|
if( !idStr::Cmpn( buf + pos, "cpu MHz", 7 ) )
|
||||||
|
{
|
||||||
|
pos = strchr( buf + pos, ':' ) - buf + 2;
|
||||||
|
end = strchr( buf + pos, '\n' ) - buf;
|
||||||
|
if( pos < len && end < len )
|
||||||
|
{
|
||||||
|
buf[end] = '\0';
|
||||||
|
ret = atof( buf + pos );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "failed parsing /proc/cpuinfo\n" );
|
||||||
|
ret = MeasureClockTicks();
|
||||||
|
init = true;
|
||||||
|
common->Printf( "measured CPU frequency: %g MHz\n", ret / 1000000.0 );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
common->Printf( "/proc/cpuinfo CPU frequency: %g MHz\n", ret );
|
||||||
|
ret *= 1000000;
|
||||||
|
init = true;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
pos = strchr( buf + pos, '\n' ) - buf + 1;
|
||||||
|
}
|
||||||
|
common->Printf( "failed parsing /proc/cpuinfo\n" );
|
||||||
|
ret = MeasureClockTicks();
|
||||||
|
init = true;
|
||||||
|
common->Printf( "measured CPU frequency: %g MHz\n", ret / 1000000.0 );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_CPUCount
|
||||||
|
|
||||||
|
numLogicalCPUCores - the number of logical CPU per core
|
||||||
|
numPhysicalCPUCores - the total number of cores per package
|
||||||
|
numCPUPackages - the total number of packages (physical processors)
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
// RB begin
|
||||||
|
void Sys_CPUCount( int& numLogicalCPUCores, int& numPhysicalCPUCores, int& numCPUPackages )
|
||||||
|
{
|
||||||
|
static bool init = false;
|
||||||
|
static double ret;
|
||||||
|
|
||||||
|
static int s_numLogicalCPUCores;
|
||||||
|
static int s_numPhysicalCPUCores;
|
||||||
|
static int s_numCPUPackages;
|
||||||
|
|
||||||
|
int fd, len, pos, end;
|
||||||
|
char buf[ 4096 ];
|
||||||
|
|
||||||
|
if( init )
|
||||||
|
{
|
||||||
|
numPhysicalCPUCores = s_numPhysicalCPUCores;
|
||||||
|
numLogicalCPUCores = s_numLogicalCPUCores;
|
||||||
|
numCPUPackages = s_numCPUPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_numPhysicalCPUCores = 1;
|
||||||
|
s_numLogicalCPUCores = 1;
|
||||||
|
s_numCPUPackages = 1;
|
||||||
|
|
||||||
|
fd = open( "/proc/cpuinfo", O_RDONLY );
|
||||||
|
if( fd != -1 )
|
||||||
|
{
|
||||||
|
len = read( fd, buf, 4096 );
|
||||||
|
close( fd );
|
||||||
|
pos = 0;
|
||||||
|
while( pos < len )
|
||||||
|
{
|
||||||
|
if( !idStr::Cmpn( buf + pos, "processor", 9 ) )
|
||||||
|
{
|
||||||
|
pos = strchr( buf + pos, ':' ) - buf + 2;
|
||||||
|
end = strchr( buf + pos, '\n' ) - buf;
|
||||||
|
if( pos < len && end < len )
|
||||||
|
{
|
||||||
|
buf[end] = '\0';
|
||||||
|
int processor = atoi( buf + pos );
|
||||||
|
|
||||||
|
if( ( processor + 1 ) > s_numPhysicalCPUCores )
|
||||||
|
{
|
||||||
|
s_numPhysicalCPUCores = processor + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "failed parsing /proc/cpuinfo\n" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !idStr::Cmpn( buf + pos, "core id", 7 ) )
|
||||||
|
{
|
||||||
|
pos = strchr( buf + pos, ':' ) - buf + 2;
|
||||||
|
end = strchr( buf + pos, '\n' ) - buf;
|
||||||
|
if( pos < len && end < len )
|
||||||
|
{
|
||||||
|
buf[end] = '\0';
|
||||||
|
int coreId = atoi( buf + pos );
|
||||||
|
|
||||||
|
if( ( coreId + 1 ) > s_numLogicalCPUCores )
|
||||||
|
{
|
||||||
|
s_numLogicalCPUCores = coreId + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Printf( "failed parsing /proc/cpuinfo\n" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = strchr( buf + pos, '\n' ) - buf + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "/proc/cpuinfo CPU processors: %d\n", s_numPhysicalCPUCores );
|
||||||
|
common->Printf( "/proc/cpuinfo CPU logical cores: %d\n", s_numLogicalCPUCores );
|
||||||
|
|
||||||
|
numPhysicalCPUCores = s_numPhysicalCPUCores;
|
||||||
|
numLogicalCPUCores = s_numLogicalCPUCores;
|
||||||
|
numCPUPackages = s_numCPUPackages;
|
||||||
|
}
|
||||||
|
// RB end
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_GetSystemRam
|
||||||
|
returns in megabytes
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
int Sys_GetSystemRam()
|
||||||
|
{
|
||||||
|
long count, page_size;
|
||||||
|
int mb;
|
||||||
|
|
||||||
|
count = sysconf( _SC_PHYS_PAGES );
|
||||||
|
if( count == -1 )
|
||||||
|
{
|
||||||
|
common->Printf( "GetSystemRam: sysconf _SC_PHYS_PAGES failed\n" );
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
page_size = sysconf( _SC_PAGE_SIZE );
|
||||||
|
if( page_size == -1 )
|
||||||
|
{
|
||||||
|
common->Printf( "GetSystemRam: sysconf _SC_PAGE_SIZE failed\n" );
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
mb = ( int )( ( double )count * ( double )page_size / ( 1024 * 1024 ) );
|
||||||
|
// round to the nearest 16Mb
|
||||||
|
mb = ( mb + 8 ) & ~15;
|
||||||
|
return mb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DoStartProcess
|
||||||
|
if we don't fork, this function never returns
|
||||||
|
the no-fork lets you keep the terminal when you're about to spawn an installer
|
||||||
|
|
||||||
|
if the command contains spaces, system() is used. Otherwise the more straightforward execl ( system() blows though )
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Sys_DoStartProcess( const char* exeName, bool dofork )
|
||||||
|
{
|
||||||
|
bool use_system = false;
|
||||||
|
if( strchr( exeName, ' ' ) )
|
||||||
|
{
|
||||||
|
use_system = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set exec rights when it's about a single file to execute
|
||||||
|
struct stat buf;
|
||||||
|
if( stat( exeName, &buf ) == -1 )
|
||||||
|
{
|
||||||
|
printf( "stat %s failed: %s\n", exeName, strerror( errno ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( chmod( exeName, buf.st_mode | S_IXUSR ) == -1 )
|
||||||
|
{
|
||||||
|
printf( "cmod +x %s failed: %s\n", exeName, strerror( errno ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( dofork )
|
||||||
|
{
|
||||||
|
switch( fork() )
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
// main thread
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
if( use_system )
|
||||||
|
{
|
||||||
|
printf( "system %s\n", exeName );
|
||||||
|
system( exeName );
|
||||||
|
_exit( 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf( "execl %s\n", exeName );
|
||||||
|
execl( exeName, exeName, NULL );
|
||||||
|
printf( "execl failed: %s\n", strerror( errno ) );
|
||||||
|
_exit( -1 );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( use_system )
|
||||||
|
{
|
||||||
|
printf( "system %s\n", exeName );
|
||||||
|
system( exeName );
|
||||||
|
sleep( 1 ); // on some systems I've seen that starting the new process and exiting this one should not be too close
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf( "execl %s\n", exeName );
|
||||||
|
execl( exeName, exeName, NULL );
|
||||||
|
printf( "execl failed: %s\n", strerror( errno ) );
|
||||||
|
}
|
||||||
|
// terminate
|
||||||
|
_exit( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
Sys_OpenURL
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void idSysLocal::OpenURL( const char* url, bool quit )
|
||||||
|
{
|
||||||
|
const char* script_path;
|
||||||
|
idFile* script_file;
|
||||||
|
char cmdline[ 1024 ];
|
||||||
|
|
||||||
|
static bool quit_spamguard = false;
|
||||||
|
|
||||||
|
if( quit_spamguard )
|
||||||
|
{
|
||||||
|
common->DPrintf( "Sys_OpenURL: already in a doexit sequence, ignoring %s\n", url );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "Open URL: %s\n", url );
|
||||||
|
// opening an URL on *nix can mean a lot of things ..
|
||||||
|
// just spawn a script instead of deciding for the user :-)
|
||||||
|
|
||||||
|
// look in the savepath first, then in the basepath
|
||||||
|
script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_savepath" ), "", "openurl.sh" );
|
||||||
|
script_file = fileSystem->OpenExplicitFileRead( script_path );
|
||||||
|
if( !script_file )
|
||||||
|
{
|
||||||
|
script_path = fileSystem->BuildOSPath( cvarSystem->GetCVarString( "fs_basepath" ), "", "openurl.sh" );
|
||||||
|
script_file = fileSystem->OpenExplicitFileRead( script_path );
|
||||||
|
}
|
||||||
|
if( !script_file )
|
||||||
|
{
|
||||||
|
common->Printf( "Can't find URL script 'openurl.sh' in either savepath or basepath\n" );
|
||||||
|
common->Printf( "OpenURL '%s' failed\n", url );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fileSystem->CloseFile( script_file );
|
||||||
|
|
||||||
|
// if we are going to quit, only accept a single URL before quitting and spawning the script
|
||||||
|
if( quit )
|
||||||
|
{
|
||||||
|
quit_spamguard = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
common->Printf( "URL script: %s\n", script_path );
|
||||||
|
|
||||||
|
// StartProcess is going to execute a system() call with that - hence the &
|
||||||
|
idStr::snPrintf( cmdline, 1024, "%s '%s' &", script_path, url );
|
||||||
|
sys->StartProcess( cmdline, quit );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
Sys_DoPreferences
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
void Sys_DoPreferences() { }
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_FPU_SetDAZ
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_FPU_SetDAZ( bool enable )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
DWORD dwData;
|
||||||
|
|
||||||
|
_asm {
|
||||||
|
movzx ecx, byte ptr enable
|
||||||
|
and ecx, 1
|
||||||
|
shl ecx, 6
|
||||||
|
STMXCSR dword ptr dwData
|
||||||
|
mov eax, dwData
|
||||||
|
and eax, ~(1<<6) // clear DAX bit
|
||||||
|
or eax, ecx // set the DAZ bit
|
||||||
|
mov dwData, eax
|
||||||
|
LDMXCSR dword ptr dwData
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_FPU_SetFTZ
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void Sys_FPU_SetFTZ( bool enable )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
DWORD dwData;
|
||||||
|
|
||||||
|
_asm {
|
||||||
|
movzx ecx, byte ptr enable
|
||||||
|
and ecx, 1
|
||||||
|
shl ecx, 15
|
||||||
|
STMXCSR dword ptr dwData
|
||||||
|
mov eax, dwData
|
||||||
|
and eax, ~(1<<15) // clear FTZ bit
|
||||||
|
or eax, ecx // set the FTZ bit
|
||||||
|
mov dwData, eax
|
||||||
|
LDMXCSR dword ptr dwData
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
mem consistency stuff
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ID_MCHECK
|
||||||
|
|
||||||
|
const char* mcheckstrings[] =
|
||||||
|
{
|
||||||
|
"MCHECK_DISABLED",
|
||||||
|
"MCHECK_OK",
|
||||||
|
"MCHECK_FREE", // block freed twice
|
||||||
|
"MCHECK_HEAD", // memory before the block was clobbered
|
||||||
|
"MCHECK_TAIL" // memory after the block was clobbered
|
||||||
|
};
|
||||||
|
|
||||||
|
void abrt_func( mcheck_status status )
|
||||||
|
{
|
||||||
|
Sys_Printf( "memory consistency failure: %s\n", mcheckstrings[ status + 1 ] );
|
||||||
|
Posix_SetExit( EXIT_FAILURE );
|
||||||
|
common->Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_GetCmdLine
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
const char* Sys_GetCmdLine()
|
||||||
|
{
|
||||||
|
return "TODO Sys_GetCmdLine";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_ReLaunch
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void Sys_ReLaunch( void* data, const unsigned int dataSize )
|
||||||
|
{
|
||||||
|
idLib::Error( "Could not start process: TODO Sys_ReLaunch() " );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===============
|
||||||
|
main
|
||||||
|
===============
|
||||||
|
*/
|
||||||
|
int main( int argc, const char** argv )
|
||||||
|
{
|
||||||
|
#ifdef ID_MCHECK
|
||||||
|
// must have -lmcheck linkage
|
||||||
|
mcheck( abrt_func );
|
||||||
|
Sys_Printf( "memory consistency checking enabled\n" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Posix_EarlyInit( );
|
||||||
|
|
||||||
|
if( argc > 1 )
|
||||||
|
{
|
||||||
|
common->Init( argc - 1, &argv[1], NULL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common->Init( 0, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
Posix_LateInit( );
|
||||||
|
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
common->Frame();
|
||||||
|
}
|
||||||
|
}
|
111
neo/sys/posix/posix_achievements.cpp
Normal file
111
neo/sys/posix/posix_achievements.cpp
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 BFG Edition GPL Source Code
|
||||||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
#pragma hdrstop
|
||||||
|
#include "../../idlib/precompiled.h"
|
||||||
|
|
||||||
|
#include "posix_achievements.h"
|
||||||
|
#include "../sys_session_local.h"
|
||||||
|
|
||||||
|
extern idCVar achievements_Verbose;
|
||||||
|
|
||||||
|
#define STEAM_ACHIEVEMENT_PREFIX "ach_"
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idAchievementSystemWin::idAchievementSystemWin
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idAchievementSystemWin::idAchievementSystemWin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idAchievementSystemWin::IsInitialized
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idAchievementSystemWin::IsInitialized()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================================
|
||||||
|
idAchievementSystemWin::AchievementUnlock
|
||||||
|
================================
|
||||||
|
*/
|
||||||
|
void idAchievementSystemWin::AchievementUnlock( idLocalUser* user, int achievementID )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idAchievementSystemWin::AchievementLock
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idAchievementSystemWin::AchievementLock( idLocalUser* user, const int achievementID )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idAchievementSystemWin::AchievementLockAll
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idAchievementSystemWin::AchievementLockAll( idLocalUser* user, const int maxId )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idAchievementSystemWin::GetAchievementDescription
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idAchievementSystemWin::GetAchievementDescription( idLocalUser* user, const int achievementID, achievementDescription_t& data ) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idAchievementSystemWin::GetAchievementState
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idAchievementSystemWin::GetAchievementState( idLocalUser* user, idArray< bool, idAchievementSystem::MAX_ACHIEVEMENTS >& achievements ) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================================
|
||||||
|
idAchievementSystemWin::Pump
|
||||||
|
================================
|
||||||
|
*/
|
||||||
|
void idAchievementSystemWin::Pump()
|
||||||
|
{
|
||||||
|
}
|
50
neo/sys/posix/posix_achievements.h
Normal file
50
neo/sys/posix/posix_achievements.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 BFG Edition GPL Source Code
|
||||||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
#ifndef __POSIX_ACHIEVEMENTS_H__
|
||||||
|
#define __POSIX_ACHIEVEMENTS_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
================================================
|
||||||
|
idAchievementSystemWin
|
||||||
|
================================================
|
||||||
|
*/
|
||||||
|
class idAchievementSystemWin : public idAchievementSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
idAchievementSystemWin();
|
||||||
|
|
||||||
|
bool IsInitialized();
|
||||||
|
void AchievementUnlock( idLocalUser* user, const int achievementID );
|
||||||
|
void AchievementLock( idLocalUser* user, const int achievementID );
|
||||||
|
void AchievementLockAll( idLocalUser* user, const int maxId );
|
||||||
|
void Pump();
|
||||||
|
bool GetAchievementDescription( idLocalUser* user, const int id, achievementDescription_t& data ) const;
|
||||||
|
bool GetAchievementState( idLocalUser* user, idArray< bool, idAchievementSystem::MAX_ACHIEVEMENTS >& achievements ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __POSIX_ACHIEVEMENTS_H__
|
131
neo/sys/posix/posix_localuser.cpp
Normal file
131
neo/sys/posix/posix_localuser.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 BFG Edition GPL Source Code
|
||||||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma hdrstop
|
||||||
|
#include "../../idlib/precompiled.h"
|
||||||
|
#include "posix_localuser.h"
|
||||||
|
|
||||||
|
extern idCVar win_userPersistent;
|
||||||
|
extern idCVar win_userOnline;
|
||||||
|
extern idCVar win_isInParty;
|
||||||
|
extern idCVar win_partyCount;
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLocalUserWin::Init
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idLocalUserWin::Init( int inputDevice_, const char* gamertag_, int numLocalUsers )
|
||||||
|
{
|
||||||
|
if( numLocalUsers == 1 ) // Check for 1, since this is now incremented before we get in here
|
||||||
|
{
|
||||||
|
// This is the master user
|
||||||
|
gamertag = gamertag_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// On steam, we need to generate a name based off the master user for split-screen users.
|
||||||
|
// We use the number of users on the system to generate the name rather than the device
|
||||||
|
// number so that it is always consistently "username (2)" for the second player.
|
||||||
|
gamertag.Format( "%s (%i)", gamertag_, numLocalUsers );
|
||||||
|
}
|
||||||
|
|
||||||
|
inputDevice = inputDevice_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLocalUserWin::IsProfileReady
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idLocalUserWin::IsProfileReady() const
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
return win_userPersistent.GetBool();
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLocalUserWin::IsOnline
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idLocalUserWin::IsOnline() const
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
return win_userOnline.GetBool();
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLocalUserWin::IsInParty
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idLocalUserWin::IsInParty() const
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
return win_isInParty.GetBool();
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLocalUserWin::GetPartyCount
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idLocalUserWin::GetPartyCount() const
|
||||||
|
{
|
||||||
|
// TODO: Implement
|
||||||
|
#ifdef _DEBUG
|
||||||
|
return win_partyCount.GetInteger();
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLocalUserWin::VerifyUserState
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idLocalUserWin::VerifyUserState( winUserState_t& state )
|
||||||
|
{
|
||||||
|
|
||||||
|
if( state.inputDevice != inputDevice )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
96
neo/sys/posix/posix_localuser.h
Normal file
96
neo/sys/posix/posix_localuser.h
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 BFG Edition GPL Source Code
|
||||||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
#ifndef __POSIX_LOCALUSER_H__
|
||||||
|
#define __POSIX_LOCALUSER_H__
|
||||||
|
|
||||||
|
// This is to quickly get/set the data needed for disc-swapping
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int inputDevice;
|
||||||
|
} winUserState_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
================================================
|
||||||
|
idLocalUserWin
|
||||||
|
================================================
|
||||||
|
*/
|
||||||
|
class idLocalUserWin : public idLocalUser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const int MAX_GAMERTAG = 64; // max number of bytes for a gamertag
|
||||||
|
static const int MAX_GAMERTAG_CHARS = 16; // max number of UTF-8 characters to show
|
||||||
|
|
||||||
|
idLocalUserWin() : inputDevice( 0 ) {}
|
||||||
|
|
||||||
|
//==========================================================================================
|
||||||
|
// idLocalUser interface
|
||||||
|
//==========================================================================================
|
||||||
|
virtual bool IsProfileReady() const;
|
||||||
|
virtual bool IsOnline() const;
|
||||||
|
virtual bool IsInParty() const;
|
||||||
|
virtual int GetPartyCount() const;
|
||||||
|
virtual uint32 GetOnlineCaps() const
|
||||||
|
{
|
||||||
|
return ( IsPersistent() && IsOnline() ) ? ( CAP_IS_ONLINE | CAP_CAN_PLAY_ONLINE ) : 0;
|
||||||
|
}
|
||||||
|
virtual int GetInputDevice() const
|
||||||
|
{
|
||||||
|
return inputDevice;
|
||||||
|
}
|
||||||
|
virtual const char* GetGamerTag() const
|
||||||
|
{
|
||||||
|
return gamertag.c_str();
|
||||||
|
}
|
||||||
|
virtual void PumpPlatform() {}
|
||||||
|
|
||||||
|
//==========================================================================================
|
||||||
|
// idLocalUserWin interface
|
||||||
|
//==========================================================================================
|
||||||
|
void SetInputDevice( int inputDevice_ )
|
||||||
|
{
|
||||||
|
inputDevice = inputDevice_;
|
||||||
|
}
|
||||||
|
void SetGamerTag( const char* gamerTag_ )
|
||||||
|
{
|
||||||
|
gamertag = gamerTag_;
|
||||||
|
}
|
||||||
|
winUserState_t GetUserState()
|
||||||
|
{
|
||||||
|
winUserState_t a = { inputDevice };
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
bool VerifyUserState( winUserState_t& state );
|
||||||
|
|
||||||
|
void Init( int inputDevice_, const char* gamertag_, int numLocalUsers );
|
||||||
|
|
||||||
|
private:
|
||||||
|
idStrStatic< MAX_GAMERTAG > gamertag;
|
||||||
|
int inputDevice;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __POSIX_LOCALUSER_H__
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
Doom 3 GPL Source Code
|
Doom 3 GPL Source Code
|
||||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 2012 Robert Beckebans
|
||||||
|
|
||||||
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
||||||
|
|
||||||
|
@ -46,6 +47,8 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sys/statvfs.h>
|
||||||
// RB end
|
// RB end
|
||||||
|
|
||||||
#include "posix_public.h"
|
#include "posix_public.h"
|
||||||
|
@ -95,10 +98,12 @@ void Posix_Exit( int ret )
|
||||||
}
|
}
|
||||||
// at this point, too late to catch signals
|
// at this point, too late to catch signals
|
||||||
Posix_ClearSigs();
|
Posix_ClearSigs();
|
||||||
if( asyncThread.threadHandle )
|
|
||||||
{
|
//if( asyncThread.threadHandle )
|
||||||
Sys_DestroyThread( asyncThread );
|
//{
|
||||||
}
|
// Sys_DestroyThread( asyncThread );
|
||||||
|
//}
|
||||||
|
|
||||||
// process spawning. it's best when it happens after everything has shut down
|
// process spawning. it's best when it happens after everything has shut down
|
||||||
if( exit_spawn[0] )
|
if( exit_spawn[0] )
|
||||||
{
|
{
|
||||||
|
@ -233,6 +238,26 @@ int Sys_Milliseconds()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RB: added for BFG
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_Microseconds
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
uint64 Sys_Microseconds()
|
||||||
|
{
|
||||||
|
static uint64 ticksPerMicrosecondTimes1024 = 0;
|
||||||
|
|
||||||
|
if( ticksPerMicrosecondTimes1024 == 0 )
|
||||||
|
{
|
||||||
|
ticksPerMicrosecondTimes1024 = ( ( uint64 )Sys_ClockTicksPerSecond() << 10 ) / 1000000;
|
||||||
|
assert( ticksPerMicrosecondTimes1024 > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( ( uint64 )( ( int64 )Sys_GetClockTicks() << 10 ) ) / ticksPerMicrosecondTimes1024;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_Mkdir
|
Sys_Mkdir
|
||||||
|
@ -243,6 +268,51 @@ void Sys_Mkdir( const char* path )
|
||||||
mkdir( path, 0777 );
|
mkdir( path, 0777 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
Sys_Rmdir
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
bool Sys_Rmdir( const char* path )
|
||||||
|
{
|
||||||
|
return ( rmdir( path ) == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_IsFileWritable
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool Sys_IsFileWritable( const char* path )
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if( stat( path, &st ) == -1 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( st.st_mode & S_IWRITE ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_IsFolder
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
sysFolder_t Sys_IsFolder( const char* path )
|
||||||
|
{
|
||||||
|
struct stat buffer;
|
||||||
|
|
||||||
|
if( stat( path, &buffer ) < 0 )
|
||||||
|
{
|
||||||
|
return FOLDER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( buffer.st_mode & S_IFDIR ) != 0 ? FOLDER_YES : FOLDER_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RB end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_ListFiles
|
Sys_ListFiles
|
||||||
|
@ -319,12 +389,13 @@ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list
|
||||||
EVENT LOOP
|
EVENT LOOP
|
||||||
============================================================================
|
============================================================================
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
#define MAX_QUED_EVENTS 256
|
#define MAX_QUED_EVENTS 256
|
||||||
#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
|
#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
|
||||||
|
|
||||||
static sysEvent_t eventQue[MAX_QUED_EVENTS];
|
static sysEvent_t eventQue[MAX_QUED_EVENTS];
|
||||||
static int eventHead, eventTail;
|
static int eventHead, eventTail;
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
|
@ -333,11 +404,12 @@ Posix_QueEvent
|
||||||
ptr should either be null, or point to a block of data that can be freed later
|
ptr should either be null, or point to a block of data that can be freed later
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
void Posix_QueEvent( sysEventType_t type, int value, int value2,
|
void Posix_QueEvent( sysEventType_t type, int value, int value2,
|
||||||
int ptrLength, void* ptr )
|
int ptrLength, void* ptr )
|
||||||
{
|
{
|
||||||
sysEvent_t* ev;
|
sysEvent_t* ev;
|
||||||
|
|
||||||
ev = &eventQue[eventHead & MASK_QUED_EVENTS];
|
ev = &eventQue[eventHead & MASK_QUED_EVENTS];
|
||||||
if( eventHead - eventTail >= MAX_QUED_EVENTS )
|
if( eventHead - eventTail >= MAX_QUED_EVENTS )
|
||||||
{
|
{
|
||||||
|
@ -351,29 +423,31 @@ void Posix_QueEvent( sysEventType_t type, int value, int value2,
|
||||||
}
|
}
|
||||||
eventTail++;
|
eventTail++;
|
||||||
}
|
}
|
||||||
|
|
||||||
eventHead++;
|
eventHead++;
|
||||||
|
|
||||||
ev->evType = type;
|
ev->evType = type;
|
||||||
ev->evValue = value;
|
ev->evValue = value;
|
||||||
ev->evValue2 = value2;
|
ev->evValue2 = value2;
|
||||||
ev->evPtrLength = ptrLength;
|
ev->evPtrLength = ptrLength;
|
||||||
ev->evPtr = ptr;
|
ev->evPtr = ptr;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
common->Printf( "Event %d: %d %d\n", ev->evType, ev->evValue, ev->evValue2 );
|
common->Printf( "Event %d: %d %d\n", ev->evType, ev->evValue, ev->evValue2 );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_GetEvent
|
Sys_GetEvent
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
sysEvent_t Sys_GetEvent()
|
sysEvent_t Sys_GetEvent()
|
||||||
{
|
{
|
||||||
static sysEvent_t ev;
|
static sysEvent_t ev;
|
||||||
|
|
||||||
// return if we have data
|
// return if we have data
|
||||||
if( eventHead > eventTail )
|
if( eventHead > eventTail )
|
||||||
{
|
{
|
||||||
|
@ -382,19 +456,22 @@ sysEvent_t Sys_GetEvent()
|
||||||
}
|
}
|
||||||
// return the empty event with the current time
|
// return the empty event with the current time
|
||||||
memset( &ev, 0, sizeof( ev ) );
|
memset( &ev, 0, sizeof( ev ) );
|
||||||
|
|
||||||
return ev;
|
return ev;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_ClearEvents
|
Sys_ClearEvents
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
void Sys_ClearEvents()
|
void Sys_ClearEvents()
|
||||||
{
|
{
|
||||||
eventHead = eventTail = 0;
|
eventHead = eventTail = 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
|
@ -516,7 +593,7 @@ const char* Sys_DefaultCDPath()
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
long Sys_FileTimeStamp( FILE* fp )
|
ID_TIME_T Sys_FileTimeStamp( idFileHandle fp )
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
fstat( fileno( fp ), &st );
|
fstat( fileno( fp ), &st );
|
||||||
|
@ -567,6 +644,7 @@ void Sys_FlushCacheMemory( void* base, int bytes )
|
||||||
// Sys_Printf("Sys_FlushCacheMemory stub\n");
|
// Sys_Printf("Sys_FlushCacheMemory stub\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool Sys_FPU_StackIsEmpty()
|
bool Sys_FPU_StackIsEmpty()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -584,6 +662,7 @@ const char* Sys_FPU_GetState()
|
||||||
void Sys_FPU_SetPrecision( int precision )
|
void Sys_FPU_SetPrecision( int precision )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
|
@ -615,18 +694,59 @@ void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes )
|
||||||
common->DPrintf( "TODO: Sys_SetPhysicalWorkMemory\n" );
|
common->DPrintf( "TODO: Sys_SetPhysicalWorkMemory\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RB begin
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
================
|
||||||
Sys_GetDriveFreeSpace
|
Sys_GetDriveFreeSpace
|
||||||
return in MegaBytes
|
returns in megabytes
|
||||||
===========
|
================
|
||||||
*/
|
*/
|
||||||
int Sys_GetDriveFreeSpace( const char* path )
|
int Sys_GetDriveFreeSpace( const char* path )
|
||||||
{
|
{
|
||||||
common->DPrintf( "TODO: Sys_GetDriveFreeSpace\n" );
|
int ret = 26;
|
||||||
return 1000 * 1024;
|
|
||||||
|
struct statvfs st;
|
||||||
|
|
||||||
|
if( statvfs( path, &st ) == 0 )
|
||||||
|
{
|
||||||
|
unsigned long blocksize = st.f_bsize;
|
||||||
|
unsigned long freeblocks = st.f_bfree;
|
||||||
|
|
||||||
|
unsigned long free = blocksize * freeblocks;
|
||||||
|
|
||||||
|
ret = ( double )( free ) / ( 1024.0 * 1024.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_GetDriveFreeSpaceInBytes
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int64 Sys_GetDriveFreeSpaceInBytes( const char* path )
|
||||||
|
{
|
||||||
|
int64 ret = 1;
|
||||||
|
|
||||||
|
struct statvfs st;
|
||||||
|
|
||||||
|
if( statvfs( path, &st ) == 0 )
|
||||||
|
{
|
||||||
|
unsigned long blocksize = st.f_bsize;
|
||||||
|
unsigned long freeblocks = st.f_bfree;
|
||||||
|
|
||||||
|
unsigned long free = blocksize * freeblocks;
|
||||||
|
|
||||||
|
ret = free;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RB end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_AlreadyRunning
|
Sys_AlreadyRunning
|
||||||
|
@ -645,12 +765,15 @@ Posix_EarlyInit
|
||||||
*/
|
*/
|
||||||
void Posix_EarlyInit()
|
void Posix_EarlyInit()
|
||||||
{
|
{
|
||||||
memset( &asyncThread, 0, sizeof( asyncThread ) );
|
//memset( &asyncThread, 0, sizeof( asyncThread ) );
|
||||||
|
|
||||||
exit_spawn[0] = '\0';
|
exit_spawn[0] = '\0';
|
||||||
Posix_InitSigs();
|
Posix_InitSigs();
|
||||||
|
|
||||||
// set the base time
|
// set the base time
|
||||||
Sys_Milliseconds();
|
Sys_Milliseconds();
|
||||||
Posix_InitPThreads();
|
|
||||||
|
//Posix_InitPThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -664,10 +787,12 @@ void Posix_LateInit()
|
||||||
com_pid.SetInteger( getpid() );
|
com_pid.SetInteger( getpid() );
|
||||||
common->Printf( "pid: %d\n", com_pid.GetInteger() );
|
common->Printf( "pid: %d\n", com_pid.GetInteger() );
|
||||||
common->Printf( "%d MB System Memory\n", Sys_GetSystemRam() );
|
common->Printf( "%d MB System Memory\n", Sys_GetSystemRam() );
|
||||||
#ifndef ID_DEDICATED
|
|
||||||
common->Printf( "%d MB Video Memory\n", Sys_GetVideoRam() );
|
//#ifndef ID_DEDICATED
|
||||||
#endif
|
//common->Printf( "%d MB Video Memory\n", Sys_GetVideoRam() );
|
||||||
Posix_StartAsyncThread( );
|
//#endif
|
||||||
|
|
||||||
|
//Posix_StartAsyncThread( );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -826,7 +951,7 @@ void tty_Show()
|
||||||
|
|
||||||
// RB begin
|
// RB begin
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
//__android_log_print(ANDROID_LOG_DEBUG, "Techyon_DEBUG", "%s", buf);
|
//__android_log_print(ANDROID_LOG_DEBUG, "RBDoom3_DEBUG", "%s", buf);
|
||||||
#endif
|
#endif
|
||||||
// RB end
|
// RB end
|
||||||
|
|
||||||
|
@ -1164,6 +1289,7 @@ called during frame loops, pacifier updates etc.
|
||||||
this is only for console input polling and misc mouse grab tasks
|
this is only for console input polling and misc mouse grab tasks
|
||||||
the actual mouse and keyboard input is in the Sys_Poll logic
|
the actual mouse and keyboard input is in the Sys_Poll logic
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
void Sys_GenerateEvents()
|
void Sys_GenerateEvents()
|
||||||
{
|
{
|
||||||
char* s;
|
char* s;
|
||||||
|
@ -1171,13 +1297,14 @@ void Sys_GenerateEvents()
|
||||||
{
|
{
|
||||||
char* b;
|
char* b;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = strlen( s ) + 1;
|
len = strlen( s ) + 1;
|
||||||
b = ( char* )Mem_Alloc( len );
|
b = ( char* )Mem_Alloc( len );
|
||||||
strcpy( b, s );
|
strcpy( b, s );
|
||||||
Posix_QueEvent( SE_CONSOLE, 0, 0, len, b );
|
Posix_QueEvent( SE_CONSOLE, 0, 0, len, b );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
|
@ -1196,7 +1323,7 @@ void Sys_DebugPrintf( const char* fmt, ... )
|
||||||
va_end( argptr );
|
va_end( argptr );
|
||||||
msg[sizeof( msg ) - 1] = '\0';
|
msg[sizeof( msg ) - 1] = '\0';
|
||||||
|
|
||||||
__android_log_print( ANDROID_LOG_DEBUG, "Techyon_Debug", msg );
|
__android_log_print( ANDROID_LOG_DEBUG, "RBDoom3_Debug", msg );
|
||||||
#else
|
#else
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
|
||||||
|
@ -1211,7 +1338,7 @@ void Sys_DebugPrintf( const char* fmt, ... )
|
||||||
void Sys_DebugVPrintf( const char* fmt, va_list arg )
|
void Sys_DebugVPrintf( const char* fmt, va_list arg )
|
||||||
{
|
{
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
__android_log_vprint( ANDROID_LOG_DEBUG, "Techyon_Debug", fmt, arg );
|
__android_log_vprint( ANDROID_LOG_DEBUG, "RBDoom3_Debug", fmt, arg );
|
||||||
#else
|
#else
|
||||||
tty_Hide();
|
tty_Hide();
|
||||||
vprintf( fmt, arg );
|
vprintf( fmt, arg );
|
||||||
|
@ -1230,7 +1357,7 @@ void Sys_Printf( const char* fmt, ... )
|
||||||
va_end( argptr );
|
va_end( argptr );
|
||||||
msg[sizeof( msg ) - 1] = '\0';
|
msg[sizeof( msg ) - 1] = '\0';
|
||||||
|
|
||||||
__android_log_print( ANDROID_LOG_DEBUG, "Techyon", msg );
|
__android_log_print( ANDROID_LOG_DEBUG, "RBDoom3", msg );
|
||||||
#else
|
#else
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
|
||||||
|
@ -1245,7 +1372,7 @@ void Sys_Printf( const char* fmt, ... )
|
||||||
void Sys_VPrintf( const char* fmt, va_list arg )
|
void Sys_VPrintf( const char* fmt, va_list arg )
|
||||||
{
|
{
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
__android_log_vprint( ANDROID_LOG_DEBUG, "Techyon", fmt, arg );
|
__android_log_vprint( ANDROID_LOG_DEBUG, "RBDoom3", fmt, arg );
|
||||||
#else
|
#else
|
||||||
tty_Hide();
|
tty_Hide();
|
||||||
vprintf( fmt, arg );
|
vprintf( fmt, arg );
|
||||||
|
@ -1272,8 +1399,12 @@ void Sys_Error( const char* error, ... )
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
================
|
||||||
Sys_FreeOpenAL
|
Sys_SetLanguageFromSystem
|
||||||
===============
|
================
|
||||||
*/
|
*/
|
||||||
void Sys_FreeOpenAL() { }
|
extern idCVar sys_lang;
|
||||||
|
void Sys_SetLanguageFromSystem()
|
||||||
|
{
|
||||||
|
sys_lang.SetString( Sys_DefaultLanguage() );
|
||||||
|
}
|
||||||
|
|
|
@ -46,10 +46,9 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include "../../idlib/precompiled.h"
|
#include "../../idlib/precompiled.h"
|
||||||
|
|
||||||
idPort clientPort, serverPort;
|
idUDP clientPort, serverPort;
|
||||||
|
|
||||||
idCVar net_ip( "net_ip", "localhost", CVAR_SYSTEM, "local IP address" );
|
idCVar net_ip( "net_ip", "localhost", CVAR_SYSTEM, "local IP address" );
|
||||||
idCVar net_port( "net_port", "", CVAR_SYSTEM | CVAR_INTEGER, "local IP port number" );
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -540,12 +539,47 @@ static int IPSocket( const char* net_interface, int port, netadr_t* bound_to = N
|
||||||
return newsocket;
|
return newsocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_GetLocalIPCount
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int Sys_GetLocalIPCount()
|
||||||
|
{
|
||||||
|
return num_interfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_GetLocalIP
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
const char* Sys_GetLocalIP( int i )
|
||||||
|
{
|
||||||
|
if( ( i < 0 ) || ( i >= num_interfaces ) )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char s[64];
|
||||||
|
|
||||||
|
unsigned char bytes[4];
|
||||||
|
bytes[0] = netint[i].ip & 0xFF;
|
||||||
|
bytes[1] = ( netint[i].ip >> 8 ) & 0xFF;
|
||||||
|
bytes[2] = ( netint[i].ip >> 16 ) & 0xFF;
|
||||||
|
bytes[3] = ( netint[i].ip >> 24 ) & 0xFF;
|
||||||
|
|
||||||
|
idStr::snPrintf( s, sizeof( s ), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
idPort::idPort
|
idUDP::idUDP
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
idPort::idPort()
|
idUDP::idUDP()
|
||||||
{
|
{
|
||||||
netSocket = 0;
|
netSocket = 0;
|
||||||
memset( &bound_to, 0, sizeof( bound_to ) );
|
memset( &bound_to, 0, sizeof( bound_to ) );
|
||||||
|
@ -553,20 +587,20 @@ idPort::idPort()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
idPort::~idPort
|
idUDP::~idUDP
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
idPort::~idPort()
|
idUDP::~idUDP()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
idPort::Close
|
idUDP::Close
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void idPort::Close()
|
void idUDP::Close()
|
||||||
{
|
{
|
||||||
if( netSocket )
|
if( netSocket )
|
||||||
{
|
{
|
||||||
|
@ -578,10 +612,10 @@ void idPort::Close()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
idPort::GetPacket
|
idUDP::GetPacket
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
bool idPort::GetPacket( netadr_t& net_from, void* data, int& size, int maxSize )
|
bool idUDP::GetPacket( netadr_t& net_from, void* data, int& size, int maxSize )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct sockaddr_in from;
|
struct sockaddr_in from;
|
||||||
|
@ -602,7 +636,7 @@ bool idPort::GetPacket( netadr_t& net_from, void* data, int& size, int maxSize )
|
||||||
// those commonly happen, don't verbose
|
// those commonly happen, don't verbose
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
common->DPrintf( "idPort::GetPacket recvfrom(): %s\n", strerror( errno ) );
|
common->DPrintf( "idUDP::GetPacket recvfrom(): %s\n", strerror( errno ) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,10 +649,10 @@ bool idPort::GetPacket( netadr_t& net_from, void* data, int& size, int maxSize )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
idPort::GetPacketBlocking
|
idUDP::GetPacketBlocking
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
bool idPort::GetPacketBlocking( netadr_t& net_from, void* data, int& size, int maxSize, int timeout )
|
bool idUDP::GetPacketBlocking( netadr_t& net_from, void* data, int& size, int maxSize, int timeout )
|
||||||
{
|
{
|
||||||
fd_set set;
|
fd_set set;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -644,12 +678,12 @@ bool idPort::GetPacketBlocking( netadr_t& net_from, void* data, int& size, int m
|
||||||
{
|
{
|
||||||
if( errno == EINTR )
|
if( errno == EINTR )
|
||||||
{
|
{
|
||||||
common->DPrintf( "idPort::GetPacketBlocking: select EINTR\n" );
|
common->DPrintf( "idUDP::GetPacketBlocking: select EINTR\n" );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
common->Error( "idPort::GetPacketBlocking: select failed: %s\n", strerror( errno ) );
|
common->Error( "idUDP::GetPacketBlocking: select failed: %s\n", strerror( errno ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,7 +699,7 @@ bool idPort::GetPacketBlocking( netadr_t& net_from, void* data, int& size, int m
|
||||||
if( ret == -1 )
|
if( ret == -1 )
|
||||||
{
|
{
|
||||||
// there should be no blocking errors once select declares things are good
|
// there should be no blocking errors once select declares things are good
|
||||||
common->DPrintf( "idPort::GetPacketBlocking: %s\n", strerror( errno ) );
|
common->DPrintf( "idUDP::GetPacketBlocking: %s\n", strerror( errno ) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert( ret < maxSize );
|
assert( ret < maxSize );
|
||||||
|
@ -676,17 +710,17 @@ bool idPort::GetPacketBlocking( netadr_t& net_from, void* data, int& size, int m
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
idPort::SendPacket
|
idUDP::SendPacket
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void idPort::SendPacket( const netadr_t to, const void* data, int size )
|
void idUDP::SendPacket( const netadr_t to, const void* data, int size )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
if( to.type == NA_BAD )
|
if( to.type == NA_BAD )
|
||||||
{
|
{
|
||||||
common->Warning( "idPort::SendPacket: bad address type NA_BAD - ignored" );
|
common->Warning( "idUDP::SendPacket: bad address type NA_BAD - ignored" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,16 +734,16 @@ void idPort::SendPacket( const netadr_t to, const void* data, int size )
|
||||||
ret = sendto( netSocket, data, size, 0, ( struct sockaddr* ) &addr, sizeof( addr ) );
|
ret = sendto( netSocket, data, size, 0, ( struct sockaddr* ) &addr, sizeof( addr ) );
|
||||||
if( ret == -1 )
|
if( ret == -1 )
|
||||||
{
|
{
|
||||||
common->Printf( "idPort::SendPacket ERROR: to %s: %s\n", Sys_NetAdrToString( to ), strerror( errno ) );
|
common->Printf( "idUDP::SendPacket ERROR: to %s: %s\n", Sys_NetAdrToString( to ), strerror( errno ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
idPort::InitForPort
|
idUDP::InitForPort
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
bool idPort::InitForPort( int portNumber )
|
bool idUDP::InitForPort( int portNumber )
|
||||||
{
|
{
|
||||||
netSocket = IPSocket( net_ip.GetString(), portNumber, &bound_to );
|
netSocket = IPSocket( net_ip.GetString(), portNumber, &bound_to );
|
||||||
if( netSocket <= 0 )
|
if( netSocket <= 0 )
|
||||||
|
@ -721,209 +755,4 @@ bool idPort::InitForPort( int portNumber )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
idTCP::idTCP
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
idTCP::idTCP()
|
|
||||||
{
|
|
||||||
fd = 0;
|
|
||||||
memset( &address, 0, sizeof( address ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
idTCP::~idTCP
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
idTCP::~idTCP()
|
|
||||||
{
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
idTCP::Init
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
bool idTCP::Init( const char* host, short port )
|
|
||||||
{
|
|
||||||
struct sockaddr_in sadr;
|
|
||||||
if( !Sys_StringToNetAdr( host, &address, true ) )
|
|
||||||
{
|
|
||||||
common->Printf( "Couldn't resolve server name \"%s\"\n", host );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
address.type = NA_IP;
|
|
||||||
if( !address.port )
|
|
||||||
{
|
|
||||||
address.port = port;
|
|
||||||
}
|
|
||||||
common->Printf( "\"%s\" resolved to %i.%i.%i.%i:%i\n", host,
|
|
||||||
address.ip[0], address.ip[1], address.ip[2], address.ip[3], address.port );
|
|
||||||
NetadrToSockadr( &address, &sadr );
|
|
||||||
|
|
||||||
if( fd )
|
|
||||||
{
|
|
||||||
common->Warning( "idTCP::Init: already initialized?\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( fd = socket( PF_INET, SOCK_STREAM, 0 ) ) == -1 )
|
|
||||||
{
|
|
||||||
fd = 0;
|
|
||||||
common->Printf( "ERROR: idTCP::Init: socket: %s\n", strerror( errno ) );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( connect( fd, ( const sockaddr* )&sadr, sizeof( sadr ) ) == -1 )
|
|
||||||
{
|
|
||||||
common->Printf( "ERROR: idTCP::Init: connect: %s\n", strerror( errno ) );
|
|
||||||
close( fd );
|
|
||||||
fd = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int status;
|
|
||||||
if( ( status = fcntl( fd, F_GETFL, 0 ) ) != -1 )
|
|
||||||
{
|
|
||||||
status |= O_NONBLOCK; /* POSIX */
|
|
||||||
status = fcntl( fd, F_SETFL, status );
|
|
||||||
}
|
|
||||||
if( status == -1 )
|
|
||||||
{
|
|
||||||
common->Printf( "ERROR: idTCP::Init: fcntl / O_NONBLOCK: %s\n", strerror( errno ) );
|
|
||||||
close( fd );
|
|
||||||
fd = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
common->DPrintf( "Opened TCP connection\n" );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
idTCP::Close
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
void idTCP::Close()
|
|
||||||
{
|
|
||||||
if( fd )
|
|
||||||
{
|
|
||||||
close( fd );
|
|
||||||
}
|
|
||||||
fd = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
idTCP::Read
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
int idTCP::Read( void* data, int size )
|
|
||||||
{
|
|
||||||
int nbytes;
|
|
||||||
|
|
||||||
if( !fd )
|
|
||||||
{
|
|
||||||
common->Printf( "idTCP::Read: not initialized\n" );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_GNU_SOURCE)
|
|
||||||
// handle EINTR interrupted system call with TEMP_FAILURE_RETRY - this is probably GNU libc specific
|
|
||||||
if( ( nbytes = TEMP_FAILURE_RETRY( read( fd, data, size ) ) ) == -1 )
|
|
||||||
{
|
|
||||||
#else
|
|
||||||
do
|
|
||||||
{
|
|
||||||
nbytes = read( fd, data, size );
|
|
||||||
}
|
|
||||||
while( nbytes == -1 && errno == EINTR );
|
|
||||||
if( nbytes == -1 )
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
if( errno == EAGAIN )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
common->Printf( "ERROR: idTCP::Read: %s\n", strerror( errno ) );
|
|
||||||
Close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// a successful read of 0 bytes indicates remote has closed the connection
|
|
||||||
if( nbytes == 0 )
|
|
||||||
{
|
|
||||||
common->DPrintf( "idTCP::Read: read 0 bytes - assume connection closed\n" );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nbytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
idTCP::Write
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void got_SIGPIPE( int signum )
|
|
||||||
{
|
|
||||||
common->Printf( "idTCP: SIGPIPE\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
int idTCP::Write( void* data, int size )
|
|
||||||
{
|
|
||||||
int nbytes;
|
|
||||||
|
|
||||||
if( !fd )
|
|
||||||
{
|
|
||||||
common->Printf( "idTCP::Write: not initialized\n" );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sigaction bak_action;
|
|
||||||
struct sigaction action;
|
|
||||||
|
|
||||||
action.sa_handler = got_SIGPIPE;
|
|
||||||
sigemptyset( &action.sa_mask );
|
|
||||||
action.sa_flags = 0;
|
|
||||||
|
|
||||||
if( sigaction( SIGPIPE, &action, &bak_action ) != 0 )
|
|
||||||
{
|
|
||||||
common->Printf( "ERROR: idTCP::Write: failed to set temporary SIGPIPE handler\n" );
|
|
||||||
Close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_GNU_SOURCE)
|
|
||||||
// handle EINTR interrupted system call with TEMP_FAILURE_RETRY - this is probably GNU libc specific
|
|
||||||
if( ( nbytes = TEMP_FAILURE_RETRY( write( fd, data, size ) ) ) == -1 )
|
|
||||||
{
|
|
||||||
#else
|
|
||||||
do
|
|
||||||
{
|
|
||||||
nbytes = write( fd, data, size );
|
|
||||||
}
|
|
||||||
while( nbytes == -1 && errno == EINTR );
|
|
||||||
if( nbytes == -1 )
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
common->Printf( "ERROR: idTCP::Write: %s\n", strerror( errno ) );
|
|
||||||
Close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( sigaction( SIGPIPE, &bak_action, NULL ) != 0 )
|
|
||||||
{
|
|
||||||
common->Printf( "ERROR: idTCP::Write: failed to reset SIGPIPE handler\n" );
|
|
||||||
Close();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nbytes;
|
|
||||||
}
|
|
||||||
|
|
|
@ -57,5 +57,7 @@ void Posix_Shutdown();
|
||||||
void Sys_FPE_handler( int signum, siginfo_t* info, void* context );
|
void Sys_FPE_handler( int signum, siginfo_t* info, void* context );
|
||||||
void Sys_DoStartProcess( const char* exeName, bool dofork = true ); // if not forking, current process gets replaced
|
void Sys_DoStartProcess( const char* exeName, bool dofork = true ); // if not forking, current process gets replaced
|
||||||
|
|
||||||
|
char* Posix_ConsoleInput();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
848
neo/sys/posix/posix_savegame.cpp
Normal file
848
neo/sys/posix/posix_savegame.cpp
Normal file
|
@ -0,0 +1,848 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 BFG Edition GPL Source Code
|
||||||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma hdrstop
|
||||||
|
#include "../../idlib/precompiled.h"
|
||||||
|
#include "../sys_session_local.h"
|
||||||
|
#include "../sys_savegame.h"
|
||||||
|
|
||||||
|
idCVar savegame_winInduceDelay( "savegame_winInduceDelay", "0", CVAR_INTEGER, "on windows, this is a delay induced before any file operation occurs" );
|
||||||
|
extern idCVar fs_savepath;
|
||||||
|
extern idCVar saveGame_checksum;
|
||||||
|
extern idCVar savegame_error;
|
||||||
|
|
||||||
|
#define SAVEGAME_SENTINAL 0x12358932
|
||||||
|
|
||||||
|
// RB begin
|
||||||
|
#define ERROR_SUCCESS 0
|
||||||
|
// RB end
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
void Sys_ExecuteSavegameCommandAsync
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void Sys_ExecuteSavegameCommandAsyncImpl( idSaveLoadParms* savegameParms )
|
||||||
|
{
|
||||||
|
assert( savegameParms != NULL );
|
||||||
|
|
||||||
|
session->GetSaveGameManager().GetSaveGameThread().data.saveLoadParms = savegameParms;
|
||||||
|
|
||||||
|
if( session->GetSaveGameManager().GetSaveGameThread().GetThreadHandle() == 0 )
|
||||||
|
{
|
||||||
|
session->GetSaveGameManager().GetSaveGameThread().StartWorkerThread( "Savegame", CORE_ANY );
|
||||||
|
}
|
||||||
|
|
||||||
|
session->GetSaveGameManager().GetSaveGameThread().SignalWork();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLocalUser * GetLocalUserFromUserId
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idLocalUserWin* GetLocalUserFromSaveParms( const saveGameThreadArgs_t& data )
|
||||||
|
{
|
||||||
|
if( ( data.saveLoadParms != NULL ) && ( data.saveLoadParms->inputDeviceId >= 0 ) )
|
||||||
|
{
|
||||||
|
idLocalUser* user = session->GetSignInManager().GetLocalUserByInputDevice( data.saveLoadParms->inputDeviceId );
|
||||||
|
if( user != NULL )
|
||||||
|
{
|
||||||
|
idLocalUserWin* userWin = static_cast< idLocalUserWin* >( user );
|
||||||
|
if( userWin != NULL && data.saveLoadParms->userId == idStr::Hash( userWin->GetGamerTag() ) )
|
||||||
|
{
|
||||||
|
return userWin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSaveGameThread::SaveGame
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::Save()
|
||||||
|
{
|
||||||
|
idLocalUserWin* user = GetLocalUserFromSaveParms( data );
|
||||||
|
if( user == NULL )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_INVALID_USER;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
idSaveLoadParms* callback = data.saveLoadParms;
|
||||||
|
idStr saveFolder = "savegame";
|
||||||
|
|
||||||
|
saveFolder.AppendPath( callback->directory );
|
||||||
|
|
||||||
|
// Check for the required storage space.
|
||||||
|
int64 requiredSizeBytes = 0;
|
||||||
|
{
|
||||||
|
for( int i = 0; i < callback->files.Num(); i++ )
|
||||||
|
{
|
||||||
|
idFile_SaveGame* file = callback->files[i];
|
||||||
|
requiredSizeBytes += ( file->Length() + sizeof( unsigned int ) ); // uint for checksum
|
||||||
|
if( file->type == SAVEGAMEFILE_PIPELINED )
|
||||||
|
{
|
||||||
|
requiredSizeBytes += MIN_SAVEGAME_SIZE_BYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// Check size of previous files if needed
|
||||||
|
// ALL THE FILES RIGHT NOW---- could use pattern later...
|
||||||
|
idStrList filesToDelete;
|
||||||
|
if( ( callback->mode & SAVEGAME_MBF_DELETE_FILES ) && !callback->cancelled )
|
||||||
|
{
|
||||||
|
if( fileSystem->IsFolder( saveFolder.c_str(), "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
idFileList* files = fileSystem->ListFilesTree( saveFolder.c_str(), "*.*" );
|
||||||
|
for( int i = 0; i < files->GetNumFiles(); i++ )
|
||||||
|
{
|
||||||
|
requiredSizeBytes -= fileSystem->GetFileLength( files->GetFile( i ) );
|
||||||
|
filesToDelete.Append( files->GetFile( i ) );
|
||||||
|
}
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inform user about size required if necessary
|
||||||
|
if( requiredSizeBytes > 0 && !callback->cancelled )
|
||||||
|
{
|
||||||
|
user->StorageSizeAvailable( requiredSizeBytes, callback->requiredSpaceInBytes );
|
||||||
|
if( callback->requiredSpaceInBytes > 0 )
|
||||||
|
{
|
||||||
|
// check to make sure savepath actually exists before erroring
|
||||||
|
idStr directory = fs_savepath.GetString();
|
||||||
|
directory += "\\"; // so it doesn't think the last part is a file and ignores in the directory creation
|
||||||
|
fileSystem->CreateOSPath( directory ); // we can't actually check FileExists in production builds, so just try to create it
|
||||||
|
user->StorageSizeAvailable( requiredSizeBytes, callback->requiredSpaceInBytes );
|
||||||
|
|
||||||
|
if( callback->requiredSpaceInBytes > 0 )
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_INSUFFICIENT_ROOM;
|
||||||
|
// safe to return, haven't written any files yet
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all previous files if needed
|
||||||
|
// ALL THE FILES RIGHT NOW---- could use pattern later...
|
||||||
|
for( int i = 0; i < filesToDelete.Num() && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
fileSystem->RemoveFile( filesToDelete[i].c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the raw files.
|
||||||
|
for( int i = 0; i < callback->files.Num() && ret == ERROR_SUCCESS && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
idFile_SaveGame* file = callback->files[i];
|
||||||
|
|
||||||
|
idStr fileName = saveFolder;
|
||||||
|
fileName.AppendPath( file->GetName() );
|
||||||
|
idStr tempFileName = va( "%s.temp", fileName.c_str() );
|
||||||
|
|
||||||
|
idFile* outputFile = fileSystem->OpenFileWrite( tempFileName, "fs_savePath" );
|
||||||
|
if( outputFile == NULL )
|
||||||
|
{
|
||||||
|
idLib::Warning( "[%s]: Couldn't open file for writing, %s", __FUNCTION__, tempFileName.c_str() );
|
||||||
|
file->error = true;
|
||||||
|
callback->errorCode = SAVEGAME_E_UNKNOWN;
|
||||||
|
ret = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( file->type & SAVEGAMEFILE_PIPELINED ) != 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
idFile_SaveGamePipelined* inputFile = dynamic_cast< idFile_SaveGamePipelined* >( file );
|
||||||
|
assert( inputFile != NULL );
|
||||||
|
|
||||||
|
blockForIO_t block;
|
||||||
|
while( inputFile->NextWriteBlock( & block ) )
|
||||||
|
{
|
||||||
|
if( ( size_t )outputFile->Write( block.data, block.bytes ) != block.bytes )
|
||||||
|
{
|
||||||
|
idLib::Warning( "[%s]: Write failed.", __FUNCTION__ );
|
||||||
|
file->error = true;
|
||||||
|
callback->errorCode = SAVEGAME_E_INSUFFICIENT_ROOM;
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if( ( file->type & SAVEGAMEFILE_BINARY ) || ( file->type & SAVEGAMEFILE_COMPRESSED ) )
|
||||||
|
{
|
||||||
|
if( saveGame_checksum.GetBool() )
|
||||||
|
{
|
||||||
|
unsigned int checksum = MD5_BlockChecksum( file->GetDataPtr(), file->Length() );
|
||||||
|
size_t size = outputFile->WriteBig( checksum );
|
||||||
|
if( size != sizeof( checksum ) )
|
||||||
|
{
|
||||||
|
idLib::Warning( "[%s]: Write failed.", __FUNCTION__ );
|
||||||
|
file->error = true;
|
||||||
|
callback->errorCode = SAVEGAME_E_INSUFFICIENT_ROOM;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = outputFile->Write( file->GetDataPtr(), file->Length() );
|
||||||
|
if( size != ( size_t )file->Length() )
|
||||||
|
{
|
||||||
|
idLib::Warning( "[%s]: Write failed.", __FUNCTION__ );
|
||||||
|
file->error = true;
|
||||||
|
callback->errorCode = SAVEGAME_E_INSUFFICIENT_ROOM;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idLib::PrintfIf( saveGame_verbose.GetBool(), "Saved %s (%s)\n", fileName.c_str(), outputFile->GetFullPath() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete outputFile;
|
||||||
|
|
||||||
|
if( ret == ERROR_SUCCESS )
|
||||||
|
{
|
||||||
|
// Remove the old file
|
||||||
|
if( !fileSystem->RenameFile( tempFileName, fileName, "fs_savePath" ) )
|
||||||
|
{
|
||||||
|
idLib::Warning( "Could not start to rename temporary file %s to %s.", tempFileName.c_str(), fileName.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileSystem->RemoveFile( tempFileName );
|
||||||
|
idLib::Warning( "Invalid write to temporary file %s.", tempFileName.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->cancelled )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removed because it seemed a bit drastic
|
||||||
|
#if 0
|
||||||
|
// If there is an error, delete the partially saved folder
|
||||||
|
if( callback->errorCode != SAVEGAME_E_NONE )
|
||||||
|
{
|
||||||
|
if( fileSystem->IsFolder( saveFolder, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
idFileList* files = fileSystem->ListFilesTree( saveFolder, "/|*" );
|
||||||
|
for( int i = 0; i < files->GetNumFiles(); i++ )
|
||||||
|
{
|
||||||
|
fileSystem->RemoveFile( files->GetFile( i ) );
|
||||||
|
}
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
fileSystem->RemoveDir( saveFolder );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocal::LoadGame
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::Load()
|
||||||
|
{
|
||||||
|
idSaveLoadParms* callback = data.saveLoadParms;
|
||||||
|
idStr saveFolder = "savegame";
|
||||||
|
|
||||||
|
saveFolder.AppendPath( callback->directory );
|
||||||
|
|
||||||
|
if( fileSystem->IsFolder( saveFolder, "fs_savePath" ) != FOLDER_YES )
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
for( int i = 0; i < callback->files.Num() && ret == ERROR_SUCCESS && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
idFile_SaveGame* file = callback->files[i];
|
||||||
|
|
||||||
|
idStr filename = saveFolder;
|
||||||
|
filename.AppendPath( file->GetName() );
|
||||||
|
|
||||||
|
idFile* inputFile = fileSystem->OpenFileRead( filename.c_str() );
|
||||||
|
if( inputFile == NULL )
|
||||||
|
{
|
||||||
|
file->error = true;
|
||||||
|
if( !( file->type & SAVEGAMEFILE_OPTIONAL ) )
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_CORRUPTED;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( file->type & SAVEGAMEFILE_PIPELINED ) != 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
idFile_SaveGamePipelined* outputFile = dynamic_cast< idFile_SaveGamePipelined* >( file );
|
||||||
|
assert( outputFile != NULL );
|
||||||
|
|
||||||
|
size_t lastReadBytes = 0;
|
||||||
|
blockForIO_t block;
|
||||||
|
while( outputFile->NextReadBlock( &block, lastReadBytes ) && !callback->cancelled )
|
||||||
|
{
|
||||||
|
lastReadBytes = inputFile->Read( block.data, block.bytes );
|
||||||
|
if( lastReadBytes != block.bytes )
|
||||||
|
{
|
||||||
|
// Notify end-of-file to the save game file which will cause all reads on the
|
||||||
|
// other end of the pipeline to return zero bytes after the pipeline is drained.
|
||||||
|
outputFile->NextReadBlock( NULL, lastReadBytes );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
size_t size = inputFile->Length();
|
||||||
|
|
||||||
|
unsigned int originalChecksum = 0;
|
||||||
|
if( ( file->type & SAVEGAMEFILE_BINARY ) != 0 || ( file->type & SAVEGAMEFILE_COMPRESSED ) != 0 )
|
||||||
|
{
|
||||||
|
if( saveGame_checksum.GetBool() )
|
||||||
|
{
|
||||||
|
if( size >= sizeof( originalChecksum ) )
|
||||||
|
{
|
||||||
|
inputFile->ReadBig( originalChecksum );
|
||||||
|
size -= sizeof( originalChecksum );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file->SetLength( size );
|
||||||
|
|
||||||
|
size_t sizeRead = inputFile->Read( ( void* )file->GetDataPtr(), size );
|
||||||
|
if( sizeRead != size )
|
||||||
|
{
|
||||||
|
file->error = true;
|
||||||
|
callback->errorCode = SAVEGAME_E_CORRUPTED;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( file->type & SAVEGAMEFILE_BINARY ) != 0 || ( file->type & SAVEGAMEFILE_COMPRESSED ) != 0 )
|
||||||
|
{
|
||||||
|
if( saveGame_checksum.GetBool() )
|
||||||
|
{
|
||||||
|
unsigned int checksum = MD5_BlockChecksum( file->GetDataPtr(), file->Length() );
|
||||||
|
if( checksum != originalChecksum )
|
||||||
|
{
|
||||||
|
file->error = true;
|
||||||
|
callback->errorCode = SAVEGAME_E_CORRUPTED;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete inputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->cancelled )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSaveGameThread::Delete
|
||||||
|
|
||||||
|
This deletes a complete savegame directory
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::Delete()
|
||||||
|
{
|
||||||
|
idSaveLoadParms* callback = data.saveLoadParms;
|
||||||
|
idStr saveFolder = "savegame";
|
||||||
|
|
||||||
|
saveFolder.AppendPath( callback->directory );
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
if( fileSystem->IsFolder( saveFolder, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
idFileList* files = fileSystem->ListFilesTree( saveFolder, "/|*" );
|
||||||
|
for( int i = 0; i < files->GetNumFiles() && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
fileSystem->RemoveFile( files->GetFile( i ) );
|
||||||
|
}
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
|
||||||
|
fileSystem->RemoveDir( saveFolder );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->cancelled )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSaveGameThread::Enumerate
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::Enumerate()
|
||||||
|
{
|
||||||
|
idSaveLoadParms* callback = data.saveLoadParms;
|
||||||
|
idStr saveFolder = "savegame";
|
||||||
|
|
||||||
|
callback->detailList.Clear();
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
if( fileSystem->IsFolder( saveFolder, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
idFileList* files = fileSystem->ListFilesTree( saveFolder, SAVEGAME_DETAILS_FILENAME );
|
||||||
|
const idStrList& fileList = files->GetList();
|
||||||
|
|
||||||
|
for( int i = 0; i < fileList.Num() && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
idSaveGameDetails* details = callback->detailList.Alloc();
|
||||||
|
// We have more folders on disk than we have room in our save detail list, stop trying to read them in and continue with what we have
|
||||||
|
if( details == NULL )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idStr directory = fileList[i];
|
||||||
|
|
||||||
|
idFile* file = fileSystem->OpenFileRead( directory.c_str() );
|
||||||
|
|
||||||
|
if( file != NULL )
|
||||||
|
{
|
||||||
|
// Read the DETAIL file for the enumerated data
|
||||||
|
if( callback->mode & SAVEGAME_MBF_READ_DETAILS )
|
||||||
|
{
|
||||||
|
if( !SavegameReadDetailsFromFile( file, *details ) )
|
||||||
|
{
|
||||||
|
details->damaged = true;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RB: FIXME ?
|
||||||
|
|
||||||
|
// use current time
|
||||||
|
time_t aclock;
|
||||||
|
time( &aclock );
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Use the date from the directory
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA attrData;
|
||||||
|
BOOL attrRet = GetFileAttributesEx( file->GetFullPath(), GetFileExInfoStandard, &attrData );
|
||||||
|
delete file;
|
||||||
|
if( attrRet == TRUE )
|
||||||
|
{
|
||||||
|
FILETIME lastWriteTime = attrData.ftLastWriteTime;
|
||||||
|
const ULONGLONG second = 10000000L; // One second = 10,000,000 * 100 nsec
|
||||||
|
SYSTEMTIME base_st = { 1970, 1, 0, 1, 0, 0, 0, 0 };
|
||||||
|
ULARGE_INTEGER itime;
|
||||||
|
FILETIME base_ft;
|
||||||
|
BOOL success = SystemTimeToFileTime( &base_st, &base_ft );
|
||||||
|
|
||||||
|
itime.QuadPart = ( ( ULARGE_INTEGER* )&lastWriteTime )->QuadPart;
|
||||||
|
if( success )
|
||||||
|
{
|
||||||
|
itime.QuadPart -= ( ( ULARGE_INTEGER* )&base_ft )->QuadPart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hard coded number of 100-nanosecond units from 1/1/1601 to 1/1/1970
|
||||||
|
itime.QuadPart -= 116444736000000000LL;
|
||||||
|
}
|
||||||
|
itime.QuadPart /= second;
|
||||||
|
details->date = itime.QuadPart;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// RB end
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
details->damaged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate the game details struct
|
||||||
|
directory = directory.StripFilename();
|
||||||
|
details->slotName = directory.c_str() + saveFolder.Length() + 1; // Strip off the prefix too
|
||||||
|
// JDC: I hit this all the time assert( fileSystem->IsFolder( directory.c_str(), "fs_savePath" ) == FOLDER_YES );
|
||||||
|
}
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND;
|
||||||
|
ret = -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->cancelled )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSaveGameThread::EnumerateFiles
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::EnumerateFiles()
|
||||||
|
{
|
||||||
|
idSaveLoadParms* callback = data.saveLoadParms;
|
||||||
|
idStr folder = "savegame";
|
||||||
|
|
||||||
|
folder.AppendPath( callback->directory );
|
||||||
|
|
||||||
|
callback->files.Clear();
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
if( fileSystem->IsFolder( folder, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
// get listing of all the files, but filter out below
|
||||||
|
idFileList* files = fileSystem->ListFilesTree( folder, "*.*" );
|
||||||
|
|
||||||
|
// look for the instance pattern
|
||||||
|
for( int i = 0; i < files->GetNumFiles() && ret == 0 && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
idStr fullFilename = files->GetFile( i );
|
||||||
|
idStr filename = fullFilename;
|
||||||
|
filename.StripPath();
|
||||||
|
|
||||||
|
if( filename.IcmpPrefix( callback->pattern ) != 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( !callback->postPattern.IsEmpty() && filename.Right( callback->postPattern.Length() ).IcmpPrefix( callback->postPattern ) != 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the DETAIL file for the enumerated data
|
||||||
|
if( callback->mode & SAVEGAME_MBF_READ_DETAILS )
|
||||||
|
{
|
||||||
|
idSaveGameDetails& details = callback->description;
|
||||||
|
idFile* uncompressed = fileSystem->OpenFileRead( fullFilename.c_str() );
|
||||||
|
|
||||||
|
if( uncompressed == NULL )
|
||||||
|
{
|
||||||
|
details.damaged = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !SavegameReadDetailsFromFile( uncompressed, details ) )
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete uncompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate the game details struct
|
||||||
|
details.slotName = callback->directory;
|
||||||
|
assert( fileSystem->IsFolder( details.slotName, "fs_savePath" ) == FOLDER_YES );
|
||||||
|
}
|
||||||
|
|
||||||
|
idFile_SaveGame* file = new( TAG_SAVEGAMES ) idFile_SaveGame( filename, SAVEGAMEFILE_AUTO_DELETE );
|
||||||
|
callback->files.Append( file );
|
||||||
|
}
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND;
|
||||||
|
ret = -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->cancelled )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSaveGameThread::DeleteFiles
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::DeleteFiles()
|
||||||
|
{
|
||||||
|
idSaveLoadParms* callback = data.saveLoadParms;
|
||||||
|
idStr folder = "savegame";
|
||||||
|
|
||||||
|
folder.AppendPath( callback->directory );
|
||||||
|
|
||||||
|
// delete the explicitly requested files first
|
||||||
|
for( int j = 0; j < callback->files.Num() && !callback->cancelled; ++j )
|
||||||
|
{
|
||||||
|
idFile_SaveGame* file = callback->files[j];
|
||||||
|
idStr fullpath = folder;
|
||||||
|
fullpath.AppendPath( file->GetName() );
|
||||||
|
fileSystem->RemoveFile( fullpath );
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
if( fileSystem->IsFolder( folder, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
// get listing of all the files, but filter out below
|
||||||
|
idFileList* files = fileSystem->ListFilesTree( folder, "*.*" );
|
||||||
|
|
||||||
|
// look for the instance pattern
|
||||||
|
for( int i = 0; i < files->GetNumFiles() && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
idStr filename = files->GetFile( i );
|
||||||
|
filename.StripPath();
|
||||||
|
|
||||||
|
// If there are post/pre patterns to match, make sure we adhere to the patterns
|
||||||
|
if( callback->pattern.IsEmpty() || ( filename.IcmpPrefix( callback->pattern ) != 0 ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( callback->postPattern.IsEmpty() || ( filename.Right( callback->postPattern.Length() ).IcmpPrefix( callback->postPattern ) != 0 ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSystem->RemoveFile( files->GetFile( i ) );
|
||||||
|
}
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND;
|
||||||
|
ret = -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->cancelled )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSaveGameThread::DeleteAll
|
||||||
|
|
||||||
|
This deletes all savegame directories
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::DeleteAll()
|
||||||
|
{
|
||||||
|
idSaveLoadParms* callback = data.saveLoadParms;
|
||||||
|
idStr saveFolder = "savegame";
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if( fileSystem->IsFolder( saveFolder, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
idFileList* files = fileSystem->ListFilesTree( saveFolder, "/|*" );
|
||||||
|
// remove directories after files
|
||||||
|
for( int i = 0; i < files->GetNumFiles() && !callback->cancelled; i++ )
|
||||||
|
{
|
||||||
|
// contained files should always be first
|
||||||
|
if( fileSystem->IsFolder( files->GetFile( i ), "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
fileSystem->RemoveDir( files->GetFile( i ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileSystem->RemoveFile( files->GetFile( i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback->errorCode = SAVEGAME_E_FOLDER_NOT_FOUND;
|
||||||
|
ret = -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->cancelled )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSaveGameThread::Run
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSaveGameThread::Run()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
idLocalUserWin* user = GetLocalUserFromSaveParms( data );
|
||||||
|
if( user != NULL && !user->IsStorageDeviceAvailable() )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_UNABLE_TO_SELECT_STORAGE_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( savegame_winInduceDelay.GetInteger() > 0 )
|
||||||
|
{
|
||||||
|
Sys_Sleep( savegame_winInduceDelay.GetInteger() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( data.saveLoadParms->mode & SAVEGAME_MBF_SAVE )
|
||||||
|
{
|
||||||
|
ret = Save();
|
||||||
|
}
|
||||||
|
else if( data.saveLoadParms->mode & SAVEGAME_MBF_LOAD )
|
||||||
|
{
|
||||||
|
ret = Load();
|
||||||
|
}
|
||||||
|
else if( data.saveLoadParms->mode & SAVEGAME_MBF_ENUMERATE )
|
||||||
|
{
|
||||||
|
ret = Enumerate();
|
||||||
|
}
|
||||||
|
else if( data.saveLoadParms->mode & SAVEGAME_MBF_DELETE_FOLDER )
|
||||||
|
{
|
||||||
|
ret = Delete();
|
||||||
|
}
|
||||||
|
else if( data.saveLoadParms->mode & SAVEGAME_MBF_DELETE_ALL_FOLDERS )
|
||||||
|
{
|
||||||
|
ret = DeleteAll();
|
||||||
|
}
|
||||||
|
else if( data.saveLoadParms->mode & SAVEGAME_MBF_DELETE_FILES )
|
||||||
|
{
|
||||||
|
ret = DeleteFiles();
|
||||||
|
}
|
||||||
|
else if( data.saveLoadParms->mode & SAVEGAME_MBF_ENUMERATE_FILES )
|
||||||
|
{
|
||||||
|
ret = EnumerateFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if something failed and no one set an error code, do it now.
|
||||||
|
if( ret != 0 && data.saveLoadParms->errorCode == SAVEGAME_E_NONE )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{
|
||||||
|
// if anything horrible happens, leave it up to the savegame processors to handle in PostProcess().
|
||||||
|
data.saveLoadParms->errorCode = SAVEGAME_E_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure to cancel any save game file pipelines.
|
||||||
|
if( data.saveLoadParms->errorCode != SAVEGAME_E_NONE )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->CancelSaveGameFilePipelines();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override error if cvar set
|
||||||
|
if( savegame_error.GetInteger() != 0 )
|
||||||
|
{
|
||||||
|
data.saveLoadParms->errorCode = ( saveGameError_t )savegame_error.GetInteger();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the waiting caller that we are done
|
||||||
|
data.saveLoadParms->callbackSignal.Raise();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Sys_SaveGameCheck
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void Sys_SaveGameCheck( bool& exists, bool& autosaveExists )
|
||||||
|
{
|
||||||
|
exists = false;
|
||||||
|
autosaveExists = false;
|
||||||
|
|
||||||
|
const idStr autosaveFolderStr = AddSaveFolderPrefix( SAVEGAME_AUTOSAVE_FOLDER, idSaveGameManager::PACKAGE_GAME );
|
||||||
|
const char* autosaveFolder = autosaveFolderStr.c_str();
|
||||||
|
const char* saveFolder = "savegame";
|
||||||
|
|
||||||
|
if( fileSystem->IsFolder( saveFolder, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
idFileList* files = fileSystem->ListFiles( saveFolder, "/" );
|
||||||
|
const idStrList& fileList = files->GetList();
|
||||||
|
|
||||||
|
idLib::PrintfIf( saveGame_verbose.GetBool(), "found %d savegames\n", fileList.Num() );
|
||||||
|
|
||||||
|
for( int i = 0; i < fileList.Num(); i++ )
|
||||||
|
{
|
||||||
|
const char* directory = va( "%s/%s", saveFolder, fileList[i].c_str() );
|
||||||
|
|
||||||
|
if( fileSystem->IsFolder( directory, "fs_savePath" ) == FOLDER_YES )
|
||||||
|
{
|
||||||
|
exists = true;
|
||||||
|
|
||||||
|
idLib::PrintfIf( saveGame_verbose.GetBool(), "found savegame: %s\n", fileList[i].c_str() );
|
||||||
|
|
||||||
|
if( idStr::Icmp( fileList[i].c_str(), autosaveFolder ) == 0 )
|
||||||
|
{
|
||||||
|
autosaveExists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSystem->FreeFileList( files );
|
||||||
|
}
|
||||||
|
}
|
751
neo/sys/posix/posix_session_local.cpp
Normal file
751
neo/sys/posix/posix_session_local.cpp
Normal file
|
@ -0,0 +1,751 @@
|
||||||
|
/*
|
||||||
|
================================================================================================
|
||||||
|
CONFIDENTIAL AND PROPRIETARY INFORMATION/NOT FOR DISCLOSURE WITHOUT WRITTEN PERMISSION
|
||||||
|
Copyright 2010 id Software LLC, a ZeniMax Media company. All Rights Reserved.
|
||||||
|
================================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
================================================================================================
|
||||||
|
|
||||||
|
Contains the windows implementation of the network session
|
||||||
|
|
||||||
|
================================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma hdrstop
|
||||||
|
#include "../../idlib/precompiled.h"
|
||||||
|
#include "../../framework/Common_local.h"
|
||||||
|
#include "../sys_session_local.h"
|
||||||
|
#include "../sys_stats.h"
|
||||||
|
#include "../sys_savegame.h"
|
||||||
|
#include "../sys_lobby_backend_direct.h"
|
||||||
|
#include "../sys_voicechat.h"
|
||||||
|
#include "posix_achievements.h"
|
||||||
|
//#include "_local.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
Global variables
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern idCVar net_port;
|
||||||
|
|
||||||
|
class idLobbyToSessionCBLocal;
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::idSessionLocalWin
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
class idSessionLocalWin : public idSessionLocal
|
||||||
|
{
|
||||||
|
friend class idLobbyToSessionCBLocal;
|
||||||
|
|
||||||
|
public:
|
||||||
|
idSessionLocalWin();
|
||||||
|
virtual ~idSessionLocalWin();
|
||||||
|
|
||||||
|
// idSessionLocal interface
|
||||||
|
virtual void Initialize();
|
||||||
|
virtual void Shutdown();
|
||||||
|
|
||||||
|
virtual void InitializeSoundRelatedSystems();
|
||||||
|
virtual void ShutdownSoundRelatedSystems();
|
||||||
|
|
||||||
|
virtual void PlatformPump();
|
||||||
|
|
||||||
|
virtual void InviteFriends();
|
||||||
|
virtual void InviteParty();
|
||||||
|
virtual void ShowPartySessions();
|
||||||
|
|
||||||
|
virtual void ShowSystemMarketplaceUI() const;
|
||||||
|
|
||||||
|
virtual void ListServers( const idCallback& callback );
|
||||||
|
virtual void CancelListServers();
|
||||||
|
virtual int NumServers() const;
|
||||||
|
virtual const serverInfo_t* ServerInfo( int i ) const;
|
||||||
|
virtual void ConnectToServer( int i );
|
||||||
|
virtual void ShowServerGamerCardUI( int i );
|
||||||
|
|
||||||
|
virtual void ShowLobbyUserGamerCardUI( lobbyUserID_t lobbyUserID );
|
||||||
|
|
||||||
|
virtual void ShowOnlineSignin() {}
|
||||||
|
virtual void UpdateRichPresence() {}
|
||||||
|
virtual void CheckVoicePrivileges() {}
|
||||||
|
|
||||||
|
virtual bool ProcessInputEvent( const sysEvent_t* ev );
|
||||||
|
|
||||||
|
// System UI
|
||||||
|
virtual bool IsSystemUIShowing() const;
|
||||||
|
virtual void SetSystemUIShowing( bool show );
|
||||||
|
|
||||||
|
// Invites
|
||||||
|
virtual void HandleBootableInvite( int64 lobbyId = 0 );
|
||||||
|
virtual void ClearBootableInvite();
|
||||||
|
virtual void ClearPendingInvite();
|
||||||
|
|
||||||
|
virtual bool HasPendingBootableInvite();
|
||||||
|
virtual void SetDiscSwapMPInvite( void* parm );
|
||||||
|
virtual void* GetDiscSwapMPInviteParms();
|
||||||
|
|
||||||
|
virtual void EnumerateDownloadableContent();
|
||||||
|
|
||||||
|
virtual void HandleServerQueryRequest( lobbyAddress_t& remoteAddr, idBitMsg& msg, int msgType );
|
||||||
|
virtual void HandleServerQueryAck( lobbyAddress_t& remoteAddr, idBitMsg& msg );
|
||||||
|
|
||||||
|
// Leaderboards
|
||||||
|
virtual void LeaderboardUpload( lobbyUserID_t lobbyUserID, const leaderboardDefinition_t* leaderboard, const column_t* stats, const idFile_Memory* attachment = NULL );
|
||||||
|
virtual void LeaderboardDownload( int sessionUserIndex, const leaderboardDefinition_t* leaderboard, int startingRank, int numRows, const idLeaderboardCallback& callback );
|
||||||
|
virtual void LeaderboardDownloadAttachment( int sessionUserIndex, const leaderboardDefinition_t* leaderboard, int64 attachmentID );
|
||||||
|
|
||||||
|
// Scoring (currently just for TrueSkill)
|
||||||
|
virtual void SetLobbyUserRelativeScore( lobbyUserID_t lobbyUserID, int relativeScore, int team ) {}
|
||||||
|
|
||||||
|
virtual void LeaderboardFlush();
|
||||||
|
|
||||||
|
virtual idNetSessionPort& GetPort( bool dedicated = false );
|
||||||
|
virtual idLobbyBackend* CreateLobbyBackend( const idMatchParameters& p, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType );
|
||||||
|
virtual idLobbyBackend* FindLobbyBackend( const idMatchParameters& p, int numPartyUsers, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType );
|
||||||
|
virtual idLobbyBackend* JoinFromConnectInfo( const lobbyConnectInfo_t& connectInfo , idLobbyBackend::lobbyBackendType_t lobbyType );
|
||||||
|
virtual void DestroyLobbyBackend( idLobbyBackend* lobbyBackend );
|
||||||
|
virtual void PumpLobbies();
|
||||||
|
virtual void JoinAfterSwap( void* joinID );
|
||||||
|
|
||||||
|
virtual bool GetLobbyAddressFromNetAddress( const netadr_t& netAddr, lobbyAddress_t& outAddr ) const;
|
||||||
|
virtual bool GetNetAddressFromLobbyAddress( const lobbyAddress_t& lobbyAddress, netadr_t& outNetAddr ) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Connect_f( const idCmdArgs& args );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void EnsurePort();
|
||||||
|
|
||||||
|
idLobbyBackend* CreateLobbyInternal( idLobbyBackend::lobbyBackendType_t lobbyType );
|
||||||
|
|
||||||
|
idArray< idLobbyBackend*, 3 > lobbyBackends;
|
||||||
|
|
||||||
|
idNetSessionPort port;
|
||||||
|
bool canJoinLocalHost;
|
||||||
|
|
||||||
|
idLobbyToSessionCBLocal* lobbyToSessionCB;
|
||||||
|
};
|
||||||
|
|
||||||
|
idSessionLocalWin sessionLocalWin;
|
||||||
|
idSession* session = &sessionLocalWin;
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idLobbyToSessionCBLocal
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
class idLobbyToSessionCBLocal : public idLobbyToSessionCB
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
idLobbyToSessionCBLocal( idSessionLocalWin* sessionLocalWin_ ) : sessionLocalWin( sessionLocalWin_ ) { }
|
||||||
|
|
||||||
|
virtual bool CanJoinLocalHost() const
|
||||||
|
{
|
||||||
|
sessionLocalWin->EnsurePort();
|
||||||
|
return sessionLocalWin->canJoinLocalHost;
|
||||||
|
}
|
||||||
|
virtual class idLobbyBackend* GetLobbyBackend( idLobbyBackend::lobbyBackendType_t type ) const
|
||||||
|
{
|
||||||
|
return sessionLocalWin->lobbyBackends[ type ];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
idSessionLocalWin* sessionLocalWin;
|
||||||
|
};
|
||||||
|
|
||||||
|
idLobbyToSessionCBLocal lobbyToSessionCBLocal( &sessionLocalWin );
|
||||||
|
idLobbyToSessionCB* lobbyToSessionCB = &lobbyToSessionCBLocal;
|
||||||
|
|
||||||
|
class idVoiceChatMgrWin : public idVoiceChatMgr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool GetLocalChatDataInternal( int talkerIndex, byte* data, int& dataSize )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual void SubmitIncomingChatDataInternal( int talkerIndex, const byte* data, int dataSize ) { }
|
||||||
|
virtual bool TalkerHasData( int talkerIndex )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool RegisterTalkerInternal( int index )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual void UnregisterTalkerInternal( int index ) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::idSessionLocalWin
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idSessionLocalWin::idSessionLocalWin()
|
||||||
|
{
|
||||||
|
signInManager = new( TAG_SYSTEM ) idSignInManagerWin;
|
||||||
|
saveGameManager = new( TAG_SAVEGAMES ) idSaveGameManager();
|
||||||
|
voiceChat = new( TAG_SYSTEM ) idVoiceChatMgrWin();
|
||||||
|
lobbyToSessionCB = new( TAG_SYSTEM ) idLobbyToSessionCBLocal( this );
|
||||||
|
|
||||||
|
canJoinLocalHost = false;
|
||||||
|
|
||||||
|
lobbyBackends.Zero();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::idSessionLocalWin
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idSessionLocalWin::~idSessionLocalWin()
|
||||||
|
{
|
||||||
|
delete voiceChat;
|
||||||
|
delete lobbyToSessionCB;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::Initialize
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::Initialize()
|
||||||
|
{
|
||||||
|
idSessionLocal::Initialize();
|
||||||
|
|
||||||
|
// The shipping path doesn't load title storage
|
||||||
|
// Instead, we inject values through code which is protected through steam DRM
|
||||||
|
titleStorageVars.Set( "MAX_PLAYERS_ALLOWED", "8" );
|
||||||
|
titleStorageLoaded = true;
|
||||||
|
|
||||||
|
// First-time check for downloadable content once game is launched
|
||||||
|
EnumerateDownloadableContent();
|
||||||
|
|
||||||
|
GetPartyLobby().Initialize( idLobby::TYPE_PARTY, sessionCallbacks );
|
||||||
|
GetGameLobby().Initialize( idLobby::TYPE_GAME, sessionCallbacks );
|
||||||
|
GetGameStateLobby().Initialize( idLobby::TYPE_GAME_STATE, sessionCallbacks );
|
||||||
|
|
||||||
|
achievementSystem = new( TAG_SYSTEM ) idAchievementSystemWin();
|
||||||
|
achievementSystem->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::Shutdown
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::Shutdown()
|
||||||
|
{
|
||||||
|
NET_VERBOSE_PRINT( "NET: Shutdown\n" );
|
||||||
|
idSessionLocal::Shutdown();
|
||||||
|
|
||||||
|
MoveToMainMenu();
|
||||||
|
|
||||||
|
// Wait until we fully shutdown
|
||||||
|
while( localState != STATE_IDLE && localState != STATE_PRESS_START )
|
||||||
|
{
|
||||||
|
Pump();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( achievementSystem != NULL )
|
||||||
|
{
|
||||||
|
achievementSystem->Shutdown();
|
||||||
|
delete achievementSystem;
|
||||||
|
achievementSystem = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::InitializeSoundRelatedSystems
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::InitializeSoundRelatedSystems()
|
||||||
|
{
|
||||||
|
if( voiceChat != NULL )
|
||||||
|
{
|
||||||
|
voiceChat->Init( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ShutdownSoundRelatedSystems
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ShutdownSoundRelatedSystems()
|
||||||
|
{
|
||||||
|
if( voiceChat != NULL )
|
||||||
|
{
|
||||||
|
voiceChat->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::PlatformPump
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::PlatformPump()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::InviteFriends
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::InviteFriends()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::InviteParty
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::InviteParty()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ShowPartySessions
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ShowPartySessions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ShowSystemMarketplaceUI
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ShowSystemMarketplaceUI() const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ListServers
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ListServers( const idCallback& callback )
|
||||||
|
{
|
||||||
|
ListServersCommon();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::CancelListServers
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::CancelListServers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::NumServers
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
int idSessionLocalWin::NumServers() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ServerInfo
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
const serverInfo_t* idSessionLocalWin::ServerInfo( int i ) const
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ConnectToServer
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ConnectToServer( int i )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::Connect_f
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::Connect_f( const idCmdArgs& args )
|
||||||
|
{
|
||||||
|
if( args.Argc() < 2 )
|
||||||
|
{
|
||||||
|
idLib::Printf( "Usage: Connect to IP. Use with net_port. \n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cancel();
|
||||||
|
|
||||||
|
if( signInManager->GetMasterLocalUser() == NULL )
|
||||||
|
{
|
||||||
|
signInManager->RegisterLocalUser( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
lobbyConnectInfo_t connectInfo;
|
||||||
|
|
||||||
|
Sys_StringToNetAdr( args.Argv( 1 ), &connectInfo.netAddr, true );
|
||||||
|
connectInfo.netAddr.port = net_port.GetInteger();
|
||||||
|
|
||||||
|
ConnectAndMoveToLobby( GetPartyLobby(), connectInfo, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
void Connect_f
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
CONSOLE_COMMAND( connect, "Connect to the specified IP", NULL )
|
||||||
|
{
|
||||||
|
sessionLocalWin.Connect_f( args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ShowServerGamerCardUI
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ShowServerGamerCardUI( int i )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ShowLobbyUserGamerCardUI(
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ShowLobbyUserGamerCardUI( lobbyUserID_t lobbyUserID )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ProcessInputEvent
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idSessionLocalWin::ProcessInputEvent( const sysEvent_t* ev )
|
||||||
|
{
|
||||||
|
if( GetSignInManager().ProcessInputEvent( ev ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::IsSystemUIShowing
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idSessionLocalWin::IsSystemUIShowing() const
|
||||||
|
{
|
||||||
|
// RB: TODO track SDL_ACTIVEENT
|
||||||
|
return isSysUIShowing;
|
||||||
|
|
||||||
|
//return !win32.activeApp || isSysUIShowing; // If the user alt+tabs away, treat it the same as bringing up the steam overlay
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::SetSystemUIShowing
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::SetSystemUIShowing( bool show )
|
||||||
|
{
|
||||||
|
isSysUIShowing = show;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::HandleServerQueryRequest
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::HandleServerQueryRequest( lobbyAddress_t& remoteAddr, idBitMsg& msg, int msgType )
|
||||||
|
{
|
||||||
|
NET_VERBOSE_PRINT( "HandleServerQueryRequest from %s\n", remoteAddr.ToString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::HandleServerQueryAck
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::HandleServerQueryAck( lobbyAddress_t& remoteAddr, idBitMsg& msg )
|
||||||
|
{
|
||||||
|
NET_VERBOSE_PRINT( "HandleServerQueryAck from %s\n", remoteAddr.ToString() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ClearBootableInvite
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ClearBootableInvite()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::ClearPendingInvite
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::ClearPendingInvite()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::HandleBootableInvite
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::HandleBootableInvite( int64 lobbyId )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::HasPendingBootableInvite
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idSessionLocalWin::HasPendingBootableInvite()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocal::SetDiscSwapMPInvite
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::SetDiscSwapMPInvite( void* parm )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocal::GetDiscSwapMPInviteParms
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void* idSessionLocalWin::GetDiscSwapMPInviteParms()
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::EnumerateDownloadableContent
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::EnumerateDownloadableContent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::LeaderboardUpload
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::LeaderboardUpload( lobbyUserID_t lobbyUserID, const leaderboardDefinition_t* leaderboard, const column_t* stats, const idFile_Memory* attachment )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::LeaderboardFlush
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::LeaderboardFlush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::LeaderboardDownload
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::LeaderboardDownload( int sessionUserIndex, const leaderboardDefinition_t* leaderboard, int startingRank, int numRows, const idLeaderboardCallback& callback )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::LeaderboardDownloadAttachment
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::LeaderboardDownloadAttachment( int sessionUserIndex, const leaderboardDefinition_t* leaderboard, int64 attachmentID )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::EnsurePort
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::EnsurePort()
|
||||||
|
{
|
||||||
|
// Init the port using reqular windows sockets
|
||||||
|
if( port.IsOpen() )
|
||||||
|
{
|
||||||
|
return; // Already initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
if( port.InitPort( net_port.GetInteger(), false ) )
|
||||||
|
{
|
||||||
|
canJoinLocalHost = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Assume this is another instantiation on the same machine, and just init using any available port
|
||||||
|
port.InitPort( PORT_ANY, false );
|
||||||
|
canJoinLocalHost = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::GetPort
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idNetSessionPort& idSessionLocalWin::GetPort( bool dedicated )
|
||||||
|
{
|
||||||
|
EnsurePort();
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::CreateLobbyBackend
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idLobbyBackend* idSessionLocalWin::CreateLobbyBackend( const idMatchParameters& p, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType )
|
||||||
|
{
|
||||||
|
idLobbyBackend* lobbyBackend = CreateLobbyInternal( lobbyType );
|
||||||
|
lobbyBackend->StartHosting( p, skillLevel, lobbyType );
|
||||||
|
return lobbyBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::FindLobbyBackend
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idLobbyBackend* idSessionLocalWin::FindLobbyBackend( const idMatchParameters& p, int numPartyUsers, float skillLevel, idLobbyBackend::lobbyBackendType_t lobbyType )
|
||||||
|
{
|
||||||
|
idLobbyBackend* lobbyBackend = CreateLobbyInternal( lobbyType );
|
||||||
|
lobbyBackend->StartFinding( p, numPartyUsers, skillLevel );
|
||||||
|
return lobbyBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::JoinFromConnectInfo
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idLobbyBackend* idSessionLocalWin::JoinFromConnectInfo( const lobbyConnectInfo_t& connectInfo, idLobbyBackend::lobbyBackendType_t lobbyType )
|
||||||
|
{
|
||||||
|
idLobbyBackend* lobbyBackend = CreateLobbyInternal( lobbyType );
|
||||||
|
lobbyBackend->JoinFromConnectInfo( connectInfo );
|
||||||
|
return lobbyBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::DestroyLobbyBackend
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::DestroyLobbyBackend( idLobbyBackend* lobbyBackend )
|
||||||
|
{
|
||||||
|
assert( lobbyBackend != NULL );
|
||||||
|
assert( lobbyBackends[lobbyBackend->GetLobbyType()] == lobbyBackend );
|
||||||
|
|
||||||
|
lobbyBackends[lobbyBackend->GetLobbyType()] = NULL;
|
||||||
|
|
||||||
|
lobbyBackend->Shutdown();
|
||||||
|
delete lobbyBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::PumpLobbies
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::PumpLobbies()
|
||||||
|
{
|
||||||
|
assert( lobbyBackends[idLobbyBackend::TYPE_PARTY] == NULL || lobbyBackends[idLobbyBackend::TYPE_PARTY]->GetLobbyType() == idLobbyBackend::TYPE_PARTY );
|
||||||
|
assert( lobbyBackends[idLobbyBackend::TYPE_GAME] == NULL || lobbyBackends[idLobbyBackend::TYPE_GAME]->GetLobbyType() == idLobbyBackend::TYPE_GAME );
|
||||||
|
assert( lobbyBackends[idLobbyBackend::TYPE_GAME_STATE] == NULL || lobbyBackends[idLobbyBackend::TYPE_GAME_STATE]->GetLobbyType() == idLobbyBackend::TYPE_GAME_STATE );
|
||||||
|
|
||||||
|
// Pump lobbyBackends
|
||||||
|
for( int i = 0; i < lobbyBackends.Num(); i++ )
|
||||||
|
{
|
||||||
|
if( lobbyBackends[i] != NULL )
|
||||||
|
{
|
||||||
|
lobbyBackends[i]->Pump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::CreateLobbyInternal
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
idLobbyBackend* idSessionLocalWin::CreateLobbyInternal( idLobbyBackend::lobbyBackendType_t lobbyType )
|
||||||
|
{
|
||||||
|
EnsurePort();
|
||||||
|
idLobbyBackend* lobbyBackend = new( TAG_NETWORKING ) idLobbyBackendDirect();
|
||||||
|
|
||||||
|
lobbyBackend->SetLobbyType( lobbyType );
|
||||||
|
|
||||||
|
assert( lobbyBackends[lobbyType] == NULL );
|
||||||
|
lobbyBackends[lobbyType] = lobbyBackend;
|
||||||
|
|
||||||
|
return lobbyBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::JoinAfterSwap
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSessionLocalWin::JoinAfterSwap( void* joinID )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::GetLobbyAddressFromNetAddress
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idSessionLocalWin::GetLobbyAddressFromNetAddress( const netadr_t& netAddr, lobbyAddress_t& outAddr ) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSessionLocalWin::GetNetAddressFromLobbyAddress
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idSessionLocalWin::GetNetAddressFromLobbyAddress( const lobbyAddress_t& lobbyAddress, netadr_t& outNetAddr ) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -112,10 +112,6 @@ static void sig_handler( int signum, siginfo_t* info, void* context )
|
||||||
// NOTE: see sigaction man page, could verbose the whole siginfo_t and print human readable si_code
|
// NOTE: see sigaction man page, could verbose the whole siginfo_t and print human readable si_code
|
||||||
Sys_Printf( "signal caught: %s\nsi_code %d\n", strsignal( signum ), info->si_code );
|
Sys_Printf( "signal caught: %s\nsi_code %d\n", strsignal( signum ), info->si_code );
|
||||||
|
|
||||||
#ifndef ID_BT_STUB
|
|
||||||
Sys_Printf( "callstack:\n%s", Sys_GetCallStackCurStr( 30 ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( fatalError[ 0 ] )
|
if( fatalError[ 0 ] )
|
||||||
{
|
{
|
||||||
Sys_Printf( "Was in fatal error shutdown: %s\n", fatalError );
|
Sys_Printf( "Was in fatal error shutdown: %s\n", fatalError );
|
||||||
|
|
161
neo/sys/posix/posix_signin.cpp
Normal file
161
neo/sys/posix/posix_signin.cpp
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 BFG Edition GPL Source Code
|
||||||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma hdrstop
|
||||||
|
#include "../../idlib/precompiled.h"
|
||||||
|
#include "../../framework/PlayerProfile.h"
|
||||||
|
#include "../sys_session_local.h"
|
||||||
|
#include "posix_signin.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
idCVar win_userPersistent( "win_userPersistent", "1", CVAR_BOOL, "debugging cvar for profile persistence status" );
|
||||||
|
idCVar win_userOnline( "win_userOnline", "1", CVAR_BOOL, "debugging cvar for profile online status" );
|
||||||
|
idCVar win_isInParty( "win_isInParty", "0", CVAR_BOOL, "debugging cvar for platform party status" );
|
||||||
|
idCVar win_partyCount( "win_partyCount", "0", CVAR_INTEGER, "debugginc var for platform party count" );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSignInManagerWin::Shutdown
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSignInManagerWin::Shutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSignInManagerWin::Pump
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSignInManagerWin::Pump()
|
||||||
|
{
|
||||||
|
|
||||||
|
// If we have more users than we need, then set to the lower amount
|
||||||
|
// (don't remove the master user though)
|
||||||
|
if( localUsers.Num() > 1 && localUsers.Num() > maxDesiredLocalUsers )
|
||||||
|
{
|
||||||
|
localUsers.SetNum( maxDesiredLocalUsers );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ID_RETAIL
|
||||||
|
// If we don't have enough, then make sure we do
|
||||||
|
// NOTE - We always want at least one user on windows for now,
|
||||||
|
// and this master user will always use controller 0
|
||||||
|
while( localUsers.Num() < minDesiredLocalUsers )
|
||||||
|
{
|
||||||
|
RegisterLocalUser( localUsers.Num() );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// See if we need to save settings on any of the profiles
|
||||||
|
for( int i = 0; i < localUsers.Num(); i++ )
|
||||||
|
{
|
||||||
|
localUsers[i].Pump();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSignInManagerWin::RemoveLocalUserByIndex
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSignInManagerWin::RemoveLocalUserByIndex( int index )
|
||||||
|
{
|
||||||
|
session->OnLocalUserSignout( &localUsers[index] );
|
||||||
|
localUsers.RemoveIndex( index );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSignInManagerWin::RegisterLocalUser
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
void idSignInManagerWin::RegisterLocalUser( int inputDevice )
|
||||||
|
{
|
||||||
|
if( GetLocalUserByInputDevice( inputDevice ) != NULL )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char machineName[128];
|
||||||
|
gethostname( machineName, sizeof( machineName ) );
|
||||||
|
|
||||||
|
const char* nameSource = machineName;
|
||||||
|
|
||||||
|
idStr name( nameSource );
|
||||||
|
int nameLength = name.Length();
|
||||||
|
if( idStr::IsValidUTF8( nameSource, nameLength ) )
|
||||||
|
{
|
||||||
|
int nameIndex = 0;
|
||||||
|
int numChars = 0;
|
||||||
|
name.Empty();
|
||||||
|
while( nameIndex < nameLength && numChars++ < idLocalUserWin::MAX_GAMERTAG_CHARS )
|
||||||
|
{
|
||||||
|
uint32 c = idStr::UTF8Char( nameSource, nameIndex );
|
||||||
|
name.AppendUTF8Char( c );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
idLocalUserWin& localUser = *localUsers.Alloc();
|
||||||
|
|
||||||
|
localUser.Init( inputDevice, name.c_str(), localUsers.Num() );
|
||||||
|
localUser.SetLocalUserHandle( GetUniqueLocalUserHandle( localUser.GetGamerTag() ) );
|
||||||
|
|
||||||
|
session->OnLocalUserSignin( &localUser );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
========================
|
||||||
|
idSignInManagerWin::CreateNewUser
|
||||||
|
========================
|
||||||
|
*/
|
||||||
|
bool idSignInManagerWin::CreateNewUser( winUserState_t& state )
|
||||||
|
{
|
||||||
|
//idScopedGlobalHeap everythingHereGoesInTheGlobalHeap; // users obviously persist across maps
|
||||||
|
|
||||||
|
RemoveAllLocalUsers();
|
||||||
|
RegisterLocalUser( state.inputDevice );
|
||||||
|
|
||||||
|
if( localUsers.Num() > 0 )
|
||||||
|
{
|
||||||
|
if( !localUsers[0].VerifyUserState( state ) )
|
||||||
|
{
|
||||||
|
RemoveAllLocalUsers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSOLE_COMMAND( testRemoveAllLocalUsers, "Forces removal of local users - mainly for PC testing", NULL )
|
||||||
|
{
|
||||||
|
session->GetSignInManager().RemoveAllLocalUsers();
|
||||||
|
}
|
72
neo/sys/posix/posix_signin.h
Normal file
72
neo/sys/posix/posix_signin.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Doom 3 BFG Edition GPL Source Code
|
||||||
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
|
||||||
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
||||||
|
|
||||||
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
#ifndef __POSIX_SIGNIN_H__
|
||||||
|
#define __POSIX_SIGNIN_H__
|
||||||
|
|
||||||
|
#include "posix_localuser.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
================================================
|
||||||
|
idSignInManagerWin
|
||||||
|
================================================
|
||||||
|
*/
|
||||||
|
class idSignInManagerWin : public idSignInManagerBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
idSignInManagerWin() : dlcVersionChecked( false ) {}
|
||||||
|
virtual ~idSignInManagerWin() {}
|
||||||
|
|
||||||
|
//==========================================================================================
|
||||||
|
// idSignInManagerBase interface
|
||||||
|
//==========================================================================================
|
||||||
|
virtual void Pump();
|
||||||
|
virtual void Shutdown();
|
||||||
|
virtual int GetNumLocalUsers() const
|
||||||
|
{
|
||||||
|
return localUsers.Num();
|
||||||
|
}
|
||||||
|
virtual idLocalUser* GetLocalUserByIndex( int index )
|
||||||
|
{
|
||||||
|
return &localUsers[index];
|
||||||
|
}
|
||||||
|
virtual const idLocalUser* GetLocalUserByIndex( int index ) const
|
||||||
|
{
|
||||||
|
return &localUsers[index];
|
||||||
|
}
|
||||||
|
virtual void RemoveLocalUserByIndex( int index );
|
||||||
|
virtual void RegisterLocalUser( int inputDevice ); // Register a local user to the passed in controller
|
||||||
|
|
||||||
|
bool CreateNewUser( winUserState_t& state );
|
||||||
|
|
||||||
|
private:
|
||||||
|
idStaticList< idLocalUserWin, MAX_INPUT_DEVICES > localUsers;
|
||||||
|
bool dlcVersionChecked;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -49,6 +49,7 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
Sys_GetClockTicks
|
Sys_GetClockTicks
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
|
#if defined(_WIN32)
|
||||||
double Sys_GetClockTicks()
|
double Sys_GetClockTicks()
|
||||||
{
|
{
|
||||||
// RB begin
|
// RB begin
|
||||||
|
@ -85,12 +86,14 @@ double Sys_GetClockTicks()
|
||||||
#endif
|
#endif
|
||||||
// RB end
|
// RB end
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_ClockTicksPerSecond
|
Sys_ClockTicksPerSecond
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
|
#if defined(_WIN32)
|
||||||
double Sys_ClockTicksPerSecond()
|
double Sys_ClockTicksPerSecond()
|
||||||
{
|
{
|
||||||
static double ticks = 0;
|
static double ticks = 0;
|
||||||
|
@ -136,6 +139,7 @@ double Sys_ClockTicksPerSecond()
|
||||||
#endif
|
#endif
|
||||||
return ticks;
|
return ticks;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,12 +161,14 @@ numPhysicalCPUCores - the total number of cores per package
|
||||||
numCPUPackages - the total number of packages (physical processors)
|
numCPUPackages - the total number of packages (physical processors)
|
||||||
========================
|
========================
|
||||||
*/
|
*/
|
||||||
|
#if defined(_WIN32)
|
||||||
void Sys_CPUCount( int& numLogicalCPUCores, int& numPhysicalCPUCores, int& numCPUPackages )
|
void Sys_CPUCount( int& numLogicalCPUCores, int& numPhysicalCPUCores, int& numCPUPackages )
|
||||||
{
|
{
|
||||||
numPhysicalCPUCores = 1;
|
numPhysicalCPUCores = 1;
|
||||||
numLogicalCPUCores = SDL_GetCPUCount();
|
numLogicalCPUCores = SDL_GetCPUCount();
|
||||||
numCPUPackages = 1;
|
numCPUPackages = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
|
@ -201,10 +207,12 @@ cpuid_t Sys_GetCPUId()
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for Streaming SIMD Extensions 3 aka Prescott's New Instructions
|
// check for Streaming SIMD Extensions 3 aka Prescott's New Instructions
|
||||||
|
#if 0 //SDL_VERSION_ATLEAST(2,0,0)
|
||||||
if( SDL_HasSSE3() )
|
if( SDL_HasSSE3() )
|
||||||
{
|
{
|
||||||
flags |= CPUID_SSE3;
|
flags |= CPUID_SSE3;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// check for Hyper-Threading Technology
|
// check for Hyper-Threading Technology
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
Doom 3 GPL Source Code
|
Doom 3 GPL Source Code
|
||||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 2012 dhewg (dhewm3)
|
||||||
|
Copyright (C) 2012 Robert Beckebans
|
||||||
|
|
||||||
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
@ -28,15 +30,10 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#include "sys/platform.h"
|
#include "../../idlib/precompiled.h"
|
||||||
#include "idlib/containers/List.h"
|
|
||||||
#include "idlib/Heap.h"
|
|
||||||
#include "framework/Common.h"
|
|
||||||
#include "framework/KeyInput.h"
|
|
||||||
#include "renderer/RenderSystem.h"
|
|
||||||
#include "renderer/tr_local.h"
|
#include "renderer/tr_local.h"
|
||||||
|
#include "sdl_local.h"
|
||||||
#include "sys/sys_public.h"
|
#include "../posix/posix_public.h"
|
||||||
|
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
#define SDL_Keycode SDLKey
|
#define SDL_Keycode SDLKey
|
||||||
|
@ -115,8 +112,8 @@ static byte mapkey( SDL_Keycode key )
|
||||||
|
|
||||||
switch( key )
|
switch( key )
|
||||||
{
|
{
|
||||||
case SDLK_APPLICATION:
|
//case SDLK_APPLICATION:
|
||||||
return K_COMMAND;
|
// return K_COMMAND;
|
||||||
case SDLK_CAPSLOCK:
|
case SDLK_CAPSLOCK:
|
||||||
return K_CAPSLOCK;
|
return K_CAPSLOCK;
|
||||||
case SDLK_SCROLLLOCK:
|
case SDLK_SCROLLLOCK:
|
||||||
|
@ -137,18 +134,21 @@ static byte mapkey( SDL_Keycode key )
|
||||||
return K_LWIN;
|
return K_LWIN;
|
||||||
case SDLK_RGUI:
|
case SDLK_RGUI:
|
||||||
return K_RWIN;
|
return K_RWIN;
|
||||||
case SDLK_MENU:
|
//case SDLK_MENU:
|
||||||
return K_MENU;
|
// return K_MENU;
|
||||||
|
|
||||||
case SDLK_LALT:
|
case SDLK_LALT:
|
||||||
|
return K_LALT;
|
||||||
case SDLK_RALT:
|
case SDLK_RALT:
|
||||||
return K_ALT;
|
return K_RALT;
|
||||||
case SDLK_RCTRL:
|
case SDLK_RCTRL:
|
||||||
|
return K_RCTRL;
|
||||||
case SDLK_LCTRL:
|
case SDLK_LCTRL:
|
||||||
return K_CTRL;
|
return K_LCTRL;
|
||||||
case SDLK_RSHIFT:
|
case SDLK_RSHIFT:
|
||||||
|
return K_RSHIFT;
|
||||||
case SDLK_LSHIFT:
|
case SDLK_LSHIFT:
|
||||||
return K_SHIFT;
|
return K_LSHIFT;
|
||||||
case SDLK_INSERT:
|
case SDLK_INSERT:
|
||||||
return K_INS;
|
return K_INS;
|
||||||
case SDLK_DELETE:
|
case SDLK_DELETE:
|
||||||
|
@ -195,29 +195,29 @@ static byte mapkey( SDL_Keycode key )
|
||||||
return K_F15;
|
return K_F15;
|
||||||
|
|
||||||
case SDLK_KP_7:
|
case SDLK_KP_7:
|
||||||
return K_KP_HOME;
|
return K_KP_7;
|
||||||
case SDLK_KP_8:
|
case SDLK_KP_8:
|
||||||
return K_KP_UPARROW;
|
return K_KP_8;
|
||||||
case SDLK_KP_9:
|
case SDLK_KP_9:
|
||||||
return K_KP_PGUP;
|
return K_KP_9;
|
||||||
case SDLK_KP_4:
|
case SDLK_KP_4:
|
||||||
return K_KP_LEFTARROW;
|
return K_KP_4;
|
||||||
case SDLK_KP_5:
|
case SDLK_KP_5:
|
||||||
return K_KP_5;
|
return K_KP_5;
|
||||||
case SDLK_KP_6:
|
case SDLK_KP_6:
|
||||||
return K_KP_RIGHTARROW;
|
return K_KP_6;
|
||||||
case SDLK_KP_1:
|
case SDLK_KP_1:
|
||||||
return K_KP_END;
|
return K_KP_1;
|
||||||
case SDLK_KP_2:
|
case SDLK_KP_2:
|
||||||
return K_KP_DOWNARROW;
|
return K_KP_2;
|
||||||
case SDLK_KP_3:
|
case SDLK_KP_3:
|
||||||
return K_KP_PGDN;
|
return K_KP_3;
|
||||||
case SDLK_KP_ENTER:
|
case SDLK_KP_ENTER:
|
||||||
return K_KP_ENTER;
|
return K_KP_ENTER;
|
||||||
case SDLK_KP_0:
|
case SDLK_KP_0:
|
||||||
return K_KP_INS;
|
return K_KP_0;
|
||||||
case SDLK_KP_PERIOD:
|
case SDLK_KP_PERIOD:
|
||||||
return K_KP_DEL;
|
return K_KP_DOT;
|
||||||
case SDLK_KP_DIVIDE:
|
case SDLK_KP_DIVIDE:
|
||||||
return K_KP_SLASH;
|
return K_KP_SLASH;
|
||||||
// K_SUPERSCRIPT_TWO;
|
// K_SUPERSCRIPT_TWO;
|
||||||
|
@ -227,7 +227,7 @@ static byte mapkey( SDL_Keycode key )
|
||||||
case SDLK_KP_PLUS:
|
case SDLK_KP_PLUS:
|
||||||
return K_KP_PLUS;
|
return K_KP_PLUS;
|
||||||
case SDLK_NUMLOCKCLEAR:
|
case SDLK_NUMLOCKCLEAR:
|
||||||
return K_KP_NUMLOCK;
|
return K_NUMLOCK;
|
||||||
case SDLK_KP_MULTIPLY:
|
case SDLK_KP_MULTIPLY:
|
||||||
return K_KP_STAR;
|
return K_KP_STAR;
|
||||||
case SDLK_KP_EQUALS:
|
case SDLK_KP_EQUALS:
|
||||||
|
@ -259,9 +259,9 @@ static byte mapkey( SDL_Keycode key )
|
||||||
// K_AUX16;
|
// K_AUX16;
|
||||||
|
|
||||||
case SDLK_PRINTSCREEN:
|
case SDLK_PRINTSCREEN:
|
||||||
return K_PRINT_SCR;
|
return K_PRINTSCREEN;
|
||||||
case SDLK_MODE:
|
case SDLK_MODE:
|
||||||
return K_RIGHT_ALT;
|
return K_RALT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -273,7 +273,7 @@ static void PushConsoleEvent( const char* s )
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
len = strlen( s ) + 1;
|
len = strlen( s ) + 1;
|
||||||
b = ( char* )Mem_Alloc( len );
|
b = ( char* )Mem_Alloc( len, TAG_EVENTS );
|
||||||
strcpy( b, s );
|
strcpy( b, s );
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
@ -673,8 +673,8 @@ void Sys_ClearEvents()
|
||||||
while( SDL_PollEvent( &ev ) )
|
while( SDL_PollEvent( &ev ) )
|
||||||
;
|
;
|
||||||
|
|
||||||
kbd_polls.SetNum( 0, false );
|
kbd_polls.SetNum( 0 );
|
||||||
mouse_polls.SetNum( 0, false );
|
mouse_polls.SetNum( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -684,7 +684,7 @@ Sys_GenerateEvents
|
||||||
*/
|
*/
|
||||||
void Sys_GenerateEvents()
|
void Sys_GenerateEvents()
|
||||||
{
|
{
|
||||||
char* s = Sys_ConsoleInput();
|
char* s = Posix_ConsoleInput();
|
||||||
|
|
||||||
if( s )
|
if( s )
|
||||||
PushConsoleEvent( s );
|
PushConsoleEvent( s );
|
||||||
|
@ -724,7 +724,7 @@ Sys_EndKeyboardInputEvents
|
||||||
*/
|
*/
|
||||||
void Sys_EndKeyboardInputEvents()
|
void Sys_EndKeyboardInputEvents()
|
||||||
{
|
{
|
||||||
kbd_polls.SetNum( 0, false );
|
kbd_polls.SetNum( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -732,32 +732,55 @@ void Sys_EndKeyboardInputEvents()
|
||||||
Sys_PollMouseInputEvents
|
Sys_PollMouseInputEvents
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
int Sys_PollMouseInputEvents()
|
int Sys_PollMouseInputEvents( int mouseEvents[MAX_MOUSE_EVENTS][2] )
|
||||||
{
|
{
|
||||||
return mouse_polls.Num();
|
int numEvents = mouse_polls.Num();
|
||||||
}
|
|
||||||
|
if( numEvents > MAX_MOUSE_EVENTS )
|
||||||
/*
|
{
|
||||||
================
|
numEvents = MAX_MOUSE_EVENTS;
|
||||||
Sys_ReturnMouseInputEvent
|
}
|
||||||
================
|
|
||||||
*/
|
for( int i = 0; i < numEvents; i++ )
|
||||||
int Sys_ReturnMouseInputEvent( const int n, int& action, int& value )
|
{
|
||||||
{
|
const mouse_poll_t& mp = mouse_polls[i];
|
||||||
if( n >= mouse_polls.Num() )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
action = mouse_polls[n].action;
|
mouseEvents[i][0] = mp.action;
|
||||||
value = mouse_polls[n].value;
|
mouseEvents[i][1] = mp.value;
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
mouse_polls.SetNum( 0 );
|
||||||
|
|
||||||
|
return numEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
================
|
//=====================================================================================
|
||||||
Sys_EndMouseInputEvents
|
// Joystick Input Handling
|
||||||
================
|
//=====================================================================================
|
||||||
*/
|
|
||||||
void Sys_EndMouseInputEvents()
|
void Sys_SetRumble( int device, int low, int hi )
|
||||||
{
|
{
|
||||||
mouse_polls.SetNum( 0, false );
|
// TODO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Sys_PollJoystickInputEvents( int deviceNum )
|
||||||
|
{
|
||||||
|
// TODO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Sys_ReturnJoystickInputEvent( const int n, int& action, int& value )
|
||||||
|
{
|
||||||
|
// TODO;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Sys_EndJoystickInputEvents()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
Doom 3 GPL Source Code
|
Doom 3 GPL Source Code
|
||||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 2012 dhewg (dhewm3)
|
||||||
|
Copyright (C) 2012 Robert Beckebans
|
||||||
|
|
||||||
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||||
|
|
||||||
|
@ -29,10 +31,10 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_syswm.h>
|
#include <SDL_syswm.h>
|
||||||
|
|
||||||
#include "sys/platform.h"
|
#include "../../idlib/precompiled.h"
|
||||||
#include "framework/Licensee.h"
|
|
||||||
|
|
||||||
#include "renderer/tr_local.h"
|
#include "renderer/tr_local.h"
|
||||||
|
#include "sdl_local.h"
|
||||||
|
|
||||||
idCVar in_nograb( "in_nograb", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "prevents input grabbing" );
|
idCVar in_nograb( "in_nograb", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "prevents input grabbing" );
|
||||||
idCVar r_waylandcompat( "r_waylandcompat", "0", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "wayland compatible framebuffer" );
|
idCVar r_waylandcompat( "r_waylandcompat", "0", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "wayland compatible framebuffer" );
|
||||||
|
@ -165,7 +167,9 @@ bool GLimp_Init( glimpParms_t parms )
|
||||||
if( SDL_GL_SetSwapInterval( r_swapInterval.GetInteger() ) < 0 )
|
if( SDL_GL_SetSwapInterval( r_swapInterval.GetInteger() ) < 0 )
|
||||||
common->Warning( "SDL_GL_SWAP_CONTROL not supported" );
|
common->Warning( "SDL_GL_SWAP_CONTROL not supported" );
|
||||||
|
|
||||||
SDL_GetWindowSize( window, &glConfig.vidWidth, &glConfig.vidHeight );
|
// RB begin
|
||||||
|
SDL_GetWindowSize( window, &glConfig.nativeScreenWidth, &glConfig.nativeScreenHeight );
|
||||||
|
// RB end
|
||||||
|
|
||||||
glConfig.isFullscreen = ( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) == SDL_WINDOW_FULLSCREEN;
|
glConfig.isFullscreen = ( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) == SDL_WINDOW_FULLSCREEN;
|
||||||
#else
|
#else
|
||||||
|
@ -182,8 +186,8 @@ bool GLimp_Init( glimpParms_t parms )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
glConfig.vidWidth = window->w;
|
glConfig.nativeScreenWidth = window->w;
|
||||||
glConfig.vidHeight = window->h;
|
glConfig.nativeScreenHeight = window->h;
|
||||||
|
|
||||||
glConfig.isFullscreen = ( window->flags & SDL_FULLSCREEN ) == SDL_FULLSCREEN;
|
glConfig.isFullscreen = ( window->flags & SDL_FULLSCREEN ) == SDL_FULLSCREEN;
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,6 +201,11 @@ bool GLimp_Init( glimpParms_t parms )
|
||||||
|
|
||||||
glConfig.displayFrequency = 0;
|
glConfig.displayFrequency = 0;
|
||||||
|
|
||||||
|
// RB begin
|
||||||
|
glConfig.isStereoPixelFormat = parms.stereo;
|
||||||
|
glConfig.multisamples = parms.multiSamples;
|
||||||
|
// RB end
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,26 +288,6 @@ void GLimp_SetGamma( unsigned short red[256], unsigned short green[256], unsigne
|
||||||
common->Warning( "Couldn't set gamma ramp: %s", SDL_GetError() );
|
common->Warning( "Couldn't set gamma ramp: %s", SDL_GetError() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
GLimp_ActivateContext
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void GLimp_ActivateContext()
|
|
||||||
{
|
|
||||||
common->DPrintf( "TODO: GLimp_ActivateContext\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
=================
|
|
||||||
GLimp_DeactivateContext
|
|
||||||
=================
|
|
||||||
*/
|
|
||||||
void GLimp_DeactivateContext()
|
|
||||||
{
|
|
||||||
common->DPrintf( "TODO: GLimp_DeactivateContext\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===================
|
===================
|
||||||
GLimp_ExtensionPointer
|
GLimp_ExtensionPointer
|
||||||
|
@ -339,3 +328,77 @@ void GLimp_GrabInput( int flags )
|
||||||
SDL_WM_GrabInput( grab ? SDL_GRAB_ON : SDL_GRAB_OFF );
|
SDL_WM_GrabInput( grab ? SDL_GRAB_ON : SDL_GRAB_OFF );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
DumpAllDisplayDevices
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
void DumpAllDisplayDevices()
|
||||||
|
{
|
||||||
|
common->DPrintf( "TODO: DumpAllDisplayDevices\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class idSort_VidMode : public idSort_Quick< vidMode_t, idSort_VidMode >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int Compare( const vidMode_t& a, const vidMode_t& b ) const
|
||||||
|
{
|
||||||
|
int wd = a.width - b.width;
|
||||||
|
int hd = a.height - b.height;
|
||||||
|
int fd = a.displayHz - b.displayHz;
|
||||||
|
return ( hd != 0 ) ? hd : ( wd != 0 ) ? wd : fd;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
====================
|
||||||
|
R_GetModeListForDisplay
|
||||||
|
====================
|
||||||
|
*/
|
||||||
|
bool R_GetModeListForDisplay( const int requestedDisplayNum, idList<vidMode_t>& modeList )
|
||||||
|
{
|
||||||
|
modeList.Clear();
|
||||||
|
|
||||||
|
bool verbose = false;
|
||||||
|
|
||||||
|
const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo();
|
||||||
|
|
||||||
|
SDL_Rect** modes = SDL_ListModes( videoInfo->vfmt, SDL_OPENGL | SDL_FULLSCREEN );
|
||||||
|
|
||||||
|
if( !modes )
|
||||||
|
{
|
||||||
|
common->Warning( "Can't get list of available modes\n" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( modes == ( SDL_Rect** ) - 1 )
|
||||||
|
{
|
||||||
|
common->Printf( "Display supports any resolution\n" );
|
||||||
|
return false; // can set any resolution
|
||||||
|
}
|
||||||
|
|
||||||
|
int numModes;
|
||||||
|
for( numModes = 0; modes[numModes]; numModes++ );
|
||||||
|
|
||||||
|
if( numModes > 1 )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < numModes; i++ )
|
||||||
|
{
|
||||||
|
vidMode_t mode;
|
||||||
|
mode.width = modes[i]->w;
|
||||||
|
mode.height = modes[i]->h;
|
||||||
|
mode.displayHz = 60; // FIXME;
|
||||||
|
modeList.AddUnique( mode );
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort with lowest resolution first
|
||||||
|
modeList.SortWithTemplate( idSort_VidMode() );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
2025
neo/sys/sdl/sdl_qgl.cpp
Normal file
2025
neo/sys/sdl/sdl_qgl.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
Doom 3 BFG Edition GPL Source Code
|
Doom 3 BFG Edition GPL Source Code
|
||||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||||
|
Copyright (C) 2012 Robert Beckebans
|
||||||
|
|
||||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||||
|
|
||||||
|
@ -519,9 +520,12 @@ bool Sys_UnlockMemory( void* ptr, int bytes );
|
||||||
void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes );
|
void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes );
|
||||||
|
|
||||||
// DLL loading, the path should be a fully qualified OS path to the DLL file to be loaded
|
// DLL loading, the path should be a fully qualified OS path to the DLL file to be loaded
|
||||||
int Sys_DLL_Load( const char* dllName );
|
|
||||||
void* Sys_DLL_GetProcAddress( int dllHandle, const char* procName );
|
// RB: 64 bit fixes, changed int to intptr_t
|
||||||
void Sys_DLL_Unload( int dllHandle );
|
intptr_t Sys_DLL_Load( const char* dllName );
|
||||||
|
void* Sys_DLL_GetProcAddress( intptr_t dllHandle, const char* procName );
|
||||||
|
void Sys_DLL_Unload( intptr_t dllHandle );
|
||||||
|
// RB end
|
||||||
|
|
||||||
// event generation
|
// event generation
|
||||||
void Sys_GenerateEvents();
|
void Sys_GenerateEvents();
|
||||||
|
|
|
@ -30,8 +30,15 @@ If you have questions concerning this license or the applicable additional terms
|
||||||
#undef private
|
#undef private
|
||||||
#undef protected
|
#undef protected
|
||||||
|
|
||||||
|
// RB begin
|
||||||
|
#if defined(_WIN32)
|
||||||
#include "win32/win_achievements.h"
|
#include "win32/win_achievements.h"
|
||||||
#include "win32/win_signin.h"
|
#include "win32/win_signin.h"
|
||||||
|
#else
|
||||||
|
#include "posix/posix_achievements.h"
|
||||||
|
#include "posix/posix_signin.h"
|
||||||
|
#endif
|
||||||
|
// RB end
|
||||||
|
|
||||||
#include "sys_lobby_backend.h"
|
#include "sys_lobby_backend.h"
|
||||||
#include "sys_lobby.h"
|
#include "sys_lobby.h"
|
||||||
|
|
Loading…
Reference in a new issue