mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 11:35:05 +08:00
Compare commits
49 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7584bbe47e | ||
|
|
505b6cc264 | ||
|
|
24f23908be | ||
|
|
43bd73f37b | ||
|
|
bb2753cbfc | ||
|
|
5568eccc8a | ||
|
|
c3b2cc4423 | ||
|
|
d84130219f | ||
|
|
d97d4d6c42 | ||
|
|
15798aaf52 | ||
|
|
e53892e827 | ||
|
|
cb12af69ed | ||
|
|
e82050a4bc | ||
|
|
e4edd2da45 | ||
|
|
4f80922358 | ||
|
|
ae7ed03376 | ||
|
|
c082e46662 | ||
|
|
b0bbcab6b4 | ||
|
|
0fc83080ec | ||
|
|
73883b504f | ||
|
|
8efc9d74e8 | ||
|
|
373321ff00 | ||
|
|
a508467aac | ||
|
|
abbe993e80 | ||
|
|
c644e4d569 | ||
|
|
c200e008f1 | ||
|
|
e95a2da6d0 | ||
|
|
8afca1a79c | ||
|
|
827c9ca857 | ||
|
|
2416635ba3 | ||
|
|
39eec89580 | ||
|
|
98d88266a6 | ||
|
|
0f3359fc05 | ||
|
|
6c77608c34 | ||
|
|
abdff6eff6 | ||
|
|
95a75465c9 | ||
|
|
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/gl4es/gl4es
vendored
2
3rdparty/gl4es/gl4es
vendored
Submodule 3rdparty/gl4es/gl4es updated: 5226f5f937...e39434a2b1
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: 46d05f9ff5...d75b7f4a57
2
3rdparty/nanogl
vendored
2
3rdparty/nanogl
vendored
Submodule 3rdparty/nanogl updated: 76393a8fde...e75792de03
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. |
|
||||
@@ -534,5 +534,14 @@ typedef struct
|
||||
#define MAX_EFRAGS 8192 // Arcane Dimensions required
|
||||
#define MAX_REQUESTS 64
|
||||
|
||||
#if ! XASH_64BIT
|
||||
STATIC_ASSERT( sizeof( mextrasurf_t ) == 324, "mextrasurf_t unexpected size" );
|
||||
STATIC_ASSERT( sizeof( decal_t ) == 60, "decal_t unexpected size");
|
||||
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 176, "mfaceinfo_t unexpected size");
|
||||
#else
|
||||
STATIC_ASSERT( sizeof( mextrasurf_t) == 496, "mextrasurf_t unexpected size");
|
||||
STATIC_ASSERT( sizeof( decal_t ) == 88, "decal_t unexpected size");
|
||||
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 304, "mfaceinfo_t unexpected size");
|
||||
#endif
|
||||
|
||||
#endif//COM_MODEL_H
|
||||
|
||||
@@ -164,6 +164,10 @@ Default build-depended cvar and constant values
|
||||
#define XASH_INTERNAL_GAMELIBS
|
||||
#endif // XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
|
||||
|
||||
#if XASH_ANDROID && XASH_SDL
|
||||
#define XASH_ANDROID_ASSETS 1
|
||||
#endif
|
||||
|
||||
// Defaults
|
||||
#ifndef DEFAULT_TOUCH_ENABLE
|
||||
#define DEFAULT_TOUCH_ENABLE "0"
|
||||
|
||||
@@ -86,8 +86,6 @@ typedef uint64_t longtime_t;
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define NONNULL __attribute__((nonnull))
|
||||
#define ALLOC_CHECK(x) __attribute__((alloc_size(x)))
|
||||
#define FORCEINLINE inline __attribute__((always_inline))
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
#elif defined(_MSC_VER)
|
||||
#define EXPORT __declspec( dllexport )
|
||||
#define GAME_EXPORT
|
||||
@@ -95,8 +93,6 @@ typedef uint64_t longtime_t;
|
||||
#define NORETURN
|
||||
#define NONNULL
|
||||
#define ALLOC_CHECK(x)
|
||||
#define FORCEINLINE __forceinline
|
||||
#define NOINLINE __declspec( noinline )
|
||||
#else
|
||||
#define EXPORT
|
||||
#define GAME_EXPORT
|
||||
@@ -104,8 +100,6 @@ typedef uint64_t longtime_t;
|
||||
#define NORETURN
|
||||
#define NONNULL
|
||||
#define ALLOC_CHECK(x)
|
||||
#define FORCEINLINE
|
||||
#define NOINLINE
|
||||
#endif
|
||||
|
||||
#if ( __GNUC__ >= 3 )
|
||||
|
||||
@@ -1220,6 +1220,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
|
||||
pfnParseFileSafe,
|
||||
NET_AdrToString,
|
||||
NET_CompareAdrSort,
|
||||
Sys_GetNativeObject,
|
||||
};
|
||||
|
||||
void UI_UnloadProgs( void )
|
||||
|
||||
@@ -28,7 +28,6 @@ GNU General Public License for more details.
|
||||
#define MAX_CMD_BUFFER 8000
|
||||
#define CONNECTION_PROBLEM_TIME 15.0 // 15 seconds
|
||||
#define CL_CONNECTION_RETRIES 10
|
||||
#define CL_TEST_RETRIES_NORESPONCE 3
|
||||
#define CL_TEST_RETRIES 5
|
||||
|
||||
CVAR_DEFINE_AUTO( mp_decals, "300", FCVAR_ARCHIVE, "decals limit in multiplayer" );
|
||||
@@ -1072,6 +1071,22 @@ static void CL_SendConnectPacket( void )
|
||||
cls.timestart = Sys_DoubleTime();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_GetTestFragmentSize
|
||||
|
||||
Returns bandwidth test fragment size
|
||||
=================
|
||||
*/
|
||||
static int CL_GetTestFragmentSize( void )
|
||||
{
|
||||
const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
|
||||
if( cls.connect_retry >= 0 && cls.connect_retry < CL_TEST_RETRIES )
|
||||
return bound( FRAGMENT_MIN_SIZE, fragmentSizes[cls.connect_retry], FRAGMENT_MAX_SIZE );
|
||||
else
|
||||
return FRAGMENT_MIN_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_CheckForResend
|
||||
@@ -1083,8 +1098,9 @@ static void CL_CheckForResend( void )
|
||||
{
|
||||
netadr_t adr;
|
||||
net_gai_state_t res;
|
||||
float resendTime;
|
||||
qboolean bandwidthTest;
|
||||
|
||||
|
||||
if( cls.internetservers_wait )
|
||||
CL_SendMasterServerScanRequest();
|
||||
|
||||
@@ -1110,7 +1126,10 @@ static void CL_CheckForResend( void )
|
||||
else if( cl_resend.value > CL_MAX_RESEND_TIME )
|
||||
Cvar_SetValue( "cl_resend", CL_MAX_RESEND_TIME );
|
||||
|
||||
if(( host.realtime - cls.connect_time ) < cl_resend.value )
|
||||
bandwidthTest = !cls.legacymode && cl_test_bandwidth.value && cls.connect_retry <= CL_TEST_RETRIES;
|
||||
resendTime = bandwidthTest ? 1.0f : cl_resend.value;
|
||||
|
||||
if(( host.realtime - cls.connect_time ) < resendTime )
|
||||
return;
|
||||
|
||||
res = NET_StringToAdrNB( cls.servername, &adr );
|
||||
@@ -1137,10 +1156,11 @@ static void CL_CheckForResend( void )
|
||||
|
||||
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
|
||||
|
||||
if( cls.connect_retry == CL_TEST_RETRIES_NORESPONCE )
|
||||
if( cls.connect_retry == CL_TEST_RETRIES )
|
||||
{
|
||||
// too many fails use default connection method
|
||||
Con_Printf( "hi-speed connection is failed, use default method\n" );
|
||||
Con_Printf( "Bandwidth test failed, fallback to default connecting method\n" );
|
||||
Con_Printf( "Connecting to %s... (retry #%i)\n", cls.servername, cls.connect_retry + 1 );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "getchallenge\n" );
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_MIN_SIZE );
|
||||
cls.connect_time = host.realtime;
|
||||
@@ -1148,16 +1168,15 @@ static void CL_CheckForResend( void )
|
||||
return;
|
||||
}
|
||||
|
||||
bandwidthTest = !cls.legacymode && cl_test_bandwidth.value;
|
||||
cls.serveradr = adr;
|
||||
cls.max_fragment_size = Q_min( FRAGMENT_MAX_SIZE, cls.max_fragment_size / (cls.connect_retry + 1));
|
||||
cls.max_fragment_size = CL_GetTestFragmentSize();
|
||||
cls.connect_time = host.realtime; // for retransmit requests
|
||||
cls.connect_retry++;
|
||||
|
||||
if( bandwidthTest )
|
||||
Con_Printf( "Connecting to %s... [retry #%i, max fragment size %i]\n", cls.servername, cls.connect_retry, cls.max_fragment_size );
|
||||
Con_Printf( "Connecting to %s... (retry #%i, fragment size %i)\n", cls.servername, cls.connect_retry, cls.max_fragment_size );
|
||||
else
|
||||
Con_Printf( "Connecting to %s... [retry #%i]\n", cls.servername, cls.connect_retry );
|
||||
Con_Printf( "Connecting to %s... (retry #%i)\n", cls.servername, cls.connect_retry );
|
||||
|
||||
if( bandwidthTest )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "bandwidth %i %i\n", PROTOCOL_VERSION, cls.max_fragment_size );
|
||||
|
||||
@@ -795,25 +795,14 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
|
||||
|
||||
pmove->player_index = ps->number - 1;
|
||||
|
||||
// a1ba: workaround bug on old protocol where the server refuse to send
|
||||
// our local player in delta. cl.playernum, in theory, must be equal
|
||||
// to our local player index anyway
|
||||
// a1ba: workaround bug where the server refuse to send our local player in delta
|
||||
// cl.playernum, in theory, must be equal to our local player index anyway
|
||||
//
|
||||
// this might not be a real solution, since everything else will be bogus
|
||||
// but we need to properly run prediction and avoid potential memory
|
||||
// corruption
|
||||
// either debug this, or remove when old protocol will be dropped!!!
|
||||
if( pmove->player_index < 0 )
|
||||
{
|
||||
if( cls.legacymode )
|
||||
{
|
||||
pmove->player_index = bound( 0, cl.playernum, cl.maxclients - 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this happens, record a demo and send it to a1ba
|
||||
Host_Error( "%s: ps->number == %d\n", __func__, ps->number );
|
||||
}
|
||||
}
|
||||
pmove->player_index = bound( 0, cl.playernum, cl.maxclients - 1 );
|
||||
|
||||
pmove->multiplayer = (cl.maxclients > 1);
|
||||
pmove->runfuncs = runfuncs;
|
||||
|
||||
@@ -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) );
|
||||
|
||||
@@ -43,7 +43,7 @@ CVAR_DEFINE_AUTO( s_lerping, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "apply interpo
|
||||
static CVAR_DEFINE( s_ambient_level, "ambient_level", "0.3", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "volume of environment noises (water and wind)" );
|
||||
static CVAR_DEFINE( s_ambient_fade, "ambient_fade", "1000", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rate of volume fading when client is moving" );
|
||||
static CVAR_DEFINE_AUTO( s_combine_sounds, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "combine channels with same sounds" );
|
||||
CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "silence the audio when game window loses focus" );
|
||||
static CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "silence the audio when game window loses focus" );
|
||||
CVAR_DEFINE_AUTO( s_test, "0", 0, "engine developer cvar for quick testing new features" );
|
||||
CVAR_DEFINE_AUTO( s_samplecount, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sample count (0 for default value)" );
|
||||
CVAR_DEFINE_AUTO( s_warn_late_precache, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "warn about late precached sounds on client-side" );
|
||||
@@ -64,6 +64,12 @@ float S_GetMasterVolume( void )
|
||||
{
|
||||
float scale = 1.0f;
|
||||
|
||||
if( host.status == HOST_NOFOCUS && snd_mute_losefocus.value != 0.0f )
|
||||
{
|
||||
// we return zero volume to keep sounds running
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if( !s_listener.inmenu && soundfade.percent != 0 )
|
||||
{
|
||||
scale = bound( 0.0f, soundfade.percent / 100.0f, 1.0f );
|
||||
|
||||
@@ -221,7 +221,6 @@ extern convar_t s_musicvolume;
|
||||
extern convar_t s_lerping;
|
||||
extern convar_t s_test; // cvar to testify new effects
|
||||
extern convar_t s_samplecount;
|
||||
extern convar_t snd_mute_losefocus;
|
||||
extern convar_t s_warn_late_precache;
|
||||
|
||||
void S_InitScaletable( void );
|
||||
|
||||
@@ -20,8 +20,6 @@ GNU General Public License for more details.
|
||||
#include "vid_common.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
static CVAR_DEFINE( window_width, "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
|
||||
static CVAR_DEFINE( window_height, "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
|
||||
static CVAR_DEFINE_AUTO( vid_mode, "0", FCVAR_RENDERINFO, "current video mode index (used only for storage)" );
|
||||
static CVAR_DEFINE_AUTO( vid_rotate, "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
|
||||
static CVAR_DEFINE_AUTO( vid_scale, "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
|
||||
@@ -29,6 +27,8 @@ static CVAR_DEFINE_AUTO( vid_scale, "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "p
|
||||
CVAR_DEFINE_AUTO( vid_highdpi, "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
|
||||
CVAR_DEFINE_AUTO( vid_maximized, "0", FCVAR_RENDERINFO, "window maximized state, read-only" );
|
||||
CVAR_DEFINE( vid_fullscreen, "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen state (0 windowed, 1 fullscreen, 2 borderless)" );
|
||||
CVAR_DEFINE( window_width, "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
|
||||
CVAR_DEFINE( window_height, "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
|
||||
CVAR_DEFINE( window_xpos, "_window_xpos", "-1", FCVAR_RENDERINFO, "window position by horizontal" );
|
||||
CVAR_DEFINE( window_ypos, "_window_ypos", "-1", FCVAR_RENDERINFO, "window position by vertical" );
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ extern glwstate_t glw_state;
|
||||
extern convar_t vid_fullscreen;
|
||||
extern convar_t vid_maximized;
|
||||
extern convar_t vid_highdpi;
|
||||
extern convar_t window_width;
|
||||
extern convar_t window_height;
|
||||
extern convar_t window_xpos;
|
||||
extern convar_t window_ypos;
|
||||
extern convar_t gl_msaa_samples;
|
||||
|
||||
@@ -490,13 +490,14 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
#ifdef XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
#endif
|
||||
host.crashed = true;
|
||||
Platform_MessageBox( "Xash Error", message, false );
|
||||
|
||||
// log saved, now we can try to save configs and close log correctly, it may crash
|
||||
if( host.type == HOST_NORMAL )
|
||||
CL_Crashed();
|
||||
host.status = HOST_CRASHED;
|
||||
host.crashed = true;
|
||||
|
||||
|
||||
Sys_Quit();
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer
|
||||
ktx2_index_t index;
|
||||
size_t total_size = 0;
|
||||
size_t max_offset = 0;
|
||||
int mip, cursor;
|
||||
const byte *const levels_begin = buffer + KTX2_LEVELS_OFFSET;
|
||||
|
||||
// Sets image.type and image.flags
|
||||
@@ -125,7 +126,7 @@ static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer
|
||||
|
||||
memcpy( &index, buffer + KTX2_IDENTIFIER_SIZE + sizeof( ktx2_header_t ), sizeof( index ));
|
||||
|
||||
for( int mip = 0; mip < header->levelCount; ++mip )
|
||||
for( mip = 0; mip < header->levelCount; ++mip )
|
||||
{
|
||||
const uint32_t width = Q_max( 1, ( header->pixelWidth >> mip ));
|
||||
const uint32_t height = Q_max( 1, ( header->pixelHeight >> mip ));
|
||||
@@ -154,7 +155,7 @@ static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer
|
||||
image.rgba = Mem_Malloc( host.imagepool, image.size );
|
||||
memcpy( image.rgba, buffer, image.size );
|
||||
|
||||
for( int mip = 0, cursor = 0; mip < header->levelCount; ++mip )
|
||||
for( mip = 0, cursor = 0; mip < header->levelCount; ++mip )
|
||||
{
|
||||
ktx2_level_t level;
|
||||
memcpy( &level, levels_begin + mip * sizeof( level ), sizeof( level ));
|
||||
|
||||
@@ -127,7 +127,7 @@ GNU General Public License for more details.
|
||||
#define MAX_CUSTOM (1<<MAX_CUSTOM_BITS)// 10 bits == 1024 generic file
|
||||
#define MAX_USER_MESSAGES 197 // another 58 messages reserved for engine routines
|
||||
#define MAX_DLIGHTS 32 // dynamic lights (rendered per one frame)
|
||||
#define MAX_ELIGHTS 64 // entity only point lights
|
||||
#define MAX_ELIGHTS 128 // a1ba: increased from 64 to 128, entity only point lights
|
||||
#define MAX_LIGHTSTYLES 256 // a1ba: increased from 64 to 256, protocol limit
|
||||
#define MAX_RENDER_DECALS 4096 // max rendering decals per a level
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ GNU General Public License for more details.
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if _MSC_VER
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifdef XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
@@ -68,17 +72,15 @@ Sys_DebugBreak
|
||||
*/
|
||||
void Sys_DebugBreak( void )
|
||||
{
|
||||
#if XASH_LINUX || ( XASH_WIN32 && !XASH_64BIT )
|
||||
#if _MSC_VER
|
||||
if( Sys_DebuggerPresent() )
|
||||
_asm { int 3 }
|
||||
#elif XASH_X86
|
||||
if( Sys_DebuggerPresent() )
|
||||
asm volatile( "int $3;" );
|
||||
#else
|
||||
if( Sys_DebuggerPresent() )
|
||||
raise( SIGINT );
|
||||
#endif
|
||||
if( Sys_DebuggerPresent( ))
|
||||
__debugbreak();
|
||||
#else // !_MSC_VER
|
||||
if( Sys_DebuggerPresent( ))
|
||||
{
|
||||
INLINE_RAISE( SIGINT );
|
||||
INLINE_NANOSLEEP1(); // sometimes signal comes with delay, let it interrupt nanosleep
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -52,7 +52,7 @@ static pid_t gettid( void )
|
||||
static void *g_hsystemd;
|
||||
static int (*g_pfn_sd_notify)( int unset_environment, const char *state );
|
||||
|
||||
qboolean Sys_DebuggerPresent( void )
|
||||
qboolean Platform_DebuggerPresent( void )
|
||||
{
|
||||
char buf[4096];
|
||||
ssize_t num_read;
|
||||
|
||||
@@ -34,8 +34,8 @@ double Platform_DoubleTime( void );
|
||||
void Platform_Sleep( int msec );
|
||||
void Platform_ShellExecute( const char *path, const char *parms );
|
||||
void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow );
|
||||
qboolean Sys_DebuggerPresent( void ); // optional, see Sys_DebugBreak
|
||||
void Platform_SetStatus( const char *status );
|
||||
qboolean Platform_DebuggerPresent( void );
|
||||
|
||||
// legacy iOS port functions
|
||||
#if TARGET_OS_IOS
|
||||
@@ -64,6 +64,8 @@ const char *Android_LoadID( void );
|
||||
void Android_SaveID( const char *id );
|
||||
void Android_Init( void );
|
||||
void *Android_GetNativeObject( const char *name );
|
||||
int Android_GetKeyboardHeight( void );
|
||||
void Android_Shutdown( void );
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
@@ -140,6 +142,15 @@ static inline void Platform_Shutdown( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline qboolean Sys_DebuggerPresent( void )
|
||||
{
|
||||
#if XASH_LINUX || XASH_WIN32
|
||||
return Platform_DebuggerPresent();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -256,4 +267,89 @@ void VoiceCapture_Shutdown( void );
|
||||
qboolean VoiceCapture_Activate( qboolean activate );
|
||||
qboolean VoiceCapture_Lock( qboolean lock );
|
||||
|
||||
// this allows to make break in current line, without entering libc code
|
||||
// libc built with -fomit-frame-pointer may just eat stack frame (hello, glibc), making entering libc even more useless
|
||||
// calling syscalls directly allows to make break like if it was asm("int $3") on x86
|
||||
#if XASH_LINUX && XASH_X86
|
||||
#define INLINE_RAISE(x) asm volatile( "int $3;" );
|
||||
#define INLINE_NANOSLEEP1() // nothing!
|
||||
#elif XASH_LINUX && XASH_ARM && !XASH_64BIT
|
||||
#define INLINE_RAISE(x) do \
|
||||
{ \
|
||||
int raise_pid = getpid(); \
|
||||
int raise_tid = gettid(); \
|
||||
int raise_sig = (x); \
|
||||
__asm__ volatile ( \
|
||||
"mov r7,#268\n\t" \
|
||||
"mov r0,%0\n\t" \
|
||||
"mov r1,%1\n\t" \
|
||||
"mov r2,%2\n\t" \
|
||||
"svc 0\n\t" \
|
||||
: \
|
||||
: "r"(raise_pid), "r"(raise_tid), "r"(raise_sig) \
|
||||
: "r0", "r1", "r2", "r7", "memory" \
|
||||
); \
|
||||
} while( 0 )
|
||||
#define INLINE_NANOSLEEP1() do \
|
||||
{ \
|
||||
struct timespec ns_t1 = {1, 0}; \
|
||||
struct timespec ns_t2 = {0, 0}; \
|
||||
__asm__ volatile ( \
|
||||
"mov r7,#162\n\t" \
|
||||
"mov r0,%0\n\t" \
|
||||
"mov r1,%1\n\t" \
|
||||
"svc 0\n\t" \
|
||||
: \
|
||||
: "r"(&ns_t1), "r"(&ns_t2) \
|
||||
: "r0", "r1", "r7", "memory" \
|
||||
); \
|
||||
} while( 0 )
|
||||
#elif XASH_LINUX && XASH_ARM && XASH_64BIT
|
||||
#define INLINE_RAISE(x) do \
|
||||
{ \
|
||||
int raise_pid = getpid(); \
|
||||
int raise_tid = gettid(); \
|
||||
int raise_sig = (x); \
|
||||
__asm__ volatile ( \
|
||||
"mov x8,#131\n\t" \
|
||||
"mov x0,%0\n\t" \
|
||||
"mov x1,%1\n\t" \
|
||||
"mov x2,%2\n\t" \
|
||||
"svc 0\n\t" \
|
||||
: \
|
||||
: "r"(raise_pid), "r"(raise_tid), "r"(raise_sig) \
|
||||
: "x0", "x1", "x2", "x8", "memory", "cc" \
|
||||
); \
|
||||
} while( 0 )
|
||||
#define INLINE_NANOSLEEP1() do \
|
||||
{ \
|
||||
struct timespec ns_t1 = {1, 0}; \
|
||||
struct timespec ns_t2 = {0, 0}; \
|
||||
__asm__ volatile ( \
|
||||
"mov x8,#101\n\t" \
|
||||
"mov x0,%0\n\t" \
|
||||
"mov x1,%1\n\t" \
|
||||
"svc 0\n\t" \
|
||||
: \
|
||||
: "r"(&ns_t1), "r"(&ns_t2) \
|
||||
: "x0", "x1", "x8", "memory", "cc" \
|
||||
); \
|
||||
} while( 0 )
|
||||
#elif XASH_LINUX
|
||||
#ifdef __NR_tgkill
|
||||
#define INLINE_RAISE(x) syscall( __NR_tgkill, getpid(), gettid(), x )
|
||||
#else // __NR_tgkill
|
||||
#define INLINE_RAISE(x) raise(x)
|
||||
#endif // __NR_tgkill
|
||||
#define INLINE_NANOSLEEP1() do \
|
||||
{ \
|
||||
struct timespec ns_t1 = {1, 0}; \
|
||||
struct timespec ns_t2 = {0, 0}; \
|
||||
nanosleep( &ns_t1, &ns_t2 ); \
|
||||
} while( 0 )
|
||||
#else // generic
|
||||
#define INLINE_RAISE(x) raise(x)
|
||||
#define INLINE_NANOSLEEP1() sleep(1)
|
||||
#endif // generic
|
||||
|
||||
#endif // PLATFORM_H
|
||||
|
||||
@@ -212,8 +212,8 @@ const char *COM_NameForFunction( void *hInstance, void *function )
|
||||
// NOTE: dladdr() is a glibc extension
|
||||
{
|
||||
Dl_info info = {0};
|
||||
dladdr( (void*)function, &info );
|
||||
if( info.dli_sname )
|
||||
int ret = dladdr( (void*)function, &info );
|
||||
if( ret && info.dli_sname )
|
||||
return COM_GetPlatformNeutralName( info.dli_sname );
|
||||
}
|
||||
#ifdef XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||
|
||||
@@ -374,14 +374,8 @@ static void SDLash_ActiveEvent( int gain )
|
||||
{
|
||||
host.status = HOST_FRAME;
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
IN_ActivateMouse( );
|
||||
}
|
||||
|
||||
if( dma.initialized && snd_mute_losefocus.value )
|
||||
{
|
||||
SNDDMA_Activate( true );
|
||||
}
|
||||
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME;
|
||||
if( vid_fullscreen.value == WINDOW_MODE_FULLSCREEN )
|
||||
VID_SetMode();
|
||||
@@ -397,14 +391,8 @@ static void SDLash_ActiveEvent( int gain )
|
||||
#endif
|
||||
host.status = HOST_NOFOCUS;
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
IN_DeactivateMouse();
|
||||
}
|
||||
|
||||
if( dma.initialized && snd_mute_losefocus.value )
|
||||
{
|
||||
SNDDMA_Activate( false );
|
||||
}
|
||||
host.force_draw_version_time = host.realtime + 2.0;
|
||||
VID_RestoreScreenResolution();
|
||||
}
|
||||
@@ -654,7 +642,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,
|
||||
|
||||
@@ -44,6 +44,18 @@ Platform_GetMousePos
|
||||
void GAME_EXPORT Platform_GetMousePos( int *x, int *y )
|
||||
{
|
||||
SDL_GetMouseState( x, y );
|
||||
|
||||
if( x && window_width.value && window_width.value != refState.width )
|
||||
{
|
||||
float factor = refState.width / window_width.value;
|
||||
*x = *x * factor;
|
||||
}
|
||||
|
||||
if( y && window_height.value && window_height.value != refState.height )
|
||||
{
|
||||
float factor = refState.height / window_height.value;
|
||||
*y = *y * factor;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -576,10 +576,8 @@ static qboolean VID_SetScreenResolution( int width, int height, window_mode_t wi
|
||||
SDL_DisplayMode got;
|
||||
Uint32 wndFlags = 0;
|
||||
|
||||
#if !XASH_APPLE
|
||||
if( vid_highdpi.value )
|
||||
SetBits( wndFlags, SDL_WINDOW_ALLOW_HIGHDPI );
|
||||
#endif
|
||||
|
||||
SDL_SetWindowBordered( host.hWnd, SDL_FALSE );
|
||||
|
||||
@@ -744,7 +742,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 +784,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 +792,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 +1166,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;
|
||||
|
||||
@@ -41,7 +41,7 @@ void Platform_Sleep( int msec )
|
||||
}
|
||||
#endif // XASH_TIMER == TIMER_WIN32
|
||||
|
||||
qboolean Sys_DebuggerPresent( void )
|
||||
qboolean Platform_DebuggerPresent( void )
|
||||
{
|
||||
return IsDebuggerPresent();
|
||||
}
|
||||
|
||||
@@ -368,13 +368,12 @@ SV_NewGame_f
|
||||
*/
|
||||
static void SV_NewGame_f( void )
|
||||
{
|
||||
if( Cmd_Argc() != 1 )
|
||||
{
|
||||
if( Cmd_Argc() == 1 )
|
||||
COM_NewGame( GI->startmap );
|
||||
else if( Cmd_Argc() == 2 )
|
||||
COM_NewGame( Cmd_Argv( 1 ));
|
||||
else
|
||||
Con_Printf( S_USAGE "newgame\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
COM_NewGame( GI->startmap );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -922,11 +922,11 @@ static void SV_GenerateTestPacket( void )
|
||||
// testpacket already generated once, exit
|
||||
// testpacket and lookup table takes ~300k of memory
|
||||
// disable for low memory mode
|
||||
if( svs.testpacket_buf || XASH_LOW_MEMORY >= 0 )
|
||||
if( svs.testpacket_buf || XASH_LOW_MEMORY > 0 )
|
||||
return;
|
||||
|
||||
// don't need in singleplayer with full client
|
||||
if( svs.maxclients <= 1 && !Host_IsDedicated( ))
|
||||
if( svs.maxclients <= 1 )
|
||||
return;
|
||||
|
||||
file = FS_Open( "gfx.wad", "rb", false );
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -15,7 +15,7 @@ GNU General Public License for more details.
|
||||
|
||||
#include "port.h"
|
||||
|
||||
#if XASH_ANDROID
|
||||
#if XASH_ANDROID_ASSETS
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -328,4 +328,4 @@ void FS_InitAndroid( void )
|
||||
jni.getAssets = (*jni.env)->GetMethodID( jni.env, jni.activity_class, "getAssets", "(Z)Landroid/content/res/AssetManager;" );
|
||||
}
|
||||
|
||||
#endif // XASH_ANDROID
|
||||
#endif // XASH_ANDROID_ASSETS
|
||||
|
||||
@@ -72,7 +72,7 @@ const fs_archive_t g_archives[] =
|
||||
static const fs_archive_t g_directory_archive =
|
||||
{ NULL, SEARCHPATH_PLAIN, FS_AddDir_Fullpath, false };
|
||||
|
||||
#ifdef XASH_ANDROID
|
||||
#if XASH_ANDROID_ASSETS
|
||||
static const fs_archive_t g_android_archive =
|
||||
{ NULL, SEARCHPATH_ANDROID_ASSETS, FS_AddAndroidAssets_Fullpath, false };
|
||||
#endif
|
||||
@@ -406,7 +406,7 @@ void FS_AddGameDirectory( const char *dir, uint flags )
|
||||
|
||||
stringlistfreecontents( &list );
|
||||
|
||||
#ifdef XASH_ANDROID
|
||||
#if XASH_ANDROID_ASSETS
|
||||
FS_AddArchive_Fullpath( &g_android_archive, dir, flags );
|
||||
#endif
|
||||
|
||||
@@ -632,30 +632,23 @@ static void FS_InitGameInfo( gameinfo_t *GameInfo, const char *gamedir )
|
||||
memset( GameInfo, 0, sizeof( *GameInfo ));
|
||||
|
||||
// filesystem info
|
||||
Q_strncpy( GameInfo->gamefolder, gamedir, sizeof( GameInfo->gamefolder ));
|
||||
Q_strncpy( GameInfo->basedir, "valve", sizeof( GameInfo->basedir ));
|
||||
GameInfo->falldir[0] = 0;
|
||||
Q_strncpy( GameInfo->startmap, "c0a0", sizeof( GameInfo->startmap ));
|
||||
Q_strncpy( GameInfo->trainmap, "t0a0", sizeof( GameInfo->trainmap ));
|
||||
Q_strncpy( GameInfo->title, "New Game", sizeof( GameInfo->title ));
|
||||
GameInfo->version = 1.0f;
|
||||
|
||||
// .dll pathes
|
||||
Q_strncpy( GameInfo->gamefolder, gamedir, sizeof( GameInfo->gamefolder ));
|
||||
Q_strncpy( GameInfo->basedir, fs_basedir, sizeof( GameInfo->basedir ));
|
||||
Q_strncpy( GameInfo->sp_entity, "info_player_start", sizeof( GameInfo->sp_entity ));
|
||||
Q_strncpy( GameInfo->mp_entity, "info_player_deathmatch", sizeof( GameInfo->mp_entity ));
|
||||
Q_strncpy( GameInfo->startmap, "newmap", sizeof( GameInfo->startmap ));
|
||||
Q_strncpy( GameInfo->dll_path, "cl_dlls", sizeof( GameInfo->dll_path ));
|
||||
Q_strncpy( GameInfo->game_dll, "dlls/hl.dll", sizeof( GameInfo->game_dll ));
|
||||
Q_strncpy( GameInfo->game_dll_linux, "dlls/hl.so", sizeof( GameInfo->game_dll_linux ));
|
||||
Q_strncpy( GameInfo->game_dll_osx, "dlls/hl.dylib", sizeof( GameInfo->game_dll_osx ));
|
||||
|
||||
// .ico path
|
||||
Q_strncpy( GameInfo->iconpath, "game.ico", sizeof( GameInfo->iconpath ));
|
||||
|
||||
Q_strncpy( GameInfo->sp_entity, "info_player_start", sizeof( GameInfo->sp_entity ));
|
||||
Q_strncpy( GameInfo->mp_entity, "info_player_deathmatch", sizeof( GameInfo->mp_entity ));
|
||||
|
||||
GameInfo->max_edicts = DEFAULT_MAX_EDICTS; // default value if not specified
|
||||
GameInfo->max_tents = 500;
|
||||
GameInfo->max_beams = 128;
|
||||
GameInfo->max_particles = 4096;
|
||||
GameInfo->version = 1.0f;
|
||||
}
|
||||
|
||||
static void FS_ParseGenericGameInfo( gameinfo_t *GameInfo, const char *buf, const qboolean isGameInfo )
|
||||
@@ -1468,7 +1461,7 @@ qboolean FS_InitStdio( qboolean unused_set_to_true, const char *rootdir, const c
|
||||
|
||||
FS_InitMemory();
|
||||
|
||||
#ifdef XASH_ANDROID
|
||||
#if XASH_ANDROID_ASSETS
|
||||
FS_InitAndroid();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -383,7 +383,9 @@ static gl2wrap_prog_t *GL2_GetProg( const GLuint flags )
|
||||
{
|
||||
if( gl2wrap_config.vao_mandatory || gl2wrap_config.incremental )
|
||||
{
|
||||
for( int j = 0; j < gl2wrap_config.cycle_buffers; j++ )
|
||||
int j;
|
||||
|
||||
for( j = 0; j < gl2wrap_config.cycle_buffers; j++ )
|
||||
{
|
||||
pglBindVertexArray( prog->vao_begin[j] );
|
||||
pglEnableVertexAttribArrayARB( prog->attridx[i] );
|
||||
@@ -472,12 +474,14 @@ static void GL2_InitTriQuads( void )
|
||||
|
||||
static void GL2_InitIncrementalBuffer( int i, GLuint size )
|
||||
{
|
||||
int j;
|
||||
|
||||
gl2wrap.attrbufobj[i] = Mem_Calloc( r_temppool, gl2wrap_config.cycle_buffers * sizeof( GLuint ));
|
||||
if( gl2wrap_config.buf_storage )
|
||||
gl2wrap.mappings[i] = Mem_Calloc( r_temppool, gl2wrap_config.cycle_buffers * sizeof( void * ));
|
||||
pglGenBuffersARB( gl2wrap_config.cycle_buffers, gl2wrap.attrbufobj[i] );
|
||||
|
||||
for( int j = 0; j < gl2wrap_config.cycle_buffers; j++ )
|
||||
for( j = 0; j < gl2wrap_config.cycle_buffers; j++ )
|
||||
{
|
||||
rpglBindBufferARB( GL_ARRAY_BUFFER_ARB, gl2wrap.attrbufobj[i][j] );
|
||||
if( gl2wrap_config.buf_storage )
|
||||
@@ -628,7 +632,9 @@ int GL2_ShimInit( void )
|
||||
pglGenBuffersARB( gl2wrap_config.cycle_buffers, gl2wrap.attrbufobj[i] );
|
||||
if( gl2wrap_config.supports_mapbuffer )
|
||||
{
|
||||
for( int j = 0; j < gl2wrap_config.cycle_buffers; j++ )
|
||||
int j;
|
||||
|
||||
for( j = 0; j < gl2wrap_config.cycle_buffers; j++ )
|
||||
{
|
||||
rpglBindBufferARB( GL_ARRAY_BUFFER_ARB, gl2wrap.attrbufobj[i][j] );
|
||||
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, MAX_BEGINEND_VERTS, NULL, GL_STREAM_DRAW_ARB );
|
||||
@@ -1550,6 +1556,7 @@ static void GL2_SetupArrays( GLuint start, GLuint end )
|
||||
{
|
||||
gl2wrap_prog_t *prog;
|
||||
unsigned int flags = gl2wrap_arrays.flags;
|
||||
int i;
|
||||
|
||||
if( !flags )
|
||||
return; // Legacy pointers not used
|
||||
@@ -1573,7 +1580,7 @@ static void GL2_SetupArrays( GLuint start, GLuint end )
|
||||
pglBindVertexArray( gl2wrap_arrays.vao_dynamic );
|
||||
}
|
||||
|
||||
for( int i = 0; i < GL2_ATTR_MAX; i++ )
|
||||
for( i = 0; i < GL2_ATTR_MAX; i++ )
|
||||
{
|
||||
if( prog->attridx[i] < 0 )
|
||||
continue;
|
||||
|
||||
@@ -28,6 +28,10 @@ GNU General Public License for more details.
|
||||
#define XASH_GL_STATIC
|
||||
#define REF_GL_KEEP_MANGLED_FUNCTIONS
|
||||
#elif defined XASH_GLES3COMPAT
|
||||
#ifdef SOFTFP_LINK
|
||||
#undef APIENTRY
|
||||
#define APIENTRY __attribute__((pcs("aapcs")))
|
||||
#endif
|
||||
#define XASH_GLES
|
||||
#endif
|
||||
|
||||
|
||||
@@ -631,9 +631,12 @@ static void GL_SetTextureTarget( gl_texture_t *tex, rgbdata_t *pic )
|
||||
pic->numMips = Q_max( 1, pic->numMips );
|
||||
|
||||
// trying to determine texture type
|
||||
#ifndef XASH_GLES
|
||||
if( pic->width > 1 && pic->height <= 1 )
|
||||
tex->target = GL_TEXTURE_1D;
|
||||
else if( FBitSet( pic->flags, IMAGE_CUBEMAP ))
|
||||
else
|
||||
#endif // just skip first condition
|
||||
if( FBitSet( pic->flags, IMAGE_CUBEMAP ))
|
||||
tex->target = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
else if( FBitSet( pic->flags, IMAGE_MULTILAYER ) && pic->depth >= 1 )
|
||||
tex->target = GL_TEXTURE_2D_ARRAY_EXT;
|
||||
|
||||
@@ -780,6 +780,7 @@ extern convar_t r_traceglow;
|
||||
extern convar_t r_vbo;
|
||||
extern convar_t r_vbo_dlightmode;
|
||||
extern convar_t r_vbo_detail;
|
||||
extern convar_t r_vbo_overbrightmode;
|
||||
extern convar_t r_studio_sort_textures;
|
||||
extern convar_t r_studio_drawelements;
|
||||
extern convar_t r_ripple;
|
||||
|
||||
@@ -32,6 +32,7 @@ CVAR_DEFINE_AUTO( gl_round_down, "2", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "round tex
|
||||
CVAR_DEFINE( r_vbo, "gl_vbo", "0", FCVAR_ARCHIVE, "draw world using VBO (known to be glitchy)" );
|
||||
CVAR_DEFINE( r_vbo_detail, "gl_vbo_detail", "0", FCVAR_ARCHIVE, "detail vbo mode (0: disable, 1: multipass, 2: singlepass, broken decal dlights)" );
|
||||
CVAR_DEFINE( r_vbo_dlightmode, "gl_vbo_dlightmode", "1", FCVAR_ARCHIVE, "vbo dlight rendering mode (0-1)" );
|
||||
CVAR_DEFINE( r_vbo_overbrightmode, "gl_vbo_overbrightmode", "0", FCVAR_ARCHIVE, "vbo overbright rendering mode (0-1)" );
|
||||
CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water texture ripple simulation" );
|
||||
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
|
||||
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
|
||||
@@ -1248,6 +1249,7 @@ static void R_CheckVBO( void )
|
||||
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_dlightmode );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
|
||||
}
|
||||
|
||||
|
||||
@@ -1011,10 +1011,11 @@ static void R_CheckGamma( void )
|
||||
ClearBits( gl_overbright.flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
if( gl_overbright.value && FBitSet( r_vbo.flags, FCVAR_CHANGED ))
|
||||
if( gl_overbright.value && ( FBitSet( r_vbo.flags, FCVAR_CHANGED ) || FBitSet( r_vbo_overbrightmode.flags, FCVAR_CHANGED ) ) )
|
||||
{
|
||||
rebuild = true;
|
||||
ClearBits( r_vbo.flags, FCVAR_CHANGED );
|
||||
ClearBits( r_vbo_overbrightmode.flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
if( rebuild )
|
||||
|
||||
@@ -718,7 +718,7 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride, qboolean
|
||||
tmax = ( info->lightextents[1] / sample_size ) + 1;
|
||||
size = smax * tmax;
|
||||
if( gl_overbright.value )
|
||||
lightscale = r_vbo.value ? 171 : 256;
|
||||
lightscale = (r_vbo.value && !r_vbo_overbrightmode.value) ? 171 : 256;
|
||||
else lightscale = ( pow( 2.0f, 1.0f / v_lightgamma->value ) * 256 ) + 0.5;
|
||||
|
||||
lm = surf->samples;
|
||||
@@ -927,7 +927,8 @@ static void R_BlendLightmaps( void )
|
||||
if( gl_overbright.value )
|
||||
{
|
||||
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
|
||||
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
|
||||
if(!( r_vbo.value && !r_vbo_overbrightmode.value ))
|
||||
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2189,15 +2190,30 @@ static void R_SetLightmap( void )
|
||||
|
||||
if( gl_overbright.value )
|
||||
{
|
||||
// GLfloat color[4] = { 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f };
|
||||
if( r_vbo_overbrightmode.value == 1 )
|
||||
{
|
||||
GLfloat color[4] = { 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f };
|
||||
int tmu = glState.activeTMU;
|
||||
GL_SelectTexture( tmu - 1 );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_CONSTANT_ARB );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
|
||||
// doesn't work here for some reason
|
||||
pglTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
|
||||
GL_SelectTexture( tmu );
|
||||
}
|
||||
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2 );
|
||||
// doesn't work here for some reason
|
||||
// pglTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ R_SpriteLoadFrame
|
||||
upload a single frame
|
||||
====================
|
||||
*/
|
||||
static const dframetype_t *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
|
||||
static const byte *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
|
||||
{
|
||||
dspriteframe_t pinframe;
|
||||
mspriteframe_t *pspriteframe;
|
||||
@@ -82,7 +82,7 @@ static const dframetype_t *R_SpriteLoadFrame( model_t *mod, const void *pin, msp
|
||||
pspriteframe->gl_texturenum = gl_texturenum;
|
||||
*ppframe = pspriteframe;
|
||||
|
||||
return ( const dframetype_t* )(( const byte* )pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
|
||||
return (( const byte* )pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -92,7 +92,7 @@ R_SpriteLoadGroup
|
||||
upload a group frames
|
||||
====================
|
||||
*/
|
||||
static const dframetype_t *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
|
||||
static const byte *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
|
||||
{
|
||||
const dspritegroup_t *pingroup;
|
||||
mspritegroup_t *pspritegroup;
|
||||
@@ -128,9 +128,10 @@ static const dframetype_t *R_SpriteLoadGroup( model_t *mod, const void *pin, msp
|
||||
ptemp = R_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
|
||||
}
|
||||
|
||||
return (const dframetype_t *)ptemp;
|
||||
return ptemp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
Mod_LoadSpriteModel
|
||||
@@ -142,7 +143,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
{
|
||||
const dsprite_t *pin;
|
||||
const short *numi = NULL;
|
||||
const dframetype_t *pframetype;
|
||||
const byte *pframetype;
|
||||
msprite_t *psprite;
|
||||
int i;
|
||||
|
||||
@@ -152,7 +153,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
|
||||
numi = NULL;
|
||||
else if( pin->version == SPRITE_VERSION_HL )
|
||||
numi = (const short *)(void *)((const byte*)buffer + sizeof( dsprite_hl_t ));
|
||||
numi = (const short *)((const byte*)buffer + sizeof( dsprite_hl_t ));
|
||||
|
||||
r_texFlags = texFlags;
|
||||
sprite_version = pin->version;
|
||||
@@ -164,7 +165,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
rgbdata_t *pal;
|
||||
|
||||
pal = gEngfuncs.FS_LoadImage( "#id.pal", (byte *)&i, 768 );
|
||||
pframetype = (const dframetype_t *)(void *)((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
|
||||
pframetype = ((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
|
||||
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
|
||||
}
|
||||
else if( *numi == 256 )
|
||||
@@ -186,7 +187,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
break;
|
||||
}
|
||||
|
||||
pframetype = (const dframetype_t *)(void *)(src + 768);
|
||||
pframetype = (const byte *)(src + 768);
|
||||
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
|
||||
}
|
||||
else
|
||||
@@ -200,22 +201,26 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
|
||||
for( i = 0; i < mod->numframes; i++ )
|
||||
{
|
||||
frametype_t frametype = pframetype->type;
|
||||
frametype_t frametype;
|
||||
dframetype_t dframetype;
|
||||
|
||||
memcpy( &dframetype, pframetype, sizeof( dframetype ));
|
||||
frametype = dframetype.type;
|
||||
psprite->frames[i].type = (spriteframetype_t)frametype;
|
||||
|
||||
switch( frametype )
|
||||
{
|
||||
case FRAME_SINGLE:
|
||||
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
|
||||
pframetype = R_SpriteLoadFrame( mod, pframetype + 1, &psprite->frames[i].frameptr, i );
|
||||
pframetype = R_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
|
||||
break;
|
||||
case FRAME_GROUP:
|
||||
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + 1, &psprite->frames[i].frameptr, i );
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
|
||||
break;
|
||||
case FRAME_ANGLED:
|
||||
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + 1, &psprite->frames[i].frameptr, i );
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
|
||||
break;
|
||||
}
|
||||
if( pframetype == NULL ) break; // technically an error
|
||||
|
||||
@@ -968,6 +968,7 @@ void R_UploadRipples( texture_t *image )
|
||||
gl_texture_t *glt;
|
||||
uint32_t *pixels;
|
||||
int wbits, wmask, wshft;
|
||||
int y;
|
||||
|
||||
// discard unuseful textures
|
||||
if( !r_ripple.value || image->width > RIPPLES_CACHEWIDTH || image->width != image->height )
|
||||
@@ -1005,11 +1006,12 @@ void R_UploadRipples( texture_t *image )
|
||||
wshft = 7 - wbits;
|
||||
wmask = image->width - 1;
|
||||
|
||||
for( int y = 0; y < image->height; y++ )
|
||||
for( y = 0; y < image->height; y++ )
|
||||
{
|
||||
int ry = y << ( 7 + wshft );
|
||||
int x;
|
||||
|
||||
for( int x = 0; x < image->width; x++ )
|
||||
for( x = 0; x < image->width; x++ )
|
||||
{
|
||||
int rx = x << wshft;
|
||||
int val = g_ripple.curbuf[ry + rx] >> 4;
|
||||
|
||||
@@ -95,7 +95,11 @@ static void R_DrawStretchPicImplementation( int x, int y, int w, int h, int s1,
|
||||
//gEngfuncs.Con_Printf ("pixels is %p\n", pic->pixels[0] );
|
||||
|
||||
height = h;
|
||||
if (y < 0)
|
||||
|
||||
if( y < -h ) // out of display, out of bounds
|
||||
return;
|
||||
|
||||
if( y < 0 )
|
||||
{
|
||||
skip = -y;
|
||||
height += y;
|
||||
|
||||
@@ -46,7 +46,7 @@ R_SpriteLoadFrame
|
||||
upload a single frame
|
||||
====================
|
||||
*/
|
||||
static const dframetype_t *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
|
||||
static const byte *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
|
||||
{
|
||||
dspriteframe_t pinframe;
|
||||
mspriteframe_t *pspriteframe;
|
||||
@@ -82,7 +82,7 @@ static const dframetype_t *R_SpriteLoadFrame( model_t *mod, const void *pin, msp
|
||||
pspriteframe->gl_texturenum = gl_texturenum;
|
||||
*ppframe = pspriteframe;
|
||||
|
||||
return ( const dframetype_t* )(( const byte* )pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
|
||||
return ( const byte* )(( const byte* )pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -92,7 +92,7 @@ R_SpriteLoadGroup
|
||||
upload a group frames
|
||||
====================
|
||||
*/
|
||||
static const dframetype_t *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
|
||||
static const void *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
|
||||
{
|
||||
const dspritegroup_t *pingroup;
|
||||
mspritegroup_t *pspritegroup;
|
||||
@@ -128,7 +128,7 @@ static const dframetype_t *R_SpriteLoadGroup( model_t *mod, const void *pin, msp
|
||||
ptemp = R_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
|
||||
}
|
||||
|
||||
return (const dframetype_t *)ptemp;
|
||||
return ptemp;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -142,7 +142,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
{
|
||||
const dsprite_t *pin;
|
||||
const short *numi = NULL;
|
||||
const dframetype_t *pframetype;
|
||||
const byte *pframetype;
|
||||
msprite_t *psprite;
|
||||
int i;
|
||||
|
||||
@@ -164,7 +164,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
rgbdata_t *pal;
|
||||
|
||||
pal = gEngfuncs.FS_LoadImage( "#id.pal", (byte *)&i, 768 );
|
||||
pframetype = (const dframetype_t *)((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
|
||||
pframetype = ((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
|
||||
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
|
||||
}
|
||||
else if( *numi == 256 )
|
||||
@@ -186,7 +186,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
break;
|
||||
}
|
||||
|
||||
pframetype = (const dframetype_t *)(src + 768);
|
||||
pframetype = (const byte *)(src + 768);
|
||||
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
|
||||
}
|
||||
else
|
||||
@@ -200,22 +200,26 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
|
||||
|
||||
for( i = 0; i < mod->numframes; i++ )
|
||||
{
|
||||
frametype_t frametype = pframetype->type;
|
||||
frametype_t frametype;
|
||||
dframetype_t dframetype;
|
||||
|
||||
memcpy( &dframetype, pframetype, sizeof( dframetype ));
|
||||
frametype = dframetype.type;
|
||||
psprite->frames[i].type = (spriteframetype_t)frametype;
|
||||
|
||||
switch( frametype )
|
||||
{
|
||||
case FRAME_SINGLE:
|
||||
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
|
||||
pframetype = R_SpriteLoadFrame( mod, pframetype + 1, &psprite->frames[i].frameptr, i );
|
||||
pframetype = R_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
|
||||
break;
|
||||
case FRAME_GROUP:
|
||||
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + 1, &psprite->frames[i].frameptr, i );
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
|
||||
break;
|
||||
case FRAME_ANGLED:
|
||||
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + 1, &psprite->frames[i].frameptr, i );
|
||||
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
|
||||
break;
|
||||
}
|
||||
if( pframetype == NULL ) break; // technically an error
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -64,6 +64,7 @@ CFLAGS = {
|
||||
'msvc': ['/O2', '/Oy', '/Zi'],
|
||||
'gcc': {
|
||||
'3': ['-O3', '-fomit-frame-pointer'],
|
||||
'4': ['-Ofast', '-funsafe-math-optimizations', '-funsafe-loop-optimizations', '-fomit-frame-pointer'],
|
||||
'default': ['-Ofast', '-funsafe-math-optimizations', '-funsafe-loop-optimizations', '-fomit-frame-pointer', '-fno-semantic-interposition']
|
||||
},
|
||||
'clang': ['-Ofast'],
|
||||
@@ -78,7 +79,11 @@ CFLAGS = {
|
||||
'humanrights': {
|
||||
'msvc': ['/O2', '/Zi'],
|
||||
'owcc': ['-O3', '-foptimize-sibling-calls', '-fomit-leaf-frame-pointer', '-fomit-frame-pointer', '-fschedule-insns', '-funsafe-math-optimizations', '-funroll-loops', '-frerun-optimizer', '-finline-functions', '-finline-limit=512', '-fguess-branch-probability', '-fno-strict-aliasing', '-floop-optimize'],
|
||||
'gcc': ['-O3', '-fno-semantic-interposition'],
|
||||
'gcc': {
|
||||
'4': ['-O3'],
|
||||
'3': ['-O3'],
|
||||
'default': ['-O3','-fno-semantic-interposition'],
|
||||
},
|
||||
'default': ['-O3']
|
||||
},
|
||||
'debug': {
|
||||
@@ -116,6 +121,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 +149,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 +171,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 +203,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:
|
||||
|
||||
@@ -601,6 +601,12 @@ void WriteQCScript( void )
|
||||
fputs( "$scale 1.0\n", fp );
|
||||
fputs( "\n", fp );
|
||||
|
||||
if( model_hdr->flags & STUDIO_HAS_BONEINFO )
|
||||
{
|
||||
if( model_hdr->flags & STUDIO_HAS_BONEWEIGHTS )
|
||||
fputs( "$boneweights\n\n", fp );
|
||||
}
|
||||
|
||||
WriteBodyGroupInfo( fp );
|
||||
|
||||
fprintf( fp, "$flags %u\n\n", model_hdr->flags &~( STUDIO_HAS_BONEINFO | STUDIO_HAS_BONEWEIGHTS ) );
|
||||
@@ -611,10 +617,6 @@ void WriteQCScript( void )
|
||||
|
||||
WriteSkinFamilyInfo( fp );
|
||||
WriteTextureRenderMode( fp );
|
||||
|
||||
if( model_hdr->flags & ( STUDIO_HAS_BONEINFO | STUDIO_HAS_BONEWEIGHTS ) )
|
||||
fputs( "$boneweights\n\n", fp );
|
||||
|
||||
WriteAttachmentInfo( fp );
|
||||
|
||||
fprintf( fp, "$bbox %f %f %f", model_hdr->min[0], model_hdr->min[1], model_hdr->min[2] );
|
||||
|
||||
2
wscript
2
wscript
@@ -197,7 +197,7 @@ def configure(conf):
|
||||
if conf.env.DEST_OS == 'android':
|
||||
conf.options.NO_VGUI = True # skip vgui
|
||||
conf.options.NANOGL = True
|
||||
conf.options.GLWES = True
|
||||
conf.options.GLWES = False # deprecated
|
||||
conf.options.GL4ES = True
|
||||
conf.options.GLES3COMPAT = True
|
||||
conf.options.GL = False
|
||||
|
||||
Reference in New Issue
Block a user