/*
===========================================================================
Return to Castle Wolfenstein single player GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
RTCW SP 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.
RTCW SP 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 RTCW SP Source Code. If not, see .
In addition, the RTCW SP 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 RTCW SP 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 "../splines/q_shared.h"
#include "../splines/util_str.h"
#pragma once
#define GENTITYNUM_BITS 11 // don't need to send any more
#define MAX_GENTITIES ( 1 << GENTITYNUM_BITS )
#define Com_ClearedAllocate( x ) calloc( x,1 );
#define Com_Dealloc free
#define Com_Allocate malloc
typedef unsigned char byte;
typedef unsigned long dword;
typedef unsigned short word;
typedef unsigned int uint;
typedef unsigned long ulong;
#ifdef __cplusplus
extern "C" {
#endif
typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
#include "../client/snd_public.h"
int FS_FOpenFileRead( const char *qpath, fileHandle_t *file, qboolean uniqueFILE );
// if uniqueFILE is true, then a new FILE will be fopened even if the file
// is found in an already open pak file. If uniqueFILE is false, you must call
// FS_FCloseFile instead of fclose, otherwise the pak FILE would be improperly closed
// It is generally safe to always set uniqueFILE to true, because the majority of
// file IO goes through FS_ReadFile, which Does The Right Thing already.
int FS_FileIsInPAK( const char *filename, int *pChecksum );
// returns 1 if a file is in the PAK file, otherwise -1
int FS_Write( const void *buffer, int len, fileHandle_t f );
int FS_Read( void *buffer, int len, fileHandle_t f );
// properly handles partial reads and reads from other dlls
void FS_FCloseFile( fileHandle_t f );
// note: you can't just fclose from another DLL, due to MS libc issues
int FS_ReadFile( const char *qpath, void **buffer );
// returns the length of the file
// a null buffer will just return the file length without loading
// as a quick check for existance. -1 length == not present
// A 0 byte will always be appended at the end, so string ops are safe.
// the buffer should be considered read-only, because it may be cached
// for other uses.
void FS_ForceFlush( fileHandle_t f );
// forces flush on files we're writing to.
void FS_FreeFile( void *buffer );
// frees the memory returned by FS_ReadFile
void FS_WriteFile( const char *qpath, const void *buffer, int size );
// writes a complete file, creating any subdirectories needed
int FS_filelength( fileHandle_t f );
// doesn't work for files that are opened from a pack file
int FS_FTell( fileHandle_t f );
// where are we?
void FS_Flush( fileHandle_t f );
void QDECL FS_Printf( fileHandle_t f, const char *fmt, ... );
// like fprintf
int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode );
// opens a file for reading, writing, or appending depending on the value of mode
int FS_Seek( fileHandle_t f, long offset, int origin );
// seek on a file (doesn't work for zip files!!!!!!!!)
int Com_Milliseconds( void );
void Com_Memset( void* dest, const int val, const size_t count );
// Sys_Milliseconds should only be used for profiling purposes,
// any game related timing information should come from event timestamps
int Sys_Milliseconds( void );
// nothing outside the Cvar_*() functions should modify these fields!
typedef struct cvar_s {
char *name;
char *string;
char *resetString; // cvar_restart will reset to this value
char *latchedString; // for CVAR_LATCH vars
int flags;
qboolean modified; // set each time the cvar is changed
int modificationCount; // incremented each time the cvar is changed
float value; // atof( string )
int integer; // atoi( string )
struct cvar_s *next;
struct cvar_s *hashNext;
} cvar_t;
cvar_t *Cvar_Get( const char *var_name, const char *value, int flags );
// creates the variable if it doesn't exist, or returns the existing one
// if it exists, the value will not be changed, but flags will be ORed in
// that allows variables to be unarchived without needing bitflags
// if value is "", the value will not override a previously set value.
#define CVAR_ARCHIVE 1 // set to cause it to be saved to vars.rc
// used for system variables, not for player
// specific configurations
#ifdef __cplusplus
}
#endif
template
class idFlags
{
public:
typedef unsigned int T;
idFlags ( void ) {
flag = 0;
}
idFlags ( const char *debugnames );
idFlags ( const T val ) {
flag = val;
}
idFlags& operator=( const idFlags& src ) { flag = (T)src.flag; return *this; }
idFlags& operator=( const T& val ) { flag = val; return *this; }
void clearAll( void ) { flag = 0; }
void clear( IndexType index ) { flag &= ~( 1 << ( unsigned int )( index ) ); }
void clearMask( const T& f ) { flag &= ~f; }
void set( IndexType index ) { flag |= ( 1 << ( unsigned int )( index ) ); }
void set( IndexType index, bool on ) { if ( on ) {
flag |= ( 1 << ( unsigned int )( index ) );
} else { flag &= ~( 1 << ( unsigned int )( index ) );} }
void setAll( void ) { flag = 0xffffffff; }
void setMask( const T& mask ) { flag |= mask; }
void setVal( const T& f ) { flag = f; }
bool testAny( void ) const { return flag != 0; }
bool test( IndexType index ) const { return (bool)( ( flag & ( 1 << ( unsigned int )( index ) ) ) != 0 ); }
bool testMask( const T& mask ) const { return flag & mask; }
bool testMaskAll( const T& mask ) const { return ( flag & mask ) == mask; }
void toggle( IndexType index ) { flag ^= ( 1 << ( unsigned int )( index ) ); }
operator T( void ) const { return flag; }
unsigned int getNumBits( void ) const { return sizeof( T ) * 8; }
static const char *getDebugNames() { return debugNames; }
private:
static const char *debugNames; // list of flag names
T flag; // flag data bitmask
};
template idFlags::idFlags( const char *debugnames ) {
clearAll();
if ( !idFlags::debugNames ) {
idFlags::debugNames = debugnames;
}
}
template const char * idFlags::debugNames = 0;
template< class Type >
class idHashTable {
private:
struct hashnode_s {
idStr key;
Type value;
hashnode_s *next;
hashnode_s( const idStr &k, Type v, hashnode_s *n ) : key( k ), value( v ), next( n ) {
};
hashnode_s( const char *k, Type v, hashnode_s *n ) : key( k ), value( v ), next( n ) {
};
};
hashnode_s **m_heads;
unsigned m_tablesize;
unsigned m_numentries;
unsigned m_tablesizemask;
unsigned GetHash( const char *key );
public:
void Clear( void );
void DeleteContents( void );
unsigned Num( void ) const;
void Set( const char *key, Type &value );
bool Get( const char *key, Type **value = NULL );
bool Remove( const char *key );
~idHashTable();
idHashTable( unsigned tablesize = 1024 ) : m_tablesize( tablesize ) {
int i;
int bits;
assert( m_tablesize > 0 );
m_heads = new hashnode_s *[ m_tablesize ];
memset( m_heads, 0, sizeof( *m_heads ) * m_tablesize );
m_numentries = 0;
m_tablesizemask = 0;
bits = 0;
for ( i = 0; i < 32; i++ ) {
if ( m_tablesize & ( 1 << i ) ) {
bits++;
}
}
if ( bits == 1 ) {
m_tablesizemask = m_tablesize - 1;
}
};
idHashTable( idHashTable &map ) : m_tablesize( map.m_tablesize ) {
unsigned i;
hashnode_s *node;
hashnode_s **prev;
assert( m_tablesize > 0 );
m_heads = new hashnode_s *[ m_tablesize ];
m_numentries = map.m_numentries;
m_tablesizemask = map.m_tablesizemask;
for ( i = 0; i < m_tablesize; i++ ) {
if ( !map.m_heads[ i ] ) {
m_heads[ i ] = NULL;
continue;
}
prev = &m_heads[ i ];
for ( node = map.m_heads[ i ]; node != NULL; node = node->next ) {
*prev = new hashnode_s( node->key, node->value, NULL );
prev = &( *prev )->next;
}
}
};
};
/*
================
idHashTable::~idHashTable()
================
*/
template< class Type >
inline idHashTable::~idHashTable() {
Clear();
delete[] m_heads;
}
/*
================
idHashTable::GetHash
================
*/
template< class Type >
inline unsigned idHashTable::GetHash( const char *key ) {
unsigned h;
const char *v;
if ( m_tablesizemask ) {
h = 0;
for ( v = key; *v != '\0'; v++ ) {
h = ( 64 * h + unsigned( *v ) ) & m_tablesizemask;
}
} else {
h = 0;
for ( v = key; *v != '\0'; v++ ) {
h = ( 64 * h + unsigned( *v ) ) % m_tablesize;
}
}
return h;
}
/*
================
idHashTable::Set
================
*/
template< class Type >
inline void idHashTable::Set( const char *key, Type &value ) {
hashnode_s **head;
hashnode_s *node;
unsigned hash;
// FIXME
// if list was always sorted, we could just insert new node as soon as we get
// a node whose key is greater than the search key
hash = GetHash( key );
head = &m_heads[ hash ];
if ( *head ) {
for ( node = *head; node != NULL; node = node->next ) {
if ( node->key == key ) {
node->value = value;
return;
}
}
}
m_numentries++;
*head = new hashnode_s( key, value, *head );
}
/*
================
idHashTable::Get
================
*/
template< class Type >
inline bool idHashTable::Get( const char *key, Type **value ) {
hashnode_s **head;
hashnode_s *node;
unsigned hash;
// FIXME
// if list was always sorted, we could just insert new node as soon as we get
// a node whose key is greater than the search key
hash = GetHash( key );
head = &m_heads[ hash ];
if ( *head ) {
for ( node = *head; node != NULL; node = node->next ) {
if ( node->key == key ) {
if ( value ) {
*value = &node->value;
}
return true;
}
}
}
if ( value ) {
*value = NULL;
}
return false;
}
/*
================
idHashTable::Remove
================
*/
template< class Type >
inline bool idHashTable::Remove( const char *key ) {
hashnode_s **head;
hashnode_s *node;
hashnode_s *prev;
unsigned hash;
hash = GetHash( key );
head = &m_heads[ hash ];
if ( *head ) {
for ( prev = NULL, node = *head; node != NULL; prev = node, node = node->next ) {
if ( node->key == key ) {
if ( prev ) {
prev->next = node->next;
} else {
*head = node->next;
}
delete node;
return true;
}
}
}
return false;
}
/*
================
idHashTable::Clear
================
*/
template< class Type >
inline void idHashTable::Clear( void ) {
unsigned i;
hashnode_s *node;
hashnode_s *next;
for ( i = 0; i < m_tablesize; i++ ) {
next = m_heads[ i ];
while ( next != NULL ) {
node = next;
next = next->next;
delete node;
}
m_heads[ i ] = NULL;
}
m_numentries = 0;
}
/*
================
idHashTable::DeleteContents
================
*/
template< class Type >
inline void idHashTable::DeleteContents( void ) {
unsigned i;
hashnode_s *node;
hashnode_s *next;
for ( i = 0; i < m_tablesize; i++ ) {
next = m_heads[ i ];
while ( next != NULL ) {
node = next;
next = next->next;
delete node->value;
delete node;
}
m_heads[ i ] = NULL;
}
m_numentries = 0;
}
/*
================
idHashTable::Num
================
*/
template< class Type >
inline unsigned idHashTable::Num( void ) const {
return m_numentries;
}
#include
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
HINSTANCE reflib_library; // Handle to refresh DLL
qboolean reflib_active;
HWND hWnd;
HINSTANCE hInstance;
qboolean activeApp;
qboolean isMinimized;
OSVERSIONINFO osversion;
// when we get a windows message, we store the time off so keyboard processing
// can know the exact time of an event
unsigned sysMsgTime;
} WinVars_t;
extern WinVars_t g_wv;
//#define SND_NORMAL 0x000 // (default) Allow sound to be cut off only by the same sound on this channel
#define SND_OKTOCUT 0x001 // Allow sound to be cut off by any following sounds on this channel
#define SND_REQUESTCUT 0x002 // Allow sound to be cut off by following sounds on this channel only for sounds who request cutoff
#define SND_CUTOFF 0x004 // Cut off sounds on this channel that are marked 'SND_REQUESTCUT'
#define SND_CUTOFF_ALL 0x008 // Cut off all sounds on this channel
#define SND_NOCUT 0x010 // Don't cut off. Always let finish (overridden by SND_CUTOFF_ALL)
#ifdef __cplusplus
}
#endif