mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
Compare commits
35 Commits
continuous
...
litwater
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b6b372cfe | ||
|
|
2f31cf315c | ||
|
|
910cce56ca | ||
|
|
68dba8b4e0 | ||
|
|
dbfeacfecc | ||
|
|
0bdd4648bc | ||
|
|
ec8059173d | ||
|
|
f91e5a7647 | ||
|
|
7942d9b1bc | ||
|
|
7abf0c819f | ||
|
|
85eb82a370 | ||
|
|
90e25cc623 | ||
|
|
fca4152d5a | ||
|
|
2ccef63754 | ||
|
|
87615784b9 | ||
|
|
d3b01d313b | ||
|
|
a3897f402a | ||
|
|
21d84ee692 | ||
|
|
e30ce9c150 | ||
|
|
22391eba1b | ||
|
|
800725453a | ||
|
|
22ecec095e | ||
|
|
8545ed5ccb | ||
|
|
a4fdf19ad8 | ||
|
|
75e4a21d7a | ||
|
|
1099344a7d | ||
|
|
ab1eaed0a5 | ||
|
|
76a01d0855 | ||
|
|
b00679ee30 | ||
|
|
b3bb2fc16f | ||
|
|
86a2ea29e4 | ||
|
|
d4f8543556 | ||
|
|
e850728016 | ||
|
|
11877f4c96 | ||
|
|
2ba5030b62 |
2
3rdparty/extras/xash-extras
vendored
2
3rdparty/extras/xash-extras
vendored
Submodule 3rdparty/extras/xash-extras updated: 0c83a63d00...6d2457f66f
14
3rdparty/libbacktrace/wscript
vendored
14
3rdparty/libbacktrace/wscript
vendored
@@ -20,10 +20,10 @@ int main (void) {
|
||||
}'''
|
||||
|
||||
FRAGMENT_GETPAGESIZE='''#include <unistd.h>
|
||||
int main(void) { return getpagesize() }'''
|
||||
int main(void) { return getpagesize(); }'''
|
||||
|
||||
FRAGMENT_GETEXECNAME='''#include <stdlib.h>
|
||||
int main(void) { return getexecname() != 0 }'''
|
||||
int main(void) { return getexecname() != 0; }'''
|
||||
|
||||
FRAGMENT_STRNLEN='''#include <string.h>
|
||||
int main(int argc, char **argv) { return (int)strnlen(argv[0], 10); }'''
|
||||
@@ -120,8 +120,8 @@ def configure(conf):
|
||||
check_frag(FRAGMENT_SYNC, ' __sync extensions', 'HAVE_SYNC_FUNCTIONS'),
|
||||
check_frag(FRAGMENT_GETPAGESIZE, ' getpagesize function', 'HAVE_DECL_GETPAGESIZE'),
|
||||
check_frag(FRAGMENT_STRNLEN, ' strnlen function', 'HAVE_DECL_STRNLEN'),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'link.h', ' dl_iterate_phdr function in link.h', 'HAVE_DL_ITERATE_PHDR', after_tests=['link.h']),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', ' dl_iterate_phdr function in sys/link.h', 'HAVE_DL_ITERATE_PHDR', after_tests=['sys/link.h']),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'link.h', ' dl_iterate_phdr function in link.h', 'HAVE_DL_ITERATE_PHDR_LINK_H', after_tests=['link.h']),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', ' dl_iterate_phdr function in sys/link.h', 'HAVE_DL_ITERATE_PHDR_SYS_LINK_H', after_tests=['sys/link.h']),
|
||||
check_frag(FRAGMENT_FCNTL, 'fnctl function', 'HAVE_FCNTL'),
|
||||
check_frag(FRAGMENT_GETEXECNAME, 'getexecname function','HAVE_GETEXECNAME'),
|
||||
check_frag(FRAGMENT_GETIPINFO, '_Unwind_GetIPInfo function', 'HAVE_GETIPINFO'),
|
||||
@@ -137,6 +137,9 @@ def configure(conf):
|
||||
msg='Checking for in parallel'
|
||||
)
|
||||
|
||||
if conf.is_defined('HAVE_DL_ITERATE_PHDR_LINK_H') or conf.is_defined('HAVE_DL_ITERATE_PHDR_SYS_LINK_H'):
|
||||
conf.define('HAVE_DL_ITERATE_PHDR', 1)
|
||||
|
||||
conf.env[DEFKEYS].sort()
|
||||
|
||||
conf.write_config_header()
|
||||
@@ -181,7 +184,8 @@ def build(bld):
|
||||
|
||||
task = bld.stlib(
|
||||
source = ['libbacktrace/' + i for i in sources],
|
||||
target = 'backtrace',
|
||||
# while we're using upstream libbacktrace, sometimes compiler picks up it's own version that isn't built with required options
|
||||
target = 'backtrace_custom',
|
||||
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
|
||||
use = 'EXTRAFLAGS lzma z zstd',
|
||||
includes = '. libbacktrace/',
|
||||
|
||||
2
3rdparty/library_suffix
vendored
2
3rdparty/library_suffix
vendored
Submodule 3rdparty/library_suffix updated: 6e14ae31e8...2cb2a0e120
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: 6ce9a37f4b...e236a942e7
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: 36219aedfc...e021fb5e7f
19
Documentation/extensions/litwater.md
Normal file
19
Documentation/extensions/litwater.md
Normal file
@@ -0,0 +1,19 @@
|
||||
## Lightmapped water
|
||||
|
||||
Xash3D FWGS supports lightmapped water, as an extension. It adds three new cvars and new worldspawn key values.
|
||||
|
||||
### For level designers:
|
||||
|
||||
If you're a level designer and intend to make your level to have lightmapped water, you can put these keyvalues to worldspawn entity description (always first entity in entities list):
|
||||
|
||||
| Key | Value | Description |
|
||||
| ---------------------- | ------- | ----------- |
|
||||
| `_litwater` | integer | Set to any non-zero value to enable lightmapped water. Overrides `gl_litwater_force` cvar value. |
|
||||
| `_litwater_minlight` | integer | Minimal lightmap value water surface will receive. Helps to avoid too dark areas when water isn't properly lit. If not set, defaults to zero. |
|
||||
| `_litwater_scale` | float | Scales up lightmap value for water surfaces. If not set, defaults to 1.0. |
|
||||
|
||||
### For players:
|
||||
|
||||
Some of the maps already have computed lightmap for water surfaces and sometimes water has been properly lit but the support hasn't been declared by the level designer.
|
||||
|
||||
As a player, you can enable it in `Video options` menu or through console with `gl_litwater_force` cvar. There are also `gl_litwater_minlight` and `gl_litwater_scale` cvars that function similar to keys above. The default values has been set to `192` and `1.25` respectively to slightly avoid issues with maps that wasn't intended to have lightmapped water.
|
||||
@@ -87,6 +87,7 @@ typedef enum
|
||||
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
|
||||
IL_KTX2_RAW = BIT(8), // renderer can consume raw KTX2 files (e.g. ref_vk)
|
||||
IL_ALLOW_WAD3_LUMA = BIT(9), // allow usage of luma textures in wad3 (tilde textures)
|
||||
IL_HOST_ENDIAN = BIT(10), // buffer is already in host endian, skip byte-swapping
|
||||
} ilFlags_t;
|
||||
|
||||
// goes into rgbdata_t->encode
|
||||
|
||||
@@ -243,7 +243,10 @@ typedef int qboolean;
|
||||
#define Swap32Store( x ) ( x = Swap32( x ))
|
||||
#define Swap16Store( x ) ( x = Swap16( x ))
|
||||
|
||||
#ifdef XASH_BIG_ENDIAN
|
||||
#define LittleFourCC( a, b, c, d ) (((uint32_t)( d ) << 24 ) | ((uint32_t)( c ) << 16 ) | ((uint32_t)( b ) << 8 ) | (uint32_t)( a ))
|
||||
#define BigFourCC( a, b, c, d ) (((uint32_t)( a ) << 24 ) | ((uint32_t)( b ) << 16 ) | ((uint32_t)( c ) << 8 ) | (uint32_t)( d ))
|
||||
|
||||
#if XASH_BIG_ENDIAN
|
||||
#define LittleLong( x ) Swap32( x )
|
||||
#define LittleShort( x ) Swap16( x )
|
||||
#define LittleLongSW( x ) Swap32Store( x )
|
||||
@@ -252,6 +255,7 @@ typedef int qboolean;
|
||||
#define BigLong( x ) ( x )
|
||||
#define BigShort( x ) ( x )
|
||||
#define BigFloat( x ) ( x )
|
||||
#define HostFourCC( a, b, c, d ) BigFourCC( a, b, c, d )
|
||||
#else
|
||||
#define LittleLong( x ) ( x )
|
||||
#define LittleShort( x ) ( x )
|
||||
@@ -261,6 +265,7 @@ typedef int qboolean;
|
||||
#define BigLong( x ) Swap32( x )
|
||||
#define BigShort( x ) Swap16( x )
|
||||
#define BigFloat( x ) SwapFloat( x )
|
||||
#define HostFourCC( a, b, c, d ) LittleFourCC( a, b, c, d )
|
||||
#endif
|
||||
|
||||
#endif // XASH_TYPES_H
|
||||
|
||||
@@ -17,6 +17,20 @@ GNU General Public License for more details.
|
||||
#include "filesystem.h"
|
||||
#include "client.h"
|
||||
#include "qfont.h"
|
||||
#include "swaplib.h"
|
||||
|
||||
le_struct_begin( charinfo_swap )
|
||||
le_struct_field( charinfo, startoffset )
|
||||
le_struct_field( charinfo, charwidth )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( qfont_swap )
|
||||
le_struct_field( qfont_t, width )
|
||||
le_struct_field( qfont_t, height )
|
||||
le_struct_field( qfont_t, rowcount )
|
||||
le_struct_field( qfont_t, rowheight )
|
||||
le_struct_array_child( qfont_t, fontinfo, charinfo_swap, NUM_GLYPHS )
|
||||
le_struct_end();
|
||||
|
||||
qboolean CL_FixedFont( cl_font_t *font )
|
||||
{
|
||||
@@ -130,6 +144,7 @@ qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float
|
||||
}
|
||||
|
||||
memcpy( &src, pfile, sizeof( src ));
|
||||
le_struct_swap( qfont_swap, &src );
|
||||
Mem_Free( pfile );
|
||||
|
||||
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
|
||||
|
||||
@@ -2583,7 +2583,7 @@ static void CL_ServerList( netadr_t from, sizebuf_t *msg )
|
||||
MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP
|
||||
NET_NetadrSetType( &servadr, NA_IP );
|
||||
}
|
||||
servadr.port = MSG_ReadShort( msg ); // 2 bytes for Port
|
||||
MSG_ReadBytes( msg, &servadr.port, sizeof( servadr.port )); // 2 bytes for Port, in network byte order
|
||||
|
||||
// list is ends here
|
||||
if( !servadr.port )
|
||||
|
||||
@@ -505,9 +505,9 @@ static void R_CreateBuiltinTextures( void )
|
||||
for( int x = 0; x < 16; x++ )
|
||||
{
|
||||
if(( y < 8 ) ^ ( x < 8 ))
|
||||
data16x16[y * 16 + x] = 0xFFFF00FF;
|
||||
data16x16[y * 16 + x] = HostFourCC( 255, 0, 255, 255 );
|
||||
else
|
||||
data16x16[y * 16 + x] = 0xFF000000;
|
||||
data16x16[y * 16 + x] = HostFourCC( 0, 0, 0, 255 );
|
||||
}
|
||||
}
|
||||
ref.dllFuncs.GL_CreateTexture( REF_DEFAULT_TEXTURE, 16, 16, data16x16, 0 );
|
||||
@@ -517,7 +517,7 @@ static void R_CreateBuiltinTextures( void )
|
||||
for( int y = 0; y < 8; y++ )
|
||||
{
|
||||
for( int x = 0; x < 8; x++ )
|
||||
particle[y * 8 + x] = 0x00FFFFFF; // fill it with invisible white
|
||||
particle[y * 8 + x] = HostFourCC( 255, 255, 255, 0 ); // fill it with invisible white
|
||||
}
|
||||
|
||||
// a1ba: moved one pixel down and to the right to make it look better with linear interpolation
|
||||
@@ -530,7 +530,7 @@ static void R_CreateBuiltinTextures( void )
|
||||
if(( x == corner || x == 3 + corner ) && ( y == corner || y == 3 + corner ))
|
||||
continue;
|
||||
|
||||
particle[y * 8 + x] = 0xFFFFFFFF;
|
||||
particle[y * 8 + x] = HostFourCC( 255, 255, 255, 255 );
|
||||
}
|
||||
}
|
||||
ref.dllFuncs.GL_CreateTexture( REF_PARTICLE_TEXTURE, 8, 8, particle, TF_CLAMP|TF_HAS_ALPHA );
|
||||
@@ -541,11 +541,11 @@ static void R_CreateBuiltinTextures( void )
|
||||
ref.dllFuncs.GL_CreateTexture( REF_WHITE_TEXTURE, 4, 4, data4x4, 0 );
|
||||
|
||||
for( int x = 0; x < 16; x++ )
|
||||
data4x4[x] = 0xFF7F7F7F;
|
||||
data4x4[x] = HostFourCC( 127, 127, 127, 255 );
|
||||
ref.dllFuncs.GL_CreateTexture( REF_GRAY_TEXTURE, 4, 4, data4x4, 0 );
|
||||
|
||||
for( int x = 0; x < 16; x++ )
|
||||
data4x4[x] = 0xFF000000;
|
||||
data4x4[x] = HostFourCC( 0, 0, 0, 255 );
|
||||
ref.dllFuncs.GL_CreateTexture( REF_BLACK_TEXTURE, 4, 4, data4x4, 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -403,11 +403,11 @@ static qboolean VOX_ParseWordParams( char *psz, voxword_t *pvoxword, voxword_t *
|
||||
|
||||
command = *psz++;
|
||||
|
||||
if( !isdigit( *psz ))
|
||||
if( !isdigit((byte)*psz ))
|
||||
break;
|
||||
|
||||
memset( sznum, 0, sizeof( sznum ));
|
||||
for( i = 0; i < sizeof( sznum ) - 1 && isdigit( *psz ); i++, psz++ )
|
||||
for( i = 0; i < sizeof( sznum ) - 1 && isdigit((byte)*psz ); i++, psz++ )
|
||||
sznum[i] = *psz;
|
||||
|
||||
i = Q_atoi( sznum );
|
||||
|
||||
@@ -157,7 +157,7 @@ qboolean Sound_LoadOggVorbis( const char *name, const byte *buffer, fs_offset_t
|
||||
SetBits( sound.flags, SOUND_RESAMPLE );
|
||||
Sound_ScanVorbisComments( &vorbisFile );
|
||||
|
||||
while(( ret = ov_read( &vorbisFile, (char *)sound.wav + written, sound.size - written, 0, sound.width, 1, §ion )) != 0 )
|
||||
while(( ret = ov_read( &vorbisFile, (char *)sound.wav + written, sound.size - written, XASH_BIG_ENDIAN, sound.width, 1, §ion )) != 0 )
|
||||
{
|
||||
if( ret < 0 )
|
||||
{
|
||||
@@ -232,7 +232,7 @@ int Stream_ReadOggVorbis( stream_t *stream, int needBytes, void *buffer )
|
||||
|
||||
if( !stream->buffsize )
|
||||
{
|
||||
stream->pos = ov_read( &ctx->vf, (char *)stream->temp, OUTBUF_SIZE, 0, stream->width, 1, §ion );
|
||||
stream->pos = ov_read( &ctx->vf, (char *)stream->temp, OUTBUF_SIZE, XASH_BIG_ENDIAN, stream->width, 1, §ion );
|
||||
if( stream->pos == 0 )
|
||||
{
|
||||
break; // end of file
|
||||
|
||||
@@ -152,6 +152,8 @@ static qboolean StreamFindNextChunk( file_t *file, const char *name, int *last_c
|
||||
if( FS_Read( file, &iff_chunk_len, sizeof( iff_chunk_len )) != sizeof( iff_chunk_len ))
|
||||
return false;
|
||||
|
||||
iff_chunk_len = LittleLong( iff_chunk_len );
|
||||
|
||||
if( iff_chunk_len < 0 )
|
||||
return false; // didn't find the chunk
|
||||
|
||||
@@ -317,6 +319,15 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
memcpy( sound.wav, buffer + (iff_dataPtr - buffer), sound.size );
|
||||
|
||||
// swap 16-bit samples from little endian to native
|
||||
if( sound.width == 2 )
|
||||
{
|
||||
short *p = (short *)sound.wav;
|
||||
int count = sound.size / 2;
|
||||
for( int i = 0; i < count; i++ )
|
||||
p[i] = LittleShort( p[i] );
|
||||
}
|
||||
|
||||
// now convert 8-bit sounds to signed
|
||||
if( sound.width == 1 )
|
||||
{
|
||||
@@ -394,6 +405,7 @@ stream_t *Stream_OpenWAV( const char *filename )
|
||||
FS_Read( file, chunkName, 4 );
|
||||
|
||||
FS_Read( file, &t, sizeof( t ));
|
||||
t = LittleShort( t );
|
||||
if( t != 1 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: %s not a microsoft PCM format\n", __func__, filename );
|
||||
@@ -402,14 +414,15 @@ stream_t *Stream_OpenWAV( const char *filename )
|
||||
}
|
||||
|
||||
FS_Read( file, &t, sizeof( t ));
|
||||
sound.channels = t;
|
||||
sound.channels = LittleShort( t );
|
||||
|
||||
FS_Read( file, &sound.rate, sizeof( int ));
|
||||
sound.rate = LittleLong( sound.rate );
|
||||
|
||||
FS_Seek( file, 6, SEEK_CUR );
|
||||
|
||||
FS_Read( file, &t, sizeof( t ));
|
||||
sound.width = t / 8;
|
||||
sound.width = LittleShort( t ) / 8;
|
||||
|
||||
sound.loopstart = 0;
|
||||
|
||||
@@ -423,7 +436,7 @@ stream_t *Stream_OpenWAV( const char *filename )
|
||||
}
|
||||
|
||||
FS_Read( file, &sound.samples, sizeof( int ));
|
||||
sound.samples = ( sound.samples / sound.width ) / sound.channels;
|
||||
sound.samples = ( LittleLong( sound.samples ) / sound.width ) / sound.channels;
|
||||
|
||||
// at this point we have valid stream
|
||||
stream = Mem_Calloc( host.soundpool, sizeof( stream_t ));
|
||||
@@ -458,6 +471,14 @@ int Stream_ReadWAV( stream_t *stream, int bytes, void *buffer )
|
||||
stream->pos += bytes;
|
||||
FS_Read( stream->file, buffer, bytes );
|
||||
|
||||
if( stream->width == 2 )
|
||||
{
|
||||
short *p = (short *)buffer;
|
||||
int count = bytes / 2;
|
||||
for( int i = 0; i < count; i++ )
|
||||
p[i] = LittleShort( p[i] );
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -833,7 +833,7 @@ static uint32_t Host_CheckBugcomp( void )
|
||||
if( !Sys_CheckParm( "-bugcomp" ))
|
||||
return 0;
|
||||
|
||||
if( Sys_GetParmFromCmdLine( "-bugcomp", args ) && isalpha( args[0] ))
|
||||
if( Sys_GetParmFromCmdLine( "-bugcomp", args ) && isalpha((byte)args[0] ))
|
||||
{
|
||||
Q_splitstr( args, '+', &flags, Host_CheckBugcomp_splitstr_handler );
|
||||
}
|
||||
|
||||
@@ -16,6 +16,24 @@ GNU General Public License for more details.
|
||||
#include "imagelib.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "img_bmp.h"
|
||||
#include "swaplib.h"
|
||||
|
||||
le_struct_begin( bmp_swap )
|
||||
le_struct_field( bmp_t, fileSize )
|
||||
le_struct_field( bmp_t, reserved0 )
|
||||
le_struct_field( bmp_t, bitmapDataOffset )
|
||||
le_struct_field( bmp_t, bitmapHeaderSize )
|
||||
le_struct_field( bmp_t, width )
|
||||
le_struct_field( bmp_t, height )
|
||||
le_struct_field( bmp_t, planes )
|
||||
le_struct_field( bmp_t, bitsPerPixel )
|
||||
le_struct_field( bmp_t, compression )
|
||||
le_struct_field( bmp_t, bitmapDataSize )
|
||||
le_struct_field( bmp_t, hRes )
|
||||
le_struct_field( bmp_t, vRes )
|
||||
le_struct_field( bmp_t, colors )
|
||||
le_struct_field( bmp_t, importantColors )
|
||||
le_struct_end();
|
||||
|
||||
/*
|
||||
=============
|
||||
@@ -41,6 +59,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
buf_p = (byte *)buffer;
|
||||
memcpy( &bhdr, buf_p, sizeof( bmp_t ));
|
||||
le_struct_swap( bmp_swap, &bhdr );
|
||||
buf_p += BI_FILE_HEADER_SIZE + bhdr.bitmapHeaderSize;
|
||||
|
||||
// bogus file header check
|
||||
@@ -282,7 +301,8 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
shortPixel = *(word *)buf_p, buf_p += 2;
|
||||
shortPixel = buf_p[0] | (buf_p[1] << 8);
|
||||
buf_p += 2;
|
||||
*pixbuf++ = blue = (shortPixel & ( 31 << 10 )) >> 7;
|
||||
*pixbuf++ = green = (shortPixel & ( 31 << 5 )) >> 2;
|
||||
*pixbuf++ = red = (shortPixel & ( 31 )) << 3;
|
||||
@@ -396,7 +416,9 @@ qboolean Image_SaveBMP( const char *name, rgbdata_t *pix )
|
||||
hdr.colors = ( pixel_size == 1 ) ? 256 : 0;
|
||||
hdr.importantColors = 0;
|
||||
|
||||
le_struct_swap( bmp_swap, &hdr );
|
||||
FS_Write( pfile, &hdr, sizeof( bmp_t ));
|
||||
le_struct_swap( bmp_swap, &hdr );
|
||||
|
||||
pbBmpBits = Mem_Malloc( host.imagepool, cbBmpBits );
|
||||
|
||||
|
||||
@@ -16,6 +16,49 @@ GNU General Public License for more details.
|
||||
#include "imagelib.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "img_dds.h"
|
||||
#include "swaplib.h"
|
||||
|
||||
le_struct_begin( dds_pixf_swap )
|
||||
le_struct_field( dds_pixf_t, dwSize )
|
||||
le_struct_field( dds_pixf_t, dwFlags )
|
||||
le_struct_field( dds_pixf_t, dwFourCC )
|
||||
le_struct_field( dds_pixf_t, dwRGBBitCount )
|
||||
le_struct_field( dds_pixf_t, dwRBitMask )
|
||||
le_struct_field( dds_pixf_t, dwGBitMask )
|
||||
le_struct_field( dds_pixf_t, dwBBitMask )
|
||||
le_struct_field( dds_pixf_t, dwABitMask )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( dds_caps_swap )
|
||||
le_struct_field( dds_caps_t, dwCaps1 )
|
||||
le_struct_field( dds_caps_t, dwCaps2 )
|
||||
le_struct_field( dds_caps_t, dwCaps3 )
|
||||
le_struct_field( dds_caps_t, dwCaps4 )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( dds_swap )
|
||||
le_struct_field( dds_t, dwIdent )
|
||||
le_struct_field( dds_t, dwSize )
|
||||
le_struct_field( dds_t, dwFlags )
|
||||
le_struct_field( dds_t, dwHeight )
|
||||
le_struct_field( dds_t, dwWidth )
|
||||
le_struct_field( dds_t, dwLinearSize )
|
||||
le_struct_field( dds_t, dwDepth )
|
||||
le_struct_field( dds_t, dwMipMapCount )
|
||||
le_struct_field( dds_t, dwAlphaBitDepth )
|
||||
le_struct_array( dds_t, dwReserved1, 10 )
|
||||
le_struct_child( dds_t, dsPixelFormat, dds_pixf_swap )
|
||||
le_struct_child( dds_t, dsCaps, dds_caps_swap )
|
||||
le_struct_field( dds_t, dwTextureStage )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( dds_dxt10_swap )
|
||||
le_struct_field( dds_header_dxt10_t, dxgiFormat )
|
||||
le_struct_field( dds_header_dxt10_t, resourceDimension )
|
||||
le_struct_field( dds_header_dxt10_t, miscFlag )
|
||||
le_struct_field( dds_header_dxt10_t, arraySize )
|
||||
le_struct_field( dds_header_dxt10_t, miscFlags2 )
|
||||
le_struct_end();
|
||||
|
||||
static qboolean Image_CheckDXT3Alpha( dds_t *hdr, byte *fin )
|
||||
{
|
||||
@@ -295,6 +338,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
|
||||
memcpy( &header, buffer, sizeof( header ));
|
||||
le_struct_swap( dds_swap, &header );
|
||||
|
||||
if( header.dwIdent != DDSHEADER )
|
||||
return false; // it's not a dds file, just skip it
|
||||
@@ -315,6 +359,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
if( header.dsPixelFormat.dwFourCC == TYPE_DX10 )
|
||||
{
|
||||
memcpy( &header2, buffer + sizeof( header ), sizeof( header2 ));
|
||||
le_struct_swap( dds_dxt10_swap, &header2 );
|
||||
headersOffset += sizeof( header2 );
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,34 @@ GNU General Public License for more details.
|
||||
#include "imagelib.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "img_ktx2.h"
|
||||
#include "swaplib.h"
|
||||
|
||||
le_struct_begin( ktx2_header_swap )
|
||||
le_struct_field( ktx2_header_t, vkFormat )
|
||||
le_struct_field( ktx2_header_t, typeSize )
|
||||
le_struct_field( ktx2_header_t, pixelWidth )
|
||||
le_struct_field( ktx2_header_t, pixelHeight )
|
||||
le_struct_field( ktx2_header_t, pixelDepth )
|
||||
le_struct_field( ktx2_header_t, layerCount )
|
||||
le_struct_field( ktx2_header_t, faceCount )
|
||||
le_struct_field( ktx2_header_t, levelCount )
|
||||
le_struct_field( ktx2_header_t, supercompressionScheme )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( ktx2_index_swap )
|
||||
le_struct_field( ktx2_index_t, dfdByteOffset )
|
||||
le_struct_field( ktx2_index_t, dfdByteLength )
|
||||
le_struct_field( ktx2_index_t, kvdByteOffset )
|
||||
le_struct_field( ktx2_index_t, kvdByteLength )
|
||||
le_struct_field( ktx2_index_t, sgdByteOffset )
|
||||
le_struct_field( ktx2_index_t, sgdByteLength )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( ktx2_level_swap )
|
||||
le_struct_field( ktx2_level_t, byteOffset )
|
||||
le_struct_field( ktx2_level_t, byteLength )
|
||||
le_struct_field( ktx2_level_t, uncompressedByteLength )
|
||||
le_struct_end();
|
||||
|
||||
static void Image_KTX2Format( uint32_t ktx2_format )
|
||||
{
|
||||
@@ -125,6 +153,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 ));
|
||||
le_struct_swap( ktx2_index_swap, &index );
|
||||
|
||||
for( mip = 0; mip < header->levelCount; ++mip )
|
||||
{
|
||||
@@ -134,6 +163,7 @@ static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer
|
||||
|
||||
ktx2_level_t level;
|
||||
memcpy( &level, levels_begin + mip * sizeof( level ), sizeof( level ));
|
||||
le_struct_swap( ktx2_level_swap, &level );
|
||||
|
||||
if( mip_size != level.byteLength )
|
||||
{
|
||||
@@ -159,6 +189,7 @@ static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer
|
||||
{
|
||||
ktx2_level_t level;
|
||||
memcpy( &level, levels_begin + mip * sizeof( level ), sizeof( level ));
|
||||
le_struct_swap( ktx2_level_swap, &level );
|
||||
memcpy( image.rgba + cursor, buffer + level.byteOffset, level.byteLength );
|
||||
cursor += level.byteLength;
|
||||
}
|
||||
@@ -180,6 +211,7 @@ qboolean Image_LoadKTX2( const char *name, const byte *buffer, fs_offset_t files
|
||||
}
|
||||
|
||||
memcpy( &header, buffer + KTX2_IDENTIFIER_SIZE, sizeof( header ));
|
||||
le_struct_swap( ktx2_header_swap, &header );
|
||||
|
||||
image.width = header.pixelWidth;
|
||||
image.height = header.pixelHeight;
|
||||
|
||||
@@ -16,6 +16,16 @@ GNU General Public License for more details.
|
||||
#include "imagelib.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "img_tga.h"
|
||||
#include "swaplib.h"
|
||||
|
||||
le_struct_begin( tga_swap )
|
||||
le_struct_field( tga_t, colormap_index )
|
||||
le_struct_field( tga_t, colormap_length )
|
||||
le_struct_field( tga_t, x_origin )
|
||||
le_struct_field( tga_t, y_origin )
|
||||
le_struct_field( tga_t, width )
|
||||
le_struct_field( tga_t, height )
|
||||
le_struct_end();
|
||||
|
||||
/*
|
||||
=============
|
||||
@@ -44,10 +54,10 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
targa_header.colormap_index = buf_p[0] + buf_p[1] * 256; buf_p += 2;
|
||||
targa_header.colormap_length = buf_p[0] + buf_p[1] * 256; buf_p += 2;
|
||||
targa_header.colormap_size = *buf_p; buf_p += 1;
|
||||
targa_header.x_origin = *(short *)buf_p; buf_p += 2;
|
||||
targa_header.y_origin = *(short *)buf_p; buf_p += 2;
|
||||
targa_header.width = image.width = *(short *)buf_p; buf_p += 2;
|
||||
targa_header.height = image.height = *(short *)buf_p; buf_p += 2;
|
||||
targa_header.x_origin = buf_p[0] + buf_p[1] * 256; buf_p += 2;
|
||||
targa_header.y_origin = buf_p[0] + buf_p[1] * 256; buf_p += 2;
|
||||
targa_header.width = image.width = buf_p[0] + buf_p[1] * 256; buf_p += 2;
|
||||
targa_header.height = image.height = buf_p[0] + buf_p[1] * 256; buf_p += 2;
|
||||
targa_header.pixel_size = *buf_p++;
|
||||
targa_header.attributes = *buf_p++;
|
||||
if( targa_header.id_length != 0 ) buf_p += targa_header.id_length; // skip TARGA image comment
|
||||
@@ -284,6 +294,7 @@ qboolean Image_SaveTGA( const char *name, rgbdata_t *pix )
|
||||
|
||||
out = buffer;
|
||||
|
||||
le_struct_swap( tga_swap, &targa_header );
|
||||
memcpy( out, &targa_header, sizeof( tga_t ) );
|
||||
out += sizeof( tga_t );
|
||||
|
||||
|
||||
@@ -285,66 +285,34 @@ int Image_ComparePalette( const byte *pal )
|
||||
|
||||
static void Image_SetPalette( const byte *pal, uint *d_table )
|
||||
{
|
||||
byte rgba[4];
|
||||
uint uirgba; // TODO: palette looks byte-swapped on big-endian
|
||||
int i;
|
||||
|
||||
// setup palette
|
||||
switch( image.d_rendermode )
|
||||
{
|
||||
case LUMP_NORMAL:
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
memcpy( rgba, &pal[i * 3], 3 );
|
||||
rgba[3] = 0xFF;
|
||||
memcpy( &uirgba, rgba, sizeof( uirgba ));
|
||||
d_table[i] = uirgba;
|
||||
}
|
||||
for( int i = 0; i < 256; i++ )
|
||||
d_table[i] = HostFourCC( pal[i * 3 + 0], pal[i * 3 + 1], pal[i * 3 + 2], 0xFF );
|
||||
break;
|
||||
case LUMP_TEXGAMMA:
|
||||
for( i = 0; i < 256; i++ )
|
||||
for( int i = 0; i < 256; i++ )
|
||||
{
|
||||
rgba[0] = TextureToGamma( pal[i * 3 + 0] );
|
||||
rgba[1] = TextureToGamma( pal[i * 3 + 1] );
|
||||
rgba[2] = TextureToGamma( pal[i * 3 + 2] );
|
||||
rgba[3] = 0xFF;
|
||||
memcpy( &uirgba, rgba, sizeof( uirgba ));
|
||||
d_table[i] = uirgba;
|
||||
d_table[i] = HostFourCC(
|
||||
TextureToGamma( pal[i * 3 + 0] ),
|
||||
TextureToGamma( pal[i * 3 + 1] ),
|
||||
TextureToGamma( pal[i * 3 + 2] ),
|
||||
0xFF );
|
||||
}
|
||||
break;
|
||||
case LUMP_GRADIENT:
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
rgba[0] = pal[765];
|
||||
rgba[1] = pal[766];
|
||||
rgba[2] = pal[767];
|
||||
rgba[3] = i;
|
||||
memcpy( &uirgba, rgba, sizeof( uirgba ));
|
||||
d_table[i] = uirgba;
|
||||
}
|
||||
for( int i = 0; i < 256; i++ )
|
||||
d_table[i] = HostFourCC( pal[765], pal[766], pal[767], i );
|
||||
break;
|
||||
case LUMP_MASKED:
|
||||
for( i = 0; i < 255; i++ )
|
||||
{
|
||||
rgba[0] = pal[i*3+0];
|
||||
rgba[1] = pal[i*3+1];
|
||||
rgba[2] = pal[i*3+2];
|
||||
rgba[3] = 0xFF;
|
||||
memcpy( &uirgba, rgba, sizeof( uirgba ));
|
||||
d_table[i] = uirgba;
|
||||
}
|
||||
for( int i = 0; i < 255; i++ )
|
||||
d_table[i] = HostFourCC( pal[i * 3 + 0], pal[i * 3 + 1], pal[i * 3 + 2], 0xFF );
|
||||
d_table[255] = 0;
|
||||
break;
|
||||
case LUMP_EXTENDED:
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
rgba[0] = pal[i*4+0];
|
||||
rgba[1] = pal[i*4+1];
|
||||
rgba[2] = pal[i*4+2];
|
||||
rgba[3] = pal[i*4+3];
|
||||
memcpy( &uirgba, rgba, sizeof( uirgba ));
|
||||
d_table[i] = uirgba;
|
||||
}
|
||||
for( int i = 0; i < 256; i++ )
|
||||
d_table[i] = HostFourCC( pal[i * 4 + 0], pal[i * 4 + 1], pal[i * 4 + 2], pal[i * 4 + 3] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,43 @@ GNU General Public License for more details.
|
||||
#include "studio.h"
|
||||
#include "sprite.h"
|
||||
#include "qfont.h"
|
||||
#include "swaplib.h"
|
||||
|
||||
le_struct_begin( charinfo_swap )
|
||||
le_struct_field( charinfo, startoffset )
|
||||
le_struct_field( charinfo, charwidth )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( qfont_swap )
|
||||
le_struct_field( qfont_t, width )
|
||||
le_struct_field( qfont_t, height )
|
||||
le_struct_field( qfont_t, rowcount )
|
||||
le_struct_field( qfont_t, rowheight )
|
||||
le_struct_array_child( qfont_t, fontinfo, charinfo_swap, NUM_GLYPHS )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( lmp_swap )
|
||||
le_struct_field( lmp_t, width )
|
||||
le_struct_field( lmp_t, height )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( mip_swap )
|
||||
le_struct_field( mip_t, width )
|
||||
le_struct_field( mip_t, height )
|
||||
le_struct_array( mip_t, offsets, 4 )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( dwadinfo_swap )
|
||||
le_struct_field( dwadinfo_t, ident )
|
||||
le_struct_field( dwadinfo_t, numlumps )
|
||||
le_struct_field( dwadinfo_t, infotableofs )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( dlumpinfo_swap )
|
||||
le_struct_field( dlumpinfo_t, filepos )
|
||||
le_struct_field( dlumpinfo_t, disksize )
|
||||
le_struct_field( dlumpinfo_t, size )
|
||||
le_struct_end();
|
||||
|
||||
/*
|
||||
============
|
||||
@@ -98,6 +135,7 @@ qboolean Image_LoadFNT( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
|
||||
memcpy( &font, buffer, sizeof( font ));
|
||||
le_struct_swap( qfont_swap, &font );
|
||||
|
||||
// last sixty four bytes - what the hell ????
|
||||
size = sizeof( qfont_t ) - 4 + ( font.height * font.width * QCHAR_WIDTH ) + sizeof( short ) + 768 + 64;
|
||||
@@ -120,7 +158,8 @@ qboolean Image_LoadFNT( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
fin = buffer + sizeof( font ) - 4;
|
||||
pal = fin + (image.width * image.height);
|
||||
numcolors = *(short *)pal, pal += sizeof( short );
|
||||
numcolors = pal[0] | (pal[1] << 8);
|
||||
pal += sizeof( short );
|
||||
|
||||
if( numcolors == 768 || numcolors == 256 )
|
||||
{
|
||||
@@ -305,6 +344,7 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
{
|
||||
fin = (byte *)buffer;
|
||||
memcpy( &lmp, fin, sizeof( lmp ));
|
||||
le_struct_swap( lmp_swap, &lmp );
|
||||
image.width = lmp.width;
|
||||
image.height = lmp.height;
|
||||
rendermode = LUMP_NORMAL;
|
||||
@@ -337,7 +377,7 @@ qboolean Image_LoadLMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
}
|
||||
}
|
||||
pal = fin + pixels;
|
||||
numcolors = *(short *)pal;
|
||||
numcolors = pal[0] | (pal[1] << 8);
|
||||
if( numcolors != 256 ) pal = NULL; // corrupted lump ?
|
||||
else pal += sizeof( short );
|
||||
}
|
||||
@@ -397,6 +437,8 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
|
||||
memcpy( &mip, buffer, sizeof( mip ));
|
||||
if( !Image_CheckFlag( IL_HOST_ENDIAN ))
|
||||
le_struct_swap( mip_swap, &mip );
|
||||
image.width = mip.width;
|
||||
image.height = mip.height;
|
||||
|
||||
@@ -411,7 +453,7 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// half-life 1.0.0.1 mip version with palette
|
||||
fin = (byte *)buffer + mip.offsets[0];
|
||||
pal = (byte *)buffer + mip.offsets[0] + (((image.width * image.height) * 85)>>6);
|
||||
numcolors = *(short *)pal;
|
||||
numcolors = pal[0] | (pal[1] << 8);
|
||||
if( numcolors != 256 ) pal = NULL; // corrupted mip ?
|
||||
else pal += sizeof( short ); // skip colorsize
|
||||
|
||||
@@ -472,7 +514,7 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// three checks here: check if we can load luma, check the texture name and, finally,
|
||||
// validate that palette isn't NULL
|
||||
if( Image_CheckFlag( IL_ALLOW_WAD3_LUMA )
|
||||
&& ( mip.name[0] == '~' || ( mip.name[0] == '+' && isdigit( mip.name[1] ) && mip.name[2] == '~' ))
|
||||
&& ( mip.name[0] == '~' || ( mip.name[0] == '+' && isdigit((byte)mip.name[1] ) && mip.name[2] == '~' ))
|
||||
&& pal != NULL )
|
||||
{
|
||||
SetBits( image.flags, IMAGE_HAS_LUMA );
|
||||
@@ -596,24 +638,23 @@ Image_LoadWAD
|
||||
*/
|
||||
qboolean Image_LoadWAD( const char *name, const byte *buffer, fs_offset_t filesize )
|
||||
{
|
||||
const dwadinfo_t *header;
|
||||
const dlumpinfo_t *lumps;
|
||||
dwadinfo_t whdr;
|
||||
const unsigned char *mipdata;
|
||||
int i, j;
|
||||
|
||||
if( !buffer || filesize < sizeof( dwadinfo_t ))
|
||||
return false;
|
||||
|
||||
header = (const dwadinfo_t *)buffer;
|
||||
if( header->numlumps <= 0 || header->infotableofs <= 0 || header->infotableofs >= (int)filesize )
|
||||
memcpy( &whdr, buffer, sizeof( whdr ));
|
||||
le_struct_swap( dwadinfo_swap, &whdr );
|
||||
if( whdr.numlumps <= 0 || whdr.infotableofs <= 0 || whdr.infotableofs >= (int)filesize )
|
||||
return false;
|
||||
|
||||
lumps = (const dlumpinfo_t *)((const unsigned char *)buffer + header->infotableofs );
|
||||
|
||||
for( i = 0; i < header->numlumps; ++i )
|
||||
for( i = 0; i < whdr.numlumps; ++i )
|
||||
{
|
||||
const unsigned char *pixels, *palette, *use_palette;
|
||||
unsigned char grad_palette[256 * 3];
|
||||
dlumpinfo_t lump;
|
||||
int mip_size;
|
||||
mip_t mip;
|
||||
uint32_t width, height, offset0;
|
||||
@@ -623,16 +664,20 @@ qboolean Image_LoadWAD( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
float t;
|
||||
byte idx;
|
||||
|
||||
if( lumps[i].type != TYP_MIPTEX && lumps[i].type != TYP_PALETTE )
|
||||
memcpy( &lump, buffer + whdr.infotableofs + i * sizeof( dlumpinfo_t ), sizeof( lump ));
|
||||
le_struct_swap( dlumpinfo_swap, &lump );
|
||||
|
||||
if( lump.type != TYP_MIPTEX && lump.type != TYP_PALETTE )
|
||||
continue;
|
||||
|
||||
// get lump data and validate
|
||||
mipdata = (const unsigned char *)buffer + lumps[i].filepos;
|
||||
mip_size = lumps[i].disksize;
|
||||
if( lumps[i].filepos < 0 || lumps[i].filepos + mip_size > (int)filesize )
|
||||
mipdata = (const unsigned char *)buffer + lump.filepos;
|
||||
mip_size = lump.disksize;
|
||||
if( lump.filepos < 0 || lump.filepos + mip_size > (int)filesize )
|
||||
continue;
|
||||
|
||||
memcpy( &mip, mipdata, sizeof( mip ));
|
||||
le_struct_swap( mip_swap, &mip );
|
||||
width = mip.width;
|
||||
height = mip.height;
|
||||
|
||||
@@ -652,7 +697,7 @@ qboolean Image_LoadWAD( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
use_palette = palette;
|
||||
|
||||
// handle gradient palette
|
||||
if( lumps[i].type == TYP_PALETTE )
|
||||
if( lump.type == TYP_PALETTE )
|
||||
{
|
||||
// gradient palette
|
||||
const unsigned char *frontColorPtr = palette + 255 * 3;
|
||||
@@ -755,12 +800,16 @@ qboolean Image_SaveWAD( const char *name, rgbdata_t *pix )
|
||||
header.ident = IDWAD3HEADER;
|
||||
header.numlumps = 1;
|
||||
|
||||
le_struct_swap( dwadinfo_swap, &header );
|
||||
FS_Write( f, &header, sizeof( header ));
|
||||
le_struct_swap( mip_swap, &miptex );
|
||||
FS_Write( f, &miptex, sizeof( mip_t ));
|
||||
le_struct_swap( mip_swap, &miptex );
|
||||
FS_Write( f, pix->buffer, m0size );
|
||||
FS_Write( f, mip1_data, m1size );
|
||||
FS_Write( f, mip2_data, m2size );
|
||||
FS_Write( f, mip3_data, m3size );
|
||||
palette_size = LittleShort( palette_size );
|
||||
FS_Write( f, &palette_size, sizeof( short ));
|
||||
|
||||
if( lump_type == TYP_PALETTE )
|
||||
@@ -793,10 +842,11 @@ qboolean Image_SaveWAD( const char *name, rgbdata_t *pix )
|
||||
lump.type = (char)lump_type;
|
||||
lump.attribs = 0;
|
||||
Q_strncpy( lump.name, "tempdecal", sizeof( lump.name ));
|
||||
le_struct_swap( dlumpinfo_swap, &lump );
|
||||
FS_Write( f, &lump, sizeof( lump ));
|
||||
|
||||
FS_Seek( f, offsetof( dwadinfo_t, infotableofs ), SEEK_SET );
|
||||
infotableofs32 = (int)infotableofs;
|
||||
infotableofs32 = LittleLong((int)infotableofs );
|
||||
FS_Write( f, &infotableofs32, sizeof( int ));
|
||||
|
||||
FS_Close( f );
|
||||
|
||||
@@ -327,7 +327,7 @@ static char *COM_GetItaniumName( const char * const in_name )
|
||||
{
|
||||
// parse symbol length marker
|
||||
len = 0;
|
||||
for( ; isdigit( *f ) && remaining > 0; f++, remaining-- )
|
||||
for( ; isdigit((byte)*f ) && remaining > 0; f++, remaining-- )
|
||||
len = len * 10 + ( *f - '0' );
|
||||
|
||||
// sane value
|
||||
@@ -344,7 +344,7 @@ static char *COM_GetItaniumName( const char * const in_name )
|
||||
if( *f == 'E' )
|
||||
break;
|
||||
|
||||
if( !isdigit( *f ) || remaining <= 0 )
|
||||
if( !isdigit((byte)*f ) || remaining <= 0 )
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,32 +166,32 @@ typedef enum
|
||||
LOADLUMP_BSPX, // ... from BSPX data
|
||||
} loadlump_source_t;
|
||||
|
||||
#define LUMP_SAVESTATS BIT( 0 )
|
||||
#define LUMP_TESTONLY BIT( 1 )
|
||||
#define LUMP_SILENT BIT( 2 )
|
||||
#define LUMP_BSP30EXT BIT( 3 ) // extra marker for Mod_LoadLump
|
||||
#define LUMP_BSPX BIT( 4 )
|
||||
#define LUMP_SAVESTATS BIT( 0 )
|
||||
#define LUMP_BSHIFT_SWAP BIT( 1 )
|
||||
#define LUMP_SILENT BIT( 2 )
|
||||
#define LUMP_BSP30EXT BIT( 3 ) // extra marker for Mod_LoadLump
|
||||
#define LUMP_BSPX BIT( 4 )
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int lumpnumber;
|
||||
const int lumpnumber;
|
||||
|
||||
// BSPX
|
||||
const char lumpname[24];
|
||||
|
||||
int flags;
|
||||
const int flags;
|
||||
const size_t mincount;
|
||||
const size_t maxcount;
|
||||
const int entrysize;
|
||||
const int entrysize32; // extended size (0 if not available)
|
||||
const char *loadname;
|
||||
const void **dataptr;
|
||||
size_t *count;
|
||||
const size_t dataofs; // offsetof into dbspmodel_t for data pointer
|
||||
const size_t countofs; // offsetof into dbspmodel_t for count/size
|
||||
#if XASH_BIG_ENDIAN // do not waste memory on little endian
|
||||
const swap_struct_def_t *swap;
|
||||
size_t swaplen;
|
||||
const size_t swaplen;
|
||||
const swap_struct_def_t *swap32;
|
||||
size_t swaplen32;
|
||||
const size_t swaplen32;
|
||||
#endif
|
||||
} mlumpinfo_t;
|
||||
|
||||
@@ -344,11 +344,10 @@ le_struct_begin( mip_swap )
|
||||
le_struct_end();
|
||||
|
||||
world_static_t world;
|
||||
static dbspmodel_t srcmodel;
|
||||
static loadstat_t loadstat;
|
||||
static model_t *worldmodel;
|
||||
static byte g_visdata[(MAX_MAP_LEAFS+7)/8]; // intermediate buffer
|
||||
static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
static const mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
{
|
||||
{
|
||||
.lumpnumber = LUMP_ENTITIES,
|
||||
@@ -356,8 +355,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.maxcount = MAX_MAP_ENTSTRING,
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "entities",
|
||||
.dataptr = (const void **)&srcmodel.entdata,
|
||||
.count = &srcmodel.entdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, entdata ),
|
||||
.countofs = offsetof( dbspmodel_t, entdatasize ),
|
||||
},
|
||||
{
|
||||
.lumpnumber = LUMP_PLANES,
|
||||
@@ -365,8 +364,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.maxcount = MAX_MAP_PLANES,
|
||||
.entrysize = sizeof( dplane_t ),
|
||||
.loadname = "planes",
|
||||
.dataptr = (const void **)&srcmodel.planes,
|
||||
.count = &srcmodel.numplanes,
|
||||
.dataofs = offsetof( dbspmodel_t, planes ),
|
||||
.countofs = offsetof( dbspmodel_t, numplanes ),
|
||||
LUMP_SWAP( dplane_swap )
|
||||
},
|
||||
{
|
||||
@@ -375,16 +374,16 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.maxcount = MAX_MAP_MIPTEX,
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "textures",
|
||||
.dataptr = (const void **)&srcmodel.textures,
|
||||
.count = &srcmodel.texdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, textures ),
|
||||
.countofs = offsetof( dbspmodel_t, texdatasize ),
|
||||
},
|
||||
{
|
||||
.lumpnumber = LUMP_VERTEXES,
|
||||
.maxcount = MAX_MAP_VERTS,
|
||||
.entrysize = sizeof( dvertex_t ),
|
||||
.loadname = "vertexes",
|
||||
.dataptr = (const void **)&srcmodel.vertexes,
|
||||
.count = &srcmodel.numvertexes,
|
||||
.dataofs = offsetof( dbspmodel_t, vertexes ),
|
||||
.countofs = offsetof( dbspmodel_t, numvertexes ),
|
||||
LUMP_SWAP( dvertex_swap )
|
||||
},
|
||||
{
|
||||
@@ -392,8 +391,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.maxcount = MAX_MAP_VISIBILITY,
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "visibility",
|
||||
.dataptr = (const void **)&srcmodel.visdata,
|
||||
.count = &srcmodel.visdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, visdata ),
|
||||
.countofs = offsetof( dbspmodel_t, visdatasize ),
|
||||
},
|
||||
{
|
||||
.lumpnumber = LUMP_NODES,
|
||||
@@ -403,8 +402,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize32 = sizeof( dnode32_t ),
|
||||
.loadname = "nodes",
|
||||
.flags = CHECK_OVERFLOW,
|
||||
.dataptr = (const void **)&srcmodel.nodes,
|
||||
.count = &srcmodel.numnodes,
|
||||
.dataofs = offsetof( dbspmodel_t, nodes ),
|
||||
.countofs = offsetof( dbspmodel_t, numnodes ),
|
||||
LUMP_SWAP32( dnode_swap, dnode32_swap )
|
||||
},
|
||||
{
|
||||
@@ -414,8 +413,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize = sizeof( dtexinfo_t ),
|
||||
.loadname = "texinfo",
|
||||
.flags = CHECK_OVERFLOW,
|
||||
.dataptr = (const void **)&srcmodel.texinfo,
|
||||
.count = &srcmodel.numtexinfo,
|
||||
.dataofs = offsetof( dbspmodel_t, texinfo ),
|
||||
.countofs = offsetof( dbspmodel_t, numtexinfo ),
|
||||
LUMP_SWAP( dtexinfo_swap )
|
||||
},
|
||||
{
|
||||
@@ -426,8 +425,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize32 = sizeof( dface32_t ),
|
||||
.loadname = "faces",
|
||||
.flags = CHECK_OVERFLOW,
|
||||
.dataptr = (const void **)&srcmodel.surfaces,
|
||||
.count = &srcmodel.numsurfaces,
|
||||
.dataofs = offsetof( dbspmodel_t, surfaces ),
|
||||
.countofs = offsetof( dbspmodel_t, numsurfaces ),
|
||||
LUMP_SWAP32( dface_swap, dface32_swap )
|
||||
},
|
||||
{
|
||||
@@ -437,8 +436,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "lightmaps",
|
||||
.flags = 0,
|
||||
.dataptr = (const void **)&srcmodel.lightdata,
|
||||
.count = &srcmodel.lightdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, lightdata ),
|
||||
.countofs = offsetof( dbspmodel_t, lightdatasize ),
|
||||
},
|
||||
{
|
||||
.lumpnumber = LUMP_CLIPNODES,
|
||||
@@ -448,8 +447,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize32 = sizeof( dclipnode32_t ),
|
||||
.loadname = "clipnodes",
|
||||
.flags = 0,
|
||||
.dataptr = (const void **)&srcmodel.clipnodes,
|
||||
.count = &srcmodel.numclipnodes,
|
||||
.dataofs = offsetof( dbspmodel_t, clipnodes ),
|
||||
.countofs = offsetof( dbspmodel_t, numclipnodes ),
|
||||
LUMP_SWAP32( dclipnode_swap, dclipnode32_swap )
|
||||
},
|
||||
{
|
||||
@@ -460,8 +459,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize32 = sizeof( dleaf32_t ),
|
||||
.loadname = "leafs",
|
||||
.flags = CHECK_OVERFLOW,
|
||||
.dataptr = (const void **)&srcmodel.leafs,
|
||||
.count = &srcmodel.numleafs,
|
||||
.dataofs = offsetof( dbspmodel_t, leafs ),
|
||||
.countofs = offsetof( dbspmodel_t, numleafs ),
|
||||
LUMP_SWAP32( dleaf_swap, dleaf32_swap )
|
||||
},
|
||||
{
|
||||
@@ -472,8 +471,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize32 = sizeof( dmarkface32_t ),
|
||||
.loadname = "markfaces",
|
||||
.flags = 0,
|
||||
.dataptr = (const void **)&srcmodel.markfaces,
|
||||
.count = &srcmodel.nummarkfaces,
|
||||
.dataofs = offsetof( dbspmodel_t, markfaces ),
|
||||
.countofs = offsetof( dbspmodel_t, nummarkfaces ),
|
||||
},
|
||||
{
|
||||
.lumpnumber = LUMP_EDGES,
|
||||
@@ -483,8 +482,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize32 = sizeof( dedge32_t ),
|
||||
.loadname = "edges",
|
||||
.flags = 0,
|
||||
.dataptr = (const void **)&srcmodel.edges,
|
||||
.count = &srcmodel.numedges,
|
||||
.dataofs = offsetof( dbspmodel_t, edges ),
|
||||
.countofs = offsetof( dbspmodel_t, numedges ),
|
||||
LUMP_SWAP32( dedge_swap, dedge32_swap )
|
||||
},
|
||||
{
|
||||
@@ -494,8 +493,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize = sizeof( dsurfedge_t ),
|
||||
.loadname = "surfedges",
|
||||
.flags = 0,
|
||||
.dataptr = (const void **)&srcmodel.surfedges,
|
||||
.count = &srcmodel.numsurfedges,
|
||||
.dataofs = offsetof( dbspmodel_t, surfedges ),
|
||||
.countofs = offsetof( dbspmodel_t, numsurfedges ),
|
||||
},
|
||||
{
|
||||
.lumpnumber = LUMP_MODELS,
|
||||
@@ -504,8 +503,8 @@ static mlumpinfo_t srclumps[HEADER_LUMPS] =
|
||||
.entrysize = sizeof( dmodel_t ),
|
||||
.loadname = "models",
|
||||
.flags = CHECK_OVERFLOW,
|
||||
.dataptr = (const void **)&srcmodel.submodels,
|
||||
.count = &srcmodel.numsubmodels,
|
||||
.dataofs = offsetof( dbspmodel_t, submodels ),
|
||||
.countofs = offsetof( dbspmodel_t, numsubmodels ),
|
||||
LUMP_SWAP( dmodel_swap )
|
||||
},
|
||||
};
|
||||
@@ -518,8 +517,8 @@ static const mlumpinfo_t extlumps[EXTRA_LUMPS] =
|
||||
.maxcount = MAX_MAP_LIGHTING,
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "deluxmaps",
|
||||
.dataptr = (const void **)&srcmodel.deluxdata,
|
||||
.count = &srcmodel.deluxdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, deluxdata ),
|
||||
.countofs = offsetof( dbspmodel_t, deluxdatasize ),
|
||||
},
|
||||
{
|
||||
.lumpnumber = LUMP_FACEINFO,
|
||||
@@ -528,8 +527,8 @@ static const mlumpinfo_t extlumps[EXTRA_LUMPS] =
|
||||
.entrysize = sizeof( dfaceinfo_t ),
|
||||
.loadname = "faceinfos",
|
||||
.flags = CHECK_OVERFLOW,
|
||||
.dataptr = (const void **)&srcmodel.faceinfo,
|
||||
.count = &srcmodel.numfaceinfo,
|
||||
.dataofs = offsetof( dbspmodel_t, faceinfo ),
|
||||
.countofs = offsetof( dbspmodel_t, numfaceinfo ),
|
||||
LUMP_SWAP( dfaceinfo_swap )
|
||||
},
|
||||
{
|
||||
@@ -538,8 +537,8 @@ static const mlumpinfo_t extlumps[EXTRA_LUMPS] =
|
||||
.maxcount = MAX_MAP_LIGHTING / 3,
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "shadowmap",
|
||||
.dataptr = (const void **)&srcmodel.shadowdata,
|
||||
.count = &srcmodel.shadowdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, shadowdata ),
|
||||
.countofs = offsetof( dbspmodel_t, shadowdatasize ),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -550,16 +549,16 @@ static const mlumpinfo_t bspxlumps[] =
|
||||
.maxcount = MAX_MAP_LIGHTING,
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "rgblighting",
|
||||
.dataptr = (const void **)&srcmodel.rgblightdata,
|
||||
.count = &srcmodel.rgblightdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, rgblightdata ),
|
||||
.countofs = offsetof( dbspmodel_t, rgblightdatasize ),
|
||||
},
|
||||
{
|
||||
.lumpname = "LIGHTINGDIR",
|
||||
.maxcount = MAX_MAP_LIGHTING,
|
||||
.entrysize = sizeof( byte ),
|
||||
.loadname = "lightingdir",
|
||||
.dataptr = (const void **)&srcmodel.deluxdata,
|
||||
.count = &srcmodel.deluxdatasize,
|
||||
.dataofs = offsetof( dbspmodel_t, deluxdata ),
|
||||
.countofs = offsetof( dbspmodel_t, deluxdatasize ),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -758,7 +757,7 @@ Mod_LoadLump
|
||||
generic loader
|
||||
=================
|
||||
*/
|
||||
static void Mod_LoadLump( const void *in, const mlumpinfo_t *info, mlumpstat_t *stat, int flags, loadlump_source_t source, const void *bspx_data )
|
||||
static void Mod_LoadLump( const void *in, const mlumpinfo_t *info, mlumpstat_t *stat, int flags, loadlump_source_t source, const void *bspx_data, dbspmodel_t *bmod )
|
||||
{
|
||||
int version = ((const dheader_t *)in)->version, i;
|
||||
size_t numelems, real_entrysize;
|
||||
@@ -769,7 +768,16 @@ static void Mod_LoadLump( const void *in, const mlumpinfo_t *info, mlumpstat_t *
|
||||
case LOADLUMP_STANDARD:
|
||||
{
|
||||
const dheader_t *header = in;
|
||||
l = header->lumps[info->lumpnumber];
|
||||
int lumpnumber = info->lumpnumber;
|
||||
|
||||
if( FBitSet( flags, LUMP_BSHIFT_SWAP ))
|
||||
{
|
||||
if( lumpnumber == LUMP_ENTITIES )
|
||||
lumpnumber = LUMP_PLANES;
|
||||
else if( lumpnumber == LUMP_PLANES )
|
||||
lumpnumber = LUMP_ENTITIES;
|
||||
}
|
||||
l = header->lumps[lumpnumber];
|
||||
break;
|
||||
}
|
||||
case LOADLUMP_BSP30EXT:
|
||||
@@ -836,7 +844,7 @@ static void Mod_LoadLump( const void *in, const mlumpinfo_t *info, mlumpstat_t *
|
||||
}
|
||||
|
||||
// bmodels not required the visibility
|
||||
if( !FBitSet( flags, LUMP_TESTONLY ) && !world.loading && info->lumpnumber == LUMP_VISIBILITY )
|
||||
if( info->lumpnumber == LUMP_VISIBILITY && !world.loading && bmod )
|
||||
SetBits( flags, LUMP_SILENT ); // shut up warning
|
||||
|
||||
// fill the stats for world
|
||||
@@ -914,36 +922,31 @@ static void Mod_LoadLump( const void *in, const mlumpinfo_t *info, mlumpstat_t *
|
||||
}
|
||||
}
|
||||
|
||||
if( FBitSet( flags, LUMP_TESTONLY ))
|
||||
return; // don't fill the intermediate struct
|
||||
// if no bmod is passed, we are only testing if BSP lumps are not corrupted
|
||||
if( !bmod )
|
||||
return;
|
||||
|
||||
byte *data = (byte *)in + l.fileofs;
|
||||
|
||||
// all checks are passed, store pointers
|
||||
if( info->dataptr )
|
||||
*info->dataptr = (void *)((byte *)in + l.fileofs);
|
||||
|
||||
if( info->count )
|
||||
*info->count = numelems;
|
||||
*(byte **)((byte *)bmod + info->dataofs) = data;
|
||||
*(size_t *)((byte *)bmod + info->countofs) = numelems;
|
||||
|
||||
// finally, process the data
|
||||
#if XASH_BIG_ENDIAN
|
||||
const swap_struct_def_t *swap = real_entrysize == info->entrysize32 ? info->swap32 : info->swap;
|
||||
size_t swaplen = real_entrysize == info->entrysize32 ? info->swaplen32 : info->swaplen;
|
||||
|
||||
if( info->dataptr && *info->dataptr )
|
||||
if( swap )
|
||||
{
|
||||
byte *data = (byte *)*info->dataptr;
|
||||
|
||||
if( swap )
|
||||
{
|
||||
for( size_t j = 0; j < numelems; j++ )
|
||||
swap_struct_( swap, swaplen, data + j * real_entrysize );
|
||||
}
|
||||
// some lumps don't need a swapdef, as all needed data in the lump info
|
||||
else if( real_entrysize > 1 )
|
||||
{
|
||||
for( size_t j = 0; j < numelems; j++ )
|
||||
swap_field_( data + j * real_entrysize, real_entrysize );
|
||||
}
|
||||
for( size_t j = 0; j < numelems; j++ )
|
||||
swap_struct_( swap, swaplen, data + j * real_entrysize );
|
||||
}
|
||||
// some lumps don't need a swapdef, as all needed data in the lump info
|
||||
else if( real_entrysize > 1 )
|
||||
{
|
||||
for( size_t j = 0; j < numelems; j++ )
|
||||
swap_field_( data + j * real_entrysize, real_entrysize );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2404,6 +2407,9 @@ static void Mod_LoadEntities( model_t *mod, const dbspmodel_t *bmod )
|
||||
world.wadlist = NULL;
|
||||
world.wadcount = 0;
|
||||
|
||||
world.litwater_minlight = -1;
|
||||
world.litwater_scale = -1.0f;
|
||||
|
||||
// parse all the wads for loading textures in right ordering
|
||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||
{
|
||||
@@ -2447,6 +2453,15 @@ static void Mod_LoadEntities( model_t *mod, const dbspmodel_t *bmod )
|
||||
Mem_Free( world.generator );
|
||||
world.generator = copystring( token );
|
||||
}
|
||||
else if( !Q_stricmp( keyname, "_litwater" ))
|
||||
{
|
||||
if( Q_atoi( token ) != 0 )
|
||||
SetBits( world.flags, FWORLD_HAS_LITWATER );
|
||||
}
|
||||
else if( !Q_stricmp( keyname, "_litwater_minlight" ))
|
||||
world.litwater_minlight = Q_atoi( token );
|
||||
else if( !Q_stricmp( keyname, "_litwater_scale" ))
|
||||
world.litwater_scale = Q_atof( token );
|
||||
}
|
||||
return; // all done
|
||||
}
|
||||
@@ -2723,6 +2738,7 @@ static void Mod_InitSkyClouds( model_t *mod, const mip_t *mt, texture_t *tx, qbo
|
||||
if( custom_palette )
|
||||
size += sizeof( short ) + 768;
|
||||
|
||||
Image_SetForceFlags( IL_HOST_ENDIAN );
|
||||
r_sky = FS_LoadImage( texname, (byte *)mt, size );
|
||||
}
|
||||
else
|
||||
@@ -2905,7 +2921,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
const size_t size = Mod_CalculateMipTexSize( mipTex, usesCustomPalette );
|
||||
|
||||
Q_snprintf( texName, sizeof( texName ), "#%s:%s.mip", loadstat.name, mipTex->name );
|
||||
Image_SetForceFlags( texture_force_flags );
|
||||
Image_SetForceFlags( texture_force_flags | IL_HOST_ENDIAN );
|
||||
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texName, (byte *)mipTex, size, txFlags );
|
||||
}
|
||||
|
||||
@@ -2938,7 +2954,7 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
|
||||
Q_snprintf( texName, sizeof( texName ), "#%s:%s_luma.mip", loadstat.name, mipTex->name );
|
||||
|
||||
Image_SetForceFlags( texture_force_flags );
|
||||
Image_SetForceFlags( texture_force_flags | IL_HOST_ENDIAN );
|
||||
|
||||
if( mipTex->offsets[0] > 0 )
|
||||
{
|
||||
@@ -4227,14 +4243,12 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t buffer
|
||||
{
|
||||
dheader_t *header = (dheader_t *)mod_base;
|
||||
int *extident = (int *)(mod_base + sizeof( dheader_t ));
|
||||
dbspmodel_t *bmod = &srcmodel;
|
||||
char wadvalue[2048];
|
||||
size_t len = 0;
|
||||
int i, stat_index = 0, ret, flags = 0;
|
||||
fs_offset_t bspx_header_offset;
|
||||
|
||||
// always reset the intermediate struct
|
||||
memset( bmod, 0, sizeof( *bmod ));
|
||||
memset( &loadstat, 0, sizeof( loadstat ));
|
||||
|
||||
Q_strncpy( loadstat.name, mod->name, sizeof( loadstat.name ));
|
||||
@@ -4243,10 +4257,6 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t buffer
|
||||
// byte-swap BSP header and lump directory from little-endian
|
||||
Mod_SwapBSPLumps( mod_base, bufferlen );
|
||||
|
||||
// restore default lump numbers
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
|
||||
switch( header->version )
|
||||
{
|
||||
case HLBSP_VERSION:
|
||||
@@ -4259,8 +4269,7 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t buffer
|
||||
Mod_LumpLooksLikeEntities( mod_base + header->lumps[LUMP_PLANES].fileofs, header->lumps[LUMP_PLANES].filelen ))
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
SetBits( flags, LUMP_BSHIFT_SWAP );
|
||||
}
|
||||
break;
|
||||
case Q1BSP_VERSION:
|
||||
@@ -4274,6 +4283,7 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t buffer
|
||||
return false;
|
||||
}
|
||||
|
||||
dbspmodel_t *bmod = Mem_Calloc( mod->mempool, sizeof( *bmod ));
|
||||
bmod->version = header->version; // share up global
|
||||
if( isworld )
|
||||
{
|
||||
@@ -4286,17 +4296,17 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t buffer
|
||||
|
||||
// loading base lumps
|
||||
for( i = 0; i < ARRAYSIZE( srclumps ); i++, stat_index++ )
|
||||
Mod_LoadLump( mod_base, &srclumps[i], &worldstats[stat_index], flags, LOADLUMP_STANDARD, NULL );
|
||||
Mod_LoadLump( mod_base, &srclumps[i], &worldstats[stat_index], flags, LOADLUMP_STANDARD, NULL, bmod );
|
||||
|
||||
// loading extralumps
|
||||
for( i = 0; i < ARRAYSIZE( extlumps ); i++, stat_index++ )
|
||||
Mod_LoadLump( mod_base, &extlumps[i], &worldstats[stat_index], flags, LOADLUMP_BSP30EXT, NULL );
|
||||
Mod_LoadLump( mod_base, &extlumps[i], &worldstats[stat_index], flags, LOADLUMP_BSP30EXT, NULL, bmod );
|
||||
|
||||
// loading bspx lumps
|
||||
if( bspx_header_offset >= 0 )
|
||||
{
|
||||
for( i = 0; i < ARRAYSIZE( bspxlumps ); i++, stat_index++ )
|
||||
Mod_LoadLump( mod_base, &bspxlumps[i], &worldstats[stat_index], flags, LOADLUMP_BSPX, mod_base + bspx_header_offset );
|
||||
Mod_LoadLump( mod_base, &bspxlumps[i], &worldstats[stat_index], flags, LOADLUMP_BSPX, mod_base + bspx_header_offset, bmod );
|
||||
}
|
||||
|
||||
if( !bmod->isworld ) // a1ba: why world excluded here?
|
||||
@@ -4304,6 +4314,7 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t buffer
|
||||
if( loadstat.numerrors )
|
||||
{
|
||||
Con_DPrintf( "%s: %i error(s), %i warning(s)\n", __func__, loadstat.numerrors, loadstat.numwarnings );
|
||||
Mem_Free( bmod );
|
||||
return false; // there were errors, we can't load this map
|
||||
}
|
||||
|
||||
@@ -4368,6 +4379,7 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, byte *mod_base, size_t buffer
|
||||
Con_Reportf( "Wad files required to run the map: \"%s\"\n", wadvalue );
|
||||
}
|
||||
|
||||
Mem_Free( bmod );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4410,7 +4422,7 @@ qboolean Mod_TestBmodelLumps( file_t *f, const char *name, byte *mod_base, size_
|
||||
{
|
||||
dheader_t *header = (dheader_t *)mod_base;
|
||||
int *extident = (int *)( mod_base + sizeof( dheader_t ));
|
||||
int i, flags = LUMP_TESTONLY, stat_index = 0;
|
||||
int i, flags = 0, stat_index = 0;
|
||||
|
||||
// always reset the intermediate struct
|
||||
memset( &loadstat, 0, sizeof( loadstat_t ));
|
||||
@@ -4426,10 +4438,6 @@ qboolean Mod_TestBmodelLumps( file_t *f, const char *name, byte *mod_base, size_
|
||||
// byte-swap BSP header and lump directory from little-endian
|
||||
Mod_SwapBSPLumps( mod_base, buffersize );
|
||||
|
||||
// restore default lump numbers
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
|
||||
switch( header->version )
|
||||
{
|
||||
case HLBSP_VERSION:
|
||||
@@ -4451,11 +4459,7 @@ qboolean Mod_TestBmodelLumps( file_t *f, const char *name, byte *mod_base, size_
|
||||
return false;
|
||||
|
||||
if( ret )
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
}
|
||||
SetBits( flags, LUMP_BSHIFT_SWAP );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -4471,15 +4475,15 @@ qboolean Mod_TestBmodelLumps( file_t *f, const char *name, byte *mod_base, size_
|
||||
}
|
||||
|
||||
// get entities lump to caller
|
||||
*entities = header->lumps[srclumps[0].lumpnumber];
|
||||
*entities = header->lumps[FBitSet( flags, LUMP_BSHIFT_SWAP ) ? LUMP_PLANES : LUMP_ENTITIES];
|
||||
|
||||
// loading base lumps
|
||||
for( i = 0; i < ARRAYSIZE( srclumps ); i++, stat_index++ )
|
||||
Mod_LoadLump( mod_base, &srclumps[i], &worldstats[stat_index], flags, LOADLUMP_STANDARD, NULL );
|
||||
Mod_LoadLump( mod_base, &srclumps[i], &worldstats[stat_index], flags, LOADLUMP_STANDARD, NULL, NULL );
|
||||
|
||||
// loading extralumps
|
||||
for( i = 0; i < ARRAYSIZE( extlumps ); i++, stat_index++ )
|
||||
Mod_LoadLump( mod_base, &extlumps[i], &worldstats[stat_index], flags, LOADLUMP_BSP30EXT, NULL );
|
||||
Mod_LoadLump( mod_base, &extlumps[i], &worldstats[stat_index], flags, LOADLUMP_BSP30EXT, NULL, NULL );
|
||||
|
||||
// FIXME: BSPX testing
|
||||
|
||||
|
||||
@@ -124,6 +124,10 @@ typedef struct world_static_s
|
||||
|
||||
wadentry_t *wadlist;
|
||||
int wadcount;
|
||||
|
||||
// lightmapped water extra info
|
||||
float litwater_scale;
|
||||
int litwater_minlight;
|
||||
} world_static_t;
|
||||
|
||||
#ifndef REF_DLL
|
||||
@@ -191,6 +195,7 @@ void Mod_StudioGetAttachment( const edict_t *e, int iAttachment, float *org, flo
|
||||
void Mod_GetBonePosition( const edict_t *e, int iBone, float *org, float *ang );
|
||||
hull_t *Mod_HullForStudio( model_t *m, float frame, int seq, vec3_t ang, vec3_t org, vec3_t size, byte *pcnt, byte *pbl, int *hitboxes, edict_t *ed );
|
||||
void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc );
|
||||
void Mod_SwapStudioSeqGroupAnims( studiohdr_t *phdr, mstudioseqdesc_t *pseq, byte *buf );
|
||||
int Mod_HitgroupForStudioHull( int index );
|
||||
void Mod_ClearStudioCache( void );
|
||||
|
||||
|
||||
@@ -162,7 +162,6 @@ le_struct_begin( mstudioattachment_swap )
|
||||
le_struct_field( mstudioattachment_t, flags )
|
||||
le_struct_field( mstudioattachment_t, bone )
|
||||
le_struct_array( mstudioattachment_t, org, 3 )
|
||||
le_struct_array( mstudioattachment_t, vectors, 3 * 3 )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( mstudiobodyparts_swap )
|
||||
@@ -551,6 +550,38 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p
|
||||
}
|
||||
|
||||
|
||||
void Mod_SwapStudioSeqGroupAnims( studiohdr_t *phdr, mstudioseqdesc_t *pseq, byte *buf )
|
||||
{
|
||||
mstudioanim_t *panim = (mstudioanim_t *)( buf + pseq->animindex );
|
||||
int numanims = pseq->numblends * phdr->numbones;
|
||||
|
||||
for( int j = 0; j < numanims; j++, panim++ )
|
||||
{
|
||||
le_struct_swap( mstudioanim_swap, panim );
|
||||
|
||||
for( int k = 0; k < 6; k++ )
|
||||
{
|
||||
if( panim->offset[k] == 0 )
|
||||
continue;
|
||||
|
||||
mstudioanimvalue_t *panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[k] );
|
||||
|
||||
int frames = pseq->numframes;
|
||||
while( frames > 0 )
|
||||
{
|
||||
int valid = panimvalue->num.valid;
|
||||
int total = panimvalue->num.total;
|
||||
|
||||
for( int l = 1; l <= valid; l++ )
|
||||
panimvalue[l].value = LittleShort( panimvalue[l].value );
|
||||
|
||||
panimvalue += valid + 1;
|
||||
frames -= total;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
StudioGetAnim
|
||||
@@ -559,17 +590,10 @@ StudioGetAnim
|
||||
*/
|
||||
void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc )
|
||||
{
|
||||
mstudioseqgroup_t *pseqgroup;
|
||||
cache_user_t *paSequences;
|
||||
fs_offset_t filesize;
|
||||
byte *buf;
|
||||
|
||||
pseqgroup = (mstudioseqgroup_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqgroupindex) + pseqdesc->seqgroup;
|
||||
if( pseqdesc->seqgroup == 0 )
|
||||
return ((byte *)m_pStudioHeader + pseqdesc->animindex);
|
||||
|
||||
paSequences = (cache_user_t *)m_pSubModel->submodels;
|
||||
|
||||
cache_user_t *paSequences = (cache_user_t *)m_pSubModel->submodels;
|
||||
if( paSequences == NULL )
|
||||
{
|
||||
paSequences = (cache_user_t *)Mem_Calloc( com_studiocache, MAXSTUDIOGROUPS * sizeof( cache_user_t ));
|
||||
@@ -579,23 +603,31 @@ void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstud
|
||||
// check for already loaded
|
||||
if( !Mod_CacheCheck(( cache_user_t *)&( paSequences[pseqdesc->seqgroup] )))
|
||||
{
|
||||
string filepath, modelname, modelpath;
|
||||
|
||||
string modelname;
|
||||
COM_FileBase( m_pSubModel->name, modelname, sizeof( modelname ));
|
||||
|
||||
string modelpath;
|
||||
COM_ExtractFilePath( m_pSubModel->name, modelpath );
|
||||
|
||||
// NOTE: here we build real sub-animation filename because stupid user may rename model without recompile
|
||||
string filepath;
|
||||
Q_snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 );
|
||||
|
||||
buf = FS_LoadFile( filepath, &filesize, false );
|
||||
if( !buf || !filesize ) Host_Error( "%s: can't load %s\n", __func__, filepath );
|
||||
if( IDSEQGRPHEADER != *(uint *)buf ) Host_Error( "%s: %s is corrupted\n", __func__, filepath );
|
||||
fs_offset_t filesize;
|
||||
byte *buf = FS_LoadFile( filepath, &filesize, false );
|
||||
if( !buf || !filesize )
|
||||
Host_Error( "%s: can't load %s\n", __func__, filepath );
|
||||
if( LittleLong( IDSEQGRPHEADER ) != *(uint *)buf )
|
||||
Host_Error( "%s: %s is corrupted\n", __func__, filepath );
|
||||
|
||||
Con_Printf( "loading: %s\n", filepath );
|
||||
|
||||
paSequences[pseqdesc->seqgroup].data = Mem_Calloc( com_studiocache, filesize );
|
||||
memcpy( paSequences[pseqdesc->seqgroup].data, buf, filesize );
|
||||
Mem_Free( buf );
|
||||
|
||||
Mod_SwapStudioSeqGroupAnims( m_pStudioHeader, pseqdesc,
|
||||
(byte *)paSequences[pseqdesc->seqgroup].data );
|
||||
}
|
||||
|
||||
return ((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex);
|
||||
@@ -977,6 +1009,9 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
|
||||
if( phdr->ident != IDSTUDIOHEADER || phdr->version != STUDIO_VERSION )
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
|
||||
#if XASH_BIG_ENDIAN
|
||||
if( phdr->studiohdr2index > 0 && phdr->studiohdr2index < phdr->length )
|
||||
{
|
||||
@@ -998,7 +1033,11 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
|
||||
le_struct_swap( mstudioseqgroup_swap, (mstudioseqgroup_t *)( mod_base + phdr->seqgroupindex ) + i );
|
||||
|
||||
for( int i = 0; i < phdr->numattachments; i++ )
|
||||
le_struct_swap( mstudioattachment_swap, (mstudioattachment_t *)( mod_base + phdr->attachmentindex ) + i );
|
||||
{
|
||||
mstudioattachment_t *pattach = (mstudioattachment_t *)( mod_base + phdr->attachmentindex ) + i;
|
||||
le_struct_swap( mstudioattachment_swap, pattach );
|
||||
le_array_swap((float *)pattach->vectors, 3 * 3 );
|
||||
}
|
||||
|
||||
for( int i = 0; i < phdr->numtextures; i++ )
|
||||
le_struct_swap( mstudiotexture_swap, (mstudiotexture_t *)( mod_base + phdr->textureindex ) + i );
|
||||
@@ -1013,6 +1052,11 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
|
||||
|
||||
for( int j = 0; j < pseq->numevents; j++ )
|
||||
le_struct_swap( mstudioevent_swap, (mstudioevent_t *)( mod_base + pseq->eventindex ) + j );
|
||||
|
||||
if( pseq->seqgroup != 0 )
|
||||
continue;
|
||||
|
||||
Mod_SwapStudioSeqGroupAnims( phdr, pseq, mod_base );
|
||||
}
|
||||
|
||||
for( int i = 0; i < phdr->numbodyparts; i++ )
|
||||
@@ -1024,8 +1068,25 @@ static qboolean Mod_SwapStudioModel( const char *name, void *buffer, size_t buff
|
||||
mstudiomodel_t *pmodel = (mstudiomodel_t *)( mod_base + pbodypart->modelindex ) + j;
|
||||
le_struct_swap( mstudiomodel_swap, pmodel );
|
||||
|
||||
le_array_swap((float *)( mod_base + pmodel->vertindex ), pmodel->numverts * 3 );
|
||||
le_array_swap((float *)( mod_base + pmodel->normindex ), pmodel->numnorms * 3 );
|
||||
|
||||
for( int k = 0; k < pmodel->nummesh; k++ )
|
||||
le_struct_swap( mstudiomesh_swap, (mstudiomesh_t *)( mod_base + pmodel->meshindex ) + k );
|
||||
{
|
||||
mstudiomesh_t *pmesh = (mstudiomesh_t *)( mod_base + pmodel->meshindex ) + k;
|
||||
le_struct_swap( mstudiomesh_swap, pmesh );
|
||||
|
||||
short *ptricmds = (short *)( mod_base + pmesh->triindex );
|
||||
short n;
|
||||
while(( n = LittleShort( *ptricmds )))
|
||||
{
|
||||
*ptricmds++ = n;
|
||||
int count = abs( n ) * 4;
|
||||
for( int l = 0; l < count; l++, ptricmds++ )
|
||||
*ptricmds = LittleShort( *ptricmds );
|
||||
}
|
||||
*ptricmds = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -608,6 +608,31 @@ void GAME_EXPORT Mod_LoadCacheFile( const char *filename, cache_user_t *cu )
|
||||
cu->data = Mem_Malloc( com_studiocache, size );
|
||||
memcpy( cu->data, buf, size );
|
||||
Mem_Free( buf );
|
||||
|
||||
// this handles when studio model renderer tries to load sequence files on it's own
|
||||
// which is what they always do in HLSDK
|
||||
#if XASH_BIG_ENDIAN
|
||||
if( size >= sizeof( int ) && LittleLong( IDSEQGRPHEADER ) == *(uint *)cu->data )
|
||||
{
|
||||
studiohdr_t *phdr = (studiohdr_t *)REF_GET_PARM( PARM_GET_STUDIO_HDR, 0 );
|
||||
if( !phdr )
|
||||
return;
|
||||
|
||||
mstudioseqdesc_t *pseq = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex );
|
||||
|
||||
for( int i = 0; i < phdr->numseq; i++ )
|
||||
{
|
||||
if( pseq[i].seqgroup == 0 )
|
||||
continue;
|
||||
|
||||
mstudioseqgroup_t *pgrp = (mstudioseqgroup_t *)((byte *)phdr + phdr->seqgroupindex ) + pseq[i].seqgroup;
|
||||
|
||||
// assuming filename passes seqgroup's name
|
||||
if( !Q_stricmp( pgrp->name, filename ))
|
||||
Mod_SwapStudioSeqGroupAnims( phdr, &pseq[i], (byte *)cu->data );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -84,37 +84,37 @@ void Sound_Shutdown( void )
|
||||
|
||||
uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath )
|
||||
{
|
||||
string name;
|
||||
file_t *f;
|
||||
wavehdr_t wav;
|
||||
size_t filesize;
|
||||
uint msecs;
|
||||
|
||||
string name;
|
||||
Q_strncpy( name, filepath, sizeof( name ));
|
||||
COM_FixSlashes( name );
|
||||
|
||||
f = FS_Open( name, "rb", false );
|
||||
file_t *f = FS_Open( name, "rb", false );
|
||||
if( !f )
|
||||
return 0;
|
||||
|
||||
wavehdr_t wav;
|
||||
if( FS_Read( f, &wav, sizeof( wav )) != sizeof( wav ))
|
||||
{
|
||||
FS_Close( f );
|
||||
return 0;
|
||||
}
|
||||
|
||||
filesize = FS_FileLength( f );
|
||||
filesize -= 128; // magic number from GoldSrc, seems to be header size
|
||||
// magic number from GoldSrc, seems to be header size
|
||||
size_t filesize = FS_FileLength( f ) - 128;
|
||||
|
||||
FS_Close( f );
|
||||
|
||||
// is real wav file ?
|
||||
if( wav.riff_id != RIFFHEADER || wav.wave_id != WAVEHEADER || wav.fmt_id != FORMHEADER )
|
||||
if( wav.riff_id != LittleLong( RIFFHEADER ) || wav.wave_id != LittleLong( WAVEHEADER ) || wav.fmt_id != LittleLong( FORMHEADER ))
|
||||
return 0;
|
||||
|
||||
if( wav.nAvgBytesPerSec >= 1000 )
|
||||
msecs = (uint)((float)filesize / ((float)wav.nAvgBytesPerSec / 1000.0f));
|
||||
else msecs = (uint)(((float)filesize / (float)wav.nAvgBytesPerSec) * 1000.0f);
|
||||
int avgBytes = LittleLong( wav.nAvgBytesPerSec );
|
||||
uint msecs;
|
||||
|
||||
if( avgBytes >= 1000 )
|
||||
msecs = (uint)((float)filesize / ((float)avgBytes / 1000.0f));
|
||||
else
|
||||
msecs = (uint)(((float)filesize / (float)avgBytes) * 1000.0f);
|
||||
|
||||
return msecs;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ SYSTEM LOG
|
||||
*/
|
||||
int Sys_LogFileNo( void )
|
||||
{
|
||||
if( !s_ld.logfile )
|
||||
return -1;
|
||||
return s_ld.logfileno;
|
||||
}
|
||||
|
||||
@@ -84,7 +86,7 @@ void Sys_InitLog( void )
|
||||
|
||||
if( Sys_CheckParm( "-log" ))
|
||||
{
|
||||
if( !Sys_GetParmFromCmdLine( "-log", s_ld.log_path ) || !isalnum( s_ld.log_path[0] ))
|
||||
if( !Sys_GetParmFromCmdLine( "-log", s_ld.log_path ) || !isalnum((byte)s_ld.log_path[0] ))
|
||||
Q_strncpy( s_ld.log_path, "engine.log", sizeof( s_ld.log_path ));
|
||||
|
||||
COM_DefaultExtension( s_ld.log_path, ".log", sizeof( s_ld.log_path ));
|
||||
|
||||
@@ -27,15 +27,10 @@ static qboolean enable_libbacktrace;
|
||||
|
||||
static void Sys_BacktraceError( void *data, const char *msg, int errnum )
|
||||
{
|
||||
if( errnum < 0 )
|
||||
{
|
||||
Con_Printf( S_ERROR "no symbol info, no libbacktrace\n" );
|
||||
return;
|
||||
}
|
||||
Con_Printf( S_ERROR "libbacktrace: %s (%d)\n", msg, errnum );
|
||||
|
||||
Con_Printf( S_ERROR "libbacktrace error: %s (%d)\n", msg, errnum );
|
||||
|
||||
enable_libbacktrace = false;
|
||||
if( errnum > 0 )
|
||||
enable_libbacktrace = false;
|
||||
}
|
||||
|
||||
struct print_data
|
||||
@@ -45,8 +40,16 @@ struct print_data
|
||||
int len;
|
||||
int idx;
|
||||
int logfd;
|
||||
qboolean skip_wrappers;
|
||||
};
|
||||
|
||||
static qboolean Sys_IsCrashHandlerFrame( const char *name )
|
||||
{
|
||||
if( !name )
|
||||
return false;
|
||||
return !Q_strcmp( name, "Sys_Crash" ) || !Q_strcmp( name, "Sys_CrashDetailsLibbacktrace" );
|
||||
}
|
||||
|
||||
static void Sys_AppendPrint( struct print_data *pd, const char *fmt, ... )
|
||||
{
|
||||
va_list va;
|
||||
@@ -58,13 +61,10 @@ static void Sys_AppendPrint( struct print_data *pd, const char *fmt, ... )
|
||||
|
||||
if( len > 0 )
|
||||
{
|
||||
char ch = '\n';
|
||||
|
||||
write( pd->logfd, pd->message, len );
|
||||
write( pd->logfd, &ch, 1 );
|
||||
if( pd->logfd >= 0 )
|
||||
write( pd->logfd, pd->message, len );
|
||||
|
||||
write( STDERR_FILENO, pd->message, len );
|
||||
write( STDERR_FILENO, &ch, 1 );
|
||||
|
||||
pd->message += len;
|
||||
pd->len += len;
|
||||
@@ -84,6 +84,13 @@ static void Sys_BacktracePrintSyminfo( void *data, uintptr_t pc, const char *sym
|
||||
Dl_info dlinfo = { 0 };
|
||||
const char *module_name;
|
||||
|
||||
if( pd->skip_wrappers )
|
||||
{
|
||||
if( Sys_IsCrashHandlerFrame( symname ))
|
||||
return;
|
||||
pd->skip_wrappers = false;
|
||||
}
|
||||
|
||||
if( dladdr((void *)pc, &dlinfo ))
|
||||
module_name = dlinfo.dli_fname;
|
||||
else module_name = NULL;
|
||||
@@ -110,6 +117,13 @@ static int Sys_BacktracePrintFull( void *data, uintptr_t pc, const char *filenam
|
||||
Dl_info dlinfo = { 0 };
|
||||
const char *module_name;
|
||||
|
||||
if( pd->skip_wrappers )
|
||||
{
|
||||
if( Sys_IsCrashHandlerFrame( function ))
|
||||
return 0;
|
||||
pd->skip_wrappers = false;
|
||||
}
|
||||
|
||||
if( dladdr((void *)pc, &dlinfo ))
|
||||
module_name = dlinfo.dli_fname;
|
||||
else module_name = NULL;
|
||||
@@ -136,12 +150,13 @@ int Sys_CrashDetailsLibbacktrace( int logfd, char *message, int len, size_t max_
|
||||
struct print_data pd =
|
||||
{
|
||||
.message = message + len,
|
||||
.message_size = sizeof( message ) - len,
|
||||
.message_size = max_len - len,
|
||||
.logfd = logfd,
|
||||
.len = len,
|
||||
.skip_wrappers = true,
|
||||
};
|
||||
|
||||
backtrace_full( g_bt_state, 1, Sys_BacktracePrintFull, Sys_BacktracePrintError, &pd );
|
||||
backtrace_full( g_bt_state, 0, Sys_BacktracePrintFull, Sys_BacktracePrintError, &pd );
|
||||
|
||||
return pd.len;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context )
|
||||
|
||||
// now get log fd and write trace directly to log
|
||||
logfd = Sys_LogFileNo();
|
||||
write( logfd, message, len );
|
||||
if( logfd >= 0 )
|
||||
write( logfd, message, len );
|
||||
|
||||
#if HAVE_LIBBACKTRACE
|
||||
if( have_libbacktrace && !detailed_message )
|
||||
|
||||
@@ -106,7 +106,7 @@ qboolean SNDDMA_Init( void )
|
||||
|
||||
memset( &desired, 0, sizeof( desired ) );
|
||||
desired.freq = SOUND_DMA_SPEED;
|
||||
desired.format = AUDIO_S16LSB;
|
||||
desired.format = AUDIO_S16SYS;
|
||||
desired.samples = 1024;
|
||||
desired.channels = 2;
|
||||
desired.callback = SDL_SoundCallback;
|
||||
@@ -119,7 +119,7 @@ qboolean SNDDMA_Init( void )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( obtained.format != AUDIO_S16LSB )
|
||||
if( obtained.format != AUDIO_S16SYS )
|
||||
{
|
||||
Con_Printf( "SDL audio format %d unsupported.\n", obtained.format );
|
||||
goto fail;
|
||||
|
||||
@@ -123,7 +123,7 @@ qboolean SNDDMA_Init( void )
|
||||
|
||||
memset( &desired, 0, sizeof( desired ) );
|
||||
desired.freq = SOUND_DMA_SPEED;
|
||||
desired.format = AUDIO_S16LSB;
|
||||
desired.format = AUDIO_S16SYS;
|
||||
desired.samples = 1024;
|
||||
desired.channels = 2;
|
||||
desired.callback = SDL_SoundCallback;
|
||||
@@ -136,7 +136,7 @@ qboolean SNDDMA_Init( void )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( obtained.format != AUDIO_S16LSB )
|
||||
if( obtained.format != AUDIO_S16SYS )
|
||||
{
|
||||
Con_Printf( "SDL audio format %d unsupported.\n", obtained.format );
|
||||
goto fail;
|
||||
@@ -277,7 +277,7 @@ qboolean VoiceCapture_Init( void )
|
||||
|
||||
SDL_zero( wanted );
|
||||
wanted.freq = voice.samplerate;
|
||||
wanted.format = AUDIO_S16LSB;
|
||||
wanted.format = AUDIO_S16SYS;
|
||||
wanted.channels = VOICE_PCM_CHANNELS;
|
||||
wanted.samples = voice.frame_size;
|
||||
wanted.callback = SDL_SoundInputCallback;
|
||||
|
||||
@@ -72,7 +72,8 @@ GNU General Public License for more details.
|
||||
// Moved RenderAPI and TriAPI filling to renderer via R_FillRenderAPI and R_FillTriAPI
|
||||
// Moved detail textures parsing and cinematic texture management to engine
|
||||
// Moved creation of default textures to the engine
|
||||
#define REF_API_VERSION 15
|
||||
// 16. RefGetParm return type changed from int to intptr_t.
|
||||
#define REF_API_VERSION 16
|
||||
|
||||
#define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP|TF_ALLOW_NEAREST)
|
||||
#define TF_FONT (TF_NOMIPMAP|TF_CLAMP|TF_ALLOW_NEAREST)
|
||||
@@ -104,6 +105,7 @@ GNU General Public License for more details.
|
||||
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
|
||||
#define FWORLD_WATERALPHA BIT( 2 )
|
||||
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
|
||||
#define FWORLD_HAS_LITWATER BIT( 4 )
|
||||
|
||||
// special rendermode for screenfade modulate
|
||||
// (probably will be expanded at some point)
|
||||
@@ -342,6 +344,7 @@ typedef enum
|
||||
PARM_GET_LIGHTSTYLES_PTR = -20,
|
||||
PARM_GET_DLIGHTS_PTR = -21,
|
||||
PARM_GET_ELIGHTS_PTR = -22,
|
||||
PARM_GET_STUDIO_HDR = -23, // current m_pStudioHeader in renderer
|
||||
|
||||
// implemented by ref_dll
|
||||
|
||||
@@ -598,7 +601,7 @@ typedef struct ref_interface_s
|
||||
void (*CL_DrawBeams)( int fTrans , BEAM *beams );
|
||||
|
||||
// Xash3D Render Interface
|
||||
int (*RefGetParm)( int parm, int arg ); // generic
|
||||
intptr_t (*RefGetParm)( int parm, int arg ); // generic
|
||||
|
||||
// detail texture scale
|
||||
void (*R_GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
|
||||
|
||||
@@ -3219,9 +3219,11 @@ void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Q_strcmp( pcmd, A2S_GOLDSRC_INFO ) || pcmd[0] == A2S_GOLDSRC_PLAYERS || pcmd[0] == A2S_GOLDSRC_RULES )
|
||||
// Must check `args` because A2S_GOLDSRC_INFO contains spaces.
|
||||
// `pcmd` points only to the first word from the query string.
|
||||
if( !Q_strcmp( args, A2S_GOLDSRC_INFO ) || pcmd[0] == A2S_GOLDSRC_PLAYERS || pcmd[0] == A2S_GOLDSRC_RULES )
|
||||
{
|
||||
SV_SourceQuery_HandleConnnectionlessPacket( pcmd, from );
|
||||
SV_SourceQuery_HandleConnnectionlessPacket( args, from );
|
||||
}
|
||||
else if( !Q_strcmp( pcmd, A2A_NETINFO ))
|
||||
{
|
||||
|
||||
@@ -801,7 +801,7 @@ qboolean SV_ProcessUserAgent( netadr_t from, const char *useragent )
|
||||
{
|
||||
char c = id[i];
|
||||
|
||||
if( !isdigit( id[i] ) && !( c >= 'a' && c <= 'f' ))
|
||||
if( !isdigit((byte)id[i] ) && !( c >= 'a' && c <= 'f' ))
|
||||
{
|
||||
SV_RejectConnection( from, "invalid authentication certificate\n" );
|
||||
return false;
|
||||
|
||||
@@ -186,7 +186,7 @@ def build(bld):
|
||||
# public includes for renderers and utils use
|
||||
bld(name = 'engine_includes', export_includes = '. common common/imagelib', use = 'filesystem_includes')
|
||||
|
||||
libs = ['engine_includes', 'public', 'werror', 'backtrace', 'library_suffix', 'build_vcs']
|
||||
libs = ['engine_includes', 'public', 'werror', 'backtrace_custom', 'library_suffix', 'build_vcs']
|
||||
includes = ['server', 'client', 'client/vgui', 'common/soundlib', 'platform']
|
||||
|
||||
# basic build: dedicated only
|
||||
|
||||
@@ -929,12 +929,12 @@ void COM_TrimSpace( char *dst, const char *src, size_t size )
|
||||
return;
|
||||
|
||||
// remove spaces from the start
|
||||
for( ; *src && isspace( *src ); src++ );
|
||||
for( ; *src && isspace((byte)*src ); src++ );
|
||||
|
||||
int len = Q_strlen( src );
|
||||
|
||||
// remove spaces from the end
|
||||
for( ; len > 0 && isspace( src[len - 1] ); len-- );
|
||||
for( ; len > 0 && isspace((byte)src[len - 1] ); len-- );
|
||||
|
||||
if( len > 0 )
|
||||
{
|
||||
|
||||
@@ -170,9 +170,15 @@ static inline qboolean Q_istype( const char *str, int (*istype)( int c ))
|
||||
{
|
||||
if( likely( str && *str ))
|
||||
{
|
||||
while( istype( *str )) str++;
|
||||
if( !*str ) return true;
|
||||
// a1ba: explicitly cast char to unsigned char to not trigger UB
|
||||
// in ctype functions
|
||||
while( istype((byte)*str ))
|
||||
str++;
|
||||
|
||||
if( !*str )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,9 +82,16 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
|
||||
}
|
||||
}
|
||||
|
||||
static inline void swap_array_( byte *data, int32_t elem_size, uint32_t count )
|
||||
{
|
||||
for( uint32_t i = 0; i < count; i++ )
|
||||
swap_field_( &data[i * elem_size], elem_size );
|
||||
}
|
||||
|
||||
// do not use these macros, they will swap structs unconditionally
|
||||
// you might want to use le_/be_ macros instead
|
||||
#define swap_struct( swapdef, ptr ) swap_struct_(( swapdef ), sizeof( swapdef ) / sizeof( swapdef[0] ), (byte *)( ptr ))
|
||||
#define swap_array( ptr, count ) swap_array_((byte *)( ptr ), sizeof( *( ptr )), ( count ))
|
||||
|
||||
#define swap_struct_begin( swapdef ) static swap_struct_def_t swapdef[] = {
|
||||
#define swap_struct_end() }
|
||||
@@ -104,7 +111,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
|
||||
|
||||
// this is done in macros so we can completely avoid defining this
|
||||
// in little endian targets
|
||||
#ifdef XASH_LITTLE_ENDIAN
|
||||
#if XASH_LITTLE_ENDIAN
|
||||
#define be_struct_begin( x ) swap_struct_begin( x )
|
||||
#define be_struct_field( x, y ) swap_struct_field( x, y )
|
||||
#define be_struct_child( x, y, z ) swap_struct_child( x, y, z )
|
||||
@@ -112,6 +119,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
|
||||
#define be_struct_array_child( x, y, z, w ) swap_struct_array_child( x, y, z, w )
|
||||
#define be_struct_end() swap_struct_end()
|
||||
#define be_struct_swap( x, y ) swap_struct( x, y )
|
||||
#define be_array_swap( x, y ) swap_array( x, y )
|
||||
#define le_struct_begin( x )
|
||||
#define le_struct_field( x, y )
|
||||
#define le_struct_child( x, y, z )
|
||||
@@ -119,6 +127,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
|
||||
#define le_struct_array_child( x, y, z, w )
|
||||
#define le_struct_end() extern int _le_struct_end_dummy // define as extern variable, to let end() end with ;
|
||||
#define le_struct_swap( x, y ) (void)(y)
|
||||
#define le_array_swap( x, y ) (void)(x)
|
||||
#else
|
||||
#define be_struct_begin( x )
|
||||
#define be_struct_field( x, y )
|
||||
@@ -127,6 +136,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
|
||||
#define be_struct_array_child( x, y, z, w )
|
||||
#define be_struct_end() extern int _le_struct_end_dummy
|
||||
#define be_struct_swap( x, y ) (void)(y)
|
||||
#define be_array_swap( x, y ) (void)(x)
|
||||
#define le_struct_begin( x ) swap_struct_begin( x )
|
||||
#define le_struct_field( x, y ) swap_struct_field( x, y )
|
||||
#define le_struct_child( x, y, z ) swap_struct_child( x, y, z )
|
||||
@@ -134,6 +144,7 @@ static inline void swap_struct_( const swap_struct_def_t *def, size_t len, byte
|
||||
#define le_struct_array_child( x, y, z, w ) swap_struct_array_child( x, y, z, w )
|
||||
#define le_struct_end() swap_struct_end()
|
||||
#define le_struct_swap( x, y ) swap_struct( x, y )
|
||||
#define le_array_swap( x, y ) swap_array( x, y )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte
|
||||
return loaded;
|
||||
}
|
||||
|
||||
static int GL_RefGetParm( int parm, int arg )
|
||||
static intptr_t GL_RefGetParm( int parm, int arg )
|
||||
{
|
||||
gl_texture_t *glt;
|
||||
|
||||
@@ -230,6 +230,8 @@ static int GL_RefGetParm( int parm, int arg )
|
||||
return gl_texture_nearest.value == 0.0f;
|
||||
|
||||
return GL_TextureFilteringEnabled( R_GetTexture( arg ));
|
||||
case PARM_GET_STUDIO_HDR:
|
||||
return (intptr_t)R_StudioGetHeader();
|
||||
default:
|
||||
return ENGINE_GET_PARM_( parm, arg );
|
||||
}
|
||||
|
||||
@@ -403,6 +403,7 @@ void R_DrawSpriteModel( cl_entity_t *e );
|
||||
// gl_studio.c
|
||||
//
|
||||
void R_StudioInit( void );
|
||||
studiohdr_t *R_StudioGetHeader( void );
|
||||
void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles );
|
||||
struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e );
|
||||
int R_GetEntityRenderMode( cl_entity_t *ent );
|
||||
@@ -719,6 +720,7 @@ extern convar_t gl_msaa;
|
||||
extern convar_t gl_stencilbits;
|
||||
extern convar_t gl_overbright;
|
||||
extern convar_t gl_fog;
|
||||
extern convar_t gl_litwater_force;
|
||||
|
||||
extern convar_t r_lighting_ambient;
|
||||
extern convar_t r_studio_lambert;
|
||||
|
||||
@@ -22,6 +22,7 @@ CVAR_DEFINE_AUTO( gl_msaa, "1", FCVAR_GLCONFIG, "enable or disable multisample a
|
||||
CVAR_DEFINE_AUTO( gl_stencilbits, "8", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "pixelformat stencil bits (0 - auto)" );
|
||||
CVAR_DEFINE_AUTO( gl_overbright, "1", FCVAR_GLCONFIG, "overbrights" );
|
||||
CVAR_DEFINE_AUTO( gl_fog, "1", FCVAR_GLCONFIG, "allow for rendering fog using built-in OpenGL fog implementation" );
|
||||
CVAR_DEFINE_AUTO( gl_litwater_force, "0", FCVAR_GLCONFIG, "force enable lightmapped water, even if support not declared in the map" );
|
||||
CVAR_DEFINE_AUTO( r_lighting_ambient, "0.3", FCVAR_GLCONFIG, "map ambient lighting scale" );
|
||||
CVAR_DEFINE_AUTO( r_detailtextures, "1", FCVAR_GLCONFIG, "enable detail textures support" );
|
||||
CVAR_DEFINE_AUTO( r_novis, "0", 0, "ignore vis information (perfomance test)" );
|
||||
@@ -962,8 +963,17 @@ static void GL_InitExtensionsBigGL( void )
|
||||
pglGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig.max_vertex_uniforms );
|
||||
pglGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.max_vertex_attribs );
|
||||
|
||||
// GLSL sanity check
|
||||
if( glConfig.max_vertex_uniforms <= 0 || glConfig.max_texture_coords < glConfig.max_texture_units || glConfig.max_teximage_units < glConfig.max_texture_units )
|
||||
{
|
||||
gEngfuncs.Con_Reportf( S_NOTE "driver supports GL_ARB_shading_language_100 but has bogus limits, ignoring\n" );
|
||||
GL_SetExtension( GL_SHADER_GLSL100_EXT, false );
|
||||
glConfig.max_texture_coords = glConfig.max_teximage_units = glConfig.max_texture_units;
|
||||
glConfig.max_vertex_uniforms = 0;
|
||||
glConfig.max_vertex_attribs = 0;
|
||||
}
|
||||
#if XASH_WIN32 // Win32 only drivers?
|
||||
if( glConfig.hardware_type == GLHW_RADEON && glConfig.max_vertex_uniforms > 512 )
|
||||
else if( glConfig.hardware_type == GLHW_RADEON && glConfig.max_vertex_uniforms > 512 )
|
||||
glConfig.max_vertex_uniforms /= 4; // radeon returns not correct info
|
||||
#endif
|
||||
}
|
||||
@@ -978,8 +988,7 @@ static void GL_InitExtensionsBigGL( void )
|
||||
|
||||
if( !GL_CheckExtension( "glDrawRangeElements", drawrangeelementsfuncs, ARRAYSIZE( drawrangeelementsfuncs ), "gl_drawrangeelements", GL_DRAW_RANGEELEMENTS_EXT, 0 ) )
|
||||
{
|
||||
if( GL_CheckExtension( "glDrawRangeElementsEXT", drawrangeelementsextfuncs, ARRAYSIZE( drawrangeelementsextfuncs ),
|
||||
"gl_drawrangelements", GL_DRAW_RANGEELEMENTS_EXT, 0 ))
|
||||
if( GL_CheckExtension( "glDrawRangeElementsEXT", drawrangeelementsextfuncs, ARRAYSIZE( drawrangeelementsextfuncs ), "gl_drawrangeelements", GL_DRAW_RANGEELEMENTS_EXT, 0 ))
|
||||
{
|
||||
#if !XASH_GL_STATIC
|
||||
pglDrawRangeElements = pglDrawRangeElementsEXT;
|
||||
@@ -1175,6 +1184,7 @@ static void GL_InitCommands( void )
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_round_down );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_overbright );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_fog );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_litwater_force );
|
||||
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_polyoffset );
|
||||
gEngfuncs.Cvar_RegisterVariable( &gl_polyoffset_bmodels );
|
||||
@@ -1405,6 +1415,12 @@ void GL_SetupAttributes( int safegl )
|
||||
glw_state.extended = true;
|
||||
}
|
||||
|
||||
if( gEngfuncs.Sys_CheckParm( "-glnoerr" ))
|
||||
{
|
||||
gEngfuncs.Con_Reportf( "Creating a no-error GL context...\n" );
|
||||
gEngfuncs.GL_SetAttribute( REF_GL_CONTEXT_NO_ERROR, 1 );
|
||||
}
|
||||
|
||||
if( safegl > SAFE_DONTCARE )
|
||||
{
|
||||
safegl = -1; // can't retry anymore, can only shutdown engine
|
||||
|
||||
@@ -76,6 +76,39 @@ static inline qboolean R_SeparatePassActive( const separate_pass_t *sp )
|
||||
return sp->last >= 0 ? true : false;
|
||||
}
|
||||
|
||||
static qboolean Mod_HaveLightmappedWater( void )
|
||||
{
|
||||
// if this flag set, it's level designer's job to ensure water has been properly lit
|
||||
if( FBitSet( tr.world->flags, FWORLD_HAS_LITWATER ))
|
||||
return true;
|
||||
|
||||
// otherwise, check user preference, as some maps have lightmapped water
|
||||
return gl_litwater_force.value ? true : false;
|
||||
}
|
||||
|
||||
static int Mod_LightmappedWaterMinlight( void )
|
||||
{
|
||||
if( FBitSet( tr.world->flags, FWORLD_HAS_LITWATER ))
|
||||
{
|
||||
if( tr.world->litwater_minlight >= 0 )
|
||||
return tr.world->litwater_minlight;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float Mod_LightmappedWaterScale( void )
|
||||
{
|
||||
if( FBitSet( tr.world->flags, FWORLD_HAS_LITWATER ))
|
||||
{
|
||||
if( tr.world->litwater_scale >= 0.0f )
|
||||
return tr.world->litwater_scale;
|
||||
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
byte *Mod_GetCurrentVis( void )
|
||||
{
|
||||
if( gEngfuncs.drawFuncs->Mod_GetCurrentVis && tr.fCustomRendering )
|
||||
@@ -252,12 +285,29 @@ static void SubdividePolygon_r( model_t *loadmodel, msurface_t *warpface, int nu
|
||||
{
|
||||
VectorCopy( verts, poly->verts[i] );
|
||||
R_TextureCoord( verts, warpface, &poly->verts[i][3] );
|
||||
// lightmap texcoords for subdivided surfaces will be calculated later
|
||||
}
|
||||
}
|
||||
|
||||
// for speed reasons
|
||||
if( !FBitSet( warpface->flags, SURF_DRAWTURB ))
|
||||
static void GL_BuildLightmapWater( model_t *mod, msurface_t *fa )
|
||||
{
|
||||
float sample_size;
|
||||
glpoly2_t *poly;
|
||||
|
||||
if( !mod || !fa->texinfo || !fa->texinfo->texture )
|
||||
return; // bad polygon?
|
||||
|
||||
sample_size = gEngfuncs.Mod_SampleSizeForFace( fa );
|
||||
|
||||
for( poly = fa->polys; poly; poly = poly->next )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < poly->numverts; i++ )
|
||||
{
|
||||
// lightmap texture coordinates
|
||||
R_LightmapCoord( verts, warpface, sample_size, &poly->verts[i][5] );
|
||||
vec3_t vec;
|
||||
VectorCopy( poly->verts[i], vec );
|
||||
R_LightmapCoord( vec, fa, sample_size, &poly->verts[i][5] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -703,6 +753,8 @@ static void R_BuildLightMap( const msurface_t *surf, byte *dest, int stride, qbo
|
||||
const mextrasurf_t *info = surf->info;
|
||||
int lightscale;
|
||||
|
||||
const int litwater_minlight = Mod_LightmappedWaterMinlight();
|
||||
const float litwater_scale = Mod_LightmappedWaterScale();
|
||||
const int sample_size = gEngfuncs.Mod_SampleSizeForFace( surf );
|
||||
const int smax = ( info->lightextents[0] / sample_size ) + 1;
|
||||
const int tmax = ( info->lightextents[1] / sample_size ) + 1;
|
||||
@@ -752,6 +804,14 @@ static void R_BuildLightMap( const msurface_t *surf, byte *dest, int stride, qbo
|
||||
{
|
||||
int t = bl[i] * lightscale >> 14;
|
||||
|
||||
// amp up water lightmap to avoid too dark water
|
||||
// when the it wasn't properly lit by the level designer
|
||||
if( FBitSet( surf->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
float ft = t * litwater_scale;
|
||||
t = Q_max( Q_rint( ft ), litwater_minlight );
|
||||
}
|
||||
|
||||
if( t > 1023 )
|
||||
t = 1023;
|
||||
|
||||
@@ -977,6 +1037,58 @@ static void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples
|
||||
GL_SetupFogColorForSurfaces();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
EmitWaterLightPolys
|
||||
|
||||
Render water lightmaps
|
||||
================
|
||||
*/
|
||||
static void EmitWaterLightPolys( msurface_t *warp, float soffset, float toffset, qboolean dynamic )
|
||||
{
|
||||
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS );
|
||||
glpoly2_t *p;
|
||||
float waveHeight = RI.currententity->curstate.scale;
|
||||
|
||||
// set the current waveheight
|
||||
if( warp->polys->verts[0][2] >= RI.rvp.vieworigin[2] )
|
||||
waveHeight = -waveHeight;
|
||||
|
||||
if( useQuads )
|
||||
pglBegin( GL_QUADS );
|
||||
|
||||
for( p = warp->polys; p; p = p->next )
|
||||
{
|
||||
float *v = p->verts[0];
|
||||
int i;
|
||||
|
||||
if( !useQuads )
|
||||
pglBegin( GL_POLYGON );
|
||||
|
||||
for( i = 0; i < p->numverts; i++, v += VERTEXSIZE )
|
||||
{
|
||||
if( !dynamic ) pglTexCoord2f( v[5], v[6] );
|
||||
else pglTexCoord2f( v[5] - soffset, v[6] - toffset );
|
||||
|
||||
if( waveHeight )
|
||||
{
|
||||
float nv = r_turbsin[(int)(gp_cl->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
|
||||
nv = (r_turbsin[(int)(v[0] * 5.0f + gp_cl->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
|
||||
nv = nv * waveHeight + v[2];
|
||||
|
||||
pglVertex3f( v[0], v[1], nv );
|
||||
}
|
||||
else pglVertex3fv( v );
|
||||
}
|
||||
|
||||
if( !useQuads )
|
||||
pglEnd ();
|
||||
}
|
||||
|
||||
if( useQuads )
|
||||
pglEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
DrawGLPolyChain
|
||||
@@ -984,10 +1096,16 @@ DrawGLPolyChain
|
||||
Render lightmaps
|
||||
================
|
||||
*/
|
||||
static void DrawGLPolyChain( glpoly2_t *p, float soffset, float toffset )
|
||||
static void DrawGLPolyChain( glpoly2_t *p, float soffset, float toffset, msurface_t *surf )
|
||||
{
|
||||
const qboolean dynamic = soffset != 0.0f || toffset != 0.0f;
|
||||
|
||||
if( FBitSet( surf->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
EmitWaterLightPolys( surf, soffset, toffset, dynamic );
|
||||
return;
|
||||
}
|
||||
|
||||
for( ; p != NULL; p = p->chain )
|
||||
{
|
||||
float *v;
|
||||
@@ -1020,6 +1138,8 @@ static qboolean R_HasLightmap( void )
|
||||
switch( RI.currententity->curstate.rendermode )
|
||||
{
|
||||
case kRenderTransTexture:
|
||||
return FBitSet( RI.currentmodel->flags, MODEL_LIQUID ) ? true : false;
|
||||
|
||||
case kRenderTransColor:
|
||||
case kRenderTransAdd:
|
||||
case kRenderGlow:
|
||||
@@ -1049,21 +1169,29 @@ static void R_BlendLightmaps( void )
|
||||
pglEnable( GL_BLEND );
|
||||
else pglDisable( GL_BLEND );
|
||||
|
||||
// lightmapped solid surfaces
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglDepthFunc( GL_EQUAL );
|
||||
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
if( gl_overbright.value )
|
||||
|
||||
if( RI.currententity->curstate.rendermode == kRenderTransTexture )
|
||||
{
|
||||
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
|
||||
if(!( R_HasEnabledVBO() && !r_vbo_overbrightmode.value ))
|
||||
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
|
||||
pglBlendFunc( GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA );
|
||||
}
|
||||
else
|
||||
{
|
||||
pglBlendFunc( GL_ZERO, GL_SRC_COLOR );
|
||||
// lightmapped solid surfaces
|
||||
pglDepthMask( GL_FALSE );
|
||||
pglDepthFunc( GL_EQUAL );
|
||||
if( gl_overbright.value )
|
||||
{
|
||||
pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
|
||||
if(!( R_HasEnabledVBO() && !r_vbo_overbrightmode.value ))
|
||||
pglColor4f( 128.0f / 192.0f, 128.0f / 192.0f, 128.0f / 192.0f, 1.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
pglBlendFunc( GL_ZERO, GL_SRC_COLOR );
|
||||
}
|
||||
}
|
||||
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
||||
// render static lightmaps first
|
||||
@@ -1075,7 +1203,7 @@ static void R_BlendLightmaps( void )
|
||||
|
||||
for( surf = gl_lms.lightmap_surfaces[i]; surf != NULL; surf = surf->info->lightmapchain )
|
||||
{
|
||||
if( surf->polys ) DrawGLPolyChain( surf->polys, 0.0f, 0.0f );
|
||||
DrawGLPolyChain( surf->polys, 0.0f, 0.0f, surf );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1116,12 +1244,10 @@ static void R_BlendLightmaps( void )
|
||||
// draw all surfaces that use this lightmap
|
||||
for( drawsurf = newsurf; drawsurf != surf; drawsurf = drawsurf->info->lightmapchain )
|
||||
{
|
||||
if( drawsurf->polys )
|
||||
{
|
||||
DrawGLPolyChain( drawsurf->polys,
|
||||
DrawGLPolyChain( drawsurf->polys,
|
||||
( drawsurf->light_s - drawsurf->info->dlight_s ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
( drawsurf->light_t - drawsurf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ));
|
||||
}
|
||||
( drawsurf->light_t - drawsurf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
drawsurf );
|
||||
}
|
||||
|
||||
newsurf = drawsurf;
|
||||
@@ -1145,12 +1271,10 @@ static void R_BlendLightmaps( void )
|
||||
|
||||
for( surf = newsurf; surf != NULL; surf = surf->info->lightmapchain )
|
||||
{
|
||||
if( surf->polys )
|
||||
{
|
||||
DrawGLPolyChain( surf->polys,
|
||||
DrawGLPolyChain( surf->polys,
|
||||
( surf->light_s - surf->info->dlight_s ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
( surf->light_t - surf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ));
|
||||
}
|
||||
( surf->light_t - surf->info->dlight_t ) * ( 1.0f / (float)BLOCK_SIZE ),
|
||||
surf );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1418,8 +1542,13 @@ static void R_RenderBrushPoly( msurface_t *fa, int cull_type )
|
||||
|
||||
if( FBitSet( fa->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
// warp texture, no lightmaps
|
||||
// warp texture
|
||||
EmitWaterPolys( fa, cull_type == CULL_BACKSIDE, R_UploadRipples( t ));
|
||||
|
||||
// add lightmaps if requested
|
||||
if( Mod_HaveLightmappedWater( ))
|
||||
R_RenderLightmapForSurface( fa );
|
||||
|
||||
return;
|
||||
}
|
||||
else GL_Bind( XASH_TEXTURE0, t->gl_texturenum );
|
||||
@@ -1600,11 +1729,20 @@ void R_DrawWaterSurfaces( void )
|
||||
continue;
|
||||
|
||||
for( ; s; s = s->texturechain )
|
||||
{
|
||||
EmitWaterPolys( s, false, R_UploadRipples( t ));
|
||||
|
||||
if( Mod_HaveLightmappedWater( ))
|
||||
R_RenderLightmapForSurface( s );
|
||||
}
|
||||
|
||||
t->texturechain = NULL;
|
||||
}
|
||||
|
||||
// litwater: not sure if needed
|
||||
GL_ResetFogColor();
|
||||
R_BlendLightmaps();
|
||||
|
||||
R_ResetSeparatePass( &draw_wateralpha );
|
||||
|
||||
pglDisable( GL_BLEND );
|
||||
@@ -1717,8 +1855,16 @@ static int R_SortBrushModelSurfaces( cl_entity_t *e, model_t *clmodel, vec3_t mi
|
||||
|
||||
if( cull_type == CULL_BACKSIDE )
|
||||
{
|
||||
if( !FBitSet( psurf->flags, SURF_DRAWTURB ) && !( psurf->pdecals && e->curstate.rendermode == kRenderTransTexture ))
|
||||
continue;
|
||||
if( FBitSet( psurf->flags, SURF_DRAWTURB ))
|
||||
{
|
||||
if( Mod_HaveLightmappedWater( ))
|
||||
continue; // we don't want back faces when drawing lightmaps to avoid Z fighting
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !( psurf->pdecals && e->curstate.rendermode == kRenderTransTexture ))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if( num_sorted < gpGlobals->max_surfaces )
|
||||
@@ -3917,7 +4063,10 @@ void GL_BuildLightmaps( void )
|
||||
GL_CreateSurfaceLightmap( m->surfaces + j, m );
|
||||
|
||||
if( m->surfaces[j].flags & SURF_DRAWTURB )
|
||||
{
|
||||
GL_BuildLightmapWater( m, m->surfaces + j );
|
||||
continue;
|
||||
}
|
||||
|
||||
nColinElim += GL_BuildPolygonFromSurface( m, m->surfaces + j );
|
||||
}
|
||||
|
||||
@@ -2602,6 +2602,11 @@ static void R_StudioSetHeader( studiohdr_t *pheader )
|
||||
m_fDoRemap = false;
|
||||
}
|
||||
|
||||
studiohdr_t *R_StudioGetHeader( void )
|
||||
{
|
||||
return m_pStudioHeader;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioSetRenderModel
|
||||
|
||||
@@ -224,7 +224,7 @@ static void CL_DrawBeams( int fTrans, BEAM *beams )
|
||||
;
|
||||
}
|
||||
|
||||
static int RefGetParm( int parm, int arg )
|
||||
static intptr_t RefGetParm( int parm, int arg )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ static qboolean GAME_EXPORT Mod_ProcessRenderData( model_t *mod, qboolean create
|
||||
return loaded;
|
||||
}
|
||||
|
||||
static int GL_RefGetParm( int parm, int arg )
|
||||
static intptr_t GL_RefGetParm( int parm, int arg )
|
||||
{
|
||||
image_t *glt;
|
||||
|
||||
@@ -188,6 +188,8 @@ static int GL_RefGetParm( int parm, int arg )
|
||||
return 0; // ref_soft doesn't support sky sphere
|
||||
case PARM_TEX_FILTERING:
|
||||
return 0; // ref_soft doesn't do filtering in general
|
||||
case PARM_GET_STUDIO_HDR:
|
||||
return (intptr_t)R_StudioGetHeader();
|
||||
default:
|
||||
return ENGINE_GET_PARM_( parm, arg );
|
||||
}
|
||||
|
||||
@@ -392,6 +392,7 @@ void R_DrawSpriteModel( cl_entity_t *e );
|
||||
// gl_studio.c
|
||||
//
|
||||
void R_StudioInit( void );
|
||||
studiohdr_t *R_StudioGetHeader( void );
|
||||
void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||
void R_StudioLerpMovement( cl_entity_t *e, double time, vec3_t origin, vec3_t angles );
|
||||
struct mstudiotex_s *R_StudioGetTexture( cl_entity_t *e );
|
||||
|
||||
@@ -2267,6 +2267,11 @@ static void R_StudioSetHeader( studiohdr_t *pheader )
|
||||
m_fDoRemap = false;
|
||||
}
|
||||
|
||||
studiohdr_t *R_StudioGetHeader( void )
|
||||
{
|
||||
return m_pStudioHeader;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioSetRenderModel
|
||||
|
||||
@@ -49,12 +49,12 @@ IsValidName
|
||||
*/
|
||||
static qboolean IsValidName( char *name )
|
||||
{
|
||||
if( !( isalpha( *name ) || isdigit( *name )))
|
||||
if( !( isalpha((byte)*name ) || isdigit((byte)*name )))
|
||||
return false;
|
||||
|
||||
while( *( ++name ))
|
||||
{
|
||||
if( isalpha( *name ) || isdigit( *name )
|
||||
if( isalpha((byte)*name ) || isdigit((byte)*name )
|
||||
|| *name == '.' || *name == '-' || *name == '_'
|
||||
|| *name == ' ' || *name == '(' || *name == ')'
|
||||
|| *name == '[' || *name == ']')
|
||||
|
||||
Reference in New Issue
Block a user