mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-06 04:05:11 +08:00
Compare commits
13 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
119926805f | ||
|
|
f749b5cb4b | ||
|
|
c29ad6b598 | ||
|
|
4c5dfb963e | ||
|
|
e11f9e05d4 | ||
|
|
5c8b5b3511 | ||
|
|
2ea7162287 | ||
|
|
e62ab51842 | ||
|
|
f1bc9b87b1 | ||
|
|
a9bddaac64 | ||
|
|
6cef6f6a75 | ||
|
|
25ea6ed500 | ||
|
|
3d5173f257 |
12
.github/workflows/c-cpp.yml
vendored
12
.github/workflows/c-cpp.yml
vendored
@@ -24,14 +24,9 @@ jobs:
|
||||
# - os: ubuntu-aarch64-20.04
|
||||
# targetos: linux
|
||||
# targetarch: aarch64
|
||||
|
||||
# - os: ubuntu-20.04
|
||||
# targetos: android
|
||||
# targetarch: 32
|
||||
# - os: ubuntu-20.04
|
||||
# targetos: android
|
||||
# targetarch: 64
|
||||
|
||||
- os: ubuntu-20.04
|
||||
targetos: android
|
||||
targetarch: multiarch
|
||||
# - os: ubuntu-20.04
|
||||
# targetos: motomagx
|
||||
# targetarch: armv6
|
||||
@@ -51,7 +46,6 @@ jobs:
|
||||
env:
|
||||
SDL_VERSION: 2.28.5
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
ANDROID_SDK_TOOLS_VER: 4333796
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -54,6 +54,11 @@ CMakeFiles
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
CMakeLists.txt*
|
||||
CMakeScripts
|
||||
Testing
|
||||
compile_commands.json
|
||||
_deps
|
||||
# makedepend
|
||||
Makefile.dep
|
||||
*.bak
|
||||
|
||||
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: 46d05f9ff5...da084b47f6
2
3rdparty/nanogl
vendored
2
3rdparty/nanogl
vendored
Submodule 3rdparty/nanogl updated: 76393a8fde...f48735b730
25
Documentation/extensions/native-object.md
Normal file
25
Documentation/extensions/native-object.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# GetNativeObject API
|
||||
|
||||
To be able to use platform-specific features or get optional engine interfaces, we've added a simple call to MobilityAPI on client DLL and PhysicsAPI for server DLL and extended MenuAPI for menu DLL.
|
||||
|
||||
It's defined like this:
|
||||
|
||||
```
|
||||
void *pfnGetNativeObject( const char *name );
|
||||
```
|
||||
|
||||
#### Cross-platform objects
|
||||
|
||||
Only these objects are guaranteed to be available on all targets.
|
||||
|
||||
| Object name | Interface |
|
||||
|-------------|-----------|
|
||||
| `VFileSystem009` | Provides C++ interface to filesystem, binary-compatible with Valve's VFileSystem009. |
|
||||
| `XashFileSystemXXX` | Provides C interface to filesystem. This interface is unstable and not recommended for generic use, outside of engine internals. For more info about current version look into `filesystem.h`. |
|
||||
|
||||
#### Android-specific objects
|
||||
|
||||
| Object name | Interface |
|
||||
|-------------|-----------|
|
||||
| `JNIEnv` | Allows interfacing with Java Native Interface. |
|
||||
| `ActivityClass` | Returns JNI object for engine Android activity class. |
|
||||
@@ -1220,6 +1220,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
|
||||
pfnParseFileSafe,
|
||||
NET_AdrToString,
|
||||
NET_CompareAdrSort,
|
||||
Sys_GetNativeObject,
|
||||
};
|
||||
|
||||
void UI_UnloadProgs( void )
|
||||
|
||||
@@ -2100,9 +2100,13 @@ void Con_RunConsole( void )
|
||||
// decide on the destination height of the console
|
||||
if( host.allow_console && cls.key_dest == key_console )
|
||||
{
|
||||
#if XASH_MOBILE_PLATFORM
|
||||
con.showlines = refState.height; // always full screen on mobile devices
|
||||
#else
|
||||
if( cls.state < ca_active || cl.first_frame )
|
||||
con.showlines = refState.height; // full screen
|
||||
else con.showlines = (refState.height >> 1); // half screen
|
||||
#endif
|
||||
}
|
||||
else con.showlines = 0; // none visible
|
||||
|
||||
|
||||
@@ -2029,10 +2029,18 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx
|
||||
{
|
||||
touch.move_finger = touch.resize_finger = touch.look_finger = -1;
|
||||
// Hack for keyboard, hope it help
|
||||
// a1ba: this is absolutely horrible
|
||||
if( cls.key_dest == key_console || cls.key_dest == key_message )
|
||||
{
|
||||
if ( type == event_down ) // don't pop it again on event_up
|
||||
static float x1 = 0.0f;
|
||||
x1 += dx;
|
||||
|
||||
if( type == event_up ) // don't show keyboard on every tap
|
||||
{
|
||||
Key_EnableTextInput( true, true );
|
||||
x1 = 0.0f;
|
||||
}
|
||||
|
||||
if( cls.key_dest == key_console )
|
||||
{
|
||||
static float y1 = 0;
|
||||
@@ -2054,6 +2062,13 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx
|
||||
// exit of console area
|
||||
if( type == event_down && x < 0.1f && y > 0.9f )
|
||||
Cbuf_AddText( "escape\n" );
|
||||
|
||||
// swipe from edge to exit console/chat
|
||||
if(( x > 0.8f && x1 < -0.1f ) || ( x < 0.2f && x1 > 0.1f ))
|
||||
{
|
||||
Cbuf_AddText( "escape\n" );
|
||||
x1 = 0.0f;
|
||||
}
|
||||
}
|
||||
UI_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) );
|
||||
//MsgDev( D_NOTE, "touch %d %d\n", TO_SCRN_X(x), TO_SCRN_Y(y) );
|
||||
|
||||
@@ -93,123 +93,241 @@ static mempool_t *Mem_FindPool( poolhandle_t poolptr )
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void Mem_PoolAdd( mempool_t *pool, size_t size )
|
||||
{
|
||||
pool->totalsize += size;
|
||||
pool->realsize += sizeof( memheader_t ) + size + sizeof( byte );
|
||||
}
|
||||
|
||||
static inline void Mem_PoolSubtract( mempool_t *pool, size_t size )
|
||||
{
|
||||
pool->totalsize -= size;
|
||||
pool->realsize -= sizeof( memheader_t ) + size + sizeof( byte );
|
||||
}
|
||||
|
||||
static inline void Mem_PoolLinkAlloc( mempool_t *pool, memheader_t *mem )
|
||||
{
|
||||
mem->next = pool->chain;
|
||||
if( mem->next ) mem->next->prev = mem;
|
||||
pool->chain = mem;
|
||||
mem->prev = NULL;
|
||||
mem->pool = pool;
|
||||
}
|
||||
|
||||
static inline void Mem_PoolUnlinkAlloc( mempool_t *pool, memheader_t *mem )
|
||||
{
|
||||
if( mem->next ) mem->next->prev = mem->prev;
|
||||
if( mem->prev ) mem->prev->next = mem->next;
|
||||
else pool->chain = mem->next;
|
||||
mem->pool = NULL;
|
||||
}
|
||||
|
||||
static inline void Mem_InitAlloc( memheader_t *mem, size_t size, const char *filename, int fileline )
|
||||
{
|
||||
mem->size = size;
|
||||
mem->filename = filename;
|
||||
mem->fileline = fileline;
|
||||
mem->sentinel1 = MEMHEADER_SENTINEL1;
|
||||
*((byte *)mem + sizeof( memheader_t ) + mem->size ) = MEMHEADER_SENTINEL2;
|
||||
}
|
||||
|
||||
static const char *Mem_CheckFilename( const char *filename )
|
||||
{
|
||||
static const char *dummy = "<corrupted>\0";
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
return dummy;
|
||||
|
||||
if( memchr( filename, '\0', MAX_OSPATH ) != NULL )
|
||||
return filename;
|
||||
|
||||
return dummy;
|
||||
}
|
||||
|
||||
static qboolean Mem_CheckAllocHeader( const char *func, const memheader_t *mem, const char *filename, int fileline )
|
||||
{
|
||||
const char *memfilename;
|
||||
|
||||
if( mem->sentinel1 != MEMHEADER_SENTINEL1 )
|
||||
{
|
||||
memfilename = Mem_CheckFilename( mem->filename );
|
||||
Sys_Error( "%s: trashed header sentinel 1 (alloc at %s:%i, check at %s:%i)\n", func, memfilename, mem->fileline, filename, fileline );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( *((byte *)mem + sizeof( memheader_t ) + mem->size ) != MEMHEADER_SENTINEL2 )
|
||||
{
|
||||
memfilename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args
|
||||
Sys_Error( "%s: trashed header sentinel 2 (alloc at %s:%i, check at %s:%i)\n", func, memfilename, mem->fileline, filename, fileline );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean Mem_CheckPool( const char *func, const mempool_t *pool, const char *filename, int fileline )
|
||||
{
|
||||
if( pool->sentinel1 != MEMHEADER_SENTINEL1 )
|
||||
{
|
||||
Sys_Error( "%s: trashed pool sentinel 1 (allocpool at %s:%i, freepool at %s:%i)\n", func, pool->filename, pool->fileline, filename, fileline );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( pool->sentinel2 != MEMHEADER_SENTINEL1 )
|
||||
{
|
||||
Sys_Error( "%s: trashed pool sentinel 2 (allocpool at %s:%i, freepool at %s:%i)\n", func, pool->filename, pool->fileline, filename, fileline );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
|
||||
{
|
||||
memheader_t *mem;
|
||||
mempool_t *pool;
|
||||
|
||||
if( size <= 0 ) return NULL;
|
||||
if( !poolptr ) Sys_Error( "Mem_Alloc: pool == NULL (alloc at %s:%i)\n", filename, fileline );
|
||||
if( size <= 0 )
|
||||
return NULL;
|
||||
|
||||
if( !poolptr )
|
||||
{
|
||||
Sys_Error( "%s: pool == NULL (alloc at %s:%i)\n", __func__, filename, fileline );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem = (memheader_t *)Q_malloc( sizeof( memheader_t ) + size + sizeof( byte ));
|
||||
if( mem == NULL )
|
||||
{
|
||||
Sys_Error( "%s: out of memory (alloc size %s at %s:%i)\n", __func__, Q_memprint( size ), filename, fileline );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Mem_InitAlloc( mem, size, filename, fileline );
|
||||
|
||||
pool = Mem_FindPool( poolptr );
|
||||
Mem_PoolAdd( pool, size );
|
||||
Mem_PoolLinkAlloc( pool, mem );
|
||||
|
||||
pool->totalsize += size;
|
||||
|
||||
// big allocations are not clumped
|
||||
pool->realsize += sizeof( memheader_t ) + size + sizeof( size_t );
|
||||
mem = (memheader_t *)Q_malloc( sizeof( memheader_t ) + size + sizeof( size_t ));
|
||||
if( mem == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline );
|
||||
|
||||
mem->filename = filename;
|
||||
mem->fileline = fileline;
|
||||
mem->size = size;
|
||||
mem->pool = pool;
|
||||
mem->sentinel1 = MEMHEADER_SENTINEL1;
|
||||
// we have to use only a single byte for this sentinel, because it may not be aligned
|
||||
// and some platforms can't use unaligned accesses
|
||||
*((byte *)mem + sizeof( memheader_t ) + mem->size ) = MEMHEADER_SENTINEL2;
|
||||
// append to head of list
|
||||
mem->next = pool->chain;
|
||||
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 );
|
||||
|
||||
return (void *)((byte *)mem + sizeof( memheader_t ));
|
||||
}
|
||||
|
||||
static const char *Mem_CheckFilename( const char *filename )
|
||||
{
|
||||
static const char *dummy = "<corrupted>\0";
|
||||
const char *out = filename;
|
||||
int i;
|
||||
|
||||
if( !COM_CheckString( out ))
|
||||
return dummy;
|
||||
|
||||
for( i = 0; i < MAX_OSPATH; i++, out++ )
|
||||
{
|
||||
if( *out == '\0' )
|
||||
return filename; // valid name
|
||||
}
|
||||
|
||||
return dummy;
|
||||
}
|
||||
|
||||
static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline )
|
||||
{
|
||||
mempool_t *pool;
|
||||
|
||||
if( mem->sentinel1 != MEMHEADER_SENTINEL1 )
|
||||
{
|
||||
mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args
|
||||
Sys_Error( "Mem_Free: trashed header sentinel 1 (alloc at %s:%i, free at %s:%i)\n", mem->filename, mem->fileline, filename, fileline );
|
||||
}
|
||||
|
||||
if( *((byte *)mem + sizeof( memheader_t ) + mem->size ) != MEMHEADER_SENTINEL2 )
|
||||
{
|
||||
mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args
|
||||
Sys_Error( "Mem_Free: trashed header sentinel 2 (alloc at %s:%i, free at %s:%i)\n", mem->filename, mem->fileline, filename, fileline );
|
||||
}
|
||||
if( !Mem_CheckAllocHeader( __func__, mem, filename, fileline ))
|
||||
return;
|
||||
|
||||
pool = mem->pool;
|
||||
|
||||
// unlink memheader from doubly linked list
|
||||
if(( mem->prev ? mem->prev->next != mem : pool->chain != mem ) || ( mem->next && mem->next->prev != mem ))
|
||||
Sys_Error( "Mem_Free: not allocated or double freed (free at %s:%i)\n", filename, fileline );
|
||||
{
|
||||
Sys_Error( "%s: not allocated or double freed (free at %s:%i)\n", __func__, filename, fileline );
|
||||
return;
|
||||
}
|
||||
|
||||
if( mem->prev ) mem->prev->next = mem->next;
|
||||
else pool->chain = mem->next;
|
||||
Mem_PoolSubtract( pool, mem->size );
|
||||
Mem_PoolUnlinkAlloc( pool, mem );
|
||||
|
||||
if( mem->next )
|
||||
mem->next->prev = mem->prev;
|
||||
|
||||
// memheader has been unlinked, do the actual free now
|
||||
pool->totalsize -= mem->size;
|
||||
|
||||
pool->realsize -= sizeof( memheader_t ) + mem->size + sizeof( size_t );
|
||||
Q_free( mem );
|
||||
}
|
||||
|
||||
void _Mem_Free( void *data, const char *filename, int fileline )
|
||||
{
|
||||
if( data == NULL ) Sys_Error( "Mem_Free: data == NULL (called at %s:%i)\n", filename, fileline );
|
||||
if( data == NULL )
|
||||
{
|
||||
Sys_Error( "Mem_Free: data == NULL (called at %s:%i)\n", filename, fileline );
|
||||
return;
|
||||
}
|
||||
|
||||
Mem_FreeBlock((memheader_t *)((byte *)data - sizeof( memheader_t )), filename, fileline );
|
||||
}
|
||||
|
||||
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
|
||||
void *_Mem_Realloc( poolhandle_t poolptr, void *data, size_t size, qboolean clear, const char *filename, int fileline )
|
||||
{
|
||||
memheader_t *memhdr = NULL;
|
||||
char *nb;
|
||||
memheader_t *mem;
|
||||
uintptr_t oldmem;
|
||||
mempool_t *pool;
|
||||
size_t oldsize;
|
||||
|
||||
if( size <= 0 ) return memptr; // no need to reallocate
|
||||
if( size <= 0 )
|
||||
return data; // no need to reallocate
|
||||
|
||||
if( memptr )
|
||||
if( !poolptr )
|
||||
{
|
||||
memhdr = (memheader_t *)((byte *)memptr - sizeof( memheader_t ));
|
||||
if( size == memhdr->size ) return memptr;
|
||||
Sys_Error( "Mem_Realloc: pool == NULL (alloc at %s:%i)\n", filename, fileline );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nb = _Mem_Alloc( poolptr, size, clear, filename, fileline );
|
||||
if( !data )
|
||||
return _Mem_Alloc( poolptr, size, clear, filename, fileline );
|
||||
|
||||
if( memptr ) // first allocate?
|
||||
mem = (memheader_t *)((byte *)data - sizeof( memheader_t ));
|
||||
|
||||
if( !Mem_CheckAllocHeader( "Mem_Realloc", mem, filename, fileline ))
|
||||
return NULL;
|
||||
|
||||
oldsize = mem->size;
|
||||
if( size == oldsize )
|
||||
return data;
|
||||
|
||||
#if XASH_CUSTOM_SWAP
|
||||
{
|
||||
size_t newsize = memhdr->size < size ? memhdr->size : size; // upper data can be trucnated!
|
||||
memcpy( nb, memptr, newsize );
|
||||
_Mem_Free( memptr, filename, fileline ); // free unused old block
|
||||
char *nb = _Mem_Alloc( poolptr, size, clear, filename, fileline );
|
||||
|
||||
size_t newsize = mem->size < size ? mem->size : size; // upper data can be trucnated!
|
||||
memcpy( nb, data, newsize );
|
||||
_Mem_Free( data, filename, fileline ); // free unused old block
|
||||
|
||||
return nb;
|
||||
}
|
||||
#else // XASH_CUSTOM_SWAP
|
||||
pool = Mem_FindPool( poolptr );
|
||||
|
||||
oldmem = (uintptr_t)mem;
|
||||
mem = realloc( mem, sizeof( memheader_t ) + size + sizeof( byte ));
|
||||
|
||||
if( mem == NULL )
|
||||
{
|
||||
Sys_Error( "Mem_Realloc: out of memory (alloc size %s at %s:%i)\n", Q_memprint( size ), filename, fileline );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)nb;
|
||||
// Con_Printf( S_NOTE "%s: mem %s oldmem, size before %zu now %zu (alloc at %s:%i)\n",
|
||||
// __func__, (uintptr_t)mem != oldmem ? "!=" : "==", oldsize, size, filename, fileline );
|
||||
|
||||
Mem_InitAlloc( mem, size, filename, fileline );
|
||||
|
||||
if( size > oldsize )
|
||||
{
|
||||
Mem_PoolAdd( pool, size - oldsize );
|
||||
|
||||
if( clear )
|
||||
memset((byte *)mem + sizeof( memheader_t ) + oldsize, 0, size - oldsize );
|
||||
}
|
||||
else Mem_PoolSubtract( pool, oldsize - size );
|
||||
|
||||
// if allocation was migrated from one pool to another
|
||||
// (this is possible with original Mem_Realloc func)
|
||||
if( unlikely( mem->pool != pool ))
|
||||
{
|
||||
Mem_PoolUnlinkAlloc( mem->pool, mem );
|
||||
Mem_PoolLinkAlloc( pool, mem );
|
||||
}
|
||||
else if( oldmem != (uintptr_t)mem ) // just relink pointers
|
||||
{
|
||||
if( mem->next ) mem->next->prev = mem;
|
||||
if( mem->prev ) mem->prev->next = mem;
|
||||
else pool->chain = mem;
|
||||
}
|
||||
|
||||
return (void *)((byte *)mem + sizeof( memheader_t ));
|
||||
#endif // XASH_CUSTOM_SWAP
|
||||
}
|
||||
|
||||
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline )
|
||||
@@ -254,8 +372,7 @@ void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline )
|
||||
// unlink pool from chain
|
||||
for( chainaddress = &poolchain; *chainaddress && *chainaddress != pool; chainaddress = &((*chainaddress)->next));
|
||||
if( *chainaddress != pool ) Sys_Error( "Mem_FreePool: pool already free (freepool at %s:%i)\n", filename, fileline );
|
||||
if( pool->sentinel1 != MEMHEADER_SENTINEL1 ) Sys_Error( "Mem_FreePool: trashed pool sentinel 1 (allocpool at %s:%i, freepool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline );
|
||||
if( pool->sentinel2 != MEMHEADER_SENTINEL1 ) Sys_Error( "Mem_FreePool: trashed pool sentinel 2 (allocpool at %s:%i, freepool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline );
|
||||
Mem_CheckPool( "Mem_FreePool", pool, filename, fileline );
|
||||
*chainaddress = pool->next;
|
||||
|
||||
// free memory owned by the pool
|
||||
@@ -272,8 +389,7 @@ void _Mem_EmptyPool( poolhandle_t poolptr, const char *filename, int fileline )
|
||||
mempool_t *pool = Mem_FindPool( poolptr );
|
||||
if( !poolptr ) Sys_Error( "Mem_EmptyPool: pool == NULL (emptypool at %s:%i)\n", filename, fileline );
|
||||
|
||||
if( pool->sentinel1 != MEMHEADER_SENTINEL1 ) Sys_Error( "Mem_EmptyPool: trashed pool sentinel 1 (allocpool at %s:%i, emptypool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline );
|
||||
if( pool->sentinel2 != MEMHEADER_SENTINEL1 ) Sys_Error( "Mem_EmptyPool: trashed pool sentinel 2 (allocpool at %s:%i, emptypool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline );
|
||||
Mem_CheckPool( "Mem_FreePool", pool, filename, fileline );
|
||||
|
||||
// free memory owned by the pool
|
||||
while( pool->chain ) Mem_FreeBlock( pool->chain, filename, fileline );
|
||||
@@ -288,14 +404,19 @@ static qboolean Mem_CheckAlloc( mempool_t *pool, void *data )
|
||||
// search only one pool
|
||||
target = (memheader_t *)((byte *)data - sizeof( memheader_t ));
|
||||
for( header = pool->chain; header; header = header->next )
|
||||
if( header == target ) return true;
|
||||
{
|
||||
if( header == target )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// search all pools
|
||||
for( pool = poolchain; pool; pool = pool->next )
|
||||
{
|
||||
if( Mem_CheckAlloc( pool, data ))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -308,49 +429,24 @@ Check pointer for memory
|
||||
qboolean Mem_IsAllocatedExt( poolhandle_t poolptr, void *data )
|
||||
{
|
||||
mempool_t *pool = NULL;
|
||||
if( poolptr ) pool = Mem_FindPool( poolptr );
|
||||
|
||||
if( poolptr )
|
||||
pool = Mem_FindPool( poolptr );
|
||||
|
||||
return Mem_CheckAlloc( pool, data );
|
||||
}
|
||||
|
||||
static void Mem_CheckHeaderSentinels( void *data, const char *filename, int fileline )
|
||||
{
|
||||
memheader_t *mem;
|
||||
|
||||
if( data == NULL )
|
||||
Sys_Error( "Mem_CheckSentinels: data == NULL (sentinel check at %s:%i)\n", filename, fileline );
|
||||
|
||||
mem = (memheader_t *)((byte *) data - sizeof(memheader_t));
|
||||
|
||||
if( mem->sentinel1 != MEMHEADER_SENTINEL1 )
|
||||
{
|
||||
mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args
|
||||
Sys_Error( "Mem_CheckSentinels: trashed header sentinel 1 (block allocated at %s:%i, sentinel check at %s:%i)\n", mem->filename, mem->fileline, filename, fileline );
|
||||
}
|
||||
|
||||
if( *((byte *)mem + sizeof(memheader_t) + mem->size) != MEMHEADER_SENTINEL2 )
|
||||
{
|
||||
mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args
|
||||
Sys_Error( "Mem_CheckSentinels: trashed header sentinel 2 (block allocated at %s:%i, sentinel check at %s:%i)\n", mem->filename, mem->fileline, filename, fileline );
|
||||
}
|
||||
}
|
||||
|
||||
void _Mem_Check( const char *filename, int fileline )
|
||||
{
|
||||
memheader_t *mem;
|
||||
mempool_t *pool;
|
||||
|
||||
for( pool = poolchain; pool; pool = pool->next )
|
||||
{
|
||||
if( pool->sentinel1 != MEMHEADER_SENTINEL1 )
|
||||
Sys_Error( "Mem_CheckSentinelsGlobal: trashed pool sentinel 1 (allocpool at %s:%i, sentinel check at %s:%i)\n", pool->filename, pool->fileline, filename, fileline );
|
||||
if( pool->sentinel2 != MEMHEADER_SENTINEL1 )
|
||||
Sys_Error( "Mem_CheckSentinelsGlobal: trashed pool sentinel 2 (allocpool at %s:%i, sentinel check at %s:%i)\n", pool->filename, pool->fileline, filename, fileline );
|
||||
}
|
||||
Mem_CheckPool( "Mem_CheckSentinels", pool, filename, fileline );
|
||||
|
||||
for( pool = poolchain; pool; pool = pool->next )
|
||||
for( mem = pool->chain; mem; mem = mem->next )
|
||||
Mem_CheckHeaderSentinels((void *)((byte *) mem + sizeof(memheader_t)), filename, fileline );
|
||||
Mem_CheckAllocHeader( "Mem_CheckSentinels", mem, filename, fileline );
|
||||
}
|
||||
|
||||
void Mem_PrintStats( void )
|
||||
@@ -377,28 +473,31 @@ void Mem_PrintList( size_t minallocationsize )
|
||||
|
||||
Mem_Check();
|
||||
|
||||
Con_Printf( "memory pool list:\n"" ^3size name\n");
|
||||
Con_Printf( "memory pool list:\n" );
|
||||
Con_Printf( "\t^3size\t\t\t\tname\n");
|
||||
for( pool = poolchain; pool; pool = pool->next )
|
||||
{
|
||||
long changed_size = (long)pool->totalsize - (long)pool->lastchecksize;
|
||||
|
||||
// poolnames can contain color symbols, make sure what color is reset
|
||||
if( changed_size != 0 )
|
||||
if( pool->lastchecksize != 0 && changed_size != 0 )
|
||||
{
|
||||
char sign = (changed_size < 0) ? '-' : '+';
|
||||
|
||||
Con_Printf( "%10s (%10s actual) %s (^7%c%s change)\n", Q_memprint( pool->totalsize ), Q_memprint( pool->realsize ),
|
||||
pool->name, sign, Q_memprint( abs( changed_size )));
|
||||
Con_Printf( "%10s (%10s real)\t%s (^7%c%s change)\n", Q_memprint( pool->totalsize ), Q_memprint( pool->realsize ),
|
||||
pool->name, sign, Q_memprint( abs( changed_size )));
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( "%5s (%5s actual) %s\n", Q_memprint( pool->totalsize ), Q_memprint( pool->realsize ), pool->name );
|
||||
Con_Printf( "%10s (%10s real)\t%s\n", Q_memprint( pool->totalsize ), Q_memprint( pool->realsize ), pool->name );
|
||||
}
|
||||
|
||||
pool->lastchecksize = pool->totalsize;
|
||||
for( mem = pool->chain; mem; mem = mem->next )
|
||||
{
|
||||
if( mem->size >= minallocationsize )
|
||||
Con_Printf( "%10s allocated at %s:%i\n", Q_memprint( mem->size ), mem->filename, mem->fileline );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +215,7 @@ typedef struct ui_extendedfuncs_s {
|
||||
// network address funcs
|
||||
const char *(*pfnAdrToString)( const struct netadr_s a );
|
||||
int (*pfnCompareAdr)( const void *a, const void *b ); // netadr_t
|
||||
void *(*pfnGetNativeObject)( const char *name );
|
||||
} ui_extendedfuncs_t;
|
||||
|
||||
// deprecated export from old engine
|
||||
|
||||
@@ -107,7 +107,10 @@ typedef struct server_physics_api_s
|
||||
int (*pfnSaveFile)( const char *filename, const void *data, int len );
|
||||
const byte *(*pfnLoadImagePixels)( const char *filename, int *width, int *height );
|
||||
|
||||
const char* (*pfnGetModelName)( int modelindex );
|
||||
const char *(*pfnGetModelName)( int modelindex );
|
||||
|
||||
// FWGS extension
|
||||
void *(*pfnGetNativeObject)( const char *object );
|
||||
} server_physics_api_t;
|
||||
|
||||
// physic callbacks
|
||||
|
||||
@@ -61,23 +61,16 @@ Android_GetNativeObject
|
||||
|
||||
void *Android_GetNativeObject( const char *name )
|
||||
{
|
||||
static const char *availObjects[] = { "JNIEnv", "ActivityClass", NULL };
|
||||
void *object = NULL;
|
||||
|
||||
if( !name )
|
||||
if( !strcasecmp( name, "JNIEnv" ) )
|
||||
{
|
||||
object = (void *)availObjects;
|
||||
}
|
||||
else if( !strcasecmp( name, "JNIEnv" ) )
|
||||
{
|
||||
object = (void *)jni.env;
|
||||
return (void *)jni.env;
|
||||
}
|
||||
else if( !strcasecmp( name, "ActivityClass" ) )
|
||||
{
|
||||
object = (void *)jni.actcls;
|
||||
return (void *)jni.actcls;
|
||||
}
|
||||
|
||||
return object;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -654,7 +654,9 @@ static void SDLash_EventFilter( SDL_Event *event )
|
||||
SDLash_ActiveEvent( false );
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
if( vid_fullscreen.value == WINDOW_MODE_WINDOWED )
|
||||
#endif
|
||||
{
|
||||
SDL_Window *wnd = SDL_GetWindowFromID( event->window.windowID );
|
||||
VID_SaveWindowSize( event->window.data1, event->window.data2,
|
||||
|
||||
@@ -744,7 +744,6 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
|
||||
if( !glw_state.software )
|
||||
SetBits( wndFlags, SDL_WINDOW_OPENGL );
|
||||
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
if( window_mode == WINDOW_MODE_WINDOWED )
|
||||
{
|
||||
SDL_Rect r;
|
||||
@@ -787,10 +786,6 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
|
||||
SetBits( wndFlags, SDL_WINDOW_BORDERLESS );
|
||||
xpos = ypos = 0;
|
||||
}
|
||||
#else
|
||||
SetBits( wndFlags, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_INPUT_GRABBED );
|
||||
xpos = ypos = SDL_WINDOWPOS_UNDEFINED;
|
||||
#endif
|
||||
|
||||
if( !VID_CreateWindowWithSafeGL( wndname, xpos, ypos, width, height, wndFlags ))
|
||||
return false;
|
||||
@@ -799,14 +794,12 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
|
||||
if( FBitSet( SDL_GetWindowFlags( host.hWnd ), SDL_WINDOW_MAXIMIZED|SDL_WINDOW_FULLSCREEN_DESKTOP ) != 0 )
|
||||
SDL_GetWindowSize( host.hWnd, &width, &height );
|
||||
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
if( window_mode != WINDOW_MODE_WINDOWED )
|
||||
{
|
||||
if( !VID_SetScreenResolution( width, height, window_mode ))
|
||||
return false;
|
||||
}
|
||||
else VID_RestoreScreenResolution();
|
||||
#endif
|
||||
|
||||
VID_SetWindowIcon( host.hWnd );
|
||||
SDL_ShowWindow( host.hWnd );
|
||||
@@ -1175,6 +1168,14 @@ qboolean VID_SetMode( void )
|
||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
}
|
||||
|
||||
#if XASH_MOBILE_PLATFORM
|
||||
if( Q_strcmp( vid_fullscreen.string, DEFAULT_FULLSCREEN ))
|
||||
{
|
||||
Cvar_DirectSet( &vid_fullscreen, DEFAULT_FULLSCREEN );
|
||||
Con_Reportf( S_ERROR "VID_SetMode: windowed unavailable on this platform\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( !FBitSet( vid_fullscreen.flags, FCVAR_CHANGED ))
|
||||
Cvar_DirectSet( &vid_fullscreen, DEFAULT_FULLSCREEN );
|
||||
else
|
||||
|
||||
@@ -356,13 +356,13 @@ static void ListMissingModules( dll_user_t *hInst )
|
||||
byte *data;
|
||||
char buf[MAX_VA_STRING];
|
||||
|
||||
if ( !hInst ) return;
|
||||
|
||||
data = FS_LoadFile( hInst->dllName, NULL, false );
|
||||
if ( !data ) return;
|
||||
if( !hInst || !g_fsapi.LoadFile ) return;
|
||||
|
||||
data = g_fsapi.LoadFile( hInst->dllName, NULL, false );
|
||||
if( !data ) return;
|
||||
|
||||
importDesc = GetImportDescriptor( hInst->dllName, data, &peHeader );
|
||||
if ( !importDesc )
|
||||
if( !importDesc )
|
||||
{
|
||||
Mem_Free( data );
|
||||
return;
|
||||
|
||||
@@ -2122,6 +2122,7 @@ static server_physics_api_t gPhysicsAPI =
|
||||
COM_SaveFile,
|
||||
pfnLoadImagePixels,
|
||||
pfnGetModelName,
|
||||
Sys_GetNativeObject
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -237,7 +237,8 @@ def build(bld):
|
||||
app_name = 'xash3d-fwgs'
|
||||
)
|
||||
else:
|
||||
if bld.env.DISABLE_LAUNCHER:
|
||||
# always build as shared library on Android
|
||||
if bld.env.DISABLE_LAUNCHER and bld.env.DEST_OS != "android":
|
||||
install_path = bld.env.BINDIR
|
||||
program = 'cxxprogram' if is_cxx_link else 'cprogram'
|
||||
if bld.env.STATIC:
|
||||
|
||||
@@ -7,16 +7,16 @@ export PATH=$PATH:$JAVA_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$AN
|
||||
|
||||
pushd android
|
||||
|
||||
./gradlew assembleContinuous
|
||||
./gradlew assembleDebug
|
||||
|
||||
pushd app/build/outputs/apk/continuous
|
||||
pushd app/build/outputs/apk/debug
|
||||
|
||||
$ANDROID_HOME/build-tools/34.0.0/apksigner sign --ks $GITHUB_WORKSPACE/android/debug.keystore --ks-key-alias androiddebugkey \
|
||||
--ks-pass pass:android --key-pass pass:android --out app-continuous-signed.apk app-continuous-unsigned.apk
|
||||
--ks-pass pass:android --key-pass pass:android --out app-debug-signed.apk app-debug.apk
|
||||
|
||||
popd
|
||||
popd
|
||||
|
||||
mkdir -p artifacts/
|
||||
|
||||
mv android/app/build/outputs/apk/continuous/app-continuous-signed.apk artifacts/xash3d-fwgs-android.apk
|
||||
mv android/app/build/outputs/apk/debug/app-debug-signed.apk artifacts/xash3d-fwgs-android.apk
|
||||
|
||||
@@ -116,6 +116,22 @@ POLLY_CFLAGS = {
|
||||
# msvc sosat :(
|
||||
}
|
||||
|
||||
PROFILE_GENERATE_CFLAGS = {
|
||||
'gcc': ['-fprofile-generate=xash3d-prof'],
|
||||
}
|
||||
|
||||
PROFILE_GENERATE_LINKFLAGS = {
|
||||
'gcc': ['-fprofile-generate=xash3d-prof'],
|
||||
}
|
||||
|
||||
PROFILE_USE_CFLAGS = {
|
||||
'gcc': ['-fprofile-use=%s'],
|
||||
}
|
||||
|
||||
PROFILE_USE_LINKFLAGS = {
|
||||
'gcc': ['-fprofile-use=%s'],
|
||||
}
|
||||
|
||||
def options(opt):
|
||||
grp = opt.add_option_group('Compiler optimization options')
|
||||
|
||||
@@ -128,6 +144,12 @@ 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('--enable-profile', action = 'store_true', dest = 'PROFILE_GENERATE', default = False,
|
||||
help = 'enable profile generating build (stored in xash3d-prof directory) [default: %default]')
|
||||
|
||||
grp.add_option('--use-profile', action = 'store', dest = 'PROFILE_USE', default = None,
|
||||
help = 'use profile during build [default: %default]')
|
||||
|
||||
def configure(conf):
|
||||
conf.start_msg('Build type')
|
||||
|
||||
@@ -144,6 +166,8 @@ def configure(conf):
|
||||
|
||||
conf.msg('LTO build', 'yes' if conf.options.LTO else 'no')
|
||||
conf.msg('PolyOpt build', 'yes' if conf.options.POLLY else 'no')
|
||||
conf.msg('Generate profile', 'yes' if conf.options.PROFILE_GENERATE else 'no')
|
||||
conf.msg('Use profile', conf.options.PROFILE_USE if not conf.options.PROFILE_GENERATE else 'no')
|
||||
|
||||
# -march=native should not be used
|
||||
if conf.options.BUILD_TYPE.startswith('fast'):
|
||||
@@ -174,6 +198,13 @@ def get_optimization_flags(conf):
|
||||
if conf.options.POLLY:
|
||||
cflags += conf.get_flags_by_compiler(POLLY_CFLAGS, conf.env.COMPILER_CC)
|
||||
|
||||
if conf.options.PROFILE_GENERATE:
|
||||
linkflags+= conf.get_flags_by_compiler(PROFILE_GENERATE_LINKFLAGS, conf.env.COMPILER_CC)
|
||||
cflags += conf.get_flags_by_compiler(PROFILE_GENERATE_CFLAGS, conf.env.COMPILER_CC)
|
||||
elif conf.options.PROFILE_USE:
|
||||
linkflags+= [conf.get_flags_by_compiler(PROFILE_USE_LINKFLAGS, conf.env.COMPILER_CC)[0] % conf.options.PROFILE_USE]
|
||||
cflags += [conf.get_flags_by_compiler(PROFILE_USE_CFLAGS, conf.env.COMPILER_CC)[0] % conf.options.PROFILE_USE]
|
||||
|
||||
if conf.env.DEST_OS == 'nswitch' and conf.options.BUILD_TYPE == 'debug':
|
||||
# enable remote debugger
|
||||
cflags.append('-DNSWITCH_DEBUG')
|
||||
|
||||
82
scripts/waifulib/psp.py
Normal file
82
scripts/waifulib/psp.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# encoding: utf-8
|
||||
# psp.py -- PSP EBOOT task
|
||||
# Copyright (C) 2023 Sergey Galushko
|
||||
# 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.
|
||||
|
||||
##################################
|
||||
# PSP Tools #
|
||||
##################################
|
||||
class psp_fixup(Task.Task):
|
||||
run_str = '${FIXUP} -o ${TGT} ${SRC}'
|
||||
color = 'BLUE'
|
||||
|
||||
class psp_prxgen(Task.Task):
|
||||
run_str = '${PRXGEN} ${SRC} ${TGT}'
|
||||
color = 'BLUE'
|
||||
|
||||
class psp_strip(Task.Task):
|
||||
run_str = '${STRIP} -o ${TGT} ${SRC}'
|
||||
color = 'BLUE'
|
||||
|
||||
class psp_mksfo(Task.Task):
|
||||
run_str = '${MKSFO} -d MEMSIZE=1 ${PSP_EBOOT_TITLE} ${TGT}'
|
||||
color = 'YELLOW'
|
||||
|
||||
class psp_packpbp(Task.Task):
|
||||
run_str = '${PACK_PBP} ${TGT} ${SRC[1].abspath()} ${PSP_EBOOT_ICON} ${PSP_EBOOT_ICON1} ${PSP_EBOOT_UNKPNG} ${PSP_EBOOT_PIC1} ${PSP_EBOOT_SND0} ${SRC[0].abspath()} ${PSP_EBOOT_PSAR}'
|
||||
color = 'GREEN'
|
||||
|
||||
|
||||
@TaskGen.feature('cshlib', 'cxxshlib')
|
||||
@TaskGen.after_method('apply_link')
|
||||
def build_module(self):
|
||||
link_output = self.link_task.outputs[0]
|
||||
for d in self.env.STATIC_LINKING:
|
||||
if link_output.name.startswith(d):
|
||||
return
|
||||
fixup_output = self.path.find_or_declare(link_output.name + '_fixup')
|
||||
prxgen_output = self.path.find_or_declare(link_output.change_ext('.prx').name)
|
||||
|
||||
task = self.create_task('psp_fixup', src=link_output, tgt=fixup_output)
|
||||
task = self.create_task('psp_prxgen', src=fixup_output, tgt=prxgen_output)
|
||||
|
||||
if getattr(self, 'install_path', None):
|
||||
if self.bld.is_install:
|
||||
for k in self.install_task.inputs:
|
||||
if k == self.path.find_or_declare(link_output.name):
|
||||
self.install_task.inputs.remove(k)
|
||||
self.add_install_files(install_to=self.install_path, install_from=prxgen_output)
|
||||
|
||||
@TaskGen.feature('cprogram', 'cxxprogram', 'cprogram_static', 'cxxprogram_static')
|
||||
@TaskGen.after_method('apply_link')
|
||||
def build_eboot(self):
|
||||
finalobj_ext = '.elf'
|
||||
finalobj_tool = 'psp_strip'
|
||||
if self.env.PSP_BUILD_PRX:
|
||||
finalobj_ext = '.prx'
|
||||
finalobj_tool = 'psp_prxgen'
|
||||
|
||||
link_output = self.link_task.outputs[0]
|
||||
fixup_output = self.path.find_or_declare(link_output.name + '_fixup')
|
||||
finalobj_output = self.path.find_or_declare(link_output.change_ext(finalobj_ext).name)
|
||||
|
||||
mksfo_output = self.path.find_or_declare('PARAM.SFO')
|
||||
packpbp_output = self.path.find_or_declare('EBOOT.PBP')
|
||||
|
||||
task = self.create_task('psp_fixup', src=link_output, tgt=fixup_output)
|
||||
task = self.create_task(finalobj_tool, src=fixup_output, tgt=finalobj_output)
|
||||
task = self.create_task('psp_mksfo', tgt=mksfo_output)
|
||||
task = self.create_task('psp_packpbp', src=[finalobj_output, mksfo_output], tgt=packpbp_output)
|
||||
|
||||
if getattr(self, 'install_path', None):
|
||||
if getattr(self, 'install_task', None):
|
||||
self.install_task.inputs = self.install_task.outputs = []
|
||||
self.add_install_files(install_to=self.install_path, install_from=[packpbp_output, finalobj_output])
|
||||
@@ -16,7 +16,7 @@ class ziparchive(Task.Task):
|
||||
return 'Creating'
|
||||
|
||||
def run(self):
|
||||
outfile = self.outputs[0].path_from(self.outputs[0].ctx.launch_node())
|
||||
outfile = self.outputs[0].abspath()
|
||||
comp = zipfile.ZIP_STORED if self.compresslevel == 0 else zipfile.ZIP_DEFLATED
|
||||
|
||||
with zipfile.ZipFile(outfile, mode='w', compression=comp) as zf:
|
||||
|
||||
Reference in New Issue
Block a user