943 lines
26 KiB
C++
943 lines
26 KiB
C++
|
|
#ifndef __SYS_PUBLIC__
|
|
#define __SYS_PUBLIC__
|
|
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
Non-portable system services.
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
|
|
// Win32
|
|
#ifdef _WINDOWS
|
|
|
|
#define BUILD_STRING "win-x86"
|
|
#define BUILD_OS_ID 0
|
|
#define CPUSTRING "x86"
|
|
#define CPU_EASYARGS 1
|
|
|
|
#define ALIGN16( x ) __declspec(align(16)) x
|
|
#define PACKED
|
|
|
|
#define _alloca16( x ) ((void *)((((int)_alloca( (x)+15 )) + 15) & ~15))
|
|
|
|
#define ID_INLINE __forceinline
|
|
#define ID_STATIC_TEMPLATE static
|
|
|
|
#define assertmem( x, y ) assert( _CrtIsValidPointer( x, y, true ) )
|
|
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
#define id_attribute(x) __attribute__(x)
|
|
#else
|
|
#define id_attribute(x)
|
|
#endif
|
|
|
|
// Mac OSX
|
|
#if defined(MACOS_X) || defined(__APPLE__)
|
|
|
|
#include <sys/types.h>
|
|
|
|
#if __GNUC__ < 4
|
|
#include "osx/apple_bool.h"
|
|
#endif
|
|
|
|
#define BUILD_STRING "MacOSX-universal"
|
|
#define BUILD_OS_ID 1
|
|
#ifdef __ppc__
|
|
#define CPUSTRING "ppc"
|
|
#define CPU_EASYARGS 0
|
|
#elif defined(__i386__)
|
|
#define CPUSTRING "x86"
|
|
#define CPU_EASYARGS 1
|
|
#endif
|
|
|
|
#define ALIGN16( x ) x __attribute__ ((aligned (16)))
|
|
#ifdef __MWERKS__
|
|
#define PACKED
|
|
#else
|
|
#define PACKED __attribute__((packed))
|
|
#endif
|
|
|
|
#define _alloca alloca
|
|
#define _alloca16( x ) ((void *)((((int)alloca( (x)+15 )) + 15) & ~15))
|
|
|
|
#define __cdecl
|
|
#define ASSERT assert
|
|
|
|
#define ID_STATIC_TEMPLATE
|
|
|
|
#define assertmem( x, y )
|
|
|
|
#endif
|
|
|
|
|
|
// Linux
|
|
#ifdef __linux__
|
|
|
|
#ifdef __i386__
|
|
#define BUILD_STRING "linux-x86"
|
|
#define BUILD_OS_ID 2
|
|
#define CPUSTRING "x86"
|
|
#define CPU_EASYARGS 1
|
|
#elif defined(__ppc__)
|
|
#define BUILD_STRING "linux-ppc"
|
|
#define CPUSTRING "ppc"
|
|
#define CPU_EASYARGS 0
|
|
#endif
|
|
|
|
#define _alloca alloca
|
|
#define _alloca16( x ) ((void *)((((int)alloca( (x)+15 )) + 15) & ~15))
|
|
|
|
#define ALIGN16( x ) x
|
|
#define PACKED __attribute__((packed))
|
|
|
|
#define __cdecl
|
|
#define ASSERT assert
|
|
|
|
#define ID_INLINE inline
|
|
#define ID_STATIC_TEMPLATE
|
|
|
|
#define assertmem( x, y )
|
|
|
|
#endif
|
|
|
|
typedef enum {
|
|
CPUID_NONE = 0x00000,
|
|
CPUID_UNSUPPORTED = 0x00001, // unsupported (386/486)
|
|
CPUID_GENERIC = 0x00002, // unrecognized processor
|
|
CPUID_INTEL = 0x00004, // Intel
|
|
CPUID_AMD = 0x00008, // AMD
|
|
CPUID_MMX = 0x00010, // Multi Media Extensions
|
|
CPUID_3DNOW = 0x00020, // 3DNow!
|
|
CPUID_SSE = 0x00040, // Streaming SIMD Extensions
|
|
CPUID_SSE2 = 0x00080, // Streaming SIMD Extensions 2
|
|
CPUID_SSE3 = 0x00100, // Streaming SIMD Extentions 3 aka Prescott's New Instructions
|
|
CPUID_ALTIVEC = 0x00200, // AltiVec
|
|
CPUID_HTT = 0x01000, // Hyper-Threading Technology
|
|
CPUID_CMOV = 0x02000, // Conditional Move (CMOV) and fast floating point comparison (FCOMI) instructions
|
|
CPUID_FTZ = 0x04000, // Flush-To-Zero mode (denormal results are flushed to zero)
|
|
CPUID_DAZ = 0x08000, // Denormals-Are-Zero mode (denormal source operands are set to zero)
|
|
CPUID_EM64T = 0x10000, // 64-bit Memory Extensions
|
|
CPUID_PENTIUMM = 0x20000, // Pentium M technology - high performance per MHz
|
|
#ifdef MACOS_X
|
|
CPUID_PPC = 0x40000, // PowerPC G4/G5
|
|
#endif
|
|
// RAVEN BEGIN
|
|
CPUID_XENON = 0x80000 // Xenon PPC processor
|
|
// RAVEN END
|
|
} cpuid_t;
|
|
|
|
typedef enum {
|
|
FPU_EXCEPTION_INVALID_OPERATION = 1,
|
|
FPU_EXCEPTION_DENORMALIZED_OPERAND = 2,
|
|
FPU_EXCEPTION_DIVIDE_BY_ZERO = 4,
|
|
FPU_EXCEPTION_NUMERIC_OVERFLOW = 8,
|
|
FPU_EXCEPTION_NUMERIC_UNDERFLOW = 16,
|
|
FPU_EXCEPTION_INEXACT_RESULT = 32
|
|
} fpuExceptions_t;
|
|
|
|
typedef enum {
|
|
FPU_PRECISION_SINGLE = 0,
|
|
FPU_PRECISION_DOUBLE = 1,
|
|
FPU_PRECISION_DOUBLE_EXTENDED = 2
|
|
} fpuPrecision_t;
|
|
|
|
typedef enum {
|
|
FPU_ROUNDING_TO_NEAREST = 0,
|
|
FPU_ROUNDING_DOWN = 1,
|
|
FPU_ROUNDING_UP = 2,
|
|
FPU_ROUNDING_TO_ZERO = 3
|
|
} fpuRounding_t;
|
|
|
|
typedef enum {
|
|
SE_NONE, // evTime is still valid
|
|
SE_KEY, // evValue is a key code, evValue2 is the down flag
|
|
SE_CHAR, // evValue is an ascii char
|
|
SE_MOUSE, // evValue and evValue2 are reletive signed x / y moves
|
|
SE_JOYSTICK_AXIS, // evValue is an axis number and evValue2 is the current state (-127 to 127)
|
|
SE_CONSOLE // evPtr is a char*, from typing something at a non-game console
|
|
// RAVEN BEGIN
|
|
// rjohnson: debug event overflow stuff
|
|
,
|
|
SE_MAX
|
|
// RAVEN END
|
|
} sysEventType_t;
|
|
|
|
typedef enum {
|
|
M_ACTION1,
|
|
M_ACTION2,
|
|
M_ACTION3,
|
|
M_ACTION4,
|
|
M_ACTION5,
|
|
M_ACTION6,
|
|
M_ACTION7,
|
|
M_ACTION8,
|
|
M_DELTAX,
|
|
M_DELTAY,
|
|
M_DELTAZ
|
|
} sys_mEvents;
|
|
|
|
// RAVEN BEGIN
|
|
// rjohnson: new joystick code
|
|
#define MAX_AXIS_RANGE 127
|
|
#define JOY_TO_CURSOR_SPEED ( idMath::M_MS2SEC * common->GetUserCmdMSec() * 1.5f * 140.f )
|
|
|
|
typedef enum {
|
|
AXIS_LEFT_HORIZONTAL,
|
|
AXIS_LEFT_VERTICAL,
|
|
AXIS_RIGHT_HORIZONTAL,
|
|
AXIS_RIGHT_VERTICAL,
|
|
MAX_JOYSTICK_AXIS
|
|
} joystickAxis_t;
|
|
|
|
typedef enum {
|
|
J_ACTION_BUTTON_LEFT_SHOULDER, // K_JOY1
|
|
J_ACTION_BUTTON_RIGHT_SHOULDER, // K_JOY2
|
|
J_ACTION_BUTTON_A, // K_JOY3
|
|
J_ACTION_BUTTON_B, // K_JOY4
|
|
J_ACTION_BUTTON_Y, // K_JOY5
|
|
J_ACTION_BUTTON_X, // K_JOY6
|
|
J_ACTION_BUTTON_START, // K_JOY7
|
|
J_ACTION_BUTTON_BACK, // K_JOY8
|
|
J_ACTION_BUTTON_DPAD_UP, // K_JOY9
|
|
J_ACTION_BUTTON_DPAD_DOWN, // K_JOY10
|
|
J_ACTION_BUTTON_DPAD_RIGHT, // K_JOY11
|
|
J_ACTION_BUTTON_DPAD_LEFT, // K_JOY12
|
|
J_ACTION_BUTTON_AXIS_LEFT, // K_JOY13
|
|
J_ACTION_BUTTON_AXIS_RIGHT, // K_JOY14
|
|
J_ACTION_BUTTON_LEFT_TRIGGER, // K_JOY16
|
|
J_ACTION_BUTTON_RIGHT_TRIGGER, // K_JOY15
|
|
|
|
J_DELTA_LEFT_HORIZONTAL,
|
|
J_DELTA_LEFT_VERTICAL,
|
|
J_DELTA_RIGHT_HORIZONTAL,
|
|
J_DELTA_RIGHT_VERTICAL,
|
|
|
|
J_ACTION_BUTTON_GARBAGE,
|
|
} sys_jEvents;
|
|
// RAVEN END
|
|
|
|
typedef struct sysEvent_s {
|
|
sysEventType_t evType;
|
|
int evValue;
|
|
int evValue2;
|
|
int evPtrLength; // bytes of data pointed to by evPtr, for journaling
|
|
void * evPtr; // this must be manually freed if not NULL
|
|
} sysEvent_t;
|
|
|
|
typedef struct sysMemoryStats_s {
|
|
int memoryLoad;
|
|
int totalPhysical;
|
|
int availPhysical;
|
|
int totalPageFile;
|
|
int availPageFile;
|
|
int totalVirtual;
|
|
int availVirtual;
|
|
int availExtendedVirtual;
|
|
} sysMemoryStats_t;
|
|
|
|
typedef unsigned long address_t;
|
|
|
|
template<class type> class idList; // for Sys_ListFiles
|
|
|
|
struct sysTime_t {
|
|
int tm_sec; /* seconds after the minute - [0,59] */
|
|
int tm_min; /* minutes after the hour - [0,59] */
|
|
int tm_hour; /* hours since midnight - [0,23] */
|
|
int tm_mday; /* day of the month - [1,31] */
|
|
int tm_mon; /* months since January - [0,11] */
|
|
int tm_year; /* years since 1900 */
|
|
int tm_wday; /* days since Sunday - [0,6] */
|
|
int tm_yday; /* days since January 1 - [0,365] */
|
|
int tm_isdst; /* daylight savings time flag */
|
|
};
|
|
|
|
void Sys_Init( void );
|
|
void Sys_Shutdown( void );
|
|
void Sys_Error( const char *error, ...);
|
|
void Sys_Quit( void );
|
|
|
|
bool Sys_AlreadyRunning( void );
|
|
|
|
// note that this isn't journaled...
|
|
char * Sys_GetClipboardData( void );
|
|
void Sys_SetClipboardData( const char *string );
|
|
|
|
// will go to the various text consoles
|
|
// NOT thread safe - never use in the async paths
|
|
void Sys_Printf( const char *msg, ... )id_attribute((format(printf,1,2)));
|
|
|
|
// guaranteed to be thread-safe
|
|
void Sys_DebugPrintf( const char *fmt, ... )id_attribute((format(printf,1,2)));
|
|
void Sys_DebugVPrintf( const char *fmt, va_list arg );
|
|
|
|
// a decent minimum sleep time to avoid going below the process scheduler speeds
|
|
#define SYS_MINSLEEP 20
|
|
|
|
// allow game to yield CPU time
|
|
// NOTE: due to SYS_MINSLEEP this is very bad portability karma, and should be completely removed
|
|
void Sys_Sleep( int msec );
|
|
|
|
// returns whether the main rendering window has focus
|
|
bool Sys_IsAppActive( void );
|
|
|
|
// Sys_Milliseconds should only be used for profiling purposes,
|
|
// any game related timing information should come from event timestamps
|
|
int Sys_Milliseconds( void );
|
|
|
|
// for accurate performance testing
|
|
double Sys_GetClockTicks( void );
|
|
double Sys_ClockTicksPerSecond( void );
|
|
|
|
// returns a selection of the CPUID_* flags
|
|
cpuid_t Sys_GetProcessorId( void );
|
|
const char * Sys_GetProcessorString( void );
|
|
|
|
// returns true if the FPU stack is empty
|
|
bool Sys_FPU_StackIsEmpty( void );
|
|
|
|
// empties the FPU stack
|
|
void Sys_FPU_ClearStack( void );
|
|
|
|
// returns the FPU state as a string
|
|
const char * Sys_FPU_GetState( void );
|
|
|
|
// enables the given FPU exceptions
|
|
void Sys_FPU_EnableExceptions( int exceptions );
|
|
|
|
// sets the FPU precision
|
|
void Sys_FPU_SetPrecision( int precision );
|
|
|
|
// sets the FPU rounding mode
|
|
void Sys_FPU_SetRounding( int rounding );
|
|
|
|
// sets Flush-To-Zero mode (only available when CPUID_FTZ is set)
|
|
void Sys_FPU_SetFTZ( bool enable );
|
|
|
|
// sets Denormals-Are-Zero mode (only available when CPUID_DAZ is set)
|
|
void Sys_FPU_SetDAZ( bool enable );
|
|
|
|
// returns amount of system ram
|
|
int Sys_GetSystemRam( void );
|
|
|
|
// returns amount of video ram
|
|
int Sys_GetVideoRam( void );
|
|
|
|
// returns amount of drive space in path
|
|
int Sys_GetDriveFreeSpace( const char *path );
|
|
|
|
// returns memory stats
|
|
void Sys_GetCurrentMemoryStatus( sysMemoryStats_t &stats );
|
|
void Sys_GetExeLaunchMemoryStatus( sysMemoryStats_t &stats );
|
|
|
|
// lock and unlock memory
|
|
bool Sys_LockMemory( void *ptr, int bytes );
|
|
bool Sys_UnlockMemory( void *ptr, int bytes );
|
|
|
|
// set amount of physical work memory
|
|
void Sys_SetPhysicalWorkMemory( int minBytes, int maxBytes );
|
|
|
|
// allows retrieving the call stack at execution points
|
|
void Sys_GetCallStack( address_t *callStack, const int callStackSize );
|
|
const char * Sys_GetCallStackStr( const address_t *callStack, const int callStackSize );
|
|
const char * Sys_GetCallStackCurStr( int depth );
|
|
const char * Sys_GetCallStackCurAddressStr( int depth );
|
|
void Sys_ShutdownSymbols( void );
|
|
|
|
#ifdef _LOAD_DLL
|
|
// 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 );
|
|
void Sys_DLL_Unload( int dllHandle );
|
|
#endif // _LOAD_DLL
|
|
|
|
// event generation
|
|
void Sys_GenerateEvents( void );
|
|
sysEvent_t Sys_GetEvent( void );
|
|
void Sys_ClearEvents( void );
|
|
|
|
// input is tied to windows, so it needs to be started up and shut down whenever
|
|
// the main window is recreated
|
|
void Sys_InitInput( void );
|
|
void Sys_ShutdownInput( void );
|
|
// keyboard input polling
|
|
int Sys_PollKeyboardInputEvents( void );
|
|
int Sys_ReturnKeyboardInputEvent( const int n, int &ch, bool &state );
|
|
void Sys_EndKeyboardInputEvents( void );
|
|
int Sys_MapKey( unsigned long key, unsigned short wParam );
|
|
|
|
// mouse input polling
|
|
int Sys_PollMouseInputEvents( void );
|
|
int Sys_ReturnMouseInputEvent( const int n, int &action, int &value );
|
|
void Sys_EndMouseInputEvents( void );
|
|
|
|
// RAVEN BEGIN
|
|
// ksergent: joystick input polling
|
|
int Sys_PollJoystickInputEvents( void );
|
|
bool Sys_IsJoystickEnabled( void );
|
|
bool Sys_IsJoystickConnected( int index );
|
|
int Sys_ReturnJoystickInputEvent( const int n, int &action, int &value );
|
|
void Sys_EndJoystickInputEvents( void );
|
|
// RAVEN END
|
|
|
|
// when the console is down, or the game is about to perform a lengthy
|
|
// operation like map loading, the system can release the mouse cursor
|
|
// when in windowed mode
|
|
bool Sys_IsWindowVisible( void );
|
|
void Sys_Mkdir( const char *path );
|
|
|
|
// RAVEN BEGIN
|
|
// jscott: thread handling
|
|
void Sys_StartAsyncThread( void );
|
|
void Sys_EndAsyncThread( void );
|
|
|
|
// jscott: VTune interface
|
|
#ifndef _FINAL
|
|
void Sys_StartProfiling( void );
|
|
void Sys_StopProfiling( void );
|
|
#endif
|
|
// RAVEN END
|
|
|
|
// NOTE: do we need to guarantee the same output on all platforms?
|
|
const char * Sys_TimeStampToStr( long timeStamp );
|
|
const char * Sys_DefaultCDPath( void );
|
|
const char * Sys_DefaultBasePath( void );
|
|
const char * Sys_DefaultSavePath( void );
|
|
const char * Sys_EXEPath( void );
|
|
|
|
// for getting current system (real world) time
|
|
int Sys_RealTime( sysTime_t* sysTime );
|
|
|
|
// use fs_debug to verbose Sys_ListFiles
|
|
// returns -1 if directory was not found (the list is cleared)
|
|
int Sys_ListFiles( const char *directory, const char *extension, idList<class idStr> &list );
|
|
|
|
// RAVEN BEGIN
|
|
// rjohnson: added block
|
|
bool Sys_AppShouldSleep ( void );
|
|
// RAVEN END
|
|
|
|
/*
|
|
==============================================================
|
|
|
|
Networking
|
|
|
|
==============================================================
|
|
*/
|
|
|
|
typedef enum {
|
|
NA_BAD, // an address lookup failed
|
|
NA_LOOPBACK,
|
|
NA_BROADCAST,
|
|
NA_IP,
|
|
// RAVEN BEGIN
|
|
// rjohnson: add fake clients
|
|
NA_FAKE,
|
|
// RAVEN END
|
|
NA_GAME, // bots, etc
|
|
} netadrtype_t;
|
|
|
|
typedef struct {
|
|
netadrtype_t type;
|
|
unsigned char ip[4];
|
|
unsigned short port;
|
|
} netadr_t;
|
|
|
|
#define PORT_ANY -1
|
|
|
|
class idPort {
|
|
public:
|
|
idPort(); // this just zeros netSocket and port
|
|
~idPort();
|
|
|
|
// if the InitForPort fails, the idPort.port field will remain 0
|
|
// RAVEN BEGIN
|
|
// asalmon: option for xbox to create a VDP socket
|
|
#ifdef _XBOX
|
|
bool InitForPort( int portNumber, bool vdp = false );
|
|
#else
|
|
bool InitForPort( int portNumber );
|
|
#endif
|
|
// RAVEN END
|
|
int GetPort( void ) const { return port; }
|
|
// RAVEN BEGIN
|
|
// amccarthy: For Xbox this needs to be an unsigned int
|
|
#ifdef _XBOX
|
|
unsigned int GetSocket( void ) const { return netSocket; }
|
|
#endif
|
|
// RAVEN END
|
|
void Close();
|
|
|
|
bool GetPacket( netadr_t &from, void *data, int &size, int maxSize );
|
|
bool GetPacketBlocking( netadr_t &from, void *data, int &size, int maxSize, int timeout );
|
|
void SendPacket( const netadr_t to, const void *data, int size );
|
|
|
|
//RAVEN BEGIN
|
|
//asalmon: second version of sendPacket for Xbox avoids netadr_t
|
|
#ifdef _XBOX
|
|
bool SendPacketVDP( const struct sockaddr *to, const void *data, int size );
|
|
#endif
|
|
//RAVEN END
|
|
|
|
void GetTrafficStats( int &bytesSent, int &packetsSent, int &bytesReceived, int &packetsReceived ) const;
|
|
|
|
void SetSilent( bool silent );
|
|
bool GetSilent( void ) const;
|
|
|
|
private:
|
|
int packetsRead;
|
|
int bytesRead;
|
|
|
|
int packetsWritten;
|
|
int bytesWritten;
|
|
|
|
int port; // UDP port
|
|
//RAVEN BEGIN
|
|
//amccarthy: For Xbox this needs to be an unsigned int
|
|
#ifdef _XBOX
|
|
unsigned int netSocket; // OS specific socket
|
|
#else
|
|
int netSocket;
|
|
#endif
|
|
//RAVEN END
|
|
|
|
bool silent; // don't emit anything for a while
|
|
};
|
|
|
|
/*
|
|
===============
|
|
idPort::GetTrafficStats
|
|
===============
|
|
*/
|
|
ID_INLINE void idPort::GetTrafficStats( int &_bytesSent, int &_packetsSent, int &_bytesReceived, int &_packetsReceived ) const {
|
|
_bytesSent = bytesWritten;
|
|
_packetsSent = packetsWritten;
|
|
_bytesReceived = bytesRead;
|
|
_packetsReceived = packetsRead;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
idPort::SetSilent
|
|
===============
|
|
*/
|
|
ID_INLINE void idPort::SetSilent( bool _silent ) { silent = _silent; }
|
|
|
|
/*
|
|
===============
|
|
idPort::GetSilent
|
|
===============
|
|
*/
|
|
ID_INLINE bool idPort::GetSilent( void ) const { return silent; }
|
|
|
|
class idTCP;
|
|
class idTCPServer;
|
|
|
|
const int IDPOLL_READ = (1<<0);
|
|
const int IDPOLL_WRITE = (1<<1);
|
|
const int IDPOLL_ERROR = (1<<2);
|
|
|
|
class idPoller {
|
|
public:
|
|
idPoller();
|
|
|
|
void Clear( void );
|
|
|
|
// will replace existing entries
|
|
void Add( int fd, int which = IDPOLL_READ );
|
|
void Add( const idTCP &tcp, int which = IDPOLL_READ );
|
|
void Add( const idTCPServer &tcp, int which = IDPOLL_READ );
|
|
|
|
void Remove( int fd ) { Add(fd, 0); }
|
|
void Remove( const idTCP &tcp ) { Add(tcp, 0); }
|
|
void Remove( const idTCPServer &serv ) { Add(serv, 0); }
|
|
|
|
// returns IDPOLL_ flags
|
|
int Check( int fd );
|
|
int Check( const idTCP &tcp );
|
|
int Check( const idTCPServer &serv );
|
|
|
|
// returns the number of fds set, timeout is in ms, <0 is forever
|
|
int Poll( int timeout = -1 );
|
|
|
|
private:
|
|
int max_fd;
|
|
fd_set readfds, writefds, exceptfds;
|
|
fd_set rreadfds, rwritefds, rexceptfds;
|
|
};
|
|
|
|
class idTCPServer {
|
|
public:
|
|
idTCPServer();
|
|
virtual ~idTCPServer();
|
|
|
|
bool Listen( const char *net_interface, short port );
|
|
bool Accept( idTCP &client );
|
|
void Close();
|
|
|
|
const netadr_t &GetAddress( void ) const { return address; }
|
|
|
|
private:
|
|
netadr_t address; // local address
|
|
int fd;
|
|
|
|
friend void idPoller::Add( const idTCPServer &serv, int which );
|
|
friend void idPoller::Remove( const idTCPServer &serv );
|
|
friend int idPoller::Check( const idTCPServer &serv );
|
|
};
|
|
|
|
class idTCP {
|
|
public:
|
|
idTCP();
|
|
idTCP( const netadr_t &address, int fd );
|
|
idTCP( const idTCP &tcp );
|
|
virtual ~idTCP();
|
|
|
|
idTCP & operator = (const idTCP &tcp);
|
|
|
|
// if host is host:port, the value of port is ignored
|
|
bool Init( const char *host, short port );
|
|
void Close();
|
|
|
|
// returns -1 on failure (and closes socket)
|
|
// those are non blocking, can be used for polling
|
|
// there is no buffering, you are not guaranteed to Read or Write everything in a single call
|
|
// (specially on win32, see recv and send documentation)
|
|
int Read( void *data, int size );
|
|
int Write( const void *data, int size );
|
|
|
|
const netadr_t &GetAddress( void ) const { return address; }
|
|
|
|
private:
|
|
netadr_t address; // remote address
|
|
int fd; // OS specific socket
|
|
|
|
friend void idPoller::Add( const idTCP &tcp, int which );
|
|
friend void idPoller::Remove( const idTCP &tcp );
|
|
friend int idPoller::Check( const idTCP &tcp );
|
|
};
|
|
|
|
// parses the port number
|
|
// can also do DNS resolve if you ask for it.
|
|
// NOTE: DNS resolve is a slow/blocking call, think before you use
|
|
// ( could be exploited for server DoS )
|
|
bool Sys_StringToNetAdr( const char *s, netadr_t *a, bool doDNSResolve );
|
|
const char * Sys_NetAdrToString( const netadr_t a );
|
|
bool Sys_IsLANAddress( const netadr_t a );
|
|
bool Sys_CompareNetAdrBase( const netadr_t a, const netadr_t b );
|
|
|
|
void Sys_InitNetworking( void );
|
|
void Sys_ShutdownNetworking( void );
|
|
|
|
// read proxy information from environment
|
|
#define MAX_PROXY_LENGTH 128
|
|
bool Sys_GetHTTPProxyAddress( char proxy[ MAX_PROXY_LENGTH ] );
|
|
|
|
// RAVEN BEGIN
|
|
// ddynerman: utility functions
|
|
// TTimo: FIXME if exposed, call them Sys_
|
|
int Net_GetNumInterfaces( void );
|
|
netadr_t Net_GetInterface( int index );
|
|
|
|
// asalmon: Xbox live related functions
|
|
#ifdef _XBOX
|
|
#define NONCE_SIZE 8
|
|
bool Sys_CreateLiveMatch( void );
|
|
bool Sys_CreateSystemLinkMatch( void );
|
|
bool Sys_VerifyString(const char *string);
|
|
#endif
|
|
// RAVEN END
|
|
|
|
|
|
/*
|
|
==============================================================
|
|
|
|
Multi-threading
|
|
|
|
==============================================================
|
|
*/
|
|
|
|
typedef unsigned int (*xthread_t)( void * );
|
|
|
|
typedef enum {
|
|
THREAD_NORMAL,
|
|
THREAD_ABOVE_NORMAL,
|
|
THREAD_HIGHEST
|
|
} xthreadPriority;
|
|
|
|
typedef struct {
|
|
const char * name;
|
|
int threadHandle;
|
|
unsigned long threadId;
|
|
// RAVEN BEGIN
|
|
// ksergent: included to track multiprocessor system
|
|
#ifdef _XBOX
|
|
unsigned char cpuID;
|
|
#endif
|
|
// RAVEN END
|
|
} xthreadInfo;
|
|
|
|
const int MAX_THREADS = 10;
|
|
extern xthreadInfo *g_threads[MAX_THREADS];
|
|
extern int g_thread_count;
|
|
|
|
void Sys_CreateThread( xthread_t function, void *parms, xthreadPriority priority, xthreadInfo &info, const char *name, xthreadInfo *threads[MAX_THREADS], int *thread_count );
|
|
void Sys_DestroyThread( xthreadInfo& info ); // sets threadHandle back to 0
|
|
|
|
// find the name of the calling thread
|
|
// if index != NULL, set the index in g_threads array (use -1 for "main" thread)
|
|
const char * Sys_GetThreadName( int *index = 0 );
|
|
|
|
const int MAX_CRITICAL_SECTIONS = 4;
|
|
|
|
enum {
|
|
CRITICAL_SECTION_ZERO = 0,
|
|
CRITICAL_SECTION_ONE,
|
|
CRITICAL_SECTION_TWO,
|
|
CRITICAL_SECTION_THREE
|
|
};
|
|
|
|
void Sys_EnterCriticalSection( int index = CRITICAL_SECTION_ZERO );
|
|
void Sys_LeaveCriticalSection( int index = CRITICAL_SECTION_ZERO );
|
|
|
|
const int MAX_TRIGGER_EVENTS = 4;
|
|
|
|
enum {
|
|
TRIGGER_EVENT_ZERO = 0,
|
|
TRIGGER_EVENT_ONE,
|
|
TRIGGER_EVENT_TWO,
|
|
TRIGGER_EVENT_THREE
|
|
};
|
|
|
|
void Sys_WaitForEvent( int index = TRIGGER_EVENT_ZERO );
|
|
void Sys_TriggerEvent( int index = TRIGGER_EVENT_ZERO );
|
|
|
|
/*
|
|
==============================================================
|
|
|
|
idSys
|
|
|
|
==============================================================
|
|
*/
|
|
|
|
class idSys {
|
|
public:
|
|
virtual ~idSys() { }
|
|
virtual void DebugPrintf( const char *fmt, ... )id_attribute((format(printf,2,3))) = 0;
|
|
virtual void DebugVPrintf( const char *fmt, va_list arg ) = 0;
|
|
|
|
virtual double GetClockTicks( void ) = 0;
|
|
virtual double ClockTicksPerSecond( void ) = 0;
|
|
virtual cpuid_t GetProcessorId( void ) = 0;
|
|
virtual const char * GetProcessorString( void ) = 0;
|
|
virtual const char * FPU_GetState( void ) = 0;
|
|
virtual bool FPU_StackIsEmpty( void ) = 0;
|
|
virtual void FPU_SetFTZ( bool enable ) = 0;
|
|
virtual void FPU_SetDAZ( bool enable ) = 0;
|
|
// RAVEN BEGIN
|
|
virtual void FPU_SetPrecision( int flags ) = 0;
|
|
// RAVEN END
|
|
|
|
virtual bool LockMemory( void *ptr, int bytes ) = 0;
|
|
virtual bool UnlockMemory( void *ptr, int bytes ) = 0;
|
|
|
|
virtual void GetCallStack( address_t *callStack, const int callStackSize ) = 0;
|
|
virtual const char * GetCallStackStr( const address_t *callStack, const int callStackSize ) = 0;
|
|
virtual const char * GetCallStackCurStr( int depth ) = 0;
|
|
virtual void ShutdownSymbols( void ) = 0;
|
|
|
|
virtual int DLL_Load( const char *dllName ) = 0;
|
|
virtual void * DLL_GetProcAddress( int dllHandle, const char *procName ) = 0;
|
|
virtual void DLL_Unload( int dllHandle ) = 0;
|
|
virtual void DLL_GetFileName( const char *baseName, char *dllName, int maxLength ) = 0;
|
|
|
|
virtual sysEvent_t GenerateMouseButtonEvent( int button, bool down ) = 0;
|
|
virtual sysEvent_t GenerateMouseMoveEvent( int deltax, int deltay ) = 0;
|
|
|
|
// RAVEN BEGIN
|
|
virtual int MapKey( unsigned long lParam, unsigned short wParam ) = 0;
|
|
virtual void AddKeyPress( int key, bool state ) = 0;
|
|
virtual int GetNumKeyPresses( void ) = 0;
|
|
virtual bool GetKeyPress( const int n, int &key, bool &state ) = 0;
|
|
|
|
virtual void * CreateWindowEx( const char *className, const char *windowName, int style, int x, int y, int w, int h, void *parent, void *menu, void *instance, void *param, int extStyle = 0 ) = 0;
|
|
virtual void * GetDC( void *hWnd ) = 0;
|
|
virtual void ReleaseDC( void *hWnd, void *hDC ) = 0;
|
|
virtual void ShowWindow( void *hWnd, int show ) = 0;
|
|
virtual void UpdateWindow( void *hWnd ) = 0;
|
|
virtual bool IsWindowVisible( void *hWnd ) = 0;
|
|
virtual void SetForegroundWindow( void *hWnd ) = 0;
|
|
virtual void SetFocus( void *hWnd ) = 0;
|
|
virtual void DestroyWindow( void *hWnd ) = 0;
|
|
|
|
virtual void ShowConsole( int visLevel, bool quitOnClose ) = 0;
|
|
virtual void UpdateConsole( void ) = 0;
|
|
virtual void SetConsoleName( const char* consoleName ) = 0;
|
|
virtual bool IsAppActive( void ) const = 0;
|
|
virtual int Milliseconds( void ) = 0;
|
|
virtual void InitInput( void ) = 0;
|
|
virtual void ShutdownInput( void ) = 0;
|
|
virtual void GenerateEvents( void ) = 0;
|
|
virtual void GrabMouseCursor( bool grabIt ) = 0;
|
|
|
|
virtual FILE *FOpen( const char *name, const char *mode ) = 0;
|
|
virtual void FPrintf( FILE *file, const char *fmt ) = 0;
|
|
virtual int FTell( FILE *file ) = 0;
|
|
virtual int FSeek( FILE *file, long offset, int mode ) = 0;
|
|
virtual void FClose( FILE *file ) = 0;
|
|
virtual int FRead( void *buffer, int size, int count, FILE *file ) = 0;
|
|
virtual int FWrite( void *buffer, int size, int count, FILE *file ) = 0;
|
|
virtual long FileTimeStamp( FILE *file ) = 0;
|
|
virtual int FEof( FILE *stream ) = 0;
|
|
virtual char *FGets( char *string, int n, FILE *stream ) = 0;
|
|
virtual void FFlush( FILE *f ) = 0;
|
|
virtual int SetVBuf( FILE *stream, char *buffer, int mode, size_t size ) = 0;
|
|
// RAVEN END
|
|
|
|
virtual void OpenURL( const char *url, bool quit ) = 0;
|
|
virtual void StartProcess( const char *exePath, bool quit ) = 0;
|
|
|
|
virtual int GetGUID( char *buf, int buflen ) = 0;
|
|
};
|
|
|
|
extern idSys * sys;
|
|
|
|
// RAVEN BEGIN
|
|
// jnewquist: Scope timing tools
|
|
#if defined(_XENON)
|
|
class ScopeAutoMeasure {
|
|
public:
|
|
ID_INLINE ScopeAutoMeasure(const char *name) {
|
|
mName = name;
|
|
QueryPerformanceCounter( &mStartTime );
|
|
}
|
|
ID_INLINE ~ScopeAutoMeasure() {
|
|
LARGE_INTEGER endTime;
|
|
QueryPerformanceCounter( &endTime );
|
|
double time = (double)(endTime.QuadPart - mStartTime.QuadPart) / (Sys_ClockTicksPerSecond() * 0.000001);
|
|
printf("Time %s: %f us\n", mName, time);
|
|
}
|
|
protected:
|
|
LARGE_INTEGER mStartTime;
|
|
const char * mName;
|
|
};
|
|
|
|
#if defined(TIME_CAPTURE) //&& defined(_PROFILE)
|
|
|
|
class TimedScope {
|
|
public:
|
|
ID_INLINE TimedScope(const char *name) {
|
|
mName = name;
|
|
mNext = mFirst;
|
|
mFirst = this;
|
|
mTime.QuadPart = 0;
|
|
}
|
|
static void ComputeCost() {
|
|
LARGE_INTEGER TicksPerSecond;
|
|
QueryPerformanceFrequency( &TicksPerSecond );
|
|
sTicksPerMicrosecond = (double)TicksPerSecond.QuadPart * 0.000001;
|
|
|
|
// get a rough time estimate for the cost of a call to Sys_Milliseconds so that we can remove it from the function costs
|
|
LARGE_INTEGER before;
|
|
QueryPerformanceCounter( &before );
|
|
|
|
LARGE_INTEGER test;
|
|
for(int i=0; i<1000000; i++)
|
|
{
|
|
QueryPerformanceCounter( &test );
|
|
}
|
|
LARGE_INTEGER after;
|
|
QueryPerformanceCounter( &after );
|
|
|
|
__int64 Ticks = after.QuadPart - before.QuadPart;
|
|
sQueryPerformanceCounterCost.QuadPart = (double)Ticks/1000000.0f;
|
|
}
|
|
|
|
// automatically deducts the cost of the Sys_Milliseconds() call used to gather the timing
|
|
ID_INLINE void AddTime(unsigned long long ticks) {
|
|
// add number of microseconds
|
|
mTime.QuadPart += (ticks - sQueryPerformanceCounterCost.QuadPart)/sTicksPerMicrosecond;
|
|
}
|
|
ID_INLINE void AddCall() {
|
|
mCalls++;
|
|
}
|
|
ID_INLINE static void PrintTimes(void) {
|
|
if (!mFirst) {
|
|
return;
|
|
}
|
|
printf("Start Frame\n");
|
|
for (TimedScope* p=mFirst; p; p = p->mNext) {
|
|
printf("\t%20s: %d us\t%d calls\t %f us/call\n", p->mName, p->mTime, p->mCalls, (p->mCalls)?(double)p->mTime.QuadPart/(double)p->mCalls:0.0f);
|
|
}
|
|
printf("End Frame\n\n");
|
|
}
|
|
ID_INLINE static void ClearTimes(void) {
|
|
if (!mFirst) {
|
|
return;
|
|
}
|
|
for (TimedScope* p=mFirst; p; p = p->mNext) {
|
|
p->mTime.QuadPart = 0;
|
|
}
|
|
}
|
|
ID_INLINE static void ClearCalls(void) {
|
|
if (!mFirst) {
|
|
return;
|
|
}
|
|
for (TimedScope* p=mFirst; p; p = p->mNext) {
|
|
p->mCalls = 0;
|
|
}
|
|
}
|
|
protected:
|
|
static TimedScope * mFirst;
|
|
TimedScope * mNext;
|
|
const char * mName;
|
|
LARGE_INTEGER mTime;
|
|
unsigned int mCalls;
|
|
static LARGE_INTEGER sQueryPerformanceCounterCost;
|
|
static double sTicksPerMicrosecond;
|
|
};
|
|
|
|
class ScopeAutoTimer {
|
|
public:
|
|
ID_INLINE ScopeAutoTimer(TimedScope *scope) {
|
|
QueryPerformanceCounter( &mStartTime );
|
|
//mStartTime = Sys_Milliseconds();
|
|
mScope = scope;
|
|
}
|
|
ID_INLINE ~ScopeAutoTimer() {
|
|
LARGE_INTEGER endTime;
|
|
QueryPerformanceCounter( &endTime );
|
|
|
|
//unsigned int time = (unsigned int)Sys_Milliseconds() - mStartTime;
|
|
// pass in number of ticks used and TimedScope will adjust it to a number of microseconds
|
|
mScope->AddTime(endTime.QuadPart - mStartTime.QuadPart);
|
|
mScope->AddCall();
|
|
}
|
|
protected:
|
|
LARGE_INTEGER mStartTime;
|
|
TimedScope * mScope;
|
|
};
|
|
|
|
#define TIME_THIS_SCOPE(name) \
|
|
static TimedScope scopeTime(name); \
|
|
ScopeAutoTimer autoTimer(&scopeTime)
|
|
#else
|
|
#define TIME_THIS_SCOPE(name)
|
|
#endif
|
|
#endif
|
|
|
|
#define STRINGIZE_INDIRECT(F, X) F(X)
|
|
#define STRINGIZE(X) #X
|
|
#define __LINESTR__ STRINGIZE_INDIRECT(STRINGIZE, __LINE__)
|
|
#define __FILELINEFUNC__ (__FILE__ " " __LINESTR__ " " __FUNCTION__)
|
|
#define __FUNCLINE__ ( __FUNCTION__ " " __LINESTR__ )
|
|
|
|
// RAVEN END
|
|
|
|
#endif /* !__SYS_PUBLIC__ */
|