mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-03-09 12:11:06 +00:00
lowmemory: merge
This commit is contained in:
commit
79adaa11e0
@ -126,6 +126,9 @@ GNU General Public License for more details.
|
||||
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||
#endif
|
||||
#endif //WIN32
|
||||
#ifndef XASH_LOW_MEMORY
|
||||
#define XASH_LOW_MEMORY 0
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -142,7 +142,13 @@ typedef void (*setpair_t)( const char *key, const void *value, void *buffer, voi
|
||||
// config strings are a general means of communication from
|
||||
// the server to all connected clients.
|
||||
// each config string can be at most CS_SIZE characters.
|
||||
#if XASH_LOW_MEMORY == 0
|
||||
#define MAX_QPATH 64 // max length of a game pathname
|
||||
#elif XASH_LOW_MEMORY == 2
|
||||
#define MAX_QPATH 32 // should be enough for singleplayer
|
||||
#elif XASH_LOW_MEMORY == 1
|
||||
#define MAX_QPATH 48
|
||||
#endif
|
||||
#define MAX_OSPATH 260 // max length of a filesystem pathname
|
||||
#define CS_SIZE 64 // size of one config string
|
||||
#define CS_TIME 16 // size of time string
|
||||
|
@ -1123,8 +1123,9 @@ void CL_InitEdicts( void )
|
||||
Assert( clgame.entities == NULL );
|
||||
|
||||
if( !clgame.mempool ) return; // Host_Error without client
|
||||
|
||||
CL_UPDATE_BACKUP = ( cl.maxclients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
|
||||
#if XASH_LOW_MEMORY != 2
|
||||
CL_UPDATE_BACKUP = ( cl.maxclients <= 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
|
||||
#endif
|
||||
cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES;
|
||||
cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
|
||||
clgame.entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities );
|
||||
|
@ -21,9 +21,9 @@ GNU General Public License for more details.
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
|
||||
#if XASH_LOW_MEMORY != 2
|
||||
int CL_UPDATE_BACKUP = SINGLEPLAYER_BACKUP;
|
||||
|
||||
#endif
|
||||
/*
|
||||
===============
|
||||
CL_UserMsgStub
|
||||
@ -92,7 +92,7 @@ void CL_ParseSoundPacket( sizebuf_t *msg )
|
||||
char sentenceName[32];
|
||||
|
||||
if( FBitSet( flags, SND_SEQUENCE ))
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS );
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS_NONSENTENCE );
|
||||
else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
@ -156,7 +156,7 @@ void CL_ParseRestoreSoundPacket( sizebuf_t *msg )
|
||||
char sentenceName[32];
|
||||
|
||||
if( flags & SND_SEQUENCE )
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound + MAX_SOUNDS );
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound + MAX_SOUNDS_NONSENTENCE );
|
||||
else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
@ -881,7 +881,7 @@ void CL_ParseServerData( sizebuf_t *msg )
|
||||
cl.playernum = MSG_ReadByte( msg );
|
||||
cl.maxclients = MSG_ReadByte( msg );
|
||||
clgame.maxEntities = MSG_ReadWord( msg );
|
||||
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MSG_ReadWord( msg );
|
||||
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING );
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
|
||||
@ -1411,6 +1411,36 @@ void CL_ParseResource( sizebuf_t *msg )
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
MSG_ReadBytes( msg, pResource->rguc_reserved, sizeof( pResource->rguc_reserved ));
|
||||
|
||||
if( pResource->type == t_sound && pResource->nIndex > MAX_SOUNDS )
|
||||
{
|
||||
Mem_Free( pResource );
|
||||
Host_Error( "bad sound index\n" );
|
||||
}
|
||||
|
||||
if( pResource->type == t_model && pResource->nIndex > MAX_MODELS )
|
||||
{
|
||||
Mem_Free( pResource );
|
||||
Host_Error( "bad model index\n" );
|
||||
}
|
||||
|
||||
if( pResource->type == t_eventscript && pResource->nIndex > MAX_EVENTS )
|
||||
{
|
||||
Mem_Free( pResource );
|
||||
Host_Error( "bad event index\n" );
|
||||
}
|
||||
|
||||
if( pResource->type == t_generic && pResource->nIndex > MAX_CUSTOM )
|
||||
{
|
||||
Mem_Free( pResource );
|
||||
Host_Error( "bad file index\n" );
|
||||
}
|
||||
|
||||
if( pResource->type == t_decal && pResource->nIndex > MAX_DECALS )
|
||||
{
|
||||
Mem_Free( pResource );
|
||||
Host_Error( "bad decal index\n" );
|
||||
}
|
||||
|
||||
CL_AddToResourceList( pResource, &cl.resourcesneeded );
|
||||
}
|
||||
|
||||
@ -2394,7 +2424,7 @@ void CL_ParseLegacyServerData( sizebuf_t *msg )
|
||||
cl.playernum = MSG_ReadByte( msg );
|
||||
cl.maxclients = MSG_ReadByte( msg );
|
||||
clgame.maxEntities = MSG_ReadWord( msg );
|
||||
clgame.maxEntities = bound( 600, clgame.maxEntities, 4096 );
|
||||
clgame.maxEntities = bound( 30, clgame.maxEntities, 4096 );
|
||||
clgame.maxModels = 512;
|
||||
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING );
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
|
||||
@ -2724,7 +2754,13 @@ void CL_LegacyUpdateUserinfo( sizebuf_t *msg )
|
||||
}
|
||||
else memset( player, 0, sizeof( *player ));
|
||||
}
|
||||
|
||||
#if XASH_LOW_MEMORY == 0
|
||||
#define MAX_LEGACY_RESOURCES 2048
|
||||
#elif XASH_LOW_MEMORY == 2
|
||||
#define MAX_LEGACY_RESOURCES 1
|
||||
#elif XASH_LOW_MEMORY == 1
|
||||
#define MAX_LEGACY_RESOURCES 512
|
||||
#endif
|
||||
/*
|
||||
==============
|
||||
CL_ParseResourceList
|
||||
@ -2738,17 +2774,20 @@ void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
static struct
|
||||
{
|
||||
int rescount;
|
||||
int restype[MAX_RESOURCES];
|
||||
char resnames[MAX_RESOURCES][CS_SIZE];
|
||||
int restype[MAX_LEGACY_RESOURCES];
|
||||
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
|
||||
} reslist;
|
||||
memset( &reslist, 0, sizeof( reslist ));
|
||||
|
||||
reslist.rescount = MSG_ReadWord( msg ) - 1;
|
||||
|
||||
if( reslist.rescount > MAX_LEGACY_RESOURCES )
|
||||
Host_Error("MAX_RESOURCES reached\n");
|
||||
|
||||
for( i = 0; i < reslist.rescount; i++ )
|
||||
{
|
||||
reslist.restype[i] = MSG_ReadWord( msg );
|
||||
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), CS_SIZE );
|
||||
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), MAX_QPATH );
|
||||
}
|
||||
|
||||
if( CL_IsPlaybackDemo() )
|
||||
|
@ -486,6 +486,7 @@ void V_PostRender( void )
|
||||
Con_DrawVersion();
|
||||
Con_DrawDebug(); // must be last
|
||||
Touch_Draw();
|
||||
OSK_Draw();
|
||||
|
||||
S_ExtraUpdate();
|
||||
}
|
||||
|
@ -96,7 +96,11 @@ typedef struct
|
||||
#define ANGLE_MASK (ANGLE_BACKUP - 1)
|
||||
|
||||
#define CL_UPDATE_MASK (CL_UPDATE_BACKUP - 1)
|
||||
#if XASH_LOW_MEMORY == 2
|
||||
#define CL_UPDATE_BACKUP SINGLEPLAYER_BACKUP
|
||||
#else
|
||||
extern int CL_UPDATE_BACKUP;
|
||||
#endif
|
||||
|
||||
#define SIGNONS 2 // signon messages to receive before connected
|
||||
#define INVALID_HANDLE 0xFFFF // for XashXT cache system
|
||||
@ -1115,6 +1119,26 @@ void SCR_RunCinematic( void );
|
||||
void SCR_StopCinematic( void );
|
||||
void CL_PlayVideo_f( void );
|
||||
|
||||
|
||||
//
|
||||
// keys.c
|
||||
//
|
||||
int Key_IsDown( int keynum );
|
||||
const char *Key_IsBind( int keynum );
|
||||
void Key_Event( int key, int down );
|
||||
void Key_Init( void );
|
||||
void Key_WriteBindings( file_t *f );
|
||||
const char *Key_GetBinding( int keynum );
|
||||
void Key_SetBinding( int keynum, const char *binding );
|
||||
void Key_ClearStates( void );
|
||||
const char *Key_KeynumToString( int keynum );
|
||||
int Key_StringToKeynum( const char *str );
|
||||
int Key_GetKey( const char *binding );
|
||||
void Key_EnumCmds_f( void );
|
||||
void Key_SetKeyDest( int key_dest );
|
||||
void Key_EnableTextInput( qboolean enable, qboolean force );
|
||||
void OSK_Draw( void );
|
||||
|
||||
extern rgba_t g_color_table[8];
|
||||
|
||||
#endif//CLIENT_H
|
||||
|
@ -37,15 +37,19 @@ static qboolean g_utf8 = false;
|
||||
#define COLOR_DEFAULT '7'
|
||||
#define CON_HISTORY 64
|
||||
#define MAX_DBG_NOTIFY 128
|
||||
#if XASH_LOW_MEMORY
|
||||
#define CON_NUMFONTS 1 // do not load different font textures
|
||||
#define CON_TEXTSIZE 32768 // max scrollback buffer characters in console (32 kb)
|
||||
#define CON_MAXLINES 2048 // max scrollback buffer lines in console
|
||||
#else
|
||||
#define CON_NUMFONTS 3 // maxfonts
|
||||
|
||||
#define CON_TEXTSIZE 1048576 // max scrollback buffer characters in console (1 Mb)
|
||||
#define CON_MAXLINES 16384 // max scrollback buffer lines in console
|
||||
#endif
|
||||
#define CON_LINES( i ) (con.lines[(con.lines_first + (i)) % con.maxlines])
|
||||
#define CON_LINES_COUNT con.lines_count
|
||||
#define CON_LINES_LAST() CON_LINES( CON_LINES_COUNT - 1 )
|
||||
|
||||
#define CON_TEXTSIZE 1048576 // max scrollback buffer characters in console (1 Mb)
|
||||
#define CON_MAXLINES 16384 // max scrollback buffer lines in console
|
||||
|
||||
// console color typeing
|
||||
rgba_t g_color_table[8] =
|
||||
{
|
||||
@ -663,7 +667,7 @@ static void Con_LoadConchars( void )
|
||||
int i, fontSize;
|
||||
|
||||
// load all the console fonts
|
||||
for( i = 0; i < 3; i++ )
|
||||
for( i = 0; i < CON_NUMFONTS; i++ )
|
||||
Con_LoadConsoleFont( i, con.chars + i );
|
||||
|
||||
// select properly fontsize
|
||||
@ -673,6 +677,9 @@ static void Con_LoadConchars( void )
|
||||
fontSize = 2;
|
||||
else fontSize = 1;
|
||||
|
||||
if( fontSize > CON_NUMFONTS - 1 )
|
||||
fontSize = CON_NUMFONTS - 1;
|
||||
|
||||
// sets the current font
|
||||
con.lastUsedFont = con.curFont = &con.chars[fontSize];
|
||||
}
|
||||
@ -929,7 +936,7 @@ choose font size
|
||||
*/
|
||||
void Con_SetFont( int fontNum )
|
||||
{
|
||||
fontNum = bound( 0, fontNum, 2 );
|
||||
fontNum = bound( 0, fontNum, CON_NUMFONTS - 1 );
|
||||
con.curFont = &con.chars[fontNum];
|
||||
}
|
||||
|
||||
@ -1880,8 +1887,8 @@ void Con_DrawInput( int lines )
|
||||
return;
|
||||
|
||||
y = lines - ( con.curFont->charHeight * 2 );
|
||||
Con_DrawCharacter( 8, y, ']', g_color_table[7] );
|
||||
Field_DrawInputLine( 16, y, &con.input );
|
||||
Con_DrawCharacter( con.curFont->charWidths[' '], y, ']', g_color_table[7] );
|
||||
Field_DrawInputLine( con.curFont->charWidths[' ']*2, y, &con.input );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2079,6 +2086,8 @@ void Con_DrawSolidConsole( int lines )
|
||||
// draw the background
|
||||
ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); // to prevent grab color from screenfade
|
||||
if( refState.width * 3 / 4 < refState.height && lines >= refState.height )
|
||||
ref.dllFuncs.R_DrawStretchPic( 0, lines - refState.height, refState.width, refState.height - refState.width * 3 / 4, 0, 0, 1, 1, R_GetBuiltinTexture( REF_BLACK_TEXTURE) );
|
||||
ref.dllFuncs.R_DrawStretchPic( 0, lines - refState.width * 3 / 4, refState.width, refState.width * 3 / 4, 0, 0, 1, 1, con.background );
|
||||
|
||||
if( !con.curFont || !host.allow_console )
|
||||
@ -2132,7 +2141,7 @@ void Con_DrawSolidConsole( int lines )
|
||||
y -= Con_DrawConsoleLine( y, x );
|
||||
|
||||
// top of console buffer or console window
|
||||
if( x == 0 || y < con.curFont->charHeight )
|
||||
if( x == 0 || y < con.curFont->charHeight )
|
||||
break;
|
||||
x--;
|
||||
}
|
||||
@ -2356,10 +2365,11 @@ INTERNAL RESOURCE
|
||||
*/
|
||||
void Con_VidInit( void )
|
||||
{
|
||||
Con_CheckResize();
|
||||
|
||||
Con_LoadConchars();
|
||||
|
||||
Con_CheckResize();
|
||||
#if XASH_LOW_MEMORY
|
||||
con.background = R_GetBuiltinTexture( REF_BLACK_TEXTURE );
|
||||
#else
|
||||
// loading console image
|
||||
if( host.allow_console )
|
||||
{
|
||||
@ -2434,6 +2444,7 @@ void Con_VidInit( void )
|
||||
// missed console image will be replaced as gray background like X-Ray or Crysis
|
||||
if( con.background == R_GetBuiltinTexture( REF_DEFAULT_TEXTURE ) || con.background == 0 )
|
||||
con.background = R_GetBuiltinTexture( REF_GRAY_TEXTURE );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -140,6 +140,11 @@ keyname_t keynames[] =
|
||||
{NULL, 0, NULL },
|
||||
};
|
||||
|
||||
static void OSK_EnableTextInput( qboolean enable, qboolean force );
|
||||
static qboolean OSK_KeyEvent( int key, int down );
|
||||
static convar_t *osk_enable;
|
||||
static convar_t *key_rotate;
|
||||
|
||||
/*
|
||||
===================
|
||||
Key_IsDown
|
||||
@ -514,6 +519,10 @@ void Key_Init( void )
|
||||
|
||||
// setup default binding. "unbindall" from config.cfg will be reset it
|
||||
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
|
||||
|
||||
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE, "enable built-in on-screen keyboard" );
|
||||
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE, "rotate arrow keys (0-3)" );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -586,6 +595,48 @@ static qboolean Key_IsAllowedAutoRepeat( int key )
|
||||
}
|
||||
}
|
||||
|
||||
static int Key_Rotate( int key )
|
||||
{
|
||||
if( key_rotate->value == 1.0f ) // CW
|
||||
{
|
||||
if( key == K_UPARROW )
|
||||
key = K_LEFTARROW;
|
||||
else if( key == K_LEFTARROW )
|
||||
key = K_DOWNARROW;
|
||||
else if( key == K_RIGHTARROW )
|
||||
key = K_UPARROW;
|
||||
else if( key == K_DOWNARROW )
|
||||
key = K_RIGHTARROW;
|
||||
}
|
||||
|
||||
else if( key_rotate->value == 3.0f ) // CCW
|
||||
{
|
||||
if( key == K_UPARROW )
|
||||
key = K_RIGHTARROW;
|
||||
else if( key == K_LEFTARROW )
|
||||
key = K_UPARROW;
|
||||
else if( key == K_RIGHTARROW )
|
||||
key = K_DOWNARROW;
|
||||
else if( key == K_DOWNARROW )
|
||||
key = K_LEFTARROW;
|
||||
}
|
||||
|
||||
else if( key_rotate->value == 2.0f )
|
||||
{
|
||||
if( key == K_UPARROW )
|
||||
key = K_DOWNARROW;
|
||||
else if( key == K_LEFTARROW )
|
||||
key = K_RIGHTARROW;
|
||||
else if( key == K_RIGHTARROW )
|
||||
key = K_LEFTARROW;
|
||||
else if( key == K_DOWNARROW )
|
||||
key = K_UPARROW;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
Key_Event
|
||||
@ -597,6 +648,11 @@ void Key_Event( int key, int down )
|
||||
{
|
||||
const char *kb;
|
||||
|
||||
key = Key_Rotate( key );
|
||||
|
||||
if( OSK_KeyEvent( key, down ) )
|
||||
return;
|
||||
|
||||
// key was pressed before engine was run
|
||||
if( !keys[key].down && !down )
|
||||
return;
|
||||
@ -749,6 +805,11 @@ Key_EnableTextInput
|
||||
*/
|
||||
void Key_EnableTextInput( qboolean enable, qboolean force )
|
||||
{
|
||||
if( CVAR_TO_BOOL( osk_enable ) )
|
||||
{
|
||||
OSK_EnableTextInput( enable, force );
|
||||
return;
|
||||
}
|
||||
if( enable && ( !host.textmode || force ) )
|
||||
Platform_EnableTextInput( true );
|
||||
else if( !enable )
|
||||
@ -845,3 +906,286 @@ void CL_CharEvent( int key )
|
||||
UI_CharEvent( key );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* On-screen keyboard:
|
||||
*
|
||||
* 4 lines with 13 buttons each
|
||||
* Left trigger == backspace
|
||||
* Right trigger == space
|
||||
* Any button press is button press on keyboard
|
||||
*
|
||||
* Our layout:
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
* |` |1 |2 |3 |4 |5 |6 |7 |8 |9 |0 |- |= | 0
|
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
* |q |w |e |r |t |y |u |i |o |p |[ |] |\ | 1
|
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
* |CL|a |s |d |f |g |h |j |k |l |; |' |BS| 2
|
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
* |SH|z |x |c |v |b |n |m |, |. |/ |SP|EN| 3
|
||||
* +--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
*/
|
||||
|
||||
#define MAX_OSK_ROWS 13
|
||||
#define MAX_OSK_LINES 4
|
||||
|
||||
enum
|
||||
{
|
||||
OSK_DEFAULT = 0,
|
||||
OSK_UPPER, // on caps, shift
|
||||
/*
|
||||
OSK_RUSSIAN,
|
||||
OSK_RUSSIAN_UPPER,
|
||||
*/
|
||||
OSK_LAST
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
OSK_TAB = 16,
|
||||
OSK_SHIFT,
|
||||
OSK_BACKSPACE,
|
||||
OSK_ENTER,
|
||||
OSK_SPECKEY_LAST
|
||||
};
|
||||
static const char *osk_keylayout[][4] =
|
||||
{
|
||||
{
|
||||
"`1234567890-=", // 13
|
||||
"qwertyuiop[]\\", // 13
|
||||
"\x10" "asdfghjkl;'" "\x12", // 11 + caps on a left, enter on a right
|
||||
"\x11" "zxcvbnm,./ " "\x13" // 10 + esc on left + shift on a left/right
|
||||
},
|
||||
{
|
||||
"~!@#$%^&*()_+",
|
||||
"QWERTYUIOP{}|",
|
||||
"\x10" "ASDFGHJKL:\"" "\x12",
|
||||
"\x11" "ZXCVBNM<>? " "\x13"
|
||||
}
|
||||
};
|
||||
|
||||
struct osk_s
|
||||
{
|
||||
qboolean enable;
|
||||
int curlayout;
|
||||
qboolean shift;
|
||||
qboolean sending;
|
||||
struct {
|
||||
signed char x;
|
||||
signed char y;
|
||||
char val;
|
||||
} curbutton;
|
||||
} osk;
|
||||
|
||||
static qboolean OSK_KeyEvent( int key, int down )
|
||||
{
|
||||
if( !osk.enable || !CVAR_TO_BOOL( osk_enable ) )
|
||||
return false;
|
||||
|
||||
if( osk.sending )
|
||||
{
|
||||
osk.sending = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( osk.curbutton.val == 0 )
|
||||
{
|
||||
if( key == K_ENTER )
|
||||
{
|
||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
switch ( key )
|
||||
{
|
||||
case K_ENTER:
|
||||
switch( osk.curbutton.val )
|
||||
{
|
||||
case OSK_ENTER:
|
||||
osk.sending = true;
|
||||
Key_Event( K_ENTER, down );
|
||||
//osk_enable = false; // TODO: handle multiline
|
||||
break;
|
||||
case OSK_SHIFT:
|
||||
if( !down )
|
||||
break;
|
||||
|
||||
if( osk.curlayout & 1 )
|
||||
osk.curlayout--;
|
||||
else
|
||||
osk.curlayout++;
|
||||
|
||||
osk.shift = osk.curbutton.val == OSK_SHIFT;
|
||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||
break;
|
||||
case OSK_BACKSPACE:
|
||||
Key_Event( K_BACKSPACE, down ); break;
|
||||
case OSK_TAB:
|
||||
Key_Event( K_TAB, down ); break;
|
||||
default:
|
||||
{
|
||||
int ch;
|
||||
|
||||
if( !down )
|
||||
{
|
||||
if( osk.shift && osk.curlayout & 1 )
|
||||
osk.curlayout--;
|
||||
|
||||
osk.shift = false;
|
||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||
break;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( cl_charset->string, "utf-8" ) )
|
||||
ch = (unsigned char)osk.curbutton.val;
|
||||
else
|
||||
ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val );
|
||||
|
||||
if( !ch )
|
||||
break;
|
||||
|
||||
Con_CharEvent( ch );
|
||||
if( cls.key_dest == key_menu )
|
||||
UI_CharEvent ( ch );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case K_UPARROW:
|
||||
if( down && --osk.curbutton.y < 0 )
|
||||
{
|
||||
osk.curbutton.y = MAX_OSK_LINES - 1;
|
||||
osk.curbutton.val = 0;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case K_DOWNARROW:
|
||||
if( down && ++osk.curbutton.y >= MAX_OSK_LINES )
|
||||
{
|
||||
osk.curbutton.y = 0;
|
||||
osk.curbutton.val = 0;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case K_LEFTARROW:
|
||||
if( down && --osk.curbutton.x < 0 )
|
||||
osk.curbutton.x = MAX_OSK_ROWS - 1;
|
||||
break;
|
||||
case K_RIGHTARROW:
|
||||
if( down && ++osk.curbutton.x >= MAX_OSK_ROWS )
|
||||
osk.curbutton.x = 0;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_EnableTextInput
|
||||
|
||||
Enables built-in IME
|
||||
=============
|
||||
*/
|
||||
static void OSK_EnableTextInput( qboolean enable, qboolean force )
|
||||
{
|
||||
qboolean old = osk.enable;
|
||||
|
||||
osk.enable = enable;
|
||||
|
||||
if( osk.enable && (!old || force) )
|
||||
{
|
||||
osk.curlayout = 0;
|
||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#define X_START 0.1347475f
|
||||
#define Y_START 0.567f
|
||||
#define X_STEP 0.05625
|
||||
#define Y_STEP 0.0825
|
||||
|
||||
/*
|
||||
============
|
||||
Joy_DrawSymbolButton
|
||||
|
||||
Draw button with symbol on it
|
||||
============
|
||||
*/
|
||||
static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float height )
|
||||
{
|
||||
char str[] = {symb & 255, 0};
|
||||
byte color[] = { 255, 255, 255, 255 };
|
||||
int x1 = x * refState.width,
|
||||
y1 = y * refState.height,
|
||||
w = width * refState.width,
|
||||
h = height * refState.height;
|
||||
|
||||
if( symb == osk.curbutton.val )
|
||||
{
|
||||
ref.dllFuncs.FillRGBABlend( x1, y1, w, h, 255, 160, 0, 100 );
|
||||
}
|
||||
|
||||
if( !symb || symb == ' ' || (symb >= OSK_TAB && symb < OSK_SPECKEY_LAST ) )
|
||||
return;
|
||||
|
||||
Con_DrawCharacter( x1 + 1, y1, symb, color );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_DrawSpecialButton
|
||||
|
||||
Draw special button, like shift, enter or esc
|
||||
=============
|
||||
*/
|
||||
static void OSK_DrawSpecialButton( const char *name, float x, float y, float width, float height )
|
||||
{
|
||||
byte color[] = { 0, 255, 0, 255 };
|
||||
|
||||
Con_DrawString( x * refState.width, y * refState.height, name, color );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_DrawOnScreenKeyboard
|
||||
|
||||
Draw on screen keyboard, if enabled
|
||||
=============
|
||||
*/
|
||||
void OSK_Draw( void )
|
||||
{
|
||||
const char **curlayout = osk_keylayout[osk.curlayout]; // shortcut :)
|
||||
float x, y;
|
||||
int i, j;
|
||||
|
||||
if( !osk.enable || !CVAR_TO_BOOL(osk_enable) || !osk.curbutton.val )
|
||||
return;
|
||||
|
||||
// draw keyboard
|
||||
ref.dllFuncs.FillRGBABlend( X_START * refState.width, Y_START * refState.height,
|
||||
X_STEP * MAX_OSK_ROWS * refState.width,
|
||||
Y_STEP * MAX_OSK_LINES * refState.height, 100, 100, 100, 100 );
|
||||
|
||||
OSK_DrawSpecialButton( "-]", X_START, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
|
||||
OSK_DrawSpecialButton( "<-", X_START + X_STEP * 12, Y_START + Y_STEP * 2, X_STEP, Y_STEP );
|
||||
|
||||
OSK_DrawSpecialButton( "sh", X_START, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
|
||||
OSK_DrawSpecialButton( "en", X_START + X_STEP * 12, Y_START + Y_STEP * 3, X_STEP, Y_STEP );
|
||||
|
||||
for( y = Y_START, j = 0; j < MAX_OSK_LINES; j++, y += Y_STEP )
|
||||
for( x = X_START, i = 0; i < MAX_OSK_ROWS; i++, x += X_STEP )
|
||||
OSK_DrawSymbolButton( curlayout[j][i], x, y, X_STEP, Y_STEP );
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ static void SetWidthAndHeightFromCommandLine( void )
|
||||
return;
|
||||
}
|
||||
|
||||
R_SaveVideoMode( width, height );
|
||||
R_SaveVideoMode( width, height, width, height );
|
||||
}
|
||||
|
||||
static void SetFullscreenModeFromCommandLine( void )
|
||||
|
@ -31,6 +31,10 @@ glwstate_t glw_state;
|
||||
|
||||
convar_t *window_xpos;
|
||||
convar_t *window_ypos;
|
||||
|
||||
convar_t *vid_rotate;
|
||||
convar_t *vid_scale;
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_StartupGamma
|
||||
@ -62,19 +66,21 @@ void VID_InitDefaultResolution( void )
|
||||
R_SaveVideoMode
|
||||
=================
|
||||
*/
|
||||
void R_SaveVideoMode( int w, int h )
|
||||
void R_SaveVideoMode( int w, int h , int render_w, int render_h )
|
||||
{
|
||||
refState.width = w;
|
||||
refState.height = h;
|
||||
|
||||
host.window_center_x = w / 2;
|
||||
host.window_center_y = h / 2;
|
||||
|
||||
Cvar_SetValue( "width", w );
|
||||
Cvar_SetValue( "height", h );
|
||||
|
||||
refState.width = render_w;
|
||||
refState.height = render_h;
|
||||
|
||||
host.renderinfo_changed = false;
|
||||
|
||||
// check for 4:3 or 5:4
|
||||
if( w * 3 != h * 4 && w * 4 != h * 5 )
|
||||
if( render_w * 3 != render_h * 4 && render_w * 4 != render_h * 5 )
|
||||
refState.wideScreen = true;
|
||||
else refState.wideScreen = false;
|
||||
}
|
||||
@ -175,6 +181,8 @@ void VID_Init( void )
|
||||
vid_displayfrequency = Cvar_Get ( "vid_displayfrequency", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen refresh rate" );
|
||||
vid_fullscreen = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" );
|
||||
vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
|
||||
vid_rotate = Cvar_Get( "vid_rotate", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
|
||||
vid_scale = Cvar_Get( "vid_scale", "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
|
||||
|
||||
// a1ba: planned to be named vid_mode for compability
|
||||
// but supported mode list is filled by backends, so numbers are not portable any more
|
||||
|
@ -34,8 +34,11 @@ extern glwstate_t glw_state;
|
||||
extern convar_t *vid_fullscreen;
|
||||
extern convar_t *vid_displayfrequency;
|
||||
extern convar_t *vid_highdpi;
|
||||
extern convar_t *vid_rotate;
|
||||
extern convar_t *vid_scale;
|
||||
|
||||
extern convar_t *gl_wgl_msaa_samples;
|
||||
void R_SaveVideoMode( int w, int h );
|
||||
void R_SaveVideoMode( int w, int h, int render_w, int render_h );
|
||||
void VID_CheckChanges( void );
|
||||
const char *VID_GetModeString( int vid_mode );
|
||||
void VID_StartupGamma( void );
|
||||
|
@ -137,10 +137,18 @@ typedef enum
|
||||
|
||||
#define CIN_MAIN 0
|
||||
#define CIN_LOGO 1
|
||||
|
||||
#if XASH_LOW_MEMORY == 0
|
||||
#define MAX_DECALS 512 // touching TE_DECAL messages, etc
|
||||
#define MAX_STATIC_ENTITIES 3096 // static entities that moved on the client when level is spawn
|
||||
|
||||
#elif XASH_LOW_MEMORY == 2
|
||||
#define MAX_DECALS 256 // touching TE_DECAL messages, etc
|
||||
#define MAX_STATIC_ENTITIES 32 // static entities that moved on the client when level is spawn
|
||||
#elif XASH_LOW_MEMORY == 1
|
||||
#define MAX_DECALS 512 // touching TE_DECAL messages, etc
|
||||
#define MAX_STATIC_ENTITIES 128 // static entities that moved on the client when level is spawn
|
||||
#endif
|
||||
|
||||
// filesystem flags
|
||||
#define FS_STATIC_PATH ( 1U << 0 ) // FS_ClearSearchPath will be ignore this path
|
||||
#define FS_NOWRITE_PATH ( 1U << 1 ) // default behavior - last added gamedir set as writedir. This flag disables it
|
||||
@ -811,24 +819,6 @@ void HPAK_CheckIntegrity( const char *filename );
|
||||
void HPAK_CheckSize( const char *filename );
|
||||
void HPAK_FlushHostQueue( void );
|
||||
|
||||
//
|
||||
// keys.c
|
||||
//
|
||||
int Key_IsDown( int keynum );
|
||||
const char *Key_IsBind( int keynum );
|
||||
void Key_Event( int key, int down );
|
||||
void Key_Init( void );
|
||||
void Key_WriteBindings( file_t *f );
|
||||
const char *Key_GetBinding( int keynum );
|
||||
void Key_SetBinding( int keynum, const char *binding );
|
||||
void Key_ClearStates( void );
|
||||
const char *Key_KeynumToString( int keynum );
|
||||
int Key_StringToKeynum( const char *str );
|
||||
int Key_GetKey( const char *binding );
|
||||
void Key_EnumCmds_f( void );
|
||||
void Key_SetKeyDest( int key_dest );
|
||||
void Key_EnableTextInput( qboolean enable, qboolean force );
|
||||
|
||||
#include "avi/avi.h"
|
||||
|
||||
//
|
||||
|
@ -1588,7 +1588,7 @@ void FS_ParseGenericGameInfo( gameinfo_t *GameInfo, const char *buf, const qbool
|
||||
else if( !Q_stricmp( token, isGameInfo ? "max_edicts" : "edicts" ))
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token );
|
||||
GameInfo->max_edicts = bound( 600, Q_atoi( token ), MAX_EDICTS );
|
||||
GameInfo->max_edicts = bound( MIN_EDICTS, Q_atoi( token ), MAX_EDICTS );
|
||||
}
|
||||
// only for gameinfo
|
||||
else if( isGameInfo )
|
||||
|
@ -29,8 +29,12 @@ typedef enum
|
||||
// Max length of a multicast message
|
||||
#define MAX_MULTICAST 8192 // some mods spamming for rain effect
|
||||
|
||||
#define MAX_INIT_MSG 0x20000 // max length of possible message
|
||||
|
||||
#if !XASH_LOW_MEMORY
|
||||
#define MAX_INIT_MSG 0x20000 // max length of possible message
|
||||
#else
|
||||
#define MAX_INIT_MSG 0x8000
|
||||
#endif
|
||||
// net packets type
|
||||
#define NET_HEADER_OUTOFBANDPACKET -1
|
||||
#define NET_HEADER_SPLITPACKET -2
|
||||
|
@ -78,17 +78,38 @@ GNU General Public License for more details.
|
||||
#define PORT_SERVER 27015
|
||||
|
||||
#define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2)
|
||||
#define SINGLEPLAYER_BACKUP 16 // same for single player
|
||||
#define SINGLEPLAYER_BACKUP 16 // same for single player
|
||||
#define CMD_BACKUP 64 // allow a lot of command backups for very fast systems
|
||||
#define CMD_MASK (CMD_BACKUP - 1)
|
||||
#define NUM_PACKET_ENTITIES 256 // 170 Mb for multiplayer with 32 players
|
||||
#define MAX_CUSTOM_BASELINES 64
|
||||
|
||||
#define NET_LEGACY_EXT_SPLIT (1U<<1)
|
||||
#define NETSPLIT_BACKUP 8
|
||||
#define NETSPLIT_BACKUP_MASK (NETSPLIT_BACKUP - 1)
|
||||
#define NETSPLIT_HEADER_SIZE 18
|
||||
|
||||
#if XASH_LOW_MEMORY == 2
|
||||
#undef MULTIPLAYER_BACKUP
|
||||
#undef SINGLEPLAYER_BACKUP
|
||||
#undef NUM_PACKET_ENTITIES
|
||||
#undef MAX_CUSTOM_BASELINES
|
||||
#undef NET_MAX_FRAGMENT
|
||||
#define MULTIPLAYER_BACKUP 4 // breaks protocol in legacy mode, new protocol status unknown
|
||||
#define SINGLEPLAYER_BACKUP 4
|
||||
#define NUM_PACKET_ENTITIES 32
|
||||
#define MAX_CUSTOM_BASELINES 8
|
||||
#define NET_MAX_FRAGMENT 32768
|
||||
#elif XASH_LOW_MEMORY == 1
|
||||
#undef SINGLEPLAYER_BACKUP
|
||||
#undef NUM_PACKET_ENTITIES
|
||||
#undef MAX_CUSTOM_BASELINES
|
||||
#undef NET_MAX_FRAGMENT
|
||||
#define SINGLEPLAYER_BACKUP 4
|
||||
#define NUM_PACKET_ENTITIES 64
|
||||
#define MAX_CUSTOM_BASELINES 8
|
||||
#define NET_MAX_FRAGMENT 32768
|
||||
#endif
|
||||
|
||||
typedef struct netsplit_chain_packet_s
|
||||
{
|
||||
// bool vector
|
||||
|
@ -119,12 +119,15 @@ GNU General Public License for more details.
|
||||
|
||||
#define MAX_SOUND_BITS 11
|
||||
#define MAX_SOUNDS (1<<MAX_SOUND_BITS) // 11 bits == 2048 sounds
|
||||
#define MAX_SOUNDS_NONSENTENCE MAX_SOUNDS
|
||||
|
||||
#define MAX_ENTITY_BITS 13 // 13 bits = 8192 edicts
|
||||
#define MAX_EDICTS (1<<MAX_ENTITY_BITS)
|
||||
#define MAX_EDICTS_BYTES ((MAX_EDICTS + 7) / 8)
|
||||
#define LAST_EDICT (MAX_EDICTS - 1)
|
||||
|
||||
#define MIN_EDICTS 64
|
||||
|
||||
#define MAX_CUSTOM_BITS 10
|
||||
#define MAX_CUSTOM (1<<MAX_CUSTOM_BITS)// 10 bits == 1024 generic file
|
||||
#define MAX_USER_MESSAGES 197 // another 58 messages reserved for engine routines
|
||||
@ -179,6 +182,59 @@ GNU General Public License for more details.
|
||||
#define FRAGMENT_MAX_SIZE 64000 // maximal fragment size
|
||||
#define FRAGMENT_LOCAL_SIZE FRAGMENT_MAX_SIZE // local connection
|
||||
|
||||
#if XASH_LOW_MEMORY == 2
|
||||
#undef MAX_VISIBLE_PACKET
|
||||
#undef MAX_VISIBLE_PACKET_VIS_BYTES
|
||||
#undef MAX_EVENTS
|
||||
#undef MAX_SUPPORTED_MODELS
|
||||
#undef MAX_MODELS
|
||||
#undef MAX_SOUNDS
|
||||
#undef MAX_CUSTOM
|
||||
#undef MAX_DLIGHTS
|
||||
#undef MAX_ELIGHTS
|
||||
#undef MAX_RENDER_DECALS
|
||||
#undef MAX_RESOURCES
|
||||
// memory reduced protocol, not for use in multiplayer (but still compatible)
|
||||
#define MAX_VISIBLE_PACKET 128
|
||||
#define MAX_VISIBLE_PACKET_VIS_BYTES ((MAX_VISIBLE_PACKET + 7) / 8)
|
||||
|
||||
#define MAX_EVENTS 128
|
||||
|
||||
#define MAX_SUPPORTED_MODELS 512
|
||||
|
||||
#define MAX_MODELS 512
|
||||
|
||||
|
||||
#define MAX_SOUNDS 512
|
||||
#define MAX_CUSTOM 32
|
||||
|
||||
#define MAX_DLIGHTS 16 // dynamic lights (rendered per one frame)
|
||||
#define MAX_ELIGHTS 32 // entity only point lights
|
||||
#define MAX_RENDER_DECALS 64 // max rendering decals per a level
|
||||
#define MAX_RESOURCES 1024
|
||||
#elif XASH_LOW_MEMORY == 1
|
||||
#undef MAX_VISIBLE_PACKET
|
||||
#undef MAX_VISIBLE_PACKET_VIS_BYTES
|
||||
#undef MAX_EVENTS
|
||||
#undef MAX_SUPPORTED_MODELS
|
||||
#undef MAX_MODELS
|
||||
#undef MAX_CUSTOM
|
||||
#undef MAX_RENDER_DECALS
|
||||
#undef MAX_RESOURCES
|
||||
#define MAX_VISIBLE_PACKET 256
|
||||
#define MAX_VISIBLE_PACKET_VIS_BYTES ((MAX_VISIBLE_PACKET + 7) / 8)
|
||||
|
||||
#define MAX_EVENTS 128
|
||||
|
||||
#define MAX_SUPPORTED_MODELS 1024
|
||||
|
||||
#define MAX_MODELS 1024
|
||||
|
||||
#define MAX_CUSTOM 512
|
||||
#define MAX_RENDER_DECALS 128
|
||||
#define MAX_RESOURCES 1024
|
||||
#endif
|
||||
|
||||
// Quake1 Protocol
|
||||
#define PROTOCOL_VERSION_QUAKE 15
|
||||
|
||||
|
@ -18,6 +18,15 @@ GNU General Public License for more details.
|
||||
#define MEMHEADER_SENTINEL1 0xDEADF00D
|
||||
#define MEMHEADER_SENTINEL2 0xDF
|
||||
|
||||
#ifdef XASH_CUSTOM_SWAP
|
||||
#include "platform/swap/swap.h"
|
||||
#define Q_malloc SWAP_Malloc
|
||||
#define Q_free SWAP_Free
|
||||
#else
|
||||
#define Q_malloc malloc
|
||||
#define Q_free free
|
||||
#endif
|
||||
|
||||
typedef struct memheader_s
|
||||
{
|
||||
struct memheader_s *next; // next and previous memheaders in chain belonging to pool
|
||||
@ -58,7 +67,7 @@ void *_Mem_Alloc( byte *poolptr, size_t size, qboolean clear, const char *filena
|
||||
|
||||
// big allocations are not clumped
|
||||
pool->realsize += sizeof( memheader_t ) + size + sizeof( int );
|
||||
mem = (memheader_t *)malloc( sizeof( memheader_t ) + size + sizeof( int ));
|
||||
mem = (memheader_t *)Q_malloc( sizeof( memheader_t ) + size + sizeof( int ));
|
||||
if( mem == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline );
|
||||
|
||||
mem->filename = filename;
|
||||
@ -74,7 +83,8 @@ void *_Mem_Alloc( byte *poolptr, size_t size, qboolean clear, const char *filena
|
||||
mem->prev = NULL;
|
||||
pool->chain = mem;
|
||||
if( mem->next ) mem->next->prev = mem;
|
||||
if( clear ) memset((void *)((byte *)mem + sizeof( memheader_t )), 0, mem->size );
|
||||
if( clear )
|
||||
memset((void *)((byte *)mem + sizeof( memheader_t )), 0, mem->size );
|
||||
|
||||
return (void *)((byte *)mem + sizeof( memheader_t ));
|
||||
}
|
||||
@ -128,7 +138,7 @@ static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline
|
||||
pool->totalsize -= mem->size;
|
||||
|
||||
pool->realsize -= sizeof( memheader_t ) + mem->size + sizeof( int );
|
||||
free( mem );
|
||||
Q_free( mem );
|
||||
}
|
||||
|
||||
void _Mem_Free( void *data, const char *filename, int fileline )
|
||||
@ -166,7 +176,7 @@ byte *_Mem_AllocPool( const char *name, const char *filename, int fileline )
|
||||
{
|
||||
mempool_t *pool;
|
||||
|
||||
pool = (mempool_t *)malloc( sizeof( mempool_t ));
|
||||
pool = (mempool_t *)Q_malloc( sizeof( mempool_t ));
|
||||
if( pool == NULL ) Sys_Error( "Mem_AllocPool: out of memory (allocpool at %s:%i)\n", filename, fileline );
|
||||
memset( pool, 0, sizeof( mempool_t ));
|
||||
|
||||
@ -203,7 +213,7 @@ void _Mem_FreePool( byte **poolptr, const char *filename, int fileline )
|
||||
while( pool->chain ) Mem_FreeBlock( pool->chain, filename, fileline );
|
||||
// free the pool itself
|
||||
memset( pool, 0xBF, sizeof( mempool_t ));
|
||||
free( pool );
|
||||
Q_free( pool );
|
||||
*poolptr = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -327,14 +327,35 @@ qboolean VID_SetMode( void )
|
||||
|
||||
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen )
|
||||
{
|
||||
int render_w, render_h;
|
||||
uint rotate = vid_rotate->value;
|
||||
|
||||
Android_GetScreenRes(&width, &height);
|
||||
|
||||
render_w = width;
|
||||
render_h = height;
|
||||
|
||||
Con_Reportf( "R_ChangeDisplaySettings: forced resolution to %dx%d)\n", width, height);
|
||||
|
||||
R_SaveVideoMode( width, height );
|
||||
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale->value, vid_scale->value ) )
|
||||
{
|
||||
if( rotate & 1 )
|
||||
{
|
||||
int swap = render_w;
|
||||
|
||||
host.window_center_x = width / 2;
|
||||
host.window_center_y = height / 2;
|
||||
render_w = render_h;
|
||||
render_h = swap;
|
||||
}
|
||||
|
||||
render_h /= vid_scale->value;
|
||||
render_w /= vid_scale->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "failed to setup screen transform\n" );
|
||||
}
|
||||
|
||||
R_SaveVideoMode( width, height, render_w, render_h );
|
||||
|
||||
refState.wideScreen = true; // V_AdjustFov will check for widescreen
|
||||
|
||||
|
@ -37,6 +37,8 @@ struct evdev_s
|
||||
qboolean shift;
|
||||
} evdev;
|
||||
|
||||
static convar_t *evdev_keydebug;
|
||||
|
||||
static int KeycodeFromEvdev(int keycode, int value)
|
||||
{
|
||||
switch (keycode) {
|
||||
@ -119,6 +121,10 @@ static int KeycodeFromEvdev(int keycode, int value)
|
||||
case BTN_LEFT: return K_MOUSE1;
|
||||
case BTN_RIGHT: return K_MOUSE2;
|
||||
case BTN_MIDDLE: return K_MOUSE3;
|
||||
case KEY_POWER: return K_ESCAPE;
|
||||
case KEY_VOLUMEDOWN: return K_PGDN;
|
||||
case KEY_VOLUMEUP: return K_PGUP;
|
||||
case KEY_PLAYPAUSE: return K_ENTER;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -216,7 +222,7 @@ void Evdev_Autodetect_f( void )
|
||||
open:
|
||||
Q_strncpy( evdev.paths[evdev.devices], path, MAX_STRING );
|
||||
evdev.fds[evdev.devices++] = fd;
|
||||
Msg( "Opened device %s\n", path );
|
||||
Con_Printf( "Opened device %s\n", path );
|
||||
#if XASH_INPUT == INPUT_EVDEV
|
||||
if( Sys_CheckParm( "-grab" ) )
|
||||
ioctl( evdev.fds[i], EVIOCGRAB, (void*) 1 );
|
||||
@ -244,7 +250,7 @@ void Evdev_OpenDevice ( const char *path )
|
||||
|
||||
if ( evdev.devices >= MAX_EVDEV_DEVICES )
|
||||
{
|
||||
Msg( "Only %d devices supported!\n", MAX_EVDEV_DEVICES );
|
||||
Con_Printf( "Only %d devices supported!\n", MAX_EVDEV_DEVICES );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -256,7 +262,7 @@ void Evdev_OpenDevice ( const char *path )
|
||||
{
|
||||
if( !Q_strncmp( evdev.paths[i], path, MAX_STRING ) )
|
||||
{
|
||||
Msg( "device %s already open!\n", path );
|
||||
Con_Printf( "device %s already open!\n", path );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -267,7 +273,7 @@ void Evdev_OpenDevice ( const char *path )
|
||||
Con_Reportf( S_ERROR "Could not open input device %s: %s\n", path, strerror( errno ) );
|
||||
return;
|
||||
}
|
||||
Msg( "Input device #%d: %s opened sucessfully\n", evdev.devices, path );
|
||||
Con_Printf( "Input device #%d: %s opened sucessfully\n", evdev.devices, path );
|
||||
evdev.fds[evdev.devices] = ret;
|
||||
Q_strncpy( evdev.paths[evdev.devices++], path, MAX_STRING );
|
||||
|
||||
@ -280,7 +286,7 @@ void Evdev_OpenDevice ( const char *path )
|
||||
void Evdev_OpenDevice_f( void )
|
||||
{
|
||||
if( Cmd_Argc() < 2 )
|
||||
Msg( S_USAGE "evdev_opendevice <path>\n" );
|
||||
Con_Printf( S_USAGE "evdev_opendevice <path>\n" );
|
||||
|
||||
Evdev_OpenDevice( Cmd_Argv( 1 ) );
|
||||
}
|
||||
@ -308,13 +314,13 @@ void Evdev_CloseDevice_f ( void )
|
||||
|
||||
if( i >= evdev.devices )
|
||||
{
|
||||
Msg( "Device %s is not open\n", arg );
|
||||
Con_Printf( "Device %s is not open\n", arg );
|
||||
return;
|
||||
}
|
||||
|
||||
close( evdev.fds[i] );
|
||||
evdev.devices--;
|
||||
Msg( "Device %s closed successfully\n", evdev.paths[i] );
|
||||
Con_Printf( "Device %s closed successfully\n", evdev.paths[i] );
|
||||
|
||||
for( ; i < evdev.devices; i++ )
|
||||
{
|
||||
@ -360,7 +366,11 @@ void IN_EvdevFrame ( void )
|
||||
else if ( ( ev.type == EV_KEY ) && (cls.key_dest == key_game || XASH_INPUT == INPUT_EVDEV ) )
|
||||
{
|
||||
int key = KeycodeFromEvdev( ev.code, ev.value );
|
||||
Key_Event ( key , ev.value );
|
||||
|
||||
if( CVAR_TO_BOOL(evdev_keydebug) )
|
||||
Con_Printf( "key %d %d %d\n", ev.code, key, ev.value );
|
||||
|
||||
Key_Event( key , ev.value );
|
||||
|
||||
if( evdev.chars && ev.value )
|
||||
{
|
||||
@ -452,6 +462,7 @@ void Evdev_Shutdown( void )
|
||||
Cmd_RemoveCommand( "evdev_open" );
|
||||
Cmd_RemoveCommand( "evdev_close" );
|
||||
Cmd_RemoveCommand( "evdev_autodetect" );
|
||||
evdev_keydebug = Cvar_Get( "evdev_keydebug", "0", 0, "print key events to console" );
|
||||
|
||||
for( i = 0; i < evdev.devices; i++ )
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ void GL_SwapBuffers( void )
|
||||
{
|
||||
}
|
||||
|
||||
void FB_GetScreenRes(int *x, int *y)
|
||||
void FB_GetScreenRes( int *x, int *y )
|
||||
{
|
||||
*x = fb.vinfo.xres;
|
||||
*y = fb.vinfo.yres;
|
||||
@ -121,16 +121,34 @@ qboolean VID_SetMode( void )
|
||||
|
||||
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen )
|
||||
{
|
||||
int render_w, render_h;
|
||||
uint rotate = vid_rotate->value;
|
||||
|
||||
FB_GetScreenRes( &width, &height );
|
||||
|
||||
Con_Reportf( "R_ChangeDisplaySettings: forced resolution to %dx%d)\n", width, height);
|
||||
render_w = width;
|
||||
render_h = height;
|
||||
|
||||
R_SaveVideoMode( width, height );
|
||||
Con_Reportf( "R_ChangeDisplaySettings: forced resolution to %dx%d)\n", width, height );
|
||||
|
||||
host.window_center_x = width / 2;
|
||||
host.window_center_y = height / 2;
|
||||
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale->value, vid_scale->value ) )
|
||||
{
|
||||
if( rotate & 1 )
|
||||
{
|
||||
int swap = render_w;
|
||||
|
||||
refState.wideScreen = true; // V_AdjustFov will check for widescreen
|
||||
render_w = render_h;
|
||||
render_h = swap;
|
||||
}
|
||||
|
||||
render_h /= vid_scale->value;
|
||||
render_w /= vid_scale->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "failed to setup screen transform\n" );
|
||||
}
|
||||
R_SaveVideoMode( width, height, render_w, render_h );
|
||||
|
||||
return rserr_ok;
|
||||
}
|
||||
@ -204,6 +222,13 @@ void SW_UnlockBuffer( void )
|
||||
|
||||
qboolean SW_CreateBuffer( int width, int height, uint *stride, uint *bpp, uint *r, uint *g, uint *b )
|
||||
{
|
||||
if( width > fb.vinfo.xres_virtual || height > fb.vinfo.yres_virtual )
|
||||
{
|
||||
Con_Printf( S_ERROR "requested size %dx%d not fit to framebuffer size %dx%d\n",
|
||||
width, height, fb.vinfo.xres_virtual, fb.vinfo.yres_virtual );
|
||||
return false;
|
||||
}
|
||||
|
||||
*bpp = fb.vinfo.bits_per_pixel >> 3;
|
||||
*stride = fb.vinfo.xres_virtual;
|
||||
*r = FB_BF_TO_MASK(fb.vinfo.red);
|
||||
|
@ -423,14 +423,11 @@ static void SDLash_EventFilter( SDL_Event *event )
|
||||
VID_RestoreScreenResolution();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
{
|
||||
int w = VID_MIN_WIDTH, h = VID_MIN_HEIGHT;
|
||||
if( vid_fullscreen->value )
|
||||
break;
|
||||
|
||||
SDL_GL_GetDrawableSize( host.hWnd, &w, &h );
|
||||
R_SaveVideoMode( w, h );
|
||||
VID_SaveWindowSize( event->window.data1, event->window.data2 );
|
||||
SCR_VidInit(); // tell the client.dll what vid_mode has changed
|
||||
break;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ void GL_InitExtensions( void );
|
||||
qboolean GL_CreateContext( void );
|
||||
qboolean GL_UpdateContext( void );
|
||||
qboolean GL_DeleteContext( void );
|
||||
|
||||
void VID_SaveWindowSize( int width, int height );
|
||||
|
||||
#endif // XASH_SDL
|
||||
#endif // KEYWRAPPER_H
|
||||
|
@ -449,7 +449,38 @@ qboolean GL_UpdateContext( void )
|
||||
return true;
|
||||
}
|
||||
|
||||
qboolean VID_SetScreenResolution( int width, int height )
|
||||
void VID_SaveWindowSize( int width, int height )
|
||||
{
|
||||
int render_w = width, render_h = height;
|
||||
uint rotate = vid_rotate->value;
|
||||
|
||||
if( !glw_state.software )
|
||||
SDL_GL_GetDrawableSize( host.hWnd, &render_w, &render_h );
|
||||
else
|
||||
SDL_RenderSetLogicalSize( sw.renderer, width, height );
|
||||
|
||||
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale->value, vid_scale->value ) )
|
||||
{
|
||||
if( rotate & 1 )
|
||||
{
|
||||
int swap = render_w;
|
||||
|
||||
render_w = render_h;
|
||||
render_h = swap;
|
||||
}
|
||||
|
||||
render_h /= vid_scale->value;
|
||||
render_w /= vid_scale->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "failed to setup screen transform\n" );
|
||||
}
|
||||
|
||||
R_SaveVideoMode( width, height, render_w, render_h );
|
||||
}
|
||||
|
||||
static qboolean VID_SetScreenResolution( int width, int height )
|
||||
{
|
||||
SDL_DisplayMode want, got;
|
||||
Uint32 wndFlags = 0;
|
||||
@ -479,9 +510,8 @@ qboolean VID_SetScreenResolution( int width, int height )
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
|
||||
SDL_SetWindowSize( host.hWnd, got.w, got.h );
|
||||
|
||||
SDL_GL_GetDrawableSize( host.hWnd, &got.w, &got.h );
|
||||
VID_SaveWindowSize( got.w, got.h );
|
||||
|
||||
R_SaveVideoMode( got.w, got.h );
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -672,9 +702,9 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
|
||||
if( !GL_UpdateContext( ))
|
||||
return false;
|
||||
|
||||
SDL_GL_GetDrawableSize( host.hWnd, &width, &height );
|
||||
}
|
||||
R_SaveVideoMode( width, height );
|
||||
|
||||
VID_SaveWindowSize( width, height );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -906,11 +936,7 @@ rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen )
|
||||
#endif
|
||||
SDL_SetWindowBordered( host.hWnd, SDL_TRUE );
|
||||
SDL_SetWindowSize( host.hWnd, width, height );
|
||||
if( !glw_state.software )
|
||||
SDL_GL_GetDrawableSize( host.hWnd, &width, &height );
|
||||
else
|
||||
SDL_RenderSetLogicalSize(sw.renderer, width, height);
|
||||
R_SaveVideoMode( width, height );
|
||||
VID_SaveWindowSize( width, height );
|
||||
}
|
||||
|
||||
return rserr_ok;
|
||||
|
488
engine/platform/swap/kmalloc.c
Normal file
488
engine/platform/swap/kmalloc.c
Normal file
@ -0,0 +1,488 @@
|
||||
/* $NetBSD: malloc.c,v 1.8 1997/04/07 03:12:14 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";
|
||||
#else
|
||||
static char *rcsid = "$NetBSD: malloc.c,v 1.8 1997/04/07 03:12:14 christos Exp $";
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* malloc.c (Caltech) 2/21/82
|
||||
* Chris Kingsley, kingsley@cit-20.
|
||||
*
|
||||
* This is a very fast storage allocator. It allocates blocks of a small
|
||||
* number of different sizes, and keeps free lists of each size. Blocks that
|
||||
* don't exactly fit are passed up to the next larger size. In this
|
||||
* implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
|
||||
* This is designed for use in a virtual memory environment.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "platform/swap/swap.h"
|
||||
/* #define MSTATS 1 */
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#define NULL 0
|
||||
#else
|
||||
|
||||
#define u_char unsigned char
|
||||
#define u_long unsigned long
|
||||
#define getpagesize() 4096
|
||||
#define caddr_t size_t
|
||||
#define bcopy(a,b,c) memcpy(b,a,c)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void morecore(int);
|
||||
/*
|
||||
* The overhead on a block is at least 4 bytes. When free, this space
|
||||
* contains a pointer to the next free block, and the bottom two bits must
|
||||
* be zero. When in use, the first byte is set to MAGIC, and the second
|
||||
* byte is the size index. The remaining bytes are for alignment.
|
||||
* If range checking is enabled then a second word holds the size of the
|
||||
* requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
|
||||
* The order of elements is critical: ov_magic must overlay the low order
|
||||
* bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
|
||||
*/
|
||||
union overhead {
|
||||
union overhead *ov_next; /* when free */
|
||||
struct {
|
||||
u_char ovu_magic; /* magic number */
|
||||
u_char ovu_index; /* bucket # */
|
||||
#ifdef RCHECK
|
||||
u_short ovu_rmagic; /* range magic number */
|
||||
u_long ovu_size; /* actual block size */
|
||||
#endif
|
||||
} ovu;
|
||||
#define ov_magic ovu.ovu_magic
|
||||
#define ov_index ovu.ovu_index
|
||||
#define ov_rmagic ovu.ovu_rmagic
|
||||
#define ov_size ovu.ovu_size
|
||||
};
|
||||
|
||||
static int findbucket( union overhead *freep,
|
||||
int srchlen);
|
||||
#define MAGIC 0xef /* magic # on accounting info */
|
||||
#define RMAGIC 0x5555 /* magic # on range info */
|
||||
|
||||
#ifdef RCHECK
|
||||
#define RSLOP sizeof (u_short)
|
||||
#else
|
||||
#define RSLOP 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
|
||||
* smallest allocatable block is 8 bytes. The overhead information
|
||||
* precedes the data area returned to the user.
|
||||
*/
|
||||
#define NBUCKETS 30
|
||||
static union overhead *nextf[NBUCKETS];
|
||||
/* extern char *sbrk(); */
|
||||
|
||||
static int pagesz; /* page size */
|
||||
static int pagebucket; /* page size bucket */
|
||||
|
||||
#ifdef MSTATS
|
||||
/*
|
||||
* nmalloc[i] is the difference between the number of mallocs and frees
|
||||
* for a given block size.
|
||||
*/
|
||||
static unsigned int nmalloc[NBUCKETS];
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined(RCHECK)
|
||||
#define ASSERT(p) if (!(p)) botch(__STRING(p))
|
||||
#include /* <stdio.h> */
|
||||
static
|
||||
botch(s)
|
||||
char *s;
|
||||
{
|
||||
fprintf(stderr, "\r\nassertion botched: %s\r\n", s);
|
||||
(void) fflush(stderr); /* just in case user buffered it */
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
#define ASSERT(p)
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* */
|
||||
/* malloc */
|
||||
/* malloc */
|
||||
void * SWAP_Malloc( size_t nbytes )
|
||||
{
|
||||
register union overhead *op;
|
||||
register int bucket;
|
||||
register long n;
|
||||
register unsigned amt;
|
||||
|
||||
/*
|
||||
* First time malloc is called, setup page size and
|
||||
* align break pointer so all data will be page aligned.
|
||||
*/
|
||||
if (pagesz == 0) {
|
||||
pagesz = n = getpagesize();
|
||||
op = (union overhead *)SWAP_Sbrk( 0 );
|
||||
n = n - sizeof (*op) - ((long)op & (n - 1));
|
||||
if (n < 0)
|
||||
n += pagesz;
|
||||
if (n) {
|
||||
if (SWAP_Sbrk(n) == (char *)-1) {
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
bucket = 0;
|
||||
amt = 8;
|
||||
while (pagesz > amt) {
|
||||
amt <<= 1;
|
||||
bucket++;
|
||||
}
|
||||
pagebucket = bucket;
|
||||
}
|
||||
/*
|
||||
* Convert amount of memory requested into closest block size
|
||||
* stored in hash buckets which satisfies request.
|
||||
* Account for space used per block for accounting.
|
||||
*/
|
||||
if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
|
||||
#ifndef RCHECK
|
||||
amt = 8; /* size of first bucket */
|
||||
bucket = 0;
|
||||
#else
|
||||
amt = 16; /* size of first bucket */
|
||||
bucket = 1;
|
||||
#endif
|
||||
n = -((long)sizeof (*op) + RSLOP);
|
||||
} else {
|
||||
amt = pagesz;
|
||||
bucket = pagebucket;
|
||||
}
|
||||
while (nbytes > amt + n) {
|
||||
amt <<= 1;
|
||||
if (amt == 0) {
|
||||
return (NULL);
|
||||
}
|
||||
bucket++;
|
||||
}
|
||||
/*
|
||||
* If nothing in hash bucket right now,
|
||||
* request more memory from the system.
|
||||
*/
|
||||
if ((op = nextf[bucket]) == NULL) {
|
||||
morecore(bucket);
|
||||
if ((op = nextf[bucket]) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
/* remove from linked list */
|
||||
nextf[bucket] = op->ov_next;
|
||||
op->ov_magic = MAGIC;
|
||||
op->ov_index = bucket;
|
||||
#ifdef MSTATS
|
||||
nmalloc[bucket]++;
|
||||
#endif
|
||||
#ifdef RCHECK
|
||||
/*
|
||||
* Record allocated size of block and
|
||||
* bound space with magic numbers.
|
||||
*/
|
||||
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
|
||||
op->ov_rmagic = RMAGIC;
|
||||
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
|
||||
#endif
|
||||
return ((char *)(op + 1));
|
||||
}
|
||||
|
||||
void * SWAP_Calloc(size_t nelem, size_t elsize) {
|
||||
void * ptr = SWAP_Malloc (nelem * elsize);
|
||||
// Zero out the malloc'd block.
|
||||
memset (ptr, 0, nelem * elsize);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate more memory to the indicated bucket.
|
||||
*/
|
||||
static void
|
||||
morecore(int bucket)
|
||||
{
|
||||
register union overhead *op;
|
||||
register long sz; /* size of desired block */
|
||||
long amt; /* amount to allocate */
|
||||
int nblks; /* how many blocks we get */
|
||||
|
||||
/*
|
||||
* sbrk_size <= 0 only for big, FLUFFY, requests (about
|
||||
* 2^30 bytes on a VAX, I think) or for a negative arg.
|
||||
*/
|
||||
sz = 1 << (bucket + 3);
|
||||
#ifdef DEBUG
|
||||
ASSERT(sz > 0);
|
||||
#else
|
||||
if (sz <= 0)
|
||||
return;
|
||||
#endif
|
||||
if (sz < pagesz) {
|
||||
amt = pagesz;
|
||||
nblks = amt / sz;
|
||||
} else {
|
||||
amt = sz + pagesz;
|
||||
nblks = 1;
|
||||
}
|
||||
op = (union overhead *)SWAP_Sbrk(amt);
|
||||
/* no more room! */
|
||||
if ((long)op == -1)
|
||||
return;
|
||||
/*
|
||||
* Add new memory allocated to that on
|
||||
* free list for this hash bucket.
|
||||
*/
|
||||
nextf[bucket] = op;
|
||||
while (--nblks > 0) {
|
||||
op->ov_next = (union overhead *)((caddr_t)op + sz);
|
||||
op = (union overhead *)((caddr_t)op + sz);
|
||||
}
|
||||
}
|
||||
/* */
|
||||
/* free */
|
||||
/* free */
|
||||
void SWAP_Free( void *cp)
|
||||
|
||||
{
|
||||
register long size;
|
||||
register union overhead *op;
|
||||
|
||||
if (cp == NULL)
|
||||
return;
|
||||
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
|
||||
#ifdef DEBUG
|
||||
ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
|
||||
#else
|
||||
if (op->ov_magic != MAGIC)
|
||||
return; /* sanity */
|
||||
#endif
|
||||
#ifdef RCHECK
|
||||
ASSERT(op->ov_rmagic == RMAGIC);
|
||||
ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
|
||||
#endif
|
||||
size = op->ov_index;
|
||||
ASSERT(size < NBUCKETS);
|
||||
op->ov_next = nextf[size]; /* also clobbers ov_magic */
|
||||
nextf[size] = op;
|
||||
#ifdef MSTATS
|
||||
nmalloc[size]--;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* EDB: added size lookup */
|
||||
|
||||
size_t SWAP_MallocUsableSize(void * cp)
|
||||
{
|
||||
register long size;
|
||||
register union overhead *op;
|
||||
|
||||
if (cp == NULL)
|
||||
return 0;
|
||||
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
|
||||
#ifdef DEBUG
|
||||
ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
|
||||
#else
|
||||
if (op->ov_magic != MAGIC)
|
||||
return 0; /* sanity */
|
||||
#endif
|
||||
#ifdef RCHECK
|
||||
ASSERT(op->ov_rmagic == RMAGIC);
|
||||
ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
|
||||
#endif
|
||||
return op->ov_index;
|
||||
}
|
||||
/* End EDB */
|
||||
|
||||
|
||||
/*
|
||||
* When a program attempts "storage compaction" as mentioned in the
|
||||
* old malloc man page, it realloc's an already freed block. Usually
|
||||
* this is the last block it freed; occasionally it might be farther
|
||||
* back. We have to search all the free lists for the block in order
|
||||
* to determine its bucket: 1st we make one pass thru the lists
|
||||
* checking only the first block in each; if that fails we search
|
||||
* ``realloc_srchlen'' blocks in each list for a match (the variable
|
||||
* is extern so the caller can modify it). If that fails we just copy
|
||||
* however many bytes was given to realloc() and hope it's not huge.
|
||||
*/
|
||||
int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
|
||||
|
||||
/* */
|
||||
/* realloc */
|
||||
/* realloc */
|
||||
void *
|
||||
SWAP_Realloc( void *cp,
|
||||
size_t nbytes)
|
||||
|
||||
{
|
||||
register u_long onb;
|
||||
register long i;
|
||||
union overhead *op;
|
||||
char *res;
|
||||
int was_alloced = 0;
|
||||
|
||||
if (cp == NULL)
|
||||
return (SWAP_Malloc(nbytes));
|
||||
if (nbytes == 0) {
|
||||
SWAP_Free (cp);
|
||||
return NULL;
|
||||
}
|
||||
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
|
||||
if (op->ov_magic == MAGIC) {
|
||||
was_alloced++;
|
||||
i = op->ov_index;
|
||||
} else {
|
||||
/*
|
||||
* Already free, doing "compaction".
|
||||
*
|
||||
* Search for the old block of memory on the
|
||||
* free list. First, check the most common
|
||||
* case (last element free'd), then (this failing)
|
||||
* the last ``realloc_srchlen'' items free'd.
|
||||
* If all lookups fail, then assume the size of
|
||||
* the memory block being realloc'd is the
|
||||
* largest possible (so that all "nbytes" of new
|
||||
* memory are copied into). Note that this could cause
|
||||
* a memory fault if the old area was tiny, and the moon
|
||||
* is gibbous. However, that is very unlikely.
|
||||
*/
|
||||
if ((i = findbucket(op, 1)) < 0 &&
|
||||
(i = findbucket(op, realloc_srchlen)) < 0)
|
||||
i = NBUCKETS;
|
||||
}
|
||||
onb = 1 << (i + 3);
|
||||
if (onb < pagesz)
|
||||
onb -= sizeof (*op) + RSLOP;
|
||||
else
|
||||
onb += pagesz - sizeof (*op) - RSLOP;
|
||||
/* avoid the copy if same size block */
|
||||
if (was_alloced) {
|
||||
if (i) {
|
||||
i = 1 << (i + 2);
|
||||
if (i < pagesz)
|
||||
i -= sizeof (*op) + RSLOP;
|
||||
else
|
||||
i += pagesz - sizeof (*op) - RSLOP;
|
||||
}
|
||||
if (nbytes <= onb && nbytes > i) {
|
||||
#ifdef RCHECK
|
||||
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
|
||||
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
|
||||
#endif
|
||||
return(cp);
|
||||
} else
|
||||
SWAP_Free(cp);
|
||||
}
|
||||
if ((res = SWAP_Malloc(nbytes)) == NULL)
|
||||
return (NULL);
|
||||
if (cp != res) /* common optimization if "compacting" */
|
||||
bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search ``srchlen'' elements of each free list for a block whose
|
||||
* header starts at ``freep''. If srchlen is -1 search the whole list.
|
||||
* Return bucket number, or -1 if not found.
|
||||
*/
|
||||
static int
|
||||
findbucket( union overhead *freep,
|
||||
int srchlen)
|
||||
|
||||
{
|
||||
register union overhead *p;
|
||||
register int i, j;
|
||||
|
||||
for (i = 0; i < NBUCKETS; i++) {
|
||||
j = 0;
|
||||
for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
|
||||
if (p == freep)
|
||||
return (i);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifdef MSTATS
|
||||
/*
|
||||
* mstats - print out statistics about malloc
|
||||
*
|
||||
* Prints two lines of numbers, one showing the length of the free list
|
||||
* for each size category, the second showing the number of mallocs -
|
||||
* frees for each size category.
|
||||
*/
|
||||
/* */
|
||||
mstats(void)
|
||||
{
|
||||
register int i, j;
|
||||
register union overhead *p;
|
||||
int totfree = 0,
|
||||
totused = 0;
|
||||
|
||||
fprintf(stderr, "Memory allocation statistics\nfree:\t");
|
||||
for (i = 0; i < NBUCKETS; i++) {
|
||||
for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
|
||||
;
|
||||
fprintf(stderr, " %d", j);
|
||||
totfree += j * (1 << (i + 3));
|
||||
}
|
||||
fprintf(stderr, "\nused:\t");
|
||||
for (i = 0; i < NBUCKETS; i++) {
|
||||
fprintf(stderr, " %d", nmalloc[i]);
|
||||
totused += nmalloc[i] * (1 << (i + 3));
|
||||
}
|
||||
fprintf(stderr, "\n\tTotal in use: %d, total free: %d, total allocated: %d\n",
|
||||
totused, totfree, totused + totfree);
|
||||
}
|
||||
#endif
|
||||
|
108
engine/platform/swap/sbrk.c
Normal file
108
engine/platform/swap/sbrk.c
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
sbrk.c - swap memory allocation
|
||||
Copyright (C) 2019 mittorn
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include "platform/swap/swap.h"
|
||||
#include "string.h"
|
||||
|
||||
#ifndef XASH_DEFAULT_SWAP_PATH
|
||||
#define XASH_DEFAULT_SWAP_PATH "/tmp/xash3d-swap"
|
||||
#endif
|
||||
#define PAGE_SIZE 4096
|
||||
static struct sbrk_state_s
|
||||
{
|
||||
void *top;
|
||||
int fd;
|
||||
size_t size;
|
||||
size_t prealloc;
|
||||
pid_t pid;
|
||||
} s;
|
||||
|
||||
static void SWAP_Initialize(void)
|
||||
{
|
||||
char *path;
|
||||
char *prealloc = getenv("SWAP_SIZE");
|
||||
int fd;
|
||||
|
||||
if( s.top )
|
||||
return;
|
||||
|
||||
path = getenv("SWAP_PATH");
|
||||
if( !path )
|
||||
path = XASH_DEFAULT_SWAP_PATH;
|
||||
fd = open( path, O_CREAT|O_RDWR, 0600 );
|
||||
|
||||
if( prealloc ) s.prealloc = atoi(prealloc);
|
||||
else s.prealloc = 128*1024*1024;
|
||||
s.prealloc &= ~(PAGE_SIZE - 1);
|
||||
|
||||
s.fd = fd;
|
||||
ftruncate( fd, s.prealloc );
|
||||
s.top = mmap( 0, s.prealloc, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );
|
||||
|
||||
// space will be freed on exit
|
||||
//unlink(path);
|
||||
}
|
||||
|
||||
void *SWAP_Sbrk(size_t size)
|
||||
{
|
||||
char buf[64];
|
||||
SWAP_Initialize();
|
||||
|
||||
if( size == 0 )
|
||||
return s.top;
|
||||
else if( size > 0 )
|
||||
{
|
||||
void *res;
|
||||
|
||||
//write(1, buf, snprintf(buf, 32, "allocating %d\n", size) );
|
||||
res = s.top;
|
||||
s.size += size;
|
||||
s.top = res + size;
|
||||
if( s.size + size > s.prealloc )
|
||||
return (void*)-1;
|
||||
|
||||
memset( res, 0, size );
|
||||
return res;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
void *res = s.top;
|
||||
|
||||
if( -size > s.size )
|
||||
res = (void*)-1;
|
||||
else
|
||||
{
|
||||
s.top += size;
|
||||
s.size += size;
|
||||
//write(1, buf, snprintf(buf, 32, "freed %d\n", -size) );
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
21
engine/platform/swap/swap.h
Normal file
21
engine/platform/swap/swap.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
sbrk_swap.h - swap memory allocation
|
||||
Copyright (C) 2019 mittorn
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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.
|
||||
*/
|
||||
//#include <stdint.h>
|
||||
void *SWAP_Sbrk( size_t size );
|
||||
void *SWAP_Malloc( size_t size );
|
||||
void *SWAP_Calloc( size_t nelem, size_t size );
|
||||
void SWAP_Free( void *cp );
|
||||
void *SWAP_Realloc( void *cp, size_t size );
|
||||
size_t SWAP_MallocUsableSize( void * cp );
|
@ -88,6 +88,7 @@ typedef struct ref_globals_s
|
||||
// viewport width and height
|
||||
int width;
|
||||
int height;
|
||||
|
||||
qboolean fullScreen;
|
||||
qboolean wideScreen;
|
||||
|
||||
@ -211,6 +212,14 @@ enum
|
||||
REF_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008
|
||||
};
|
||||
|
||||
typedef enum ref_screen_rotation_e
|
||||
{
|
||||
REF_ROTATE_NONE = 0,
|
||||
REF_ROTATE_CW = 1,
|
||||
REF_ROTATE_UD = 2,
|
||||
REF_ROTATE_CCW = 3,
|
||||
} ref_screen_rotation_t;
|
||||
|
||||
typedef struct remap_info_s
|
||||
{
|
||||
unsigned short textures[MAX_SKINS];// alias textures
|
||||
@ -435,6 +444,7 @@ typedef struct ref_interface_s
|
||||
// const char *(*R_GetInitError)( void );
|
||||
void (*R_Shutdown)( void );
|
||||
const char *(*R_GetConfigName)( void ); // returns config name without extension
|
||||
qboolean (*R_SetDisplayTransform)( ref_screen_rotation_t rotate, int x, int y, float scale_x, float scale_y );
|
||||
|
||||
// only called for GL contexts
|
||||
void (*GL_SetupAttributes)( int safegl );
|
||||
|
@ -32,7 +32,11 @@ GNU General Public License for more details.
|
||||
//=============================================================================
|
||||
|
||||
#define SV_UPDATE_MASK (SV_UPDATE_BACKUP - 1)
|
||||
#if XASH_LOW_MEMORY == 2
|
||||
#define SV_UPDATE_BACKUP SINGLEPLAYER_BACKUP
|
||||
#else
|
||||
extern int SV_UPDATE_BACKUP;
|
||||
#endif
|
||||
|
||||
// hostflags
|
||||
#define SVF_SKIPLOCALHOST BIT( 0 )
|
||||
|
@ -2042,10 +2042,10 @@ int SV_BuildSoundMsg( sizebuf_t *msg, edict_t *ent, int chan, const char *sample
|
||||
{
|
||||
sound_idx = Q_atoi( sample + 1 );
|
||||
|
||||
if( sound_idx >= MAX_SOUNDS )
|
||||
if( sound_idx >= MAX_SOUNDS_NONSENTENCE )
|
||||
{
|
||||
SetBits( flags, SND_SENTENCE|SND_SEQUENCE );
|
||||
sound_idx -= MAX_SOUNDS;
|
||||
sound_idx -= MAX_SOUNDS_NONSENTENCE;
|
||||
}
|
||||
else SetBits( flags, SND_SENTENCE );
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ GNU General Public License for more details.
|
||||
#include "server.h"
|
||||
#include "net_encode.h"
|
||||
#include "library.h"
|
||||
|
||||
#if XASH_LOW_MEMORY != 2
|
||||
int SV_UPDATE_BACKUP = SINGLEPLAYER_BACKUP;
|
||||
|
||||
#endif
|
||||
server_t sv; // local server
|
||||
server_static_t svs; // persistant server info
|
||||
svgame_static_t svgame; // persistant game info
|
||||
@ -752,7 +752,9 @@ void SV_SetupClients( void )
|
||||
|
||||
// feedback for cvar
|
||||
Cvar_FullSet( "maxplayers", va( "%d", svs.maxclients ), FCVAR_LATCH );
|
||||
#if XASH_LOW_MEMORY != 2
|
||||
SV_UPDATE_BACKUP = ( svs.maxclients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
|
||||
#endif
|
||||
|
||||
svs.clients = Z_Realloc( svs.clients, sizeof( sv_client_t ) * svs.maxclients );
|
||||
svs.num_client_entities = svs.maxclients * SV_UPDATE_BACKUP * NUM_PACKET_ENTITIES;
|
||||
|
@ -14,6 +14,10 @@ def options(opt):
|
||||
help = 'enable console input from stdin (always enabled for dedicated) [default: %default]')
|
||||
grp.add_option('--fbdev', action = 'store_true', dest = 'FBDEV_SW', default = False,
|
||||
help = 'build fbdev-only software-only engine')
|
||||
grp.add_option('--disable-async-resolve', action = 'store_true', dest = 'NO_ASYNC_RESOLVE', default = False,
|
||||
help = 'disable asynchronous name resolution')
|
||||
grp.add_option('--enable-custom-swap', action = 'store_true', dest = 'CUSTOM_SWAP', default = False,
|
||||
help = 'enable custom swap allocator. For devices with no swap support')
|
||||
|
||||
opt.load('sdl2')
|
||||
|
||||
@ -28,7 +32,8 @@ def configure(conf):
|
||||
conf.check_cc(lib = i)
|
||||
elif conf.options.FBDEV_SW:
|
||||
conf.define('XASH_FBDEV', 1)
|
||||
conf.check_cc(lib = 'asound')
|
||||
conf.check_cc( lib = 'asound' )
|
||||
conf.check_cc( lib = 'rt' )
|
||||
else:
|
||||
conf.load('sdl2')
|
||||
if not conf.env.HAVE_SDL2:
|
||||
@ -38,8 +43,15 @@ def configure(conf):
|
||||
if conf.options.USE_SELECT == None:
|
||||
conf.options.USE_SELECT = conf.options.DEDICATED
|
||||
|
||||
conf.define_cond('SINGLE_BINARY', conf.env.SINGLE_BINARY)
|
||||
|
||||
if not conf.env.DEST_OS in ['win32', 'android'] and not conf.options.NO_ASYNC_RESOLVE:
|
||||
conf.check_cc( lib='pthread' )
|
||||
|
||||
if conf.options.CUSTOM_SWAP:
|
||||
conf.define('XASH_CUSTOM_SWAP',1)
|
||||
conf.env.CUSTOM_SWAP = True
|
||||
conf.define_cond('SINGLE_BINARY', conf.env.SINGLE_BINARY)
|
||||
conf.define_cond('XASH_NO_ASYNC_NS_RESOLVE', conf.options.NO_ASYNC_RESOLVE)
|
||||
conf.define_cond('XASH_USE_SELECT', conf.options.USE_SELECT or conf.options.DEDICATED)
|
||||
conf.define_cond('SUPPORT_BSP2_FORMAT', conf.options.SUPPORT_BSP2_FORMAT)
|
||||
conf.define_cond('XASH_64BIT', conf.env.DEST_SIZEOF_VOID_P != 4)
|
||||
@ -57,8 +69,9 @@ def build(bld):
|
||||
|
||||
# basic build: dedicated only, no dependencies
|
||||
if bld.env.DEST_OS != 'win32':
|
||||
libs += [ 'DL' , 'M' , 'RT', 'PTHREAD']
|
||||
libs += [ 'DL' , 'M' , 'RT', 'PTHREAD', 'ASOUND']
|
||||
source += bld.path.ant_glob(['platform/posix/*.c'])
|
||||
|
||||
else:
|
||||
libs += ['USER32', 'SHELL32', 'GDI32', 'ADVAPI32', 'DBGHELP', 'PSAPI', 'WS2_32' ]
|
||||
source += bld.path.ant_glob(['platform/win32/*.c'])
|
||||
@ -66,7 +79,8 @@ def build(bld):
|
||||
if bld.env.DEST_OS == 'linux':
|
||||
source += bld.path.ant_glob(['platform/linux/*.c'])
|
||||
|
||||
source += bld.path.ant_glob(['platform/stub/*.c'])
|
||||
if bld.env.CUSTOM_SWAP:
|
||||
source += bld.path.ant_glob(['platform/swap/*.c'])
|
||||
|
||||
if bld.env.HAVE_SDL2:
|
||||
libs.append('SDL2')
|
||||
@ -83,12 +97,6 @@ def build(bld):
|
||||
'client/vgui/*.c',
|
||||
'client/avi/*.c'])
|
||||
|
||||
if bld.env.DEST_OS == 'linux' and not bld.env.HAVE_SDL2:
|
||||
libs.append('RT')
|
||||
if not bld.env.DEDICATED:
|
||||
libs.append('ASOUND')
|
||||
|
||||
|
||||
# HACK: public headers must be put before common, so we don't get wrong mathlib included
|
||||
includes = ['common', 'server', 'client', 'client/vgui', '.', '../public', '../common', '../pm_shared' ]
|
||||
|
||||
|
@ -308,6 +308,30 @@ void R_ProcessEntData( qboolean allocate )
|
||||
gEngfuncs.drawFuncs->R_ProcessEntData( allocate );
|
||||
}
|
||||
|
||||
qboolean R_SetDisplayTransform( ref_screen_rotation_t rotate, int offset_x, int offset_y, float scale_x, float scale_y )
|
||||
{
|
||||
qboolean ret = true;
|
||||
if( rotate > 0 )
|
||||
{
|
||||
gEngfuncs.Con_Printf("rotation transform not supported\n");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if( offset_x || offset_y )
|
||||
{
|
||||
gEngfuncs.Con_Printf("offset transform not supported\n");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if( scale_x != 1.0f || scale_y != 1.0f )
|
||||
{
|
||||
gEngfuncs.Con_Printf("scale transform not supported\n");
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *R_GetConfigName( void )
|
||||
{
|
||||
return "opengl";
|
||||
@ -318,6 +342,7 @@ ref_interface_t gReffuncs =
|
||||
R_Init,
|
||||
R_Shutdown,
|
||||
R_GetConfigName,
|
||||
R_SetDisplayTransform,
|
||||
|
||||
GL_SetupAttributes,
|
||||
GL_InitExtensions,
|
||||
|
9
wscript
9
wscript
@ -76,6 +76,9 @@ def options(opt):
|
||||
grp.add_option('--enable-poly-opt', action = 'store_true', dest = 'POLLY', default = False,
|
||||
help = 'enable polyhedral optimization if possible [default: %default]')
|
||||
|
||||
grp.add_option('--low-memory-mode', action = 'store', dest = 'LOW_MEMORY', default = 0,
|
||||
help = 'enable low memory mode (only for devices have <128 ram)')
|
||||
|
||||
opt.load('subproject')
|
||||
|
||||
opt.add_subproject(subdirs())
|
||||
@ -108,7 +111,7 @@ def configure(conf):
|
||||
conf.env.MSVC_TARGETS = ['x86'] # explicitly request x86 target for MSVC
|
||||
if sys.platform == 'win32':
|
||||
conf.load('msvc msvc_pdb msdev msvs')
|
||||
conf.load('subproject xcompile compiler_c compiler_cxx gitversion clang_compilation_database strip_on_install waf_unit_test pthreads')
|
||||
conf.load('subproject xcompile compiler_c compiler_cxx gitversion clang_compilation_database strip_on_install waf_unit_test')
|
||||
|
||||
# Every static library must have fPIC
|
||||
if conf.env.DEST_OS != 'win32' and '-fPIC' in conf.env.CFLAGS_cshlib:
|
||||
@ -262,7 +265,6 @@ def configure(conf):
|
||||
conf.env.SINGLE_BINARY = conf.options.SINGLE_BINARY or conf.env.DEDICATED
|
||||
|
||||
if conf.env.DEST_OS != 'win32':
|
||||
conf.check_pthread_flag()
|
||||
conf.check_cc(lib='dl', mandatory=False)
|
||||
|
||||
if not conf.env.LIB_M: # HACK: already added in xcompile!
|
||||
@ -301,6 +303,9 @@ def configure(conf):
|
||||
|
||||
conf.define('XASH_BUILD_COMMIT', conf.env.GIT_VERSION if conf.env.GIT_VERSION else 'notset')
|
||||
|
||||
if conf.options.LOW_MEMORY:
|
||||
conf.define('XASH_LOW_MEMORY', int(conf.options.LOW_MEMORY))
|
||||
|
||||
for i in SUBDIRS:
|
||||
if not i.is_enabled(conf):
|
||||
continue
|
||||
|
Loading…
x
Reference in New Issue
Block a user