Compare commits

..

13 Commits

Author SHA1 Message Date
Alibek Omarov
119926805f mainui: update 2024-02-21 03:39:11 +03:00
Alibek Omarov
f749b5cb4b 3rdparty: nanogl: update 2024-02-21 02:57:18 +03:00
Alibek Omarov
c29ad6b598 scripts: waifulib: compiler_optimizations: add option to use profiling 2024-02-21 02:57:07 +03:00
Alibek Omarov
4c5dfb963e engine: zone: few more tunings for realloc 2024-02-21 00:59:02 +03:00
Alibek Omarov
e11f9e05d4 engine: server: add GetNativeObject to server's PhysicsAPI 2024-02-19 17:49:37 +03:00
Alibek Omarov
5c8b5b3511 Documentation: extensions: add doc about native-object 2024-02-19 17:49:37 +03:00
Alibek Omarov
2ea7162287 engine: gameui: add GetNativeObject to extended menu API 2024-02-19 17:49:37 +03:00
Alibek Omarov
e62ab51842 engine: platforms: android: platforms aren't expected to get NULL or zero sized native object names anymore 2024-02-19 17:49:37 +03:00
Bohdan Shulyar
f1bc9b87b1 platform: android: port to SDL 2024-02-19 17:47:40 +03:00
Alibek Omarov
a9bddaac64 engine: platform: win32: do not call filesystem functions if filesystem_stdio was failed to load 2024-02-19 06:27:24 +03:00
Alibek Omarov
6cef6f6a75 engine: zone: refactoring 2024-02-19 06:13:54 +03:00
Alibek Omarov
25ea6ed500 scripts: waifulib: don't use relative path while creating ZIP file (so cwd might not be equal to sources path) 2024-02-19 05:00:12 +03:00
Alibek Omarov
3d5173f257 engine: zone: implement Mem_Realloc through standard realloc 2024-02-19 04:22:16 +03:00
21 changed files with 415 additions and 157 deletions

View File

@@ -24,14 +24,9 @@ jobs:
# - os: ubuntu-aarch64-20.04 # - os: ubuntu-aarch64-20.04
# targetos: linux # targetos: linux
# targetarch: aarch64 # targetarch: aarch64
- os: ubuntu-20.04
# - os: ubuntu-20.04 targetos: android
# targetos: android targetarch: multiarch
# targetarch: 32
# - os: ubuntu-20.04
# targetos: android
# targetarch: 64
# - os: ubuntu-20.04 # - os: ubuntu-20.04
# targetos: motomagx # targetos: motomagx
# targetarch: armv6 # targetarch: armv6
@@ -51,7 +46,6 @@ jobs:
env: env:
SDL_VERSION: 2.28.5 SDL_VERSION: 2.28.5
GH_CPU_ARCH: ${{ matrix.targetarch }} GH_CPU_ARCH: ${{ matrix.targetarch }}
ANDROID_SDK_TOOLS_VER: 4333796
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3

5
.gitignore vendored
View File

@@ -54,6 +54,11 @@ CMakeFiles
Makefile Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt install_manifest.txt
CMakeLists.txt*
CMakeScripts
Testing
compile_commands.json
_deps
# makedepend # makedepend
Makefile.dep Makefile.dep
*.bak *.bak

View 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. |

View File

@@ -1220,6 +1220,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
pfnParseFileSafe, pfnParseFileSafe,
NET_AdrToString, NET_AdrToString,
NET_CompareAdrSort, NET_CompareAdrSort,
Sys_GetNativeObject,
}; };
void UI_UnloadProgs( void ) void UI_UnloadProgs( void )

View File

@@ -2100,9 +2100,13 @@ void Con_RunConsole( void )
// decide on the destination height of the console // decide on the destination height of the console
if( host.allow_console && cls.key_dest == key_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 ) if( cls.state < ca_active || cl.first_frame )
con.showlines = refState.height; // full screen con.showlines = refState.height; // full screen
else con.showlines = (refState.height >> 1); // half screen else con.showlines = (refState.height >> 1); // half screen
#endif
} }
else con.showlines = 0; // none visible else con.showlines = 0; // none visible

View File

@@ -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; touch.move_finger = touch.resize_finger = touch.look_finger = -1;
// Hack for keyboard, hope it help // Hack for keyboard, hope it help
// a1ba: this is absolutely horrible
if( cls.key_dest == key_console || cls.key_dest == key_message ) 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 ); Key_EnableTextInput( true, true );
x1 = 0.0f;
}
if( cls.key_dest == key_console ) if( cls.key_dest == key_console )
{ {
static float y1 = 0; 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 // exit of console area
if( type == event_down && x < 0.1f && y > 0.9f ) if( type == event_down && x < 0.1f && y > 0.9f )
Cbuf_AddText( "escape\n" ); 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) ); 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) ); //MsgDev( D_NOTE, "touch %d %d\n", TO_SCRN_X(x), TO_SCRN_Y(y) );

View File

@@ -93,123 +93,241 @@ static mempool_t *Mem_FindPool( poolhandle_t poolptr )
} }
#endif #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 ) void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{ {
memheader_t *mem; memheader_t *mem;
mempool_t *pool; mempool_t *pool;
if( size <= 0 ) return NULL; if( size <= 0 )
if( !poolptr ) Sys_Error( "Mem_Alloc: pool == NULL (alloc at %s:%i)\n", filename, fileline ); 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 ); 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 ) if( clear )
memset((void *)((byte *)mem + sizeof( memheader_t )), 0, mem->size ); memset((void *)((byte *)mem + sizeof( memheader_t )), 0, mem->size );
return (void *)((byte *)mem + sizeof( memheader_t )); 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 ) static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline )
{ {
mempool_t *pool; mempool_t *pool;
if( mem->sentinel1 != MEMHEADER_SENTINEL1 ) if( !Mem_CheckAllocHeader( __func__, mem, filename, fileline ))
{ return;
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 );
}
pool = mem->pool; pool = mem->pool;
// unlink memheader from doubly linked list // unlink memheader from doubly linked list
if(( mem->prev ? mem->prev->next != mem : pool->chain != mem ) || ( mem->next && mem->next->prev != mem )) 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; Mem_PoolSubtract( pool, mem->size );
else pool->chain = mem->next; 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 ); Q_free( mem );
} }
void _Mem_Free( void *data, const char *filename, int fileline ) 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 ); 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; memheader_t *mem;
char *nb; 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 )); Sys_Error( "Mem_Realloc: pool == NULL (alloc at %s:%i)\n", filename, fileline );
if( size == memhdr->size ) return memptr; 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! char *nb = _Mem_Alloc( poolptr, size, clear, filename, fileline );
memcpy( nb, memptr, newsize );
_Mem_Free( memptr, filename, fileline ); // free unused old block 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 ) 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 // unlink pool from chain
for( chainaddress = &poolchain; *chainaddress && *chainaddress != pool; chainaddress = &((*chainaddress)->next)); 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( *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 ); Mem_CheckPool( "Mem_FreePool", pool, 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 );
*chainaddress = pool->next; *chainaddress = pool->next;
// free memory owned by the pool // 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 ); mempool_t *pool = Mem_FindPool( poolptr );
if( !poolptr ) Sys_Error( "Mem_EmptyPool: pool == NULL (emptypool at %s:%i)\n", filename, fileline ); 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 ); Mem_CheckPool( "Mem_FreePool", pool, 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 );
// free memory owned by the pool // free memory owned by the pool
while( pool->chain ) Mem_FreeBlock( pool->chain, filename, fileline ); 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 // search only one pool
target = (memheader_t *)((byte *)data - sizeof( memheader_t )); target = (memheader_t *)((byte *)data - sizeof( memheader_t ));
for( header = pool->chain; header; header = header->next ) for( header = pool->chain; header; header = header->next )
if( header == target ) return true; {
if( header == target )
return true;
}
} }
else else
{ {
// search all pools // search all pools
for( pool = poolchain; pool; pool = pool->next ) for( pool = poolchain; pool; pool = pool->next )
{
if( Mem_CheckAlloc( pool, data )) if( Mem_CheckAlloc( pool, data ))
return true; return true;
}
} }
return false; return false;
} }
@@ -308,49 +429,24 @@ Check pointer for memory
qboolean Mem_IsAllocatedExt( poolhandle_t poolptr, void *data ) qboolean Mem_IsAllocatedExt( poolhandle_t poolptr, void *data )
{ {
mempool_t *pool = NULL; mempool_t *pool = NULL;
if( poolptr ) pool = Mem_FindPool( poolptr );
if( poolptr )
pool = Mem_FindPool( poolptr );
return Mem_CheckAlloc( pool, data ); 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 ) void _Mem_Check( const char *filename, int fileline )
{ {
memheader_t *mem; memheader_t *mem;
mempool_t *pool; mempool_t *pool;
for( pool = poolchain; pool; pool = pool->next ) for( pool = poolchain; pool; pool = pool->next )
{ Mem_CheckPool( "Mem_CheckSentinels", pool, filename, fileline );
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 );
}
for( pool = poolchain; pool; pool = pool->next ) for( pool = poolchain; pool; pool = pool->next )
for( mem = pool->chain; mem; mem = mem->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 ) void Mem_PrintStats( void )
@@ -377,28 +473,31 @@ void Mem_PrintList( size_t minallocationsize )
Mem_Check(); 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 ) for( pool = poolchain; pool; pool = pool->next )
{ {
long changed_size = (long)pool->totalsize - (long)pool->lastchecksize; long changed_size = (long)pool->totalsize - (long)pool->lastchecksize;
// poolnames can contain color symbols, make sure what color is reset // 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) ? '-' : '+'; char sign = (changed_size < 0) ? '-' : '+';
Con_Printf( "%10s (%10s actual) %s (^7%c%s change)\n", Q_memprint( pool->totalsize ), Q_memprint( pool->realsize ), 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 ))); pool->name, sign, Q_memprint( abs( changed_size )));
} }
else 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; pool->lastchecksize = pool->totalsize;
for( mem = pool->chain; mem; mem = mem->next ) for( mem = pool->chain; mem; mem = mem->next )
{
if( mem->size >= minallocationsize ) if( mem->size >= minallocationsize )
Con_Printf( "%10s allocated at %s:%i\n", Q_memprint( mem->size ), mem->filename, mem->fileline ); Con_Printf( "%10s allocated at %s:%i\n", Q_memprint( mem->size ), mem->filename, mem->fileline );
}
} }
} }

View File

@@ -215,6 +215,7 @@ typedef struct ui_extendedfuncs_s {
// network address funcs // network address funcs
const char *(*pfnAdrToString)( const struct netadr_s a ); const char *(*pfnAdrToString)( const struct netadr_s a );
int (*pfnCompareAdr)( const void *a, const void *b ); // netadr_t int (*pfnCompareAdr)( const void *a, const void *b ); // netadr_t
void *(*pfnGetNativeObject)( const char *name );
} ui_extendedfuncs_t; } ui_extendedfuncs_t;
// deprecated export from old engine // deprecated export from old engine

View File

@@ -107,7 +107,10 @@ typedef struct server_physics_api_s
int (*pfnSaveFile)( const char *filename, const void *data, int len ); int (*pfnSaveFile)( const char *filename, const void *data, int len );
const byte *(*pfnLoadImagePixels)( const char *filename, int *width, int *height ); 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; } server_physics_api_t;
// physic callbacks // physic callbacks

View File

@@ -61,23 +61,16 @@ Android_GetNativeObject
void *Android_GetNativeObject( const char *name ) void *Android_GetNativeObject( const char *name )
{ {
static const char *availObjects[] = { "JNIEnv", "ActivityClass", NULL }; if( !strcasecmp( name, "JNIEnv" ) )
void *object = NULL;
if( !name )
{ {
object = (void *)availObjects; return (void *)jni.env;
}
else if( !strcasecmp( name, "JNIEnv" ) )
{
object = (void *)jni.env;
} }
else if( !strcasecmp( name, "ActivityClass" ) ) else if( !strcasecmp( name, "ActivityClass" ) )
{ {
object = (void *)jni.actcls; return (void *)jni.actcls;
} }
return object; return NULL;
} }
/* /*

View File

@@ -654,7 +654,9 @@ static void SDLash_EventFilter( SDL_Event *event )
SDLash_ActiveEvent( false ); SDLash_ActiveEvent( false );
break; break;
case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_RESIZED:
#if !XASH_MOBILE_PLATFORM
if( vid_fullscreen.value == WINDOW_MODE_WINDOWED ) if( vid_fullscreen.value == WINDOW_MODE_WINDOWED )
#endif
{ {
SDL_Window *wnd = SDL_GetWindowFromID( event->window.windowID ); SDL_Window *wnd = SDL_GetWindowFromID( event->window.windowID );
VID_SaveWindowSize( event->window.data1, event->window.data2, VID_SaveWindowSize( event->window.data1, event->window.data2,

View File

@@ -744,7 +744,6 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
if( !glw_state.software ) if( !glw_state.software )
SetBits( wndFlags, SDL_WINDOW_OPENGL ); SetBits( wndFlags, SDL_WINDOW_OPENGL );
#if !XASH_MOBILE_PLATFORM
if( window_mode == WINDOW_MODE_WINDOWED ) if( window_mode == WINDOW_MODE_WINDOWED )
{ {
SDL_Rect r; SDL_Rect r;
@@ -787,10 +786,6 @@ qboolean VID_CreateWindow( int width, int height, window_mode_t window_mode )
SetBits( wndFlags, SDL_WINDOW_BORDERLESS ); SetBits( wndFlags, SDL_WINDOW_BORDERLESS );
xpos = ypos = 0; 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 )) if( !VID_CreateWindowWithSafeGL( wndname, xpos, ypos, width, height, wndFlags ))
return false; 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 ) if( FBitSet( SDL_GetWindowFlags( host.hWnd ), SDL_WINDOW_MAXIMIZED|SDL_WINDOW_FULLSCREEN_DESKTOP ) != 0 )
SDL_GetWindowSize( host.hWnd, &width, &height ); SDL_GetWindowSize( host.hWnd, &width, &height );
#if !XASH_MOBILE_PLATFORM
if( window_mode != WINDOW_MODE_WINDOWED ) if( window_mode != WINDOW_MODE_WINDOWED )
{ {
if( !VID_SetScreenResolution( width, height, window_mode )) if( !VID_SetScreenResolution( width, height, window_mode ))
return false; return false;
} }
else VID_RestoreScreenResolution(); else VID_RestoreScreenResolution();
#endif
VID_SetWindowIcon( host.hWnd ); VID_SetWindowIcon( host.hWnd );
SDL_ShowWindow( host.hWnd ); SDL_ShowWindow( host.hWnd );
@@ -1175,6 +1168,14 @@ qboolean VID_SetMode( void )
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 ) #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 )) if( !FBitSet( vid_fullscreen.flags, FCVAR_CHANGED ))
Cvar_DirectSet( &vid_fullscreen, DEFAULT_FULLSCREEN ); Cvar_DirectSet( &vid_fullscreen, DEFAULT_FULLSCREEN );
else else

View File

@@ -356,13 +356,13 @@ static void ListMissingModules( dll_user_t *hInst )
byte *data; byte *data;
char buf[MAX_VA_STRING]; char buf[MAX_VA_STRING];
if ( !hInst ) return; if( !hInst || !g_fsapi.LoadFile ) return;
data = FS_LoadFile( hInst->dllName, NULL, false ); data = g_fsapi.LoadFile( hInst->dllName, NULL, false );
if ( !data ) return; if( !data ) return;
importDesc = GetImportDescriptor( hInst->dllName, data, &peHeader ); importDesc = GetImportDescriptor( hInst->dllName, data, &peHeader );
if ( !importDesc ) if( !importDesc )
{ {
Mem_Free( data ); Mem_Free( data );
return; return;

View File

@@ -2122,6 +2122,7 @@ static server_physics_api_t gPhysicsAPI =
COM_SaveFile, COM_SaveFile,
pfnLoadImagePixels, pfnLoadImagePixels,
pfnGetModelName, pfnGetModelName,
Sys_GetNativeObject
}; };
/* /*

View File

@@ -237,7 +237,8 @@ def build(bld):
app_name = 'xash3d-fwgs' app_name = 'xash3d-fwgs'
) )
else: 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 install_path = bld.env.BINDIR
program = 'cxxprogram' if is_cxx_link else 'cprogram' program = 'cxxprogram' if is_cxx_link else 'cprogram'
if bld.env.STATIC: if bld.env.STATIC:

View File

@@ -7,16 +7,16 @@ export PATH=$PATH:$JAVA_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$AN
pushd android 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 \ $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
popd popd
mkdir -p artifacts/ 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

View File

@@ -116,6 +116,22 @@ POLLY_CFLAGS = {
# msvc sosat :( # 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): def options(opt):
grp = opt.add_option_group('Compiler optimization options') 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, grp.add_option('--enable-poly-opt', action = 'store_true', dest = 'POLLY', default = False,
help = 'enable polyhedral optimization if possible [default: %default]') 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): def configure(conf):
conf.start_msg('Build type') 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('LTO build', 'yes' if conf.options.LTO else 'no')
conf.msg('PolyOpt build', 'yes' if conf.options.POLLY 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 # -march=native should not be used
if conf.options.BUILD_TYPE.startswith('fast'): if conf.options.BUILD_TYPE.startswith('fast'):
@@ -174,6 +198,13 @@ def get_optimization_flags(conf):
if conf.options.POLLY: if conf.options.POLLY:
cflags += conf.get_flags_by_compiler(POLLY_CFLAGS, conf.env.COMPILER_CC) 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': if conf.env.DEST_OS == 'nswitch' and conf.options.BUILD_TYPE == 'debug':
# enable remote debugger # enable remote debugger
cflags.append('-DNSWITCH_DEBUG') cflags.append('-DNSWITCH_DEBUG')

82
scripts/waifulib/psp.py Normal file
View 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])

View File

@@ -16,7 +16,7 @@ class ziparchive(Task.Task):
return 'Creating' return 'Creating'
def run(self): 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 comp = zipfile.ZIP_STORED if self.compresslevel == 0 else zipfile.ZIP_DEFLATED
with zipfile.ZipFile(outfile, mode='w', compression=comp) as zf: with zipfile.ZipFile(outfile, mode='w', compression=comp) as zf: