diff --git a/common/bspfile.h b/common/bspfile.h index ec1575b5..201e03dd 100644 --- a/common/bspfile.h +++ b/common/bspfile.h @@ -117,14 +117,14 @@ BRUSH MODELS #define LUMP_FACEINFO 1 // landscape and lightmap resolution info #define LUMP_CUBEMAPS 2 // cubemap description #define LUMP_VERTNORMALS 3 // phong shaded vertex normals -#define LUMP_VERTEX_LIGHT 4 // contain compressed light cubes per empty leafs +#define LUMP_LEAF_LIGHTING 4 // store vertex lighting for statics #define LUMP_WORLDLIGHTS 5 // list of all the virtual and real lights (used to relight models in-game) -#define LUMP_COLLISION 6 // physics engine collision hull dump -#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp +#define LUMP_COLLISION 6 // physics engine collision hull dump (userdata) +#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp (userdata) #define LUMP_SHADOWMAP 8 // contains shadow map for direct light -#define LUMP_UNUSED1 9 // one lump reserved for me -#define LUMP_UNUSED2 10 // one lump reserved for me -#define LUMP_UNUSED3 11 // one lump reserved for me +#define LUMP_VERTEX_LIGHT 9 // store vertex lighting for statics +#define LUMP_UNUSED0 10 // one lump reserved for me +#define LUMP_UNUSED1 11 // one lump reserved for me #define EXTRA_LUMPS 12 // count of the extra lumps // texture flags diff --git a/common/com_model.h b/common/com_model.h index d71e98fa..0a85c084 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -166,6 +166,7 @@ struct decal_s // Xash3D specific vec3_t position; // location of the decal center in world space. glpoly_t *polys; // precomputed decal vertices + int reserved[4]; // just for future expansions or mod-makers }; typedef struct mleaf_s diff --git a/common/event_api.h b/common/event_api.h index 20e50705..8b7ae640 100644 --- a/common/event_api.h +++ b/common/event_api.h @@ -51,6 +51,8 @@ typedef struct event_api_s struct pmtrace_s *( *EV_VisTraceLine )( float *start, float *end, int flags ); struct physent_s *( *EV_GetVisent )( int idx ); int ( *EV_TestLine)( const vec3_t start, const vec3_t end, int flags ); + void ( *EV_PushTraceBounds)( int hullnum, const float *mins, const float *maxs ); + void ( *EV_PopTraceBounds)( void ); } event_api_t; -#endif//EVENT_API_H \ No newline at end of file +#endif//EVENT_API_H diff --git a/common/render_api.h b/common/render_api.h index 2e0776ca..86877a3f 100644 --- a/common/render_api.h +++ b/common/render_api.h @@ -96,7 +96,7 @@ typedef enum TF_BORDER = (1<<19), // zero clamp for projected textures TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page -// reserved + TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C // reserved // reserved TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage @@ -214,7 +214,7 @@ typedef struct render_api_s void (*GL_DrawParticles)( const struct ref_viewpass_s *rvp, qboolean trans_pass, float frametime ); void (*EnvShot)( const float *vieworg, const char *name, qboolean skyshot, int shotsize ); // store skybox into gfx\env folder int (*SPR_LoadExt)( const char *szPicName, unsigned int texFlags ); // extended version of SPR_Load - colorVec (*LightVec)( const float *start, const float *end, float *lightspot ); + colorVec (*LightVec)( const float *start, const float *end, float *lightspot, float *lightvec ); struct mstudiotex_s *( *StudioGetTexture )( struct cl_entity_s *e ); const struct ref_overview_s *( *GetOverviewParms )( void ); const char *( *GetFileByIndex )( int fileindex ); diff --git a/contib/a1batross/xash3d.files b/contib/a1batross/xash3d.files index 97887702..2e9429e0 100644 --- a/contib/a1batross/xash3d.files +++ b/contib/a1batross/xash3d.files @@ -150,6 +150,7 @@ engine/common/mathlib.h engine/common/matrixlib.c engine/common/masterlist.c engine/common/mod_bmodel.c +engine/common/mod_dbghulls.c engine/common/mod_local.h engine/common/mod_studio.c engine/common/model.c diff --git a/engine/client/avi/avi_win.c b/engine/client/avi/avi_win.c index 36ee99ba..3edd97e3 100644 --- a/engine/client/avi/avi_win.c +++ b/engine/client/avi/avi_win.c @@ -206,8 +206,8 @@ qboolean AVI_ACMConvertAudio( movie_state_t *Avi ) return false; } - Avi->cpa_srcbuffer = (byte *)Mem_Alloc( cls.mempool, Avi->cpa_blockalign ); - Avi->cpa_dstbuffer = (byte *)Mem_Alloc( cls.mempool, dest_length ); // maintained buffer for raw data + Avi->cpa_srcbuffer = (byte *)Mem_Malloc( cls.mempool, Avi->cpa_blockalign ); + Avi->cpa_dstbuffer = (byte *)Mem_Malloc( cls.mempool, dest_length ); // maintained buffer for raw data // prep the headers! Avi->cpa_conversion_header.cbStruct = sizeof( ACMSTREAMHEADER ); @@ -533,7 +533,7 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi // read the audio header pAVIStreamReadFormat( Avi->audio_stream, pAVIStreamStart( Avi->audio_stream ), 0, &size ); - Avi->audio_header = (WAVEFORMAT *)Mem_Alloc( cls.mempool, size ); + Avi->audio_header = (WAVEFORMAT *)Mem_Malloc( cls.mempool, size ); pAVIStreamReadFormat( Avi->audio_stream, pAVIStreamStart( Avi->audio_stream ), Avi->audio_header, &size ); Avi->audio_header_size = size; Avi->audio_codec = Avi->audio_header->wFormatTag; @@ -635,7 +635,7 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio ) return NULL; } - Avi = Mem_Alloc( cls.mempool, sizeof( movie_state_t )); + Avi = Mem_Malloc( cls.mempool, sizeof( movie_state_t )); AVI_OpenVideo( Avi, fullpath, load_audio, false ); if( !AVI_IsActive( Avi )) diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 98b5e7cd..0d1048cb 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -380,7 +380,7 @@ void CL_WriteDemoHeader( const char *name ) FS_Write( cls.demofile, &demo.header, sizeof( demo.header )); demo.directory.numentries = 2; - demo.directory.entries = Mem_Alloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries ); + demo.directory.entries = Mem_Calloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries ); // DIRECTORY ENTRY # 0 demo.entry = &demo.directory.entries[0]; // only one here. @@ -812,7 +812,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length ) return false; // header is ended, skip frame case dem_userdata: FS_Read( cls.demofile, &size, sizeof( int )); - userbuf = Mem_Alloc( cls.mempool, size ); + userbuf = Mem_Malloc( cls.mempool, size ); FS_Read( cls.demofile, userbuf, size ); if( clgame.hInstance ) @@ -1316,7 +1316,7 @@ void CL_PlayDemo_f( void ) } // allocate demo entries - demo.directory.entries = Mem_Alloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries ); + demo.directory.entries = Mem_Malloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries ); for( i = 0; i < demo.directory.numentries; i++ ) { diff --git a/engine/client/cl_events.c b/engine/client/cl_events.c index cbcb3519..c7404dc9 100644 --- a/engine/client/cl_events.c +++ b/engine/client/cl_events.c @@ -164,7 +164,7 @@ void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func ) // clear existing or allocate new one if( !clgame.events[lastnum] ) - clgame.events[lastnum] = Mem_Alloc( cls.mempool, sizeof( cl_user_event_t )); + clgame.events[lastnum] = Mem_Calloc( cls.mempool, sizeof( cl_user_event_t )); else memset( clgame.events[lastnum], 0, sizeof( cl_user_event_t )); ev = clgame.events[lastnum]; diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index fa88f05a..576405d4 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -1226,6 +1226,12 @@ void CL_EmitEntities( void ) if( !cl.frames[cl.parsecountmod].valid ) return; + // animate lightestyles + CL_RunLightStyles (); + + // decay dynamic lights + CL_DecayLights (); + // compute last interpolation amount CL_UpdateFrameLerp (); diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index fff6d7cb..89182810 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -1115,16 +1115,16 @@ void CL_InitEdicts( void ) CL_UPDATE_BACKUP = ( cl.maxclients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP; cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES; - cls.packet_entities = Z_Realloc( cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities ); - clgame.entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities ); - clgame.static_entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES ); + cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities ); + clgame.entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities ); + clgame.static_entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES ); clgame.numStatics = 0; if(( clgame.maxRemapInfos - 1 ) != clgame.maxEntities ) { CL_ClearAllRemaps (); // purge old remap info clgame.maxRemapInfos = clgame.maxEntities + 1; - clgame.remap_info = (remap_info_t **)Mem_Alloc( clgame.mempool, sizeof( remap_info_t* ) * clgame.maxRemapInfos ); + clgame.remap_info = (remap_info_t **)Mem_Calloc( clgame.mempool, sizeof( remap_info_t* ) * clgame.maxRemapInfos ); } if( clgame.drawFuncs.R_ProcessEntData != NULL ) @@ -1535,7 +1535,7 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount ) Q_strncpy( pEntry->szListName, psz, sizeof( pEntry->szListName )); // name, res, pic, x, y, w, h - pEntry->pList = Mem_Alloc( cls.mempool, sizeof( client_sprite_t ) * numSprites ); + pEntry->pList = Mem_Calloc( cls.mempool, sizeof( client_sprite_t ) * numSprites ); for( index = 0; index < numSprites; index++ ) { @@ -3908,6 +3908,8 @@ static event_api_t gEventApi = CL_VisTraceLine, pfnGetVisent, CL_TestLine, + CL_PushTraceBounds, + CL_PopTraceBounds, }; static demo_api_t gDemoApi = diff --git a/engine/client/cl_gameui.c b/engine/client/cl_gameui.c index 2c62b894..5ce3de08 100644 --- a/engine/client/cl_gameui.c +++ b/engine/client/cl_gameui.c @@ -785,7 +785,7 @@ pfnMemAlloc */ static void *pfnMemAlloc( size_t cb, const char *filename, const int fileline ) { - return _Mem_Alloc( gameui.mempool, cb, filename, fileline ); + return _Mem_Alloc( gameui.mempool, cb, true, filename, fileline ); } /* @@ -1122,7 +1122,7 @@ qboolean UI_LoadProgs( void ) // setup gameinfo for( i = 0; i < SI.numgames; i++ ) { - gameui.modsInfo[i] = Mem_Alloc( gameui.mempool, sizeof( GAMEINFO )); + gameui.modsInfo[i] = Mem_Calloc( gameui.mempool, sizeof( GAMEINFO )); UI_ConvertGameInfo( gameui.modsInfo[i], SI.games[i] ); } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 8aec7a72..c80285fc 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -2061,13 +2061,11 @@ void CL_ReadPackets( void ) if( cl.maxclients > 1 && cls.state == ca_active && !host_developer.value ) Cvar_SetCheatState(); #endif - // singleplayer never has connection timeout - if( NET_IsLocalAddress( cls.netchan.remote_address )) - return; - // hot precache and downloading resources if( cls.signon == SIGNONS && cl.lastresourcecheck < host.realtime ) { + double checktime = Host_IsLocalGame() ? 0.1 : 1.0; + if( !cls.dl.custom && cl.resourcesneeded.pNext != &cl.resourcesneeded ) { // check resource for downloading and precache @@ -2075,9 +2073,14 @@ void CL_ReadPackets( void ) CL_BatchResourceRequest( false ); cls.dl.custom = true; } - cl.lastresourcecheck = host.realtime + 5.0f; // don't checking too often + + cl.lastresourcecheck = host.realtime + checktime; } + // singleplayer never has connection timeout + if( NET_IsLocalAddress( cls.netchan.remote_address )) + return; + // if in the debugger last frame, don't timeout if( host.frametime > 5.0f ) cls.netchan.last_received = Sys_DoubleTime(); @@ -2780,12 +2783,6 @@ void Host_ClientFrame( void ) // update audio SND_UpdateSound (); - // animate lightestyles - CL_RunLightStyles (); - - // decay dynamic lights - CL_DecayLights (); - // play avi-files SCR_RunCinematic (); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index b90d1de2..2e1f6142 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -285,7 +285,7 @@ void CL_ParseSoundPacket( sizebuf_t *msg ) char sentenceName[32]; if( FBitSet( flags, SND_SEQUENCE )) - Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound ); + Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS ); else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound ); handle = S_RegisterSound( sentenceName ); @@ -352,7 +352,7 @@ void CL_ParseRestoreSoundPacket( sizebuf_t *msg ) char sentenceName[32]; if( flags & SND_SEQUENCE ) - Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound ); + Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS ); else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound ); handle = S_RegisterSound( sentenceName ); @@ -778,7 +778,7 @@ int CL_EstimateNeededResources( void ) break; case t_model: nSize = FS_FileSize( p->szFileName, false ); - if( p->szFileName[0] != '*' && p->ucFlags && nSize == -1 ) + if( p->szFileName[0] != '*' && nSize == -1 ) { SetBits( p->ucFlags, RES_WASMISSING ); nTotalSize += p->nDownloadSize; @@ -897,7 +897,7 @@ void CL_ParseCustomization( sizebuf_t *msg ) if( i >= MAX_CLIENTS ) Host_Error( "Bogus player index during customization parsing.\n" ); - pRes = Mem_Alloc( cls.mempool, sizeof( resource_t )); + pRes = Mem_Calloc( cls.mempool, sizeof( resource_t )); pRes->type = MSG_ReadByte( msg ); Q_strncpy( pRes->szFileName, MSG_ReadString( msg ), sizeof( pRes->szFileName )); @@ -1576,7 +1576,7 @@ void CL_ParseResource( sizebuf_t *msg ) { resource_t *pResource; - pResource = Mem_Alloc( cls.mempool, sizeof( resource_t )); + pResource = Mem_Calloc( cls.mempool, sizeof( resource_t )); pResource->type = MSG_ReadUBitLong( msg, 4 ); Q_strncpy( pResource->szFileName, MSG_ReadString( msg ), sizeof( pResource->szFileName )); @@ -1834,7 +1834,7 @@ void CL_ParseResourceList( sizebuf_t *msg ) for( i = 0; i < total; i++ ) { - pResource = Mem_Alloc( cls.mempool, sizeof( resource_t )); + pResource = Mem_Calloc( cls.mempool, sizeof( resource_t )); pResource->type = MSG_ReadUBitLong( msg, 4 ); Q_strncpy( pResource->szFileName, MSG_ReadString( msg ), sizeof( pResource->szFileName )); @@ -1982,8 +1982,8 @@ void CL_ParseScreenFade( sizebuf_t *msg ) screenfade_t *sf = &clgame.fade; float flScale; - duration = (float)MSG_ReadShort( msg ); - holdTime = (float)MSG_ReadShort( msg ); + duration = (float)MSG_ReadWord( msg ); + holdTime = (float)MSG_ReadWord( msg ); sf->fadeFlags = MSG_ReadShort( msg ); flScale = ( sf->fadeFlags & FFADE_LONGFADE ) ? (1.0f / 256.0f) : (1.0f / 4096.0f); diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index 7c9c44f4..3672f3fc 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -81,6 +81,31 @@ void CL_PopPMStates( void ) } } +/* +============= +CL_PushTraceBounds + +============= +*/ +void CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs ) +{ + hullnum = bound( 0, hullnum, 3 ); + VectorCopy( mins, clgame.pmove->player_mins[hullnum] ); + VectorCopy( maxs, clgame.pmove->player_maxs[hullnum] ); +} + +/* +============= +CL_PopTraceBounds + +============= +*/ +void CL_PopTraceBounds( void ) +{ + memcpy( clgame.pmove->player_mins, host.player_mins, sizeof( host.player_mins )); + memcpy( clgame.pmove->player_maxs, host.player_maxs, sizeof( host.player_maxs )); +} + /* =============== CL_IsPredicted diff --git a/engine/client/cl_remap.c b/engine/client/cl_remap.c index 5c79d6b7..30ab070e 100644 --- a/engine/client/cl_remap.c +++ b/engine/client/cl_remap.c @@ -288,7 +288,7 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) // e.g. playermodel 'barney' with playermodel 'gordon' if( clgame.remap_info[i] ) CL_FreeRemapInfo( clgame.remap_info[i] ); // free old info size = sizeof( remap_info_t ) + ( sizeof( mstudiotexture_t ) * phdr->numtextures ); - info = clgame.remap_info[i] = Mem_Alloc( clgame.mempool, size ); + info = clgame.remap_info[i] = Mem_Calloc( clgame.mempool, size ); info->ptexture = (mstudiotexture_t *)(info + 1); // textures are immediately comes after remap_info } else @@ -325,7 +325,7 @@ void CL_AllocRemapInfo( int topcolor, int bottomcolor ) // this code catches studiomodel change with another studiomodel with remap textures // e.g. playermodel 'barney' with playermodel 'gordon' if( clgame.remap_info[i] ) CL_FreeRemapInfo( clgame.remap_info[i] ); // free old info - info = clgame.remap_info[i] = Mem_Alloc( clgame.mempool, sizeof( remap_info_t )); + info = clgame.remap_info[i] = Mem_Calloc( clgame.mempool, sizeof( remap_info_t )); } else { diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 8c08bf64..d3b09c05 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -176,7 +176,7 @@ SCR_RSpeeds */ void SCR_RSpeeds( void ) { - char msg[MAX_SYSPATH]; + char msg[2048]; if( !host.allow_console ) return; @@ -202,6 +202,9 @@ void SCR_RSpeeds( void ) Con_DrawString( x, y, p, color ); y += height; + // handle '\n\n' + if( *p == '\n' ) + y += height; if( end ) p = end + 1; else break; } while( 1 ); diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 16aba9b8..1398660c 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -127,7 +127,7 @@ void CL_AddClientResource( const char *filename, int type ) if( p != &cl.resourcesneeded ) return; // already in list? - pResource = Mem_Alloc( cls.mempool, sizeof( resource_t )); + pResource = Mem_Calloc( cls.mempool, sizeof( resource_t )); Q_strncpy( pResource->szFileName, filename, sizeof( pResource->szFileName )); pResource->type = type; @@ -325,7 +325,7 @@ CL_InitTempents */ void CL_InitTempEnts( void ) { - cl_tempents = Mem_Alloc( cls.mempool, sizeof( TEMPENTITY ) * GI->max_tents ); + cl_tempents = Mem_Calloc( cls.mempool, sizeof( TEMPENTITY ) * GI->max_tents ); CL_ClearTempEnts(); // load tempent sprites (glowshell, muzzleflashes etc) diff --git a/engine/client/client.h b/engine/client/client.h index a0666e9c..b3e71102 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -909,6 +909,8 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q int CL_TestLine( const vec3_t start, const vec3_t end, int flags ); pmtrace_t *CL_VisTraceLine( vec3_t start, vec3_t end, int flags ); pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags ); +void CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs ); +void CL_PopTraceBounds( void ); void CL_MoveSpectatorCamera( void ); void CL_SetLastUpdate( void ); void CL_RedoPrediction( void ); diff --git a/engine/client/console.c b/engine/client/console.c index 32865913..684d42ab 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -1124,9 +1124,9 @@ void Con_Init( void ) // init the console buffer con.bufsize = CON_TEXTSIZE; - con.buffer = (char *)Z_Malloc( con.bufsize ); + con.buffer = (char *)Z_Calloc( con.bufsize ); con.maxlines = CON_MAXLINES; - con.lines = (con_lineinfo_t *)Z_Malloc( con.maxlines * sizeof( *con.lines )); + con.lines = (con_lineinfo_t *)Z_Calloc( con.maxlines * sizeof( *con.lines )); con.lines_first = con.lines_count = 0; con.num_times = CON_TIMES; // default as 4 diff --git a/engine/client/gl_alias.c b/engine/client/gl_alias.c index 0ce8b5ef..9340cb2c 100644 --- a/engine/client/gl_alias.c +++ b/engine/client/gl_alias.c @@ -318,10 +318,10 @@ void GL_MakeAliasModelDisplayLists( model_t *m ) // save the data out m_pAliasHeader->poseverts = g_numorder; - m_pAliasHeader->commands = Mem_Alloc( m->mempool, g_numcommands * 4 ); + m_pAliasHeader->commands = Mem_Malloc( m->mempool, g_numcommands * 4 ); memcpy( m_pAliasHeader->commands, g_commands, g_numcommands * 4 ); - m_pAliasHeader->posedata = Mem_Alloc( m->mempool, m_pAliasHeader->numposes * m_pAliasHeader->poseverts * sizeof( trivertex_t )); + m_pAliasHeader->posedata = Mem_Malloc( m->mempool, m_pAliasHeader->numposes * m_pAliasHeader->poseverts * sizeof( trivertex_t )); verts = m_pAliasHeader->posedata; for( i = 0; i < m_pAliasHeader->numposes; i++ ) @@ -453,7 +453,7 @@ rgbdata_t *Mod_CreateSkinData( model_t *mod, byte *data, int width, int height ) i = mod->numtextures; mod->textures = (texture_t **)Mem_Realloc( mod->mempool, mod->textures, ( i + 1 ) * sizeof( texture_t* )); size = width * height + 768; - tx = Mem_Alloc( mod->mempool, sizeof( *tx ) + size ); + tx = Mem_Calloc( mod->mempool, sizeof( *tx ) + size ); mod->textures[i] = tx; Q_strncpy( tx->name, "DM_Skin", sizeof( tx->name )); @@ -639,7 +639,7 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded ) // skin and group info size = sizeof( aliashdr_t ) + (pinmodel->numframes - 1) * sizeof( maliasframedesc_t ); - m_pAliasHeader = Mem_Alloc( mod->mempool, size ); + m_pAliasHeader = Mem_Calloc( mod->mempool, size ); mod->flags = pinmodel->flags; // share effects flags // endian-adjust and copy the data, starting with the alias model header @@ -863,40 +863,44 @@ void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorScale( lightDir, 2048.0f, vecEnd ); VectorAdd( vecEnd, vecSrc, vecEnd ); - light = R_LightVec( vecSrc, vecEnd, g_alias.lightspot ); + light = R_LightVec( vecSrc, vecEnd, g_alias.lightspot, g_alias.lightvec ); - VectorScale( lightDir, 2048.0f, vecEnd ); - VectorAdd( vecEnd, vecSrc, vecEnd ); - - vecSrc[0] -= 16.0f; - vecSrc[1] -= 16.0f; - vecEnd[0] -= 16.0f; - vecEnd[1] -= 16.0f; + if( VectorIsNull( g_alias.lightvec )) + { + vecSrc[0] -= 16.0f; + vecSrc[1] -= 16.0f; + vecEnd[0] -= 16.0f; + vecEnd[1] -= 16.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - vecSrc[0] += 32.0f; - vecEnd[0] += 32.0f; + vecSrc[0] += 32.0f; + vecEnd[0] += 32.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - vecSrc[1] += 32.0f; - vecEnd[1] += 32.0f; + vecSrc[1] += 32.0f; + vecEnd[1] += 32.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - vecSrc[0] -= 32.0f; - vecEnd[0] -= 32.0f; + vecSrc[0] -= 32.0f; + vecEnd[0] -= 32.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3]; - lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3]; - VectorNormalize( lightDir ); + lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3]; + lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3]; + VectorNormalize( lightDir ); + } + else + { + VectorCopy( g_alias.lightvec, lightDir ); + } } VectorSet( finalLight, light.r, light.g, light.b ); @@ -1313,6 +1317,8 @@ static void R_AliasDrawLightTrace( cl_entity_t *e ) { if( r_drawentities->value == 7 ) { + vec3_t origin; + pglDisable( GL_TEXTURE_2D ); pglDisable( GL_DEPTH_TEST ); @@ -1322,6 +1328,13 @@ static void R_AliasDrawLightTrace( cl_entity_t *e ) pglVertex3fv( g_alias.lightspot ); pglEnd(); + pglBegin( GL_LINES ); + pglColor3f( 0, 0.5, 1 ); + VectorMA( g_alias.lightspot, -64.0f, g_alias.lightvec, origin ); + pglVertex3fv( g_alias.lightspot ); + pglVertex3fv( origin ); + pglEnd(); + pglPointSize( 5.0f ); pglColor3f( 1, 0, 0 ); pglBegin( GL_POINTS ); @@ -1429,11 +1442,16 @@ void R_DrawAliasModel( cl_entity_t *e ) R_AliasSetRemapColors( topcolor, bottomcolor ); } - pglTranslatef( m_pAliasHeader->scale_origin[0], m_pAliasHeader->scale_origin[1], m_pAliasHeader->scale_origin[2] ); - if( tr.fFlipViewModel ) + { + pglTranslatef( m_pAliasHeader->scale_origin[0], -m_pAliasHeader->scale_origin[1], m_pAliasHeader->scale_origin[2] ); pglScalef( m_pAliasHeader->scale[0], -m_pAliasHeader->scale[1], m_pAliasHeader->scale[2] ); - else pglScalef( m_pAliasHeader->scale[0], m_pAliasHeader->scale[1], m_pAliasHeader->scale[2] ); + } + else + { + pglTranslatef( m_pAliasHeader->scale_origin[0], m_pAliasHeader->scale_origin[1], m_pAliasHeader->scale_origin[2] ); + pglScalef( m_pAliasHeader->scale[0], m_pAliasHeader->scale[1], m_pAliasHeader->scale[2] ); + } anim = (int)(g_alias.time * 10) & 3; skin = bound( 0, RI.currententity->curstate.skin, m_pAliasHeader->numskins - 1 ); diff --git a/engine/client/gl_backend.c b/engine/client/gl_backend.c index 2ba36a7d..fffe2d30 100644 --- a/engine/client/gl_backend.c +++ b/engine/client/gl_backend.c @@ -463,14 +463,14 @@ qboolean VID_ScreenShot( const char *filename, int shot_type ) int width = 0, height = 0; qboolean result; - r_shot = Mem_Alloc( r_temppool, sizeof( rgbdata_t )); + r_shot = Mem_Calloc( r_temppool, sizeof( rgbdata_t )); r_shot->width = (glState.width + 3) & ~3; r_shot->height = (glState.height + 3) & ~3; r_shot->flags = IMAGE_HAS_COLOR; r_shot->type = PF_RGB_24; r_shot->size = r_shot->width * r_shot->height * PFDesc[r_shot->type].bpp; r_shot->palette = NULL; - r_shot->buffer = Mem_Alloc( r_temppool, r_shot->size ); + r_shot->buffer = Mem_Malloc( r_temppool, r_shot->size ); // get screen frame pglReadPixels( 0, 0, r_shot->width, r_shot->height, GL_RGB, GL_UNSIGNED_BYTE, r_shot->buffer ); @@ -546,10 +546,10 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo RI.params |= RP_ENVVIEW; // do not render non-bmodel entities // alloc space - temp = Mem_Alloc( r_temppool, size * size * 3 ); - buffer = Mem_Alloc( r_temppool, size * size * 3 * 6 ); - r_shot = Mem_Alloc( r_temppool, sizeof( rgbdata_t )); - r_side = Mem_Alloc( r_temppool, sizeof( rgbdata_t )); + temp = Mem_Malloc( r_temppool, size * size * 3 ); + buffer = Mem_Malloc( r_temppool, size * size * 3 * 6 ); + r_shot = Mem_Calloc( r_temppool, sizeof( rgbdata_t )); + r_side = Mem_Calloc( r_temppool, sizeof( rgbdata_t )); // use client vieworg if( !vieworg ) vieworg = RI.vieworg; @@ -568,7 +568,7 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo { R_DrawCubemapView( vieworg, r_envMapInfo[i].angles, size ); flags = r_envMapInfo[i].flags; - } + } pglReadPixels( 0, 0, size, size, GL_RGB, GL_UNSIGNED_BYTE, temp ); r_side->flags = IMAGE_HAS_COLOR; diff --git a/engine/client/gl_beams.c b/engine/client/gl_beams.c index a41e5553..76be0a69 100644 --- a/engine/client/gl_beams.c +++ b/engine/client/gl_beams.c @@ -442,19 +442,15 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f } // Iterator to resample noise waveform (it needs to be generated in powers of 2) - noiseStep = (int)((float)( NOISE_DIVISIONS - 1 ) * div * 65536.0f ); - + noiseStep = noiseIndex = (int)((float)( NOISE_DIVISIONS - 1 ) * div * 65536.0f ); + if( FBitSet( flags, FBEAM_SINENOISE )) noiseIndex = 0; - else - noiseIndex = noiseStep; brightness = 1.0f; if( FBitSet( flags, FBEAM_SHADEIN )) - { brightness = 0; - } // Choose two vectors that are perpendicular to the beam R_BeamComputePerpendicular( delta, perp1 ); @@ -1332,7 +1328,7 @@ CL_InitViewBeams */ void CL_InitViewBeams( void ) { - cl_viewbeams = Mem_Alloc( cls.mempool, sizeof( BEAM ) * GI->max_beams ); + cl_viewbeams = Mem_Calloc( cls.mempool, sizeof( BEAM ) * GI->max_beams ); CL_ClearViewBeams(); } diff --git a/engine/client/gl_decals.c b/engine/client/gl_decals.c index d30ddd3d..25b2f470 100644 --- a/engine/client/gl_decals.c +++ b/engine/client/gl_decals.c @@ -524,7 +524,7 @@ glpoly_t *R_DecalCreatePoly( decalinfo_t *decalinfo, decal_t *pdecal, msurface_t if( !lnumverts ) return NULL; // probably this never happens // allocate glpoly - poly = Mem_Alloc( com_studiocache, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float )); + poly = Mem_Calloc( com_studiocache, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float )); poly->next = pdecal->polys; poly->flags = surf->flags; pdecal->polys = poly; diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index 880422e8..f46e1e0d 100644 --- a/engine/client/gl_image.c +++ b/engine/client/gl_image.c @@ -173,7 +173,7 @@ void GL_ApplyTextureParams( gltexture_t *tex ) } // set texture anisotropy if available - if( GL_Support( GL_ANISOTROPY_EXT ) && ( tex->numMips > 1 )) + if( GL_Support( GL_ANISOTROPY_EXT ) && ( tex->numMips > 1 ) && !FBitSet( tex->flags, TF_ALPHACONTRAST )) pglTexParameterf( tex->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_anisotropy->value ); // set texture LOD bias if available @@ -256,7 +256,7 @@ static void GL_UpdateTextureParams( int iTexture ) GL_Bind( XASH_TEXTURE0, iTexture ); // set texture anisotropy if available - if( GL_Support( GL_ANISOTROPY_EXT ) && ( tex->numMips > 1 ) && !FBitSet( tex->flags, TF_DEPTHMAP )) + if( GL_Support( GL_ANISOTROPY_EXT ) && ( tex->numMips > 1 ) && !FBitSet( tex->flags, TF_DEPTHMAP|TF_ALPHACONTRAST )) pglTexParameterf( tex->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_anisotropy->value ); // set texture LOD bias if available @@ -554,10 +554,6 @@ static void GL_SetTextureDimensions( gltexture_t *tex, int width, int height, in height = scaled_height; } -#if 1 // TESTTEST - width = (width + 3) & ~3; - height = (height + 3) & ~3; -#endif if( width > maxTextureSize || height > maxTextureSize || depth > maxDepthSize ) { if( tex->target == GL_TEXTURE_1D ) @@ -709,7 +705,11 @@ static void GL_SetTextureFormat( gltexture_t *tex, pixformat_t format, int chann switch( GL_CalcTextureSamples( channelMask )) { - case 1: tex->format = GL_LUMINANCE8; break; + case 1: + if( FBitSet( tex->flags, TF_ALPHACONTRAST )) + tex->format = GL_INTENSITY8; + else tex->format = GL_LUMINANCE8; + break; case 2: tex->format = GL_LUMINANCE8_ALPHA8; break; case 3: switch( bits ) @@ -883,7 +883,7 @@ byte *GL_ApplyFilter( const byte *source, int width, int height ) byte *out = (byte *)source; int i; - if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) + if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) || glConfig.max_multisamples > 1 ) return in; for( i = 0; source && i < width * height; i++, in += 4 ) @@ -927,7 +927,7 @@ GL_BuildMipMap Operates in place, quartering the size of the texture ================= */ -static void GL_BuildMipMap( byte *in, int srcWidth, int srcHeight, int srcDepth, qboolean isNormalMap ) +static void GL_BuildMipMap( byte *in, int srcWidth, int srcHeight, int srcDepth, int flags ) { byte *out = in; int instride = ALIGN( srcWidth * 4, 1 ); @@ -937,15 +937,21 @@ static void GL_BuildMipMap( byte *in, int srcWidth, int srcHeight, int srcDepth, if( !in ) return; - mipWidth = max( 1, ( srcWidth >> 1 )); - mipHeight = max( 1, ( srcHeight >> 1 )); + mipWidth = Q_max( 1, ( srcWidth >> 1 )); + mipHeight = Q_max( 1, ( srcHeight >> 1 )); outpadding = ALIGN( mipWidth * 4, 1 ) - mipWidth * 4; row = srcWidth << 2; + if( FBitSet( flags, TF_ALPHACONTRAST )) + { + memset( in, mipWidth, mipWidth * mipHeight * 4 ); + return; + } + // move through all layers for( z = 0; z < srcDepth; z++ ) { - if( isNormalMap ) + if( FBitSet( flags, TF_NORMALMAP )) { for( y = 0; y < mipHeight; y++, in += instride * 2, out += outpadding ) { @@ -1218,10 +1224,10 @@ static qboolean GL_UploadTexture( gltexture_t *tex, rgbdata_t *pic ) if(( tex->depth == 1 ) && ( pic->width != tex->width ) || ( pic->height != tex->height )) data = GL_ResampleTexture( buf, pic->width, pic->height, tex->width, tex->height, normalMap ); else data = buf; - +#if 0 // g-cont. we can't apply gamma to each texture so we shouldn't do it at all if( !ImageDXT( pic->type ) && !FBitSet( tex->flags, TF_NOMIPMAP|TF_SKYSIDE )) data = GL_ApplyGamma( data, tex->width * tex->height * tex->depth, FBitSet( tex->flags, TF_NORMALMAP )); - +#endif if( !ImageDXT( pic->type ) && !FBitSet( tex->flags, TF_NOMIPMAP ) && FBitSet( pic->flags, IMAGE_ONEBIT_ALPHA )) data = GL_ApplyFilter( data, tex->width, tex->height ); @@ -1234,7 +1240,7 @@ static qboolean GL_UploadTexture( gltexture_t *tex, rgbdata_t *pic ) size = GL_CalcImageSize( pic->type, width, height, tex->depth ); GL_TextureImageRAW( tex, i, j, width, height, tex->depth, pic->type, data ); if( mipCount > 1 ) - GL_BuildMipMap( data, width, height, tex->depth, normalMap ); + GL_BuildMipMap( data, width, height, tex->depth, tex->flags ); tex->size += texsize; tex->numMips++; @@ -1495,11 +1501,11 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) else { // create new image - pic = Mem_Alloc( host.imagepool, sizeof( rgbdata_t )); + pic = Mem_Malloc( host.imagepool, sizeof( rgbdata_t )); memcpy( pic, src, sizeof( rgbdata_t )); // expand pic buffer for all layers - pic->buffer = Mem_Alloc( host.imagepool, pic->size * numLayers ); + pic->buffer = Mem_Malloc( host.imagepool, pic->size * numLayers ); pic->depth = 0; } @@ -1678,6 +1684,9 @@ int GL_CreateTexture( const char *name, int width, int height, const void *buffe r_empty.flags = IMAGE_HAS_COLOR | (( flags & TF_HAS_ALPHA ) ? IMAGE_HAS_ALPHA : 0 ); r_empty.buffer = (byte *)buffer; + if( FBitSet( flags, TF_ALPHACONTRAST )) + ClearBits( r_empty.flags, IMAGE_HAS_COLOR ); + if( FBitSet( flags, TF_TEXTURE_1D )) { r_empty.height = 1; diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index b290a71d..93477b88 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -38,6 +38,7 @@ extern byte *r_temppool; #define SHADEDOT_QUANT 16 // precalculated dot products for quantized angles #define SHADE_LAMBERT 1.495f +#define DEFAULT_ALPHATEST 0.0f // refparams #define RP_NONE 0 @@ -291,6 +292,12 @@ void R_Set2DMode( qboolean enable ); void R_DrawTileClear( int x, int y, int w, int h ); void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data ); +// +// gl_drawhulls.c +// +void R_DrawWorldHull( void ); +void R_DrawModelHull( void ); + // // gl_image.c // @@ -326,7 +333,7 @@ void R_PushDlights( void ); void R_AnimateLight( void ); void R_GetLightSpot( vec3_t lightspot ); void R_MarkLights( dlight_t *light, int bit, mnode_t *node ); -colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot ); +colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec ); int R_CountSurfaceDlights( msurface_t *surf ); colorVec R_LightPoint( const vec3_t p0 ); int R_CountDlights( void ); @@ -414,6 +421,7 @@ float CL_GetStudioEstimatedFrame( cl_entity_t *ent ); int R_GetEntityRenderMode( cl_entity_t *ent ); void R_DrawStudioModel( cl_entity_t *e ); player_info_t *pfnPlayerInfo( int index ); +void R_GatherPlayerLight( void ); // // gl_alias.c @@ -505,7 +513,6 @@ enum GL_ARB_DEPTH_FLOAT_EXT, GL_ARB_SEAMLESS_CUBEMAP, GL_EXT_GPU_SHADER4, // shaders only - GL_ARB_TEXTURE_RG, GL_DEPTH_TEXTURE, GL_DEBUG_OUTPUT, GL_EXTCOUNT, // must be last @@ -626,6 +633,7 @@ extern convar_t *gl_extensions; extern convar_t *gl_check_errors; extern convar_t *gl_texture_lodbias; extern convar_t *gl_texture_nearest; +extern convar_t *gl_wgl_msaa_samples; extern convar_t *gl_lightmap_nearest; extern convar_t *gl_keeptjunctions; extern convar_t *gl_round_down; @@ -639,7 +647,6 @@ extern convar_t *gl_test; // cvar to testify new effects extern convar_t *gl_msaa; extern convar_t *gl_stencilbits; - extern convar_t *r_speeds; extern convar_t *r_fullbright; extern convar_t *r_norefresh; diff --git a/engine/client/gl_rlight.c b/engine/client/gl_rlight.c index 9d9fd675..91fe10e7 100644 --- a/engine/client/gl_rlight.c +++ b/engine/client/gl_rlight.c @@ -49,7 +49,7 @@ void CL_RunLightStyles( void ) // 'm' is normal light, 'a' is no light, 'z' is double bright for( i = 0, ls = cl.lightstyles; i < MAX_LIGHTSTYLES; i++, ls++ ) { - if( r_fullbright->value || !cl.worldmodel->lightdata ) + if( !cl.worldmodel->lightdata ) { tr.lightstylevalue[i] = 256 * 256; continue; @@ -217,6 +217,7 @@ int R_CountSurfaceDlights( msurface_t *surf ) ======================================================================= */ static vec3_t g_trace_lightspot; +static vec3_t g_trace_lightvec; static float g_trace_fraction; /* @@ -230,10 +231,11 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, int i, map, side, size; float ds, dt, s, t; int sample_size; + color24 *lm, *dm; mextrasurf_t *info; msurface_t *surf; mtexinfo_t *tex; - color24 *lm; + matrix3x4 tbn; vec3_t mid; // didn't hit anything @@ -306,6 +308,31 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds ); g_trace_fraction = midf; size = smax * tmax; + dm = NULL; + + if( surf->info->deluxemap ) + { + vec3_t faceNormal; + + if( FBitSet( surf->flags, SURF_PLANEBACK )) + VectorNegate( surf->plane->normal, faceNormal ); + else VectorCopy( surf->plane->normal, faceNormal ); + + // compute face TBN +#if 1 + Vector4Set( tbn[0], surf->info->lmvecs[0][0], surf->info->lmvecs[0][1], surf->info->lmvecs[0][2], 0.0f ); + Vector4Set( tbn[1], -surf->info->lmvecs[1][0], -surf->info->lmvecs[1][1], -surf->info->lmvecs[1][2], 0.0f ); + Vector4Set( tbn[2], faceNormal[0], faceNormal[1], faceNormal[2], 0.0f ); +#else + Vector4Set( tbn[0], surf->info->lmvecs[0][0], -surf->info->lmvecs[1][0], faceNormal[0], 0.0f ); + Vector4Set( tbn[1], surf->info->lmvecs[0][1], -surf->info->lmvecs[1][1], faceNormal[1], 0.0f ); + Vector4Set( tbn[2], surf->info->lmvecs[0][2], -surf->info->lmvecs[1][2], faceNormal[2], 0.0f ); +#endif + VectorNormalize( tbn[0] ); + VectorNormalize( tbn[1] ); + VectorNormalize( tbn[2] ); + dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds ); + } for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) { @@ -324,6 +351,18 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, cv->b += LightToTexGamma( lm->b ) * scale; } lm += size; // skip to next lightmap + + if( dm != NULL ) + { + vec3_t srcNormal, lightNormal; + float f = (1.0f / 255.0f); + + VectorSet( srcNormal, (dm->r * f) * 2.0f - 1.0f, (dm->g * f) * 2.0f - 1.0f, (dm->b * f) * 2.0f - 1.0f ); + Matrix3x4_VectorIRotate( tbn, srcNormal, lightNormal ); // turn to world space + VectorScale( lightNormal, (float)scale * -1.0f, lightNormal ); // turn direction from light + VectorAdd( g_trace_lightvec, lightNormal, g_trace_lightvec ); + dm += size; // skip to next deluxmap + } } return true; @@ -340,13 +379,14 @@ R_LightVec check bspmodels to get light from ================= */ -colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot ) +colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec ) { float last_fraction; int i, maxEnts = 1; colorVec light, cv; if( lspot ) VectorClear( lspot ); + if( lvec ) VectorClear( lvec ); if( cl.worldmodel && cl.worldmodel->lightdata ) { @@ -354,7 +394,7 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot ) last_fraction = 1.0f; // get light from bmodels too - if( r_lighting_extended->value ) + if( CVAR_TO_BOOL( r_lighting_extended )) maxEnts = clgame.pmove->numphysent; // check all the bsp-models @@ -383,6 +423,7 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot ) } VectorClear( g_trace_lightspot ); + VectorClear( g_trace_lightvec ); g_trace_fraction = 1.0f; if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l )) @@ -391,6 +432,7 @@ colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot ) if( g_trace_fraction < last_fraction ) { if( lspot ) VectorCopy( g_trace_lightspot, lspot ); + if( lvec ) VectorNormalize2( g_trace_lightvec, lvec ); light.r = Q_min(( cv.r >> 7 ), 255 ); light.g = Q_min(( cv.g >> 7 ), 255 ); light.b = Q_min(( cv.b >> 7 ), 255 ); @@ -420,5 +462,5 @@ colorVec R_LightPoint( const vec3_t p0 ) VectorSet( p1, p0[0], p0[1], p0[2] - 2048.0f ); - return R_LightVec( p0, p1, NULL ); -} \ No newline at end of file + return R_LightVec( p0, p1, NULL, NULL ); +} diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 9850ccb9..0c668971 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -24,7 +24,7 @@ GNU General Public License for more details. #define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA ) -float gldepthmin, gldepthmax; +float gldepthmin, gldepthmax; ref_instance_t RI; static int R_RankForRenderMode( int rendermode ) @@ -240,10 +240,10 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type ) if( !clent || !clent->model ) return false; // if set to invisible, skip - if( clent->curstate.effects & EF_NODRAW ) + if( FBitSet( clent->curstate.effects, EF_NODRAW )) return false; // done - if( clent->curstate.rendermode != kRenderNormal && CL_FxBlend( clent ) <= 0 ) + if( !R_ModelOpaque( clent->curstate.rendermode ) && CL_FxBlend( clent ) <= 0 ) return true; // invisible if( type == ET_FRAGMENTED ) @@ -539,7 +539,7 @@ void R_SetupGL( qboolean set_gl_state ) pglMatrixMode( GL_MODELVIEW ); GL_LoadMatrix( RI.worldviewMatrix ); - if( RI.params & RP_CLIPPLANE ) + if( FBitSet( RI.params, RP_CLIPPLANE )) { GLdouble clip[4]; mplane_t *p = &RI.clipPlane; @@ -1082,8 +1082,22 @@ void R_RenderFrame( const ref_viewpass_t *rvp ) if( gl_finish->value && RI.drawWorld ) pglFinish(); - if( glConfig.max_multisamples > 1 ) - pglEnable( GL_MULTISAMPLE_ARB ); + if( glConfig.max_multisamples > 1 && FBitSet( gl_msaa->flags, FCVAR_CHANGED )) + { + if( CVAR_TO_BOOL( gl_msaa )) + { + pglEnable( GL_MULTISAMPLE_ARB ); + if( gl_msaa->value > 1.0f ) + pglEnable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB ); + else pglDisable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB ); + } + else + { + pglDisable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB ); + pglDisable( GL_MULTISAMPLE_ARB ); + } + ClearBits( gl_msaa->flags, FCVAR_CHANGED ); + } // completely override rendering if( clgame.drawFuncs.GL_RenderFrame != NULL ) @@ -1092,6 +1106,7 @@ void R_RenderFrame( const ref_viewpass_t *rvp ) if( clgame.drawFuncs.GL_RenderFrame( rvp )) { + R_GatherPlayerLight(); tr.realframecount++; tr.fResetVis = true; return; @@ -1384,7 +1399,7 @@ static const ref_overview_t *GL_GetOverviewParms( void ) static void *R_Mem_Alloc( size_t cb, const char *filename, const int fileline ) { - return _Mem_Alloc( cls.mempool, cb, filename, fileline ); + return _Mem_Alloc( cls.mempool, cb, true, filename, fileline ); } static void R_Mem_Free( void *mem, const char *filename, const int fileline ) diff --git a/engine/client/gl_rpart.c b/engine/client/gl_rpart.c index 3721cadd..b2ba1b5a 100644 --- a/engine/client/gl_rpart.c +++ b/engine/client/gl_rpart.c @@ -128,7 +128,7 @@ void CL_InitParticles( void ) { int i; - cl_particles = Mem_Alloc( cls.mempool, sizeof( particle_t ) * GI->max_particles ); + cl_particles = Mem_Calloc( cls.mempool, sizeof( particle_t ) * GI->max_particles ); CL_ClearParticles (); // this is used for EF_BRIGHTFIELD diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 190aae7c..c2f3671b 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -151,7 +151,7 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts ClearBits( warpface->flags, SURF_DRAWTURB_QUADS ); // add a point in the center to help keep warp valid - poly = Mem_Alloc( loadmodel->mempool, sizeof( glpoly_t ) + (numverts - 4) * VERTEXSIZE * sizeof( float )); + poly = Mem_Calloc( loadmodel->mempool, sizeof( glpoly_t ) + (numverts - 4) * VERTEXSIZE * sizeof( float )); poly->next = warpface->polys; poly->flags = warpface->flags; warpface->polys = poly; @@ -280,13 +280,10 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) float s, t; glpoly_t *poly; - // already created - if( !mod || fa->polys ) return; - - if( !fa->texinfo || !fa->texinfo->texture ) + if( !mod || !fa->texinfo || !fa->texinfo->texture ) return; // bad polygon ? - if( fa->flags & SURF_CONVEYOR && fa->texinfo->texture->gl_texturenum != 0 ) + if( FBitSet( fa->flags, SURF_CONVEYOR ) && fa->texinfo->texture->gl_texturenum != 0 ) { glt = R_GetTexture( fa->texinfo->texture->gl_texturenum ); tex = fa->texinfo->texture; @@ -304,8 +301,12 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) lnumverts = fa->numedges; vertpage = 0; - // draw texture - poly = Mem_Alloc( mod->mempool, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float )); + // detach if already created, reconstruct again + poly = fa->polys; + fa->polys = NULL; + + // quake simple models (healthkits etc) need to be reconstructed their polys because LM coords has changed after the map change + poly = Mem_Realloc( mod->mempool, poly, sizeof( glpoly_t ) + ( lnumverts - 4 ) * VERTEXSIZE * sizeof( float )); poly->next = fa->polys; poly->flags = fa->flags; fa->polys = poly; @@ -1294,7 +1295,7 @@ void R_DrawAlphaTextureChains( void ) GL_ResetFogColor(); R_BlendLightmaps(); RI.currententity->curstate.rendermode = kRenderNormal; // restore world rendermode - pglAlphaFunc( GL_GREATER, 0.0f ); + pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST ); } /* @@ -1564,9 +1565,10 @@ void R_DrawBrushModel( cl_entity_t *e ) e->curstate.rendermode = old_rendermode; pglDisable( GL_ALPHA_TEST ); - pglAlphaFunc( GL_GREATER, 0.0f ); + pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST ); pglDisable( GL_BLEND ); pglDepthMask( GL_TRUE ); + R_DrawModelHull(); // draw before restore R_LoadIdentity(); // restore worldmatrix } @@ -1904,6 +1906,8 @@ void R_DrawWorld( void ) skychain = NULL; R_DrawTriangleOutlines (); + + R_DrawWorldHull(); } /* @@ -1996,8 +2000,10 @@ void GL_CreateSurfaceLightmap( msurface_t *surf ) mextrasurf_t *info = surf->info; byte *base; - if( !cl.worldmodel->lightdata ) return; - if( surf->flags & SURF_DRAWTILED ) + if( !loadmodel->lightdata ) + return; + + if( FBitSet( surf->flags, SURF_DRAWTILED )) return; sample_size = Mod_SampleSizeForFace( surf ); diff --git a/engine/client/gl_sprite.c b/engine/client/gl_sprite.c index f1188fd1..40686bbd 100644 --- a/engine/client/gl_sprite.c +++ b/engine/client/gl_sprite.c @@ -78,7 +78,7 @@ static dframetype_t *R_SpriteLoadFrame( model_t *mod, void *pin, mspriteframe_t } // setup frame description - pspriteframe = Mem_Alloc( mod->mempool, sizeof( mspriteframe_t )); + pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t )); pspriteframe->width = pinframe->width; pspriteframe->height = pinframe->height; pspriteframe->up = pinframe->origin[1]; @@ -111,12 +111,12 @@ static dframetype_t *R_SpriteLoadGroup( model_t *mod, void *pin, mspriteframe_t numframes = pingroup->numframes; groupsize = sizeof( mspritegroup_t ) + (numframes - 1) * sizeof( pspritegroup->frames[0] ); - pspritegroup = Mem_Alloc( mod->mempool, groupsize ); + pspritegroup = Mem_Calloc( mod->mempool, groupsize ); pspritegroup->numframes = numframes; *ppframe = (mspriteframe_t *)pspritegroup; pin_intervals = (dspriteinterval_t *)(pingroup + 1); - poutintervals = Mem_Alloc( mod->mempool, numframes * sizeof( float )); + poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float )); pspritegroup->intervals = poutintervals; for( i = 0; i < numframes; i++ ) @@ -179,7 +179,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui { pinq1 = (dsprite_q1_t *)buffer; size = sizeof( msprite_t ) + ( pinq1->numframes - 1 ) * sizeof( psprite->frames ); - psprite = Mem_Alloc( mod->mempool, size ); + psprite = Mem_Calloc( mod->mempool, size ); mod->cache.data = psprite; // make link to extradata psprite->type = pinq1->type; @@ -199,7 +199,7 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui { pinhl = (dsprite_hl_t *)buffer; size = sizeof( msprite_t ) + ( pinhl->numframes - 1 ) * sizeof( psprite->frames ); - psprite = Mem_Alloc( mod->mempool, size ); + psprite = Mem_Calloc( mod->mempool, size ); mod->cache.data = psprite; // make link to extradata psprite->type = pinhl->type; @@ -347,7 +347,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean // determine how many frames we needs numframes = (pix->width * pix->height) / (w * h); mod->mempool = Mem_AllocPool( va( "^2%s^7", mod->name )); - psprite = Mem_Alloc( mod->mempool, sizeof( msprite_t ) + ( numframes - 1 ) * sizeof( psprite->frames )); + psprite = Mem_Calloc( mod->mempool, sizeof( msprite_t ) + ( numframes - 1 ) * sizeof( psprite->frames )); mod->cache.data = psprite; // make link to extradata psprite->type = SPR_FWD_PARALLEL_ORIENTED; @@ -367,7 +367,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean temp.type = pix->type; temp.flags = pix->flags; temp.size = w * h * PFDesc[temp.type].bpp; - temp.buffer = Mem_Alloc( r_temppool, temp.size ); + temp.buffer = Mem_Malloc( r_temppool, temp.size ); temp.palette = NULL; // chop the image and upload into video memory @@ -392,7 +392,7 @@ void Mod_LoadMapSprite( model_t *mod, const void *buffer, size_t size, qboolean // build uinque frame name Q_snprintf( texname, sizeof( texname ), "#MAP/%s_%i%i.spr", mod->name, i / 10, i % 10 ); - psprite->frames[i].frameptr = Mem_Alloc( mod->mempool, sizeof( mspriteframe_t )); + psprite->frames[i].frameptr = Mem_Calloc( mod->mempool, sizeof( mspriteframe_t )); pspriteframe = psprite->frames[i].frameptr; pspriteframe->width = w; pspriteframe->height = h; @@ -979,7 +979,7 @@ void R_DrawSpriteModel( cl_entity_t *e ) color2[1] = (float)lightColor.g * ( 1.0f / 255.0f ); color2[2] = (float)lightColor.b * ( 1.0f / 255.0f ); // NOTE: sprites with 'lightmap' looks ugly when alpha func is GL_GREATER 0.0 - pglAlphaFunc( GL_GREATER, 0.25f ); + pglAlphaFunc( GL_GREATER, 0.5f ); } if( R_SpriteAllowLerping( e, psprite )) @@ -1073,7 +1073,7 @@ void R_DrawSpriteModel( cl_entity_t *e ) pglColor4f( color2[0], color2[1], color2[2], tr.blend ); GL_Bind( XASH_TEXTURE0, tr.whiteTexture ); R_DrawSpriteQuad( frame, origin, v_right, v_up, scale ); - pglAlphaFunc( GL_GREATER, 0.0f ); + pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST ); pglDepthFunc( GL_LEQUAL ); } diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index e9785109..4673a085 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -139,7 +139,7 @@ void R_StudioInit( void ) Matrix3x4_LoadIdentity( g_studio.rotationmatrix ); Cvar_RegisterVariable( &r_glowshellfreq ); -// g-cont. especially not registered + // g-cont. cvar disabled by Valve // Cvar_RegisterVariable( &r_shadows ); g_studio.interpolate = true; @@ -718,6 +718,7 @@ float CL_GetSequenceDuration( cl_entity_t *ent, int sequence ) return 0.1f; } + /* ==================== StudioFxTransform @@ -1447,40 +1448,44 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight ) VectorScale( lightDir, 2048.0f, vecEnd ); VectorAdd( vecEnd, vecSrc, vecEnd ); - light = R_LightVec( vecSrc, vecEnd, g_studio.lightspot ); - - VectorScale( lightDir, 2048.0f, vecEnd ); - VectorAdd( vecEnd, vecSrc, vecEnd ); + light = R_LightVec( vecSrc, vecEnd, g_studio.lightspot, g_studio.lightvec ); - vecSrc[0] -= 16.0f; - vecSrc[1] -= 16.0f; - vecEnd[0] -= 16.0f; - vecEnd[1] -= 16.0f; + if( VectorIsNull( g_studio.lightvec )) + { + vecSrc[0] -= 16.0f; + vecSrc[1] -= 16.0f; + vecEnd[0] -= 16.0f; + vecEnd[1] -= 16.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[0] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - vecSrc[0] += 32.0f; - vecEnd[0] += 32.0f; + vecSrc[0] += 32.0f; + vecEnd[0] += 32.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[1] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - vecSrc[1] += 32.0f; - vecEnd[1] += 32.0f; + vecSrc[1] += 32.0f; + vecEnd[1] += 32.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[2] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - vecSrc[0] -= 32.0f; - vecEnd[0] -= 32.0f; + vecSrc[0] -= 32.0f; + vecEnd[0] -= 32.0f; - gcolor = R_LightVec( vecSrc, vecEnd, NULL ); - grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; + gcolor = R_LightVec( vecSrc, vecEnd, NULL, NULL ); + grad[3] = ( gcolor.r + gcolor.g + gcolor.b ) / 768.0f; - lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3]; - lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3]; - VectorNormalize( lightDir ); + lightDir[0] = grad[0] - grad[1] - grad[2] + grad[3]; + lightDir[1] = grad[1] + grad[0] - grad[2] - grad[3]; + VectorNormalize( lightDir ); + } + else + { + VectorCopy( g_studio.lightvec, lightDir ); + } } VectorSet( finalLight, light.r, light.g, light.b ); @@ -2186,7 +2191,7 @@ static void R_StudioDrawPoints( void ) if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED )) { - pglAlphaFunc( GL_GREATER, 0.0f ); + pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST ); pglDisable( GL_ALPHA_TEST ); } else if( FBitSet( g_nFaceFlags, STUDIO_NF_ADDITIVE ) && R_ModelOpaque( RI.currententity->curstate.rendermode )) @@ -2290,6 +2295,7 @@ static void R_StudioDrawAbsBBox( void ) TriVertex3fv( p[boxpnt[i][3]] ); } TriEnd(); + TriRenderMode( kRenderNormal ); } /* @@ -2885,6 +2891,13 @@ void R_StudioRenderFinal( void ) pglVertex3fv( g_studio.lightspot ); pglEnd(); + pglBegin( GL_LINES ); + pglColor3f( 0, 0.5, 1 ); + VectorMA( g_studio.lightspot, -64.0f, g_studio.lightvec, origin ); + pglVertex3fv( g_studio.lightspot ); + pglVertex3fv( origin ); + pglEnd(); + pglPointSize( 5.0f ); pglColor3f( 1, 0, 0 ); pglBegin( GL_POINTS ); @@ -3390,10 +3403,10 @@ void R_RunViewmodelEvents( void ) /* ================= -R_DrawViewModel +R_GatherPlayerLight ================= */ -void R_DrawViewModel( void ) +void R_GatherPlayerLight( void ) { cl_entity_t *view = &clgame.viewent; colorVec c; @@ -3402,6 +3415,18 @@ void R_DrawViewModel( void ) c = R_LightPoint( view->origin ); tr.ignore_lightgamma = false; cl.local.light_level = (c.r + c.g + c.b) / 3; +} + +/* +================= +R_DrawViewModel +================= +*/ +void R_DrawViewModel( void ) +{ + cl_entity_t *view = &clgame.viewent; + + R_GatherPlayerLight(); if( r_drawviewmodel->value == 0 ) return; @@ -3433,6 +3458,10 @@ void R_DrawViewModel( void ) pglFrontFace( GL_CW ); } + // FIXME: viewmodel is invisible when alpha to coverage is enabled + if( glConfig.max_multisamples > 1 && gl_msaa->value > 1.0f ) + pglDisable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB ); + switch( RI.currententity->model->type ) { case mod_alias: @@ -3444,6 +3473,9 @@ void R_DrawViewModel( void ) break; } + if( glConfig.max_multisamples > 1 && gl_msaa->value > 1.0f ) + pglEnable( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB ); + // restore depth range pglDepthRange( gldepthmin, gldepthmax ); @@ -3483,7 +3515,7 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture i = mod->numtextures; mod->textures = (texture_t **)Mem_Realloc( mod->mempool, mod->textures, ( i + 1 ) * sizeof( texture_t* )); size = ptexture->width * ptexture->height + 768; - tx = Mem_Alloc( mod->mempool, sizeof( *tx ) + size ); + tx = Mem_Calloc( mod->mempool, sizeof( *tx ) + size ); mod->textures[i] = tx; // store ranges into anim_min, anim_max etc diff --git a/engine/client/gl_warp.c b/engine/client/gl_warp.c index e9617792..39db7719 100644 --- a/engine/client/gl_warp.c +++ b/engine/client/gl_warp.c @@ -679,7 +679,7 @@ void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette ) // make an average value for the back to avoid // a fringe on the top level - trans = Mem_Alloc( r_temppool, r_sky->height * r_sky->height * sizeof( *trans )); + trans = Mem_Malloc( r_temppool, r_sky->height * r_sky->height * sizeof( *trans )); r = g = b = 0; for( i = 0; i < r_sky->width >> 1; i++ ) diff --git a/engine/client/in_touch.c b/engine/client/in_touch.c index 5bef8da0..74f36120 100644 --- a/engine/client/in_touch.c +++ b/engine/client/in_touch.c @@ -625,7 +625,7 @@ void IN_TouchReloadConfig_f( void ) touchbutton2_t *IN_TouchAddButton( touchbuttonlist_t *list, const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color ) { - touchbutton2_t *button = Mem_Alloc( touch.mempool, sizeof( touchbutton2_t ) ); + touchbutton2_t *button = Mem_Malloc( touch.mempool, sizeof( touchbutton2_t ) ); button->texture = -1; Q_strncpy( button->texturefile, texture, sizeof( button->texturefile ) ); Q_strncpy( button->name, name, 32 ); diff --git a/engine/client/s_dsp.c b/engine/client/s_dsp.c index f0e25270..b6144719 100644 --- a/engine/client/s_dsp.c +++ b/engine/client/s_dsp.c @@ -273,7 +273,7 @@ int DLY_Init( int idelay, float delay ) cur = &rgsxdly[idelay]; cur->cdelaysamplesmax = ((int)(delay * idsp_dma_speed) << sxhires) + 1; - cur->lpdelayline = (int *)Z_Malloc( cur->cdelaysamplesmax * sizeof( int )); + cur->lpdelayline = (int *)Z_Calloc( cur->cdelaysamplesmax * sizeof( int )); cur->xfade = 0; // init modulation diff --git a/engine/client/s_load.c b/engine/client/s_load.c index 86a12556..409909c8 100644 --- a/engine/client/s_load.c +++ b/engine/client/s_load.c @@ -104,7 +104,7 @@ static wavdata_t *S_CreateDefaultSound( void ) { wavdata_t *sc; - sc = Mem_Alloc( sndpool, sizeof( wavdata_t )); + sc = Mem_Calloc( sndpool, sizeof( wavdata_t )); sc->width = 2; sc->channels = 1; @@ -112,7 +112,7 @@ static wavdata_t *S_CreateDefaultSound( void ) sc->rate = SOUND_DMA_SPEED; sc->samples = SOUND_DMA_SPEED; sc->size = sc->samples * sc->width * sc->channels; - sc->buffer = Mem_Alloc( sndpool, sc->size ); + sc->buffer = Mem_Calloc( sndpool, sc->size ); return sc; } diff --git a/engine/client/s_main.c b/engine/client/s_main.c index 7ac6dadf..9182f465 100644 --- a/engine/client/s_main.c +++ b/engine/client/s_main.c @@ -1459,7 +1459,7 @@ rawchan_t *S_FindRawChannel( int entnum, qboolean create ) if( !raw_channels[best] ) { raw_samples = MAX_RAW_SAMPLES; - raw_channels[best] = Mem_Alloc( sndpool, sizeof( *ch ) + sizeof( portable_samplepair_t ) * ( raw_samples - 1 )); + raw_channels[best] = Mem_Calloc( sndpool, sizeof( *ch ) + sizeof( portable_samplepair_t ) * ( raw_samples - 1 )); } ch = raw_channels[best]; diff --git a/engine/client/s_vox.c b/engine/client/s_vox.c index f36ef5a5..4082f69a 100644 --- a/engine/client/s_vox.c +++ b/engine/client/s_vox.c @@ -617,6 +617,12 @@ void VOX_ReadSentenceFile( const char *psentenceFileName ) while( pch < pchlast ) { + if( g_numSentences >= MAX_SENTENCES ) + { + Con_Printf( S_ERROR "VOX_Init: too many sentences specified\n" ); + break; + } + // only process this pass on sentences pSentenceData = NULL; diff --git a/engine/client/titles.c b/engine/client/titles.c index 0a318d6b..8d77b9ee 100644 --- a/engine/client/titles.c +++ b/engine/client/titles.c @@ -317,7 +317,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize ) } // must malloc because we need to be able to clear it after initialization - clgame.titles = (client_textmessage_t *)Mem_Alloc( cls.mempool, textHeapSize + nameHeapSize + messageSize ); + clgame.titles = (client_textmessage_t *)Mem_Calloc( cls.mempool, textHeapSize + nameHeapSize + messageSize ); // copy table over memcpy( clgame.titles, textMessages, messageSize ); diff --git a/engine/client/vid_common.c b/engine/client/vid_common.c index 0cf27fcd..9b485dc3 100644 --- a/engine/client/vid_common.c +++ b/engine/client/vid_common.c @@ -26,6 +26,7 @@ convar_t *gl_extensions; convar_t *gl_texture_anisotropy; convar_t *gl_texture_lodbias; convar_t *gl_texture_nearest; +convar_t *gl_wgl_msaa_samples; convar_t *gl_lightmap_nearest; convar_t *gl_keeptjunctions; convar_t *gl_showtextures; @@ -324,7 +325,7 @@ static void GL_SetDefaults( void ) pglDisable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglDisable( GL_POLYGON_OFFSET_FILL ); - pglAlphaFunc( GL_GREATER, 0.0f ); + pglAlphaFunc( GL_GREATER, DEFAULT_ALPHATEST ); pglEnable( GL_TEXTURE_2D ); pglShadeModel( GL_SMOOTH ); pglFrontFace( GL_CCW ); @@ -458,7 +459,8 @@ void GL_InitCommands( void ) gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" ); gl_test = Cvar_Get( "gl_test", "0", 0, "engine developer cvar for quick testing new features" ); gl_wireframe = Cvar_Get( "gl_wireframe", "0", FCVAR_ARCHIVE|FCVAR_SPONLY, "show wireframe overlay" ); - gl_msaa = Cvar_Get( "gl_msaa", "0", FCVAR_GLCONFIG, "MSAA samples. Use with caution, engine may fail with some values" ); + gl_wgl_msaa_samples = Cvar_Get( "gl_wgl_msaa_samples", "4", FCVAR_GLCONFIG, "enable multisample anti-aliasing" ); + gl_msaa = Cvar_Get( "gl_msaa", "2", FCVAR_ARCHIVE, "enable multi sample anti-aliasing" ); gl_stencilbits = Cvar_Get( "gl_stencilbits", "8", FCVAR_GLCONFIG, "pixelformat stencil bits (0 - auto)" ); gl_round_down = Cvar_Get( "gl_round_down", "2", FCVAR_RENDERINFO, "round texture sizes to nearest POT value" ); // these cvar not used by engine but some mods requires this diff --git a/engine/client/vox.h b/engine/client/vox.h index 7391e2d9..7276ee45 100644 --- a/engine/client/vox.h +++ b/engine/client/vox.h @@ -18,7 +18,7 @@ GNU General Public License for more details. #define CVOXWORDMAX 64 #define CVOXZEROSCANMAX 255 // scan up to this many samples for next zero crossing -#define MAX_SENTENCES 2048 +#define MAX_SENTENCES 4096 #define SENTENCE_INDEX -99999 // unique sentence index typedef struct voxword_s diff --git a/engine/common/build.c b/engine/common/build.c index 89af30aa..83afbbd8 100644 --- a/engine/common/build.c +++ b/engine/common/build.c @@ -23,7 +23,7 @@ static char mond[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int Q_buildnum( void ) { // do not touch this! Only author of Xash3D can increase buildnumbers! -#if 1 +#if 0 int m = 0, d = 0, y = 0; static int b = 0; @@ -48,7 +48,7 @@ int Q_buildnum( void ) return b; #else - return 3847; + return 4140; #endif } diff --git a/engine/common/cmd.c b/engine/common/cmd.c index d7ccda01..dbe0f535 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -697,7 +697,7 @@ Cmd_AddClientCommand */ int Cmd_AddClientCommand( const char *cmd_name, xcommand_t function ) { - return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "server command", CMD_CLIENTDLL ); + return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "client command", CMD_CLIENTDLL ); } /* @@ -707,7 +707,7 @@ Cmd_AddGameUICommand */ int Cmd_AddGameUICommand( const char *cmd_name, xcommand_t function ) { - return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "server command", CMD_GAMEUIDLL ); + return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "gameui command", CMD_GAMEUIDLL ); } /* diff --git a/engine/common/common.h b/engine/common/common.h index 936847ec..969a53f6 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -887,7 +887,8 @@ void pfnResetTutorMessageDecayData( void ); ============================================================== */ -#define Z_Malloc( size ) Mem_Alloc( host.mempool, size ) +#define Z_Malloc( size ) Mem_Malloc( host.mempool, size ) +#define Z_Calloc( size ) Mem_Calloc( host.mempool, size ) #define Z_Realloc( ptr, size ) Mem_Realloc( host.mempool, ptr, size ) #define Z_Free( ptr ) if( ptr != NULL ) Mem_Free( ptr ) diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index 644a8a83..f977468f 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -102,7 +102,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) if( !ents && lumplen >= 10 ) { FS_Seek( f, lumpofs, SEEK_SET ); - ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 ); + ents = (char *)Mem_Calloc( host.mempool, lumplen + 1 ); FS_Read( f, ents, lumplen ); } @@ -694,7 +694,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) return false; } - buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result )); + buffer = Mem_Calloc( host.mempool, t->numfilenames * 2 * sizeof( result )); for( i = 0; i < t->numfilenames; i++ ) { @@ -736,7 +736,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) if( !ents && lumplen >= 10 ) { FS_Seek( f, lumpofs, SEEK_SET ); - ents = Z_Malloc( lumplen + 1 ); + ents = Z_Calloc( lumplen + 1 ); FS_Read( f, ents, lumplen ); } diff --git a/engine/common/crtlib.c b/engine/common/crtlib.c index 9a69b3a9..42bdc82b 100644 --- a/engine/common/crtlib.c +++ b/engine/common/crtlib.c @@ -185,7 +185,7 @@ char *_copystring( byte *mempool, const char *s, const char *filename, int filel if( !s ) return NULL; if( !mempool ) mempool = host.mempool; - b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, filename, fileline ); + b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, false, filename, fileline ); Q_strcpy( b, s ); return b; diff --git a/engine/common/crtlib.h b/engine/common/crtlib.h index 034574a8..c9ee170c 100644 --- a/engine/common/crtlib.h +++ b/engine/common/crtlib.h @@ -115,8 +115,8 @@ char *va( const char *format, ... ) _format( 1 ); // zone.c // void Memory_Init( void ); -void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, const char *filename, int fileline ); -void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline ); +void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ); +void *_Mem_Alloc( byte *poolptr, size_t size, qboolean clear, const char *filename, int fileline ); byte *_Mem_AllocPool( const char *name, const char *filename, int fileline ); void _Mem_FreePool( byte **poolptr, const char *filename, int fileline ); void _Mem_EmptyPool( byte *poolptr, const char *filename, int fileline ); @@ -126,8 +126,9 @@ qboolean Mem_IsAllocatedExt( byte *poolptr, void *data ); void Mem_PrintList( size_t minallocationsize ); void Mem_PrintStats( void ); -#define Mem_Alloc( pool, size ) _Mem_Alloc( pool, size, __FILE__, __LINE__ ) -#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, __FILE__, __LINE__ ) +#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ ) +#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ ) +#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ ) #define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ ) #define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ ) #define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ ) diff --git a/engine/common/custom.c b/engine/common/custom.c index 651be8a1..f624b0c6 100644 --- a/engine/common/custom.c +++ b/engine/common/custom.c @@ -68,7 +68,7 @@ qboolean COM_CreateCustomization( customization_t *pListHead, resource_t *pResou if( pOut ) *pOut = NULL; - pCust = Z_Malloc( sizeof( customization_t )); + pCust = Z_Calloc( sizeof( customization_t )); pCust->resource = *pResource; if( pResource->nDownloadSize <= 0 ) diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index b3630b39..685c9e2a 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -31,7 +31,7 @@ GNU General Public License for more details. #include "protocol.h" #define FILE_COPY_SIZE (1024 * 1024) -#define FILE_BUFF_SIZE (65535) +#define FILE_BUFF_SIZE (2048) // PAK errors #define PAK_LOAD_OK 0 @@ -225,7 +225,7 @@ static void stringlistappend( stringlist_t *list, char *text ) } textlen = Q_strlen( text ) + 1; - list->strings[list->numstrings] = Mem_Alloc( fs_mempool, textlen ); + list->strings[list->numstrings] = Mem_Calloc( fs_mempool, textlen ); memcpy( list->strings[list->numstrings], text, textlen ); list->numstrings++; } @@ -555,7 +555,7 @@ pack_t *FS_LoadPackPAK( const char *packfile, int *error ) return NULL; } - info = (dpackfile_t *)Mem_Alloc( fs_mempool, sizeof( *info ) * numpackfiles ); + info = (dpackfile_t *)Mem_Malloc( fs_mempool, sizeof( *info ) * numpackfiles ); lseek( packhandle, header.dirofs, SEEK_SET ); if( header.dirlen != read( packhandle, (void *)info, header.dirlen )) @@ -567,9 +567,9 @@ pack_t *FS_LoadPackPAK( const char *packfile, int *error ) return NULL; } - pack = (pack_t *)Mem_Alloc( fs_mempool, sizeof( pack_t )); + pack = (pack_t *)Mem_Calloc( fs_mempool, sizeof( pack_t )); Q_strncpy( pack->filename, packfile, sizeof( pack->filename )); - pack->files = (dpackfile_t *)Mem_Alloc( fs_mempool, numpackfiles * sizeof( dpackfile_t )); + pack->files = (dpackfile_t *)Mem_Calloc( fs_mempool, numpackfiles * sizeof( dpackfile_t )); pack->filetime = FS_SysFileTime( packfile ); pack->handle = packhandle; pack->numfiles = 0; @@ -611,7 +611,7 @@ static qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loade if( wad ) { - search = (searchpath_t *)Mem_Alloc( fs_mempool, sizeof( searchpath_t )); + search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t )); search->wad = wad; search->next = fs_searchpaths; search->flags |= flags; @@ -667,7 +667,7 @@ static qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loade { string fullpath; - search = (searchpath_t *)Mem_Alloc( fs_mempool, sizeof( searchpath_t )); + search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t )); search->pack = pak; search->next = fs_searchpaths; search->flags |= flags; @@ -744,7 +744,7 @@ void FS_AddGameDirectory( const char *dir, int flags ) // add the directory to the search path // (unpacked files have the priority over packed files) - search = (searchpath_t *)Mem_Alloc( fs_mempool, sizeof( searchpath_t )); + search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t )); Q_strncpy( search->filename, dir, sizeof ( search->filename )); search->next = fs_searchpaths; search->flags = flags; @@ -1446,64 +1446,60 @@ void FS_Init( void ) #endif // ignore commandlineoption "-game" for other stuff - if( host.type == HOST_NORMAL || Host_IsDedicated() ) - { - stringlistinit( &dirs ); - listdirectory( &dirs, "./", false ); - stringlistsort( &dirs ); - SI.numgames = 0; + stringlistinit( &dirs ); + listdirectory( &dirs, "./", false ); + stringlistsort( &dirs ); + SI.numgames = 0; - Q_strncpy( fs_basedir, SI.basedirName, sizeof( fs_basedir )); // default dir + Q_strncpy( fs_basedir, SI.basedirName, sizeof( fs_basedir )); // default dir - if( !Sys_GetParmFromCmdLine( "-game", fs_gamedir )) - Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); // gamedir == basedir - - if( FS_CheckNastyPath( fs_basedir, true )) - { - // this is completely fatal... - Sys_Error( "invalid base directory \"%s\"\n", fs_basedir ); - } + if( !Sys_GetParmFromCmdLine( "-game", fs_gamedir )) + Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); // gamedir == basedir - if( FS_CheckNastyPath( fs_gamedir, true )) - { - Con_Printf( S_ERROR "invalid game directory \"%s\"\n", fs_gamedir ); - Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); // default dir - } + if( FS_CheckNastyPath( fs_basedir, true )) + { + // this is completely fatal... + Sys_Error( "invalid base directory \"%s\"\n", fs_basedir ); + } - // validate directories - for( i = 0; i < dirs.numstrings; i++ ) - { - if( !Q_stricmp( fs_basedir, dirs.strings[i] )) - hasBaseDir = true; + if( FS_CheckNastyPath( fs_gamedir, true )) + { + Con_Printf( S_ERROR "invalid game directory \"%s\"\n", fs_gamedir ); + Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); // default dir + } - if( !Q_stricmp( fs_gamedir, dirs.strings[i] )) - hasGameDir = true; - } + // validate directories + for( i = 0; i < dirs.numstrings; i++ ) + { + if( !Q_stricmp( fs_basedir, dirs.strings[i] )) + hasBaseDir = true; - if( !hasGameDir ) - { - Con_Printf( S_ERROR "game directory \"%s\" not exist\n", fs_gamedir ); - if( hasBaseDir ) Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); - } + if( !Q_stricmp( fs_gamedir, dirs.strings[i] )) + hasGameDir = true; + } - // build list of game directories here - FS_AddGameDirectory( "./", 0 ); + if( !hasGameDir ) + { + Con_Printf( S_ERROR "game directory \"%s\" not exist\n", fs_gamedir ); + if( hasBaseDir ) Q_strncpy( fs_gamedir, fs_basedir, sizeof( fs_gamedir )); + } - for( i = 0; i < dirs.numstrings; i++ ) - { - if( !FS_SysFolderExists( dirs.strings[i] ) || ( !Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) - continue; + // build list of game directories here + FS_AddGameDirectory( "./", 0 ); - if( SI.games[SI.numgames] == NULL ) - SI.games[SI.numgames] = (gameinfo_t *)Mem_Alloc( fs_mempool, sizeof( gameinfo_t )); + for( i = 0; i < dirs.numstrings; i++ ) + { + if( !FS_SysFolderExists( dirs.strings[i] ) || ( !Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) + continue; - if( FS_ParseGameInfo( dirs.strings[i], SI.games[SI.numgames] )) - SI.numgames++; // added - } + if( SI.games[SI.numgames] == NULL ) + SI.games[SI.numgames] = (gameinfo_t *)Mem_Calloc( fs_mempool, sizeof( gameinfo_t )); - stringlistfreecontents( &dirs ); - } + if( FS_ParseGameInfo( dirs.strings[i], SI.games[SI.numgames] )) + SI.numgames++; // added + } + stringlistfreecontents( &dirs ); Con_Reportf( "FS_Init: done\n" ); } @@ -1601,7 +1597,7 @@ static file_t *FS_SysOpen( const char *filepath, const char *mode ) } } - file = (file_t *)Mem_Alloc( fs_mempool, sizeof( *file )); + file = (file_t *)Mem_Calloc( fs_mempool, sizeof( *file )); file->filetime = FS_SysFileTime( filepath ); file->ungetc = EOF; @@ -1654,7 +1650,7 @@ file_t *FS_OpenPackedFile( pack_t *pack, int pack_ind ) if( dup_handle < 0 ) return NULL; - file = (file_t *)Mem_Alloc( fs_mempool, sizeof( *file )); + file = (file_t *)Mem_Calloc( fs_mempool, sizeof( *file )); file->handle = dup_handle; file->real_length = pfile->filelen; file->offset = pfile->filepos; @@ -2145,7 +2141,7 @@ int FS_VPrintf( file_t *file, const char *format, va_list ap ) while( 1 ) { - tempbuff = (char *)Mem_Alloc( fs_mempool, buff_size ); + tempbuff = (char *)Mem_Malloc( fs_mempool, buff_size ); len = Q_vsprintf( tempbuff, format, ap ); if( len >= 0 && len < buff_size ) @@ -2333,7 +2329,7 @@ byte *FS_LoadFile( const char *path, long *filesizeptr, qboolean gamedironly ) if( file ) { filesize = file->real_length; - buf = (byte *)Mem_Alloc( fs_mempool, filesize + 1 ); + buf = (byte *)Mem_Malloc( fs_mempool, filesize + 1 ); buf[filesize] = '\0'; FS_Read( file, buf, filesize ); FS_Close( file ); @@ -2372,7 +2368,7 @@ byte *FS_LoadDirectFile(const char *path, long *filesizeptr ) // Try to load filesize = file->real_length; - buf = (byte *)Mem_Alloc( fs_mempool, filesize + 1 ); + buf = (byte *)Mem_Malloc( fs_mempool, filesize + 1 ); buf[filesize] = '\0'; FS_Read( file, buf, filesize ); FS_Close( file ); @@ -2526,7 +2522,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ) } // all done, create dll_user_t struct - hInst = Mem_Alloc( host.mempool, sizeof( dll_user_t )); + hInst = Mem_Calloc( host.mempool, sizeof( dll_user_t )); // save dllname for debug purposes Q_strncpy( hInst->dllName, dllname, sizeof( hInst->dllName )); @@ -2676,7 +2672,7 @@ FS_FileCopy */ qboolean FS_FileCopy( file_t *pOutput, file_t *pInput, int fileSize ) { - char *buf = Mem_Alloc( fs_mempool, FILE_COPY_SIZE ); + char *buf = Mem_Malloc( fs_mempool, FILE_COPY_SIZE ); int size, readSize; qboolean done = true; @@ -2734,7 +2730,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) separator = max( slash, backslash ); separator = max( separator, colon ); basepathlength = separator ? (separator + 1 - pattern) : 0; - basepath = Mem_Alloc( fs_mempool, basepathlength + 1 ); + basepath = Mem_Calloc( fs_mempool, basepathlength + 1 ); if( basepathlength ) memcpy( basepath, pattern, basepathlength ); basepath[basepathlength] = 0; @@ -2894,7 +2890,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ ) numchars += (int)Q_strlen( resultlist.strings[resultlistindex]) + 1; - search = Mem_Alloc( fs_mempool, sizeof(search_t) + numchars + numfiles * sizeof( char* )); + search = Mem_Calloc( fs_mempool, sizeof(search_t) + numchars + numfiles * sizeof( char* )); search->filenames = (char **)((char *)search + sizeof( search_t )); search->filenamesbuffer = (char *)((char *)search + sizeof( search_t ) + numfiles * sizeof( char* )); search->numfilenames = (int)numfiles; @@ -3190,7 +3186,7 @@ byte *W_ReadLump( wfile_t *wad, dlumpinfo_t *lump, long *lumpsizeptr ) return NULL; } - buf = (byte *)Mem_Alloc( wad->mempool, lump->disksize ); + buf = (byte *)Mem_Malloc( wad->mempool, lump->disksize ); size = FS_Read( wad->handle, buf, lump->disksize ); if( size < lump->disksize ) @@ -3223,7 +3219,7 @@ open the wad for reading & writing */ wfile_t *W_Open( const char *filename, int *error ) { - wfile_t *wad = (wfile_t *)Mem_Alloc( fs_mempool, sizeof( wfile_t )); + wfile_t *wad = (wfile_t *)Mem_Calloc( fs_mempool, sizeof( wfile_t )); int i, lumpcount; dlumpinfo_t *srclumps; size_t lat_size; @@ -3291,7 +3287,7 @@ wfile_t *W_Open( const char *filename, int *error ) lat_size = lumpcount * sizeof( dlumpinfo_t ); // NOTE: lumps table can be reallocated for O_APPEND mode - srclumps = (dlumpinfo_t *)Mem_Alloc( wad->mempool, lat_size ); + srclumps = (dlumpinfo_t *)Mem_Malloc( wad->mempool, lat_size ); if( FS_Read( wad->handle, srclumps, lat_size ) != lat_size ) { @@ -3303,7 +3299,7 @@ wfile_t *W_Open( const char *filename, int *error ) } // starting to add lumps - wad->lumps = (dlumpinfo_t *)Mem_Alloc( wad->mempool, lat_size ); + wad->lumps = (dlumpinfo_t *)Mem_Calloc( wad->mempool, lat_size ); wad->numlumps = 0; // sort lumps for binary search diff --git a/engine/common/host.c b/engine/common/host.c index 0da0e0ad..27b1b7e0 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -254,7 +254,7 @@ void Host_Exec_f( void ) host.config_executed = true; // adds \n\0 at end of the file - txt = Z_Malloc( len + 2 ); + txt = Z_Calloc( len + 2 ); memcpy( txt, f, len ); Q_strncat( txt, "\n", len + 2 ); Mem_Free( f ); diff --git a/engine/common/imagelib/img_bmp.c b/engine/common/imagelib/img_bmp.c index 57437a53..7ea1828b 100644 --- a/engine/common/imagelib/img_bmp.c +++ b/engine/common/imagelib/img_bmp.c @@ -148,7 +148,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize ) if( Image_CheckFlag( IL_KEEP_8BIT ) && bhdr.bitsPerPixel == 8 ) { - pixbuf = image.palette = Mem_Alloc( host.imagepool, 1024 ); + pixbuf = image.palette = Mem_Malloc( host.imagepool, 1024 ); // bmp have a reversed palette colors for( i = 0; i < bhdr.colors; i++ ) @@ -169,7 +169,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize ) buf_p += cbPalBytes; image.size = image.width * image.height * bpp; - image.rgba = Mem_Alloc( host.imagepool, image.size ); + image.rgba = Mem_Malloc( host.imagepool, image.size ); bps = image.width * (bhdr.bitsPerPixel >> 3); switch( bhdr.bitsPerPixel ) @@ -403,7 +403,7 @@ qboolean Image_SaveBMP( const char *name, rgbdata_t *pix ) FS_Write( pfile, &sw, sizeof( bmp_t )); } - pbBmpBits = Mem_Alloc( host.imagepool, cbBmpBits ); + pbBmpBits = Mem_Malloc( host.imagepool, cbBmpBits ); if( pixel_size == 1 ) { diff --git a/engine/common/imagelib/img_dds.c b/engine/common/imagelib/img_dds.c index 79f5ed74..3b6c3b3a 100644 --- a/engine/common/imagelib/img_dds.c +++ b/engine/common/imagelib/img_dds.c @@ -322,7 +322,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, size_t filesize ) } // dds files will be uncompressed on a render. requires minimal of info for set this - image.rgba = Mem_Alloc( host.imagepool, image.size ); + image.rgba = Mem_Malloc( host.imagepool, image.size ); memcpy( image.rgba, fin, image.size ); image.flags |= IMAGE_DDS_FORMAT; diff --git a/engine/common/imagelib/img_main.c b/engine/common/imagelib/img_main.c index 69c48f97..9fdf95d5 100644 --- a/engine/common/imagelib/img_main.c +++ b/engine/common/imagelib/img_main.c @@ -120,7 +120,7 @@ void Image_Reset( void ) rgbdata_t *ImagePack( void ) { - rgbdata_t *pack = Mem_Alloc( host.imagepool, sizeof( rgbdata_t )); + rgbdata_t *pack = Mem_Calloc( host.imagepool, sizeof( rgbdata_t )); // clear any force flags image.force_flags = 0; @@ -479,7 +479,7 @@ rgbdata_t *FS_CopyImage( rgbdata_t *in ) if( !in ) return NULL; - out = Mem_Alloc( host.imagepool, sizeof( rgbdata_t )); + out = Mem_Malloc( host.imagepool, sizeof( rgbdata_t )); *out = *in; switch( in->type ) @@ -494,13 +494,13 @@ rgbdata_t *FS_CopyImage( rgbdata_t *in ) if( palSize ) { - out->palette = Mem_Alloc( host.imagepool, palSize ); + out->palette = Mem_Malloc( host.imagepool, palSize ); memcpy( out->palette, in->palette, palSize ); } if( in->size ) { - out->buffer = Mem_Alloc( host.imagepool, in->size ); + out->buffer = Mem_Malloc( host.imagepool, in->size ); memcpy( out->buffer, in->buffer, in->size ); } diff --git a/engine/common/imagelib/img_quant.c b/engine/common/imagelib/img_quant.c index 2ad8f7df..c44569b4 100644 --- a/engine/common/imagelib/img_quant.c +++ b/engine/common/imagelib/img_quant.c @@ -447,7 +447,7 @@ rgbdata_t *Image_Quantize( rgbdata_t *pic ) learn(); unbiasnet(); - pic->palette = Mem_Alloc( host.imagepool, netsize * 3 ); + pic->palette = Mem_Malloc( host.imagepool, netsize * 3 ); for( i = 0; i < netsize; i++ ) { diff --git a/engine/common/imagelib/img_tga.c b/engine/common/imagelib/img_tga.c index ec5511b7..e336ef32 100644 --- a/engine/common/imagelib/img_tga.c +++ b/engine/common/imagelib/img_tga.c @@ -122,7 +122,7 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, size_t filesize ) rows = targa_header.height; image.size = image.width * image.height * 4; - targa_rgba = image.rgba = Mem_Alloc( host.imagepool, image.size ); + targa_rgba = image.rgba = Mem_Malloc( host.imagepool, image.size ); // if bit 5 of attributes isn't set, the image has been stored from bottom to top if( !Image_CheckFlag( IL_DONTFLIP_TGA ) && targa_header.attributes & 0x20 ) @@ -235,7 +235,7 @@ qboolean Image_SaveTGA( const char *name, rgbdata_t *pix ) outsize = pix->width * pix->height * 4 + 18 + Q_strlen( comment ); else outsize = pix->width * pix->height * 3 + 18 + Q_strlen( comment ); - buffer = (byte *)Mem_Alloc( host.imagepool, outsize ); + buffer = (byte *)Mem_Calloc( host.imagepool, outsize ); // prepare header buffer[0] = Q_strlen( comment ); // tga comment length diff --git a/engine/common/imagelib/img_utils.c b/engine/common/imagelib/img_utils.c index a8a2a7ba..640e584a 100644 --- a/engine/common/imagelib/img_utils.c +++ b/engine/common/imagelib/img_utils.c @@ -194,7 +194,7 @@ byte *Image_Copy( size_t size ) { byte *out; - out = Mem_Alloc( host.imagepool, size ); + out = Mem_Malloc( host.imagepool, size ); memcpy( out, image.tempbuffer, size ); return out; @@ -284,9 +284,9 @@ int Image_ComparePalette( const byte *pal ) void Image_SetPalette( const byte *pal, uint *d_table ) { - int i; byte rgba[4]; - + int i; + // setup palette switch( image.d_rendermode ) { @@ -309,6 +309,7 @@ void Image_SetPalette( const byte *pal, uint *d_table ) rgba[3] = i; d_table[i] = *(uint *)rgba; } +// d_table[0] = 0x00808080; break; case LUMP_MASKED: for( i = 0; i < 255; i++ ) @@ -408,7 +409,7 @@ static void Image_ConvertPalTo24bit( rgbdata_t *pic ) if( pic->type == PF_INDEXED_24 ) return; // does nothing - pal24 = converted = Mem_Alloc( host.imagepool, 768 ); + pal24 = converted = Mem_Malloc( host.imagepool, 768 ); pal32 = pic->palette; for( i = 0; i < 256; i++, pal24 += 3, pal32 += 4 ) @@ -426,7 +427,7 @@ static void Image_ConvertPalTo24bit( rgbdata_t *pic ) void Image_CopyPalette32bit( void ) { if( image.palette ) return; // already created ? - image.palette = Mem_Alloc( host.imagepool, 1024 ); + image.palette = Mem_Malloc( host.imagepool, 1024 ); memcpy( image.palette, image.d_currentpal, 1024 ); } @@ -722,7 +723,7 @@ void Image_Resample32Lerp( const void *indata, int inwidth, int inheight, void * fstep = (int)(inheight * 65536.0f / outheight); - resamplerow1 = (byte *)Mem_Alloc( host.imagepool, outwidth * 4 * 2); + resamplerow1 = (byte *)Mem_Malloc( host.imagepool, outwidth * 4 * 2); resamplerow2 = resamplerow1 + outwidth * 4; inrow = (const byte *)indata; @@ -869,7 +870,7 @@ void Image_Resample24Lerp( const void *indata, int inwidth, int inheight, void * fstep = (int)(inheight * 65536.0f / outheight); - resamplerow1 = (byte *)Mem_Alloc( host.imagepool, outwidth * 3 * 2 ); + resamplerow1 = (byte *)Mem_Malloc( host.imagepool, outwidth * 3 * 2 ); resamplerow2 = resamplerow1 + outwidth*3; inrow = (const byte *)indata; @@ -1206,7 +1207,7 @@ qboolean Image_AddIndexedImageToPack( const byte *in, int width, int height ) else Image_CopyPalette32bit(); // reallocate image buffer - image.rgba = Mem_Alloc( host.imagepool, image.size ); + image.rgba = Mem_Malloc( host.imagepool, image.size ); if( !expand_to_rgba ) memcpy( image.rgba, in, image.size ); else if( !Image_Copy8bitRGBA( in, image.rgba, mipsize )) return false; // probably pallette not installed diff --git a/engine/common/imagelib/img_wad.c b/engine/common/imagelib/img_wad.c index 95896b4e..e64c304b 100644 --- a/engine/common/imagelib/img_wad.c +++ b/engine/common/imagelib/img_wad.c @@ -241,7 +241,7 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, size_t filesize ) { // spr32 support image.size = image.width * image.height * 4; - image.rgba = Mem_Alloc( host.imagepool, image.size ); + image.rgba = Mem_Malloc( host.imagepool, image.size ); memcpy( image.rgba, (byte *)(pin + 1), image.size ); SetBits( image.flags, IMAGE_HAS_COLOR ); // Color. True Color! return true; diff --git a/engine/common/library.h b/engine/common/library.h index 310696b6..b328efb7 100644 --- a/engine/common/library.h +++ b/engine/common/library.h @@ -21,6 +21,10 @@ GNU General Public License for more details. #define NUMBER_OF_DIRECTORY_ENTRIES 16 #define MAX_LIBRARY_EXPORTS 4096 +#ifndef IMAGE_SIZEOF_BASE_RELOCATION +#define IMAGE_SIZEOF_BASE_RELOCATION ( sizeof( IMAGE_BASE_RELOCATION )) +#endif + typedef struct { // dos .exe header diff --git a/engine/common/masterlist.c b/engine/common/masterlist.c index 5ea022b6..dff68b04 100644 --- a/engine/common/masterlist.c +++ b/engine/common/masterlist.c @@ -102,7 +102,7 @@ static void NET_AddMaster( char *addr, qboolean save ) return; } - master = Mem_Alloc( host.mempool, sizeof( master_t ) ); + master = Mem_Malloc( host.mempool, sizeof( master_t ) ); Q_strncpy( master->address, addr, MAX_STRING ); master->sent = false; master->save = save; diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index 09a09f31..598eadb5 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -41,6 +41,8 @@ GNU General Public License for more details. #define NUMVERTEXNORMALS 162 +#define BOGUS_RANGE ((vec_t)114032.64) // world.size * 1.74 + #define SIDE_FRONT 0 #define SIDE_BACK 1 #define SIDE_ON 2 diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index 8a5118af..82bf9225 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -362,7 +362,7 @@ static int Mod_ArrayUsage( const char *szItem, int items, int maxitems, int item Con_Printf( "%-12s %7i/%-7i %8i/%-8i (%4.1f%%) ", szItem, items, maxitems, items * itemsize, maxitems * itemsize, percentage ); - if( percentage > 99.9f ) + if( percentage > 99.99f ) Con_Printf( "^1SIZE OVERFLOW!!!^7\n" ); else if( percentage > 95.0f ) Con_Printf( "^3SIZE DANGER!^7\n" ); @@ -384,7 +384,7 @@ static int Mod_GlobUsage( const char *szItem, int itemstorage, int maxstorage ) Con_Printf( "%-15s %-12s %8i/%-8i (%4.1f%%) ", szItem, "[variable]", itemstorage, maxstorage, percentage ); - if( percentage > 99.9f ) + if( percentage > 99.99f ) Con_Printf( "^1SIZE OVERFLOW!!!^7\n" ); else if( percentage > 95.0f ) Con_Printf( "^3SIZE DANGER!^7\n" ); @@ -1162,7 +1162,7 @@ static void Mod_MakeHull0( void ) int i, j; hull = &loadmodel->hulls[0]; - hull->clipnodes = out = Mem_Alloc( loadmodel->mempool, loadmodel->numnodes * sizeof( *out )); + hull->clipnodes = out = Mem_Malloc( loadmodel->mempool, loadmodel->numnodes * sizeof( *out )); in = loadmodel->nodes; hull->firstclipnode = 0; @@ -1230,7 +1230,7 @@ static void Mod_SetupHull( dbspmodel_t *bmod, model_t *mod, byte *mempool, int h count = hull->lastclipnode; // fit array to real count - hull->clipnodes = (mclipnode_t *)Mem_Alloc( mempool, sizeof( mclipnode_t ) * hull->lastclipnode ); + hull->clipnodes = (mclipnode_t *)Mem_Malloc( mempool, sizeof( mclipnode_t ) * hull->lastclipnode ); hull->planes = mod->planes; // share planes hull->lastclipnode = 0; // restart counting @@ -1281,7 +1281,7 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod ) return false; } - loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, litdatasize ); + loadmodel->lightdata = Mem_Malloc( loadmodel->mempool, litdatasize ); memcpy( loadmodel->lightdata, in + 8, litdatasize ); SetBits( loadmodel->flags, MODEL_COLORED_LIGHTING ); bmod->lightdatasize = litdatasize; @@ -1336,7 +1336,7 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod ) return; } - bmod->deluxedata_out = Mem_Alloc( loadmodel->mempool, deluxdatasize ); + bmod->deluxedata_out = Mem_Malloc( loadmodel->mempool, deluxdatasize ); memcpy( bmod->deluxedata_out, in + 8, deluxdatasize ); bmod->deluxdatasize = deluxdatasize; Mem_Free( in ); @@ -1435,7 +1435,8 @@ static void Mod_SetupSubmodels( dbspmodel_t *bmod ) } } - Mem_Free( bmod->clipnodes_out ); + if( bmod->clipnodes_out != NULL ) + Mem_Free( bmod->clipnodes_out ); } /* @@ -1457,7 +1458,7 @@ static void Mod_LoadSubmodels( dbspmodel_t *bmod ) int i, j; // allocate extradata for each dmodel_t - out = Mem_Alloc( loadmodel->mempool, bmod->numsubmodels * sizeof( *out )); + out = Mem_Malloc( loadmodel->mempool, bmod->numsubmodels * sizeof( *out )); loadmodel->numsubmodels = bmod->numsubmodels; loadmodel->submodels = out; @@ -1540,7 +1541,7 @@ static void Mod_LoadEntities( dbspmodel_t *bmod ) } // make sure what we really has terminator - loadmodel->entities = Mem_Alloc( loadmodel->mempool, bmod->entdatasize + 1 ); + loadmodel->entities = Mem_Calloc( loadmodel->mempool, bmod->entdatasize + 1 ); memcpy( loadmodel->entities, bmod->entdata, bmod->entdatasize ); // moving to private model pool if( entpatch ) Mem_Free( entpatch ); // release entpatch if present if( !bmod->isworld ) return; @@ -1623,11 +1624,12 @@ static void Mod_LoadPlanes( dbspmodel_t *bmod ) int i, j; in = bmod->planes; - loadmodel->planes = out = Mem_Alloc( loadmodel->mempool, bmod->numplanes * sizeof( *out )); + loadmodel->planes = out = Mem_Malloc( loadmodel->mempool, bmod->numplanes * sizeof( *out )); loadmodel->numplanes = bmod->numplanes; for( i = 0; i < bmod->numplanes; i++, in++, out++ ) { + out->signbits = 0; for( j = 0; j < 3; j++ ) { out->normal[j] = in->normal[j]; @@ -1656,7 +1658,7 @@ static void Mod_LoadVertexes( dbspmodel_t *bmod ) int i; in = bmod->vertexes; - out = loadmodel->vertexes = Mem_Alloc( loadmodel->mempool, bmod->numvertexes * sizeof( mvertex_t )); + out = loadmodel->vertexes = Mem_Malloc( loadmodel->mempool, bmod->numvertexes * sizeof( mvertex_t )); loadmodel->numvertexes = bmod->numvertexes; if( bmod->isworld ) ClearBounds( world.mins, world.maxs ); @@ -1690,7 +1692,7 @@ static void Mod_LoadEdges( dbspmodel_t *bmod ) medge_t *out; int i; - loadmodel->edges = out = Mem_Alloc( loadmodel->mempool, bmod->numedges * sizeof( medge_t )); + loadmodel->edges = out = Mem_Malloc( loadmodel->mempool, bmod->numedges * sizeof( medge_t )); loadmodel->numedges = bmod->numedges; if( bmod->version == QBSP2_VERSION ) @@ -1722,7 +1724,7 @@ Mod_LoadSurfEdges */ static void Mod_LoadSurfEdges( dbspmodel_t *bmod ) { - loadmodel->surfedges = Mem_Alloc( loadmodel->mempool, bmod->numsurfedges * sizeof( dsurfedge_t )); + loadmodel->surfedges = Mem_Malloc( loadmodel->mempool, bmod->numsurfedges * sizeof( dsurfedge_t )); memcpy( loadmodel->surfedges, bmod->surfedges, bmod->numsurfedges * sizeof( dsurfedge_t )); loadmodel->numsurfedges = bmod->numsurfedges; } @@ -1737,7 +1739,7 @@ static void Mod_LoadMarkSurfaces( dbspmodel_t *bmod ) msurface_t **out; int i; - loadmodel->marksurfaces = out = Mem_Alloc( loadmodel->mempool, bmod->nummarkfaces * sizeof( *out )); + loadmodel->marksurfaces = out = Mem_Malloc( loadmodel->mempool, bmod->nummarkfaces * sizeof( *out )); loadmodel->nummarksurfaces = bmod->nummarkfaces; if( bmod->version == QBSP2_VERSION ) @@ -1801,7 +1803,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) } in = bmod->textures; - loadmodel->textures = (texture_t **)Mem_Alloc( loadmodel->mempool, in->nummiptex * sizeof( texture_t* )); + loadmodel->textures = (texture_t **)Mem_Calloc( loadmodel->mempool, in->nummiptex * sizeof( texture_t* )); loadmodel->numtextures = in->nummiptex; for( i = 0; i < loadmodel->numtextures; i++ ) @@ -1809,7 +1811,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) if( in->dataofs[i] == -1 ) { // create default texture (some mods requires this) - tx = Mem_Alloc( loadmodel->mempool, sizeof( *tx )); + tx = Mem_Calloc( loadmodel->mempool, sizeof( *tx )); loadmodel->textures[i] = tx; Q_strncpy( tx->name, "*default", sizeof( tx->name )); @@ -1828,7 +1830,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) Q_snprintf( mt->name, sizeof( mt->name ), "miptex_%i", i ); } - tx = Mem_Alloc( loadmodel->mempool, sizeof( *tx )); + tx = Mem_Calloc( loadmodel->mempool, sizeof( *tx )); loadmodel->textures[i] = tx; // convert to lowercase @@ -2073,7 +2075,7 @@ static void Mod_LoadTexInfo( dbspmodel_t *bmod ) dtexinfo_t *in; // trying to load faceinfo - faceinfo = fout = Mem_Alloc( loadmodel->mempool, bmod->numfaceinfo * sizeof( *fout )); + faceinfo = fout = Mem_Calloc( loadmodel->mempool, bmod->numfaceinfo * sizeof( *fout )); fin = bmod->faceinfo; for( i = 0; i < bmod->numfaceinfo; i++, fin++, fout++ ) @@ -2084,7 +2086,7 @@ static void Mod_LoadTexInfo( dbspmodel_t *bmod ) fout->groupid = fin->groupid; } - loadmodel->texinfo = out = Mem_Alloc( loadmodel->mempool, bmod->numtexinfo * sizeof( *out )); + loadmodel->texinfo = out = Mem_Calloc( loadmodel->mempool, bmod->numtexinfo * sizeof( *out )); loadmodel->numtexinfo = bmod->numtexinfo; in = bmod->texinfo; @@ -2123,8 +2125,8 @@ static void Mod_LoadSurfaces( dbspmodel_t *bmod ) mextrasurf_t *info; msurface_t *out; - loadmodel->surfaces = out = Mem_Alloc( loadmodel->mempool, bmod->numsurfaces * sizeof( msurface_t )); - info = Mem_Alloc( loadmodel->mempool, bmod->numsurfaces * sizeof( mextrasurf_t )); + loadmodel->surfaces = out = Mem_Calloc( loadmodel->mempool, bmod->numsurfaces * sizeof( msurface_t )); + info = Mem_Calloc( loadmodel->mempool, bmod->numsurfaces * sizeof( mextrasurf_t )); loadmodel->numsurfaces = bmod->numsurfaces; // predict samplecount based on bspversion @@ -2273,7 +2275,7 @@ static void Mod_LoadNodes( dbspmodel_t *bmod ) mnode_t *out; int i, j, p; - loadmodel->nodes = out = (mnode_t *)Mem_Alloc( loadmodel->mempool, bmod->numnodes * sizeof( *out )); + loadmodel->nodes = out = (mnode_t *)Mem_Calloc( loadmodel->mempool, bmod->numnodes * sizeof( *out )); loadmodel->numnodes = bmod->numnodes; for( i = 0; i < loadmodel->numnodes; i++, out++ ) @@ -2338,7 +2340,7 @@ static void Mod_LoadLeafs( dbspmodel_t *bmod ) mleaf_t *out; int i, j, p; - loadmodel->leafs = out = (mleaf_t *)Mem_Alloc( loadmodel->mempool, bmod->numleafs * sizeof( *out )); + loadmodel->leafs = out = (mleaf_t *)Mem_Calloc( loadmodel->mempool, bmod->numleafs * sizeof( *out )); loadmodel->numleafs = bmod->numleafs; if( bmod->isworld ) @@ -2346,7 +2348,7 @@ static void Mod_LoadLeafs( dbspmodel_t *bmod ) // get visleafs from the submodel data world.visclusters = loadmodel->submodels[0].visleafs; world.visbytes = (world.visclusters + 7) >> 3; - world.visdata = (byte *)Mem_Alloc( loadmodel->mempool, world.visclusters * world.visbytes ); + world.visdata = (byte *)Mem_Malloc( loadmodel->mempool, world.visclusters * world.visbytes ); world.fatbytes = (world.visclusters + 31) >> 3; // enable full visibility as default @@ -2450,7 +2452,7 @@ static void Mod_LoadClipnodes( dbspmodel_t *bmod ) dclipnode32_t *out; int i; - bmod->clipnodes_out = out = (dclipnode32_t *)Mem_Alloc( loadmodel->mempool, bmod->numclipnodes * sizeof( *out )); + bmod->clipnodes_out = out = (dclipnode32_t *)Mem_Malloc( loadmodel->mempool, bmod->numclipnodes * sizeof( *out )); if(( bmod->version == QBSP2_VERSION ) || ( bmod->version == HLBSP_VERSION && bmod->numclipnodes >= MAX_MAP_CLIPNODES )) { @@ -2493,7 +2495,7 @@ Mod_LoadVisibility */ static void Mod_LoadVisibility( dbspmodel_t *bmod ) { - loadmodel->visdata = Mem_Alloc( loadmodel->mempool, bmod->visdatasize ); + loadmodel->visdata = Mem_Malloc( loadmodel->mempool, bmod->visdatasize ); memcpy( loadmodel->visdata, bmod->visdata, bmod->visdatasize ); } @@ -2512,7 +2514,7 @@ static void Mod_LoadLightVecs( dbspmodel_t *bmod ) return; } - bmod->deluxedata_out = Mem_Alloc( loadmodel->mempool, bmod->deluxdatasize ); + bmod->deluxedata_out = Mem_Malloc( loadmodel->mempool, bmod->deluxdatasize ); memcpy( bmod->deluxedata_out, bmod->deluxdata, bmod->deluxdatasize ); } @@ -2530,7 +2532,7 @@ static void Mod_LoadShadowmap( dbspmodel_t *bmod ) return; } - bmod->shadowdata_out = Mem_Alloc( loadmodel->mempool, bmod->shadowdatasize ); + bmod->shadowdata_out = Mem_Malloc( loadmodel->mempool, bmod->shadowdatasize ); memcpy( bmod->shadowdata_out, bmod->shadowdata, bmod->shadowdatasize ); } @@ -2554,7 +2556,7 @@ static void Mod_LoadLighting( dbspmodel_t *bmod ) case 1: if( !Mod_LoadColoredLighting( bmod )) { - loadmodel->lightdata = out = (color24 *)Mem_Alloc( loadmodel->mempool, bmod->lightdatasize * sizeof( color24 )); + loadmodel->lightdata = out = (color24 *)Mem_Malloc( loadmodel->mempool, bmod->lightdatasize * sizeof( color24 )); in = bmod->lightdata; // expand the white lighting data @@ -2563,7 +2565,7 @@ static void Mod_LoadLighting( dbspmodel_t *bmod ) } break; case 3: // load colored lighting - loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, bmod->lightdatasize ); + loadmodel->lightdata = Mem_Malloc( loadmodel->mempool, bmod->lightdatasize ); memcpy( loadmodel->lightdata, bmod->lightdata, bmod->lightdatasize ); SetBits( loadmodel->flags, MODEL_COLORED_LIGHTING ); break; @@ -2622,6 +2624,7 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld ) dheader_t *header = (dheader_t *)mod_base; dextrahdr_t *extrahdr = (dextrahdr_t *)((byte *)mod_base + sizeof( dheader_t )); dbspmodel_t *bmod = &srcmodel; + model_t *mod = loadmodel; char wadvalue[2048]; int i; @@ -2692,6 +2695,12 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld ) Mod_MakeHull0 (); Mod_SetupSubmodels( bmod ); + if( isworld ) + { + loadmodel = mod; // restore pointer to world + Mod_InitDebugHulls(); // FIXME: build hulls for separate bmodels (shells, medkits etc) + } + for( i = 0; i < bmod->wadlist.count; i++ ) Q_strncat( wadvalue, va( "%s.wad; ", bmod->wadlist.wadnames[i] ), sizeof( wadvalue )); diff --git a/engine/common/mod_dbghulls.c b/engine/common/mod_dbghulls.c new file mode 100644 index 00000000..cb5b25d3 --- /dev/null +++ b/engine/common/mod_dbghulls.c @@ -0,0 +1,777 @@ +/* +mod_bmodel.c - loading & handling world and brushmodels +Copyright (C) 2016 Uncle Mike + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include "mod_local.h" +#include "mathlib.h" +#include "world.h" +#include "gl_local.h" +#include "client.h" + +#define MAX_CLIPNODE_DEPTH 256 // should never exceeds + +#define list_entry( ptr, type, member ) \ + ((type *)((char *)(ptr) - (size_t)(&((type *)0)->member))) + +// iterate over each entry in the list +#define list_for_each_entry( pos, head, member ) \ + for( pos = list_entry( (head)->next, winding_t, member ); \ + &pos->member != (head); \ + pos = list_entry( pos->member.next, winding_t, member )) + +// iterate over the list, safe for removal of entries +#define list_for_each_entry_safe( pos, n, head, member ) \ + for( pos = list_entry( (head)->next, winding_t, member ), \ + n = list_entry( pos->member.next, winding_t, member ); \ + &pos->member != (head); \ + pos = n, n = list_entry( n->member.next, winding_t, member )) + +#define LIST_HEAD_INIT( name ) { &(name), &(name) } + +_inline void list_add__( hullnode_t *new, hullnode_t *prev, hullnode_t *next ) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +// add the new entry after the give list entry +_inline void list_add( hullnode_t *newobj, hullnode_t *head ) +{ + list_add__( newobj, head, head->next ); +} + +// add the new entry before the given list entry (list is circular) +_inline void list_add_tail( hullnode_t *newobj, hullnode_t *head ) +{ + list_add__( newobj, head->prev, head ); +} + +_inline void list_del( hullnode_t *entry ) +{ + entry->next->prev = entry->prev; + entry->prev->next = entry->next; +} + +static winding_t * winding_alloc( uint numpoints ) +{ + return (winding_t *)malloc( (int)((winding_t *)0)->p[numpoints] ); +} + +static void free_winding( winding_t *w ) +{ + // simple sentinel by Carmack + if( *(unsigned *)w == 0xDEADC0DE ) + Host_Error( "free_winding: freed a freed winding\n" ); + *(unsigned *)w = 0xDEADC0DE; + free( w ); +} + +static winding_t *winding_copy( winding_t *w ) +{ + winding_t *neww; + + neww = winding_alloc( w->numpoints ); + memcpy( neww, w, (int)((winding_t *)0)->p[w->numpoints] ); + + return neww; +} + +static void winding_reverse( winding_t *w ) +{ + vec3_t point; + int i; + + for( i = 0; i < w->numpoints / 2; i++ ) + { + VectorCopy( w->p[i], point ); + VectorCopy( w->p[w->numpoints - i - 1], w->p[i] ); + VectorCopy( point, w->p[w->numpoints - i - 1] ); + } +} + +/* + * winding_shrink + * + * Takes an over-allocated winding and allocates a new winding with just the + * required number of points. The input winding is freed. + */ +static winding_t *winding_shrink( winding_t *w ) +{ + winding_t *neww = winding_alloc( w->numpoints ); + memcpy( neww, w, (int)((winding_t *)0)->p[w->numpoints] ); + free_winding( w ); + + return neww; +} + +/* +==================== +winding_for_plane +==================== +*/ +static winding_t *winding_for_plane( const mplane_t *p ) +{ + vec3_t org, vright, vup; + int i, axis; + vec_t max, v; + winding_t *w; + + // find the major axis + max = -BOGUS_RANGE; + axis = -1; + + for( i = 0; i < 3; i++ ) + { + v = fabs( p->normal[i] ); + if( v > max ) + { + axis = i; + max = v; + } + } + + VectorClear( vup ); + switch( axis ) + { + case 0: + case 1: + vup[2] = 1; + break; + case 2: + vup[0] = 1; + break; + default: + Host_Error( "BaseWindingForPlane: no axis found\n" ); + return NULL; + } + + v = DotProduct( vup, p->normal ); + VectorMA( vup, -v, p->normal, vup ); + VectorNormalize( vup ); + VectorScale( p->normal, p->dist, org ); + CrossProduct( vup, p->normal, vright ); + VectorScale( vup, BOGUS_RANGE, vup ); + VectorScale( vright, BOGUS_RANGE, vright ); + + // project a really big axis aligned box onto the plane + w = winding_alloc( 4 ); + memset( w->p, 0, sizeof( vec3_t ) * 4 ); + w->numpoints = 4; + w->plane = p; + + VectorSubtract( org, vright, w->p[0] ); + VectorAdd( w->p[0], vup, w->p[0] ); + VectorAdd( org, vright, w->p[1] ); + VectorAdd( w->p[1], vup, w->p[1] ); + VectorAdd( org, vright, w->p[2] ); + VectorSubtract( w->p[2], vup, w->p[2] ); + VectorSubtract( org, vright, w->p[3] ); + VectorSubtract( w->p[3], vup, w->p[3] ); + + return w; +} + +/* + * =========================== + * Helper for for the clipping functions + * (winding_clip, winding_split) + * =========================== + */ +static void CalcSides( const winding_t *in, const mplane_t *split, int *sides, vec_t *dists, int counts[3], vec_t epsilon ) +{ + const vec_t *p; + int i; + + counts[0] = counts[1] = counts[2] = 0; + + switch( split->type ) + { + case PLANE_X: + case PLANE_Y: + case PLANE_Z: + p = in->p[0] + split->type; + for( i = 0; i < in->numpoints; i++, p += 3 ) + { + const vec_t dot = *p - split->dist; + + dists[i] = dot; + if( dot > epsilon ) + sides[i] = SIDE_FRONT; + else if( dot < -epsilon ) + sides[i] = SIDE_BACK; + else sides[i] = SIDE_ON; + counts[sides[i]]++; + } + break; + default: + p = in->p[0]; + for( i = 0; i < in->numpoints; i++, p += 3 ) + { + const vec_t dot = DotProduct( split->normal, p ) - split->dist; + + dists[i] = dot; + if( dot > epsilon ) + sides[i] = SIDE_FRONT; + else if( dot < -epsilon ) + sides[i] = SIDE_BACK; + else sides[i] = SIDE_ON; + counts[sides[i]]++; + } + break; + } + + sides[i] = sides[0]; + dists[i] = dists[0]; +} + +static void PushToPlaneAxis( vec_t *v, const mplane_t *p ) +{ + const int t = p->type % 3; + + v[t] = (p->dist - p->normal[(t + 1) % 3] * v[(t + 1) % 3] - p->normal[(t + 2) % 3] * v[(t + 2) % 3]) / p->normal[t]; +} + +/* +================== +winding_clip + +Clips the winding to the plane, returning the new winding on 'side'. +Frees the input winding. +If keepon is true, an exactly on-plane winding will be saved, otherwise + it will be clipped away. +================== +*/ +static winding_t *winding_clip( winding_t *in, const mplane_t *split, qboolean keepon, int side, vec_t epsilon ) +{ + vec_t *dists; + int *sides; + int counts[3]; + vec_t dot; + int i, j; + winding_t *neww; + vec_t *p1, *p2, *mid; + int maxpts; + + dists = (vec_t *)malloc(( in->numpoints + 1 ) * sizeof( vec_t )); + sides = (int *)malloc(( in->numpoints + 1 ) * sizeof( int )); + CalcSides( in, split, sides, dists, counts, epsilon ); + + if( keepon && !counts[SIDE_FRONT] && !counts[SIDE_BACK] ) + { + neww = in; + goto out_free; + } + + if( !counts[side] ) + { + free_winding( in ); + neww = NULL; + goto out_free; + } + + if( !counts[side ^ 1] ) + { + neww = in; + goto out_free; + } + + maxpts = in->numpoints + 4; + neww = winding_alloc( maxpts ); + neww->numpoints = 0; + neww->plane = in->plane; + + for( i = 0; i < in->numpoints; i++ ) + { + p1 = in->p[i]; + + if( sides[i] == SIDE_ON ) + { + VectorCopy( p1, neww->p[neww->numpoints] ); + neww->numpoints++; + continue; + } + + if( sides[i] == side ) + { + VectorCopy( p1, neww->p[neww->numpoints] ); + neww->numpoints++; + } + + if( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) + continue; + + // generate a split point + p2 = in->p[(i + 1) % in->numpoints]; + mid = neww->p[neww->numpoints++]; + + dot = dists[i] / (dists[i] - dists[i + 1]); + for( j = 0; j < 3; j++ ) + { + // avoid round off error when possible + if( in->plane->normal[j] == 1.0 ) + mid[j] = in->plane->dist; + else if( in->plane->normal[j] == -1.0 ) + mid[j] = -in->plane->dist; + else if( split->normal[j] == 1.0 ) + mid[j] = split->dist; + else if( split->normal[j] == -1.0 ) + mid[j] = -split->dist; + else mid[j] = p1[j] + dot * (p2[j] - p1[j]); + } + + if( in->plane->type < 3 ) + PushToPlaneAxis( mid, in->plane ); + } + + // free the original winding + free_winding( in ); + + // Shrink the winding back to just what it needs... + neww = winding_shrink(neww); +out_free: + free( dists ); + free( sides ); + + return neww; +} + +/* +================== +winding_split + +Splits a winding by a plane, producing one or two windings. The +original winding is not damaged or freed. If only on one side, the +returned winding will be the input winding. If on both sides, two +new windings will be created. +================== +*/ +static void winding_split( winding_t *in, const mplane_t *split, winding_t **pfront, winding_t **pback ) +{ + vec_t *dists; + int *sides; + int counts[3]; + vec_t dot; + int i, j; + winding_t *front, *back; + vec_t *p1, *p2, *mid; + int maxpts; + + dists = (vec_t *)malloc(( in->numpoints + 1 ) * sizeof( vec_t )); + sides = (int *)malloc(( in->numpoints + 1 ) * sizeof( int )); + CalcSides(in, split, sides, dists, counts, 0.04f ); + + if( !counts[0] && !counts[1] ) + { + // winding on the split plane - return copies on both sides + *pfront = winding_copy( in ); + *pback = winding_copy( in ); + goto out_free; + } + + if( !counts[0] ) + { + *pfront = NULL; + *pback = in; + goto out_free; + } + + if( !counts[1] ) + { + *pfront = in; + *pback = NULL; + goto out_free; + } + + maxpts = in->numpoints + 4; + front = winding_alloc( maxpts ); + front->numpoints = 0; + front->plane = in->plane; + back = winding_alloc( maxpts ); + back->numpoints = 0; + back->plane = in->plane; + + for( i = 0; i < in->numpoints; i++ ) + { + p1 = in->p[i]; + + if( sides[i] == SIDE_ON ) + { + VectorCopy( p1, front->p[front->numpoints] ); + VectorCopy( p1, back->p[back->numpoints] ); + front->numpoints++; + back->numpoints++; + continue; + } + + if( sides[i] == SIDE_FRONT ) + { + VectorCopy( p1, front->p[front->numpoints] ); + front->numpoints++; + } + else if( sides[i] == SIDE_BACK ) + { + VectorCopy( p1, back->p[back->numpoints] ); + back->numpoints++; + } + + if( sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i] ) + continue; + + // generate a split point + p2 = in->p[(i + 1) % in->numpoints]; + mid = front->p[front->numpoints++]; + + dot = dists[i] / (dists[i] - dists[i + 1]); + for( j = 0; j < 3; j++ ) + { + // avoid round off error when possible + if( in->plane->normal[j] == 1.0 ) + mid[j] = in->plane->dist; + else if( in->plane->normal[j] == -1.0 ) + mid[j] = -in->plane->dist; + else if( split->normal[j] == 1.0 ) + mid[j] = split->dist; + else if( split->normal[j] == -1.0 ) + mid[j] = -split->dist; + else mid[j] = p1[j] + dot * (p2[j] - p1[j]); + } + + if( in->plane->type < 3 ) + PushToPlaneAxis( mid, in->plane ); + VectorCopy( mid, back->p[back->numpoints] ); + back->numpoints++; + } + + *pfront = winding_shrink( front ); + *pback = winding_shrink( back ); +out_free: + free( dists ); + free( sides ); +} + +/* ------------------------------------------------------------------------- */ + +/* + * This is a stack of the clipnodes we have traversed + * "sides" indicates which side we went down each time + */ +static mclipnode_t *node_stack[MAX_CLIPNODE_DEPTH]; +static int side_stack[MAX_CLIPNODE_DEPTH]; +static uint node_stack_depth; + +static void push_node( mclipnode_t *node, int side ) +{ + if( node_stack_depth == MAX_CLIPNODE_DEPTH ) + Host_Error( "node stack overflow\n" ); + + node_stack[node_stack_depth] = node; + side_stack[node_stack_depth] = side; + node_stack_depth++; +} + +static void pop_node( void ) +{ + if( !node_stack_depth ) + Host_Error( "node stack underflow\n" ); + node_stack_depth--; +} + +static void free_hull_polys( hullnode_t *hull_polys ) +{ + winding_t *w, *next; + + list_for_each_entry_safe( w, next, hull_polys, chain ) + { + list_del( &w->chain ); + free_winding( w ); + } +} + +static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model ); + +static void do_hull_recursion( hull_t *hull, mclipnode_t *node, int side, hullnode_t *polys, hull_model_t *model ) +{ + winding_t *w, *next; + + if( node->children[side] >= 0 ) + { + mclipnode_t *child = hull->clipnodes + node->children[side]; + push_node( node, side ); + hull_windings_r( hull, child, polys, model ); + pop_node(); + } + else + { + switch( node->children[side] ) + { + case CONTENTS_EMPTY: + case CONTENTS_WATER: + case CONTENTS_SLIME: + case CONTENTS_LAVA: + list_for_each_entry_safe( w, next, polys, chain ) + { + list_del( &w->chain ); + list_add( &w->chain, &model->polys ); + } + break; + case CONTENTS_SOLID: + case CONTENTS_SKY: + // throw away polys... + list_for_each_entry_safe( w, next, polys, chain ) + { + if( w->pair ) + w->pair->pair = NULL; + list_del( &w->chain ); + free_winding( w ); + model->num_polys--; + } + break; + default: + Host_Error( "bad contents: %i\n", node->children[side] ); + break; + } + } +} + +static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model ) +{ + mplane_t *plane = hull->planes + node->planenum; + hullnode_t frontlist = LIST_HEAD_INIT( frontlist ); + hullnode_t backlist = LIST_HEAD_INIT( backlist ); + winding_t *w, *next, *front, *back; + int i; + + list_for_each_entry_safe( w, next, polys, chain ) + { + // PARANIOA - PAIR CHECK + ASSERT( !w->pair || w->pair->pair == w ); + + list_del( &w->chain ); + winding_split( w, plane, &front, &back ); + if( front ) list_add( &front->chain, &frontlist ); + if( back ) list_add( &back->chain, &backlist ); + + if( front && back ) + { + if( w->pair ) + { + // split the paired poly, preserve pairing + winding_t *front2, *back2; + + winding_split( w->pair, plane, &front2, &back2 ); + + front2->pair = front; + front->pair = front2; + back2->pair = back; + back->pair = back2; + + list_add( &front2->chain, &w->pair->chain ); + list_add( &back2->chain, &w->pair->chain ); + list_del( &w->pair->chain ); + free_winding( w->pair ); + model->num_polys++; + } + else + { + front->pair = NULL; + back->pair = NULL; + } + + model->num_polys++; + free_winding( w ); + } + } + + w = winding_for_plane(plane); + + for( i = 0; w && i < node_stack_depth; i++ ) + { + mplane_t *p = hull->planes + node_stack[i]->planenum; + w = winding_clip( w, p, false, side_stack[i], 0.00001 ); + } + + if( w ) + { + winding_t *tmp = winding_copy( w ); + winding_reverse( tmp ); + + w->pair = tmp; + tmp->pair = w; + + list_add( &w->chain, &frontlist ); + list_add( &tmp->chain, &backlist ); + + // PARANIOA - PAIR CHECK + ASSERT( !w->pair || w->pair->pair == w ); + model->num_polys += 2; + } + else + { + Con_Printf( S_WARN "new winding was clipped away!\n" ); + } + + do_hull_recursion( hull, node, 0, &frontlist, model ); + do_hull_recursion( hull, node, 1, &backlist, model ); +} + +static void remove_paired_polys( hull_model_t *model ) +{ + winding_t *w, *next; + + list_for_each_entry_safe( w, next, &model->polys, chain ) + { + if( w->pair ) + { + list_del( &w->chain ); + free_winding( w ); + model->num_polys--; + } + } +} + +static void make_hull_windings( hull_t *hull, hull_model_t *model ) +{ + hullnode_t head = LIST_HEAD_INIT( head ); + + Con_Reportf( "%i clipnodes...\n", hull->lastclipnode - hull->firstclipnode ); + + node_stack_depth = 0; + model->num_polys = 0; + + if( hull->planes != NULL ) + { + hull_windings_r( hull, hull->clipnodes + hull->firstclipnode, &head, model ); + remove_paired_polys( model ); + } + Con_Reportf( "%i hull polys\n", model->num_polys ); +} + +void Mod_InitDebugHulls( void ) +{ + int i; + + world.hull_models = Mem_Calloc( loadmodel->mempool, sizeof( hull_model_t ) * loadmodel->numsubmodels ); + world.num_hull_models = loadmodel->numsubmodels; + + // initialize list + for( i = 0; i < world.num_hull_models; i++ ) + { + hullnode_t *poly = &world.hull_models[i].polys; + poly->next = poly; + poly->prev = poly; + } +} + +void Mod_CreatePolygonsForHull( int hullnum ) +{ + model_t *mod = cl.worldmodel; + double start, end; + char name[8]; + int i; + + if( hullnum < 1 || hullnum > 3 ) + return; + + Con_Printf( "generating polygons for hull %u...\n", hullnum ); + start = Sys_DoubleTime(); + + // rebuild hulls list + for( i = 0; i < world.num_hull_models; i++ ) + { + hull_model_t *model = &world.hull_models[i]; + free_hull_polys( &model->polys ); + make_hull_windings( &mod->hulls[hullnum], model ); + Q_snprintf( name, sizeof( name ), "*%i", i + 1 ); + mod = Mod_FindName( name, false ); + } + end = Sys_DoubleTime(); + Con_Printf( "build time %.3f secs\n", end - start ); +} + +void Mod_ReleaseHullPolygons( void ) +{ + int i; + + // release ploygons + for( i = 0; i < world.num_hull_models; i++ ) + { + hull_model_t *model = &world.hull_models[i]; + free_hull_polys( &model->polys ); + } +} + +void R_DrawWorldHull( void ) +{ + hull_model_t *hull = &world.hull_models[0]; + winding_t *poly; + int i; + + if( FBitSet( r_showhull->flags, FCVAR_CHANGED )) + { + int val = bound( 0, (int)r_showhull->value, 3 ); + if( val ) Mod_CreatePolygonsForHull( val ); + ClearBits( r_showhull->flags, FCVAR_CHANGED ); + } + + if( !CVAR_TO_BOOL( r_showhull )) + return; + pglDisable( GL_TEXTURE_2D ); + + list_for_each_entry( poly, &hull->polys, chain ) + { + srand((unsigned long)poly); + pglColor3f( rand() % 256 / 255.0, rand() % 256 / 255.0, rand() % 256 / 255.0 ); + pglBegin( GL_POLYGON ); + for( i = 0; i < poly->numpoints; i++ ) + pglVertex3fv( poly->p[i] ); + pglEnd(); + } + pglEnable( GL_TEXTURE_2D ); +} + +void R_DrawModelHull( void ) +{ + hull_model_t *hull; + winding_t *poly; + int i; + + if( !CVAR_TO_BOOL( r_showhull )) + return; + + if( !RI.currentmodel || RI.currentmodel->name[0] != '*' ) + return; + + i = atoi( RI.currentmodel->name + 1 ); + if( i < 1 || i >= world.num_hull_models ) + return; + + hull = &world.hull_models[i]; + + pglPolygonOffset( 1.0f, 2.0 ); + pglEnable( GL_POLYGON_OFFSET_FILL ); + pglDisable( GL_TEXTURE_2D ); + list_for_each_entry( poly, &hull->polys, chain ) + { + srand((unsigned long)poly); + pglColor3f( rand() % 256 / 255.0, rand() % 256 / 255.0, rand() % 256 / 255.0 ); + pglBegin( GL_POLYGON ); + for( i = 0; i < poly->numpoints; i++ ) + pglVertex3fv( poly->p[i] ); + pglEnd(); + } + pglEnable( GL_TEXTURE_2D ); + pglDisable( GL_POLYGON_OFFSET_FILL ); +} diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 5281e103..fed45ef1 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -95,6 +95,27 @@ typedef struct #define NL_NEEDS_LOADED 1 #define NL_PRESENT 2 +typedef struct hullnode_s +{ + struct hullnode_s *next; + struct hullnode_s *prev; +} hullnode_t; + +typedef struct winding_s +{ + const mplane_t *plane; + struct winding_s *pair; + hullnode_t chain; + int numpoints; + vec3_t p[4]; // variable sized +} winding_t; + +typedef struct +{ + hullnode_t polys; + uint num_polys; +} hull_model_t; + typedef struct { msurface_t *surf; @@ -115,6 +136,9 @@ typedef struct sortedface_t *draw_surfaces; // used for sorting translucent surfaces int max_surfaces; // max surfaces per submodel (for all models) + hull_model_t *hull_models; + int num_hull_models; + // visibility info byte *visdata; // uncompressed visdata size_t visbytes; // cluster size @@ -132,6 +156,7 @@ extern byte *com_studiocache; extern model_t *loadmodel; extern convar_t *mod_studiocache; extern convar_t *r_wadtextures; +extern convar_t *r_showhull; // // model.c @@ -172,6 +197,13 @@ byte *Mod_GetPVSForPoint( const vec3_t p ); void Mod_UnloadBrushModel( model_t *mod ); void Mod_PrintWorldStats_f( void ); +// +// mod_dbghulls.c +// +void Mod_InitDebugHulls( void ); +void Mod_CreatePolygonsForHull( int hullnum ); +void Mod_ReleaseHullPolygons( void ); + // // mod_studio.c // diff --git a/engine/common/mod_studio.c b/engine/common/mod_studio.c index ca826d66..1cc8a4cf 100644 --- a/engine/common/mod_studio.c +++ b/engine/common/mod_studio.c @@ -598,7 +598,7 @@ void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstud mstudioseqgroup_t *pseqgroup; cache_user_t *paSequences; size_t filesize; - byte *buf; + byte *buf; pseqgroup = (mstudioseqgroup_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqgroupindex) + pseqdesc->seqgroup; if( pseqdesc->seqgroup == 0 ) @@ -608,7 +608,7 @@ void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstud if( paSequences == NULL ) { - paSequences = (cache_user_t *)Mem_Alloc( com_studiocache, MAXSTUDIOGROUPS * sizeof( cache_user_t )); + paSequences = (cache_user_t *)Mem_Calloc( com_studiocache, MAXSTUDIOGROUPS * sizeof( cache_user_t )); m_pSubModel->submodels = (void *)paSequences; } @@ -628,8 +628,8 @@ void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstud if( IDSEQGRPHEADER != *(uint *)buf ) Host_Error( "StudioGetAnim: %s is corrupted\n", filepath ); Con_Printf( "loading: %s\n", filepath ); - - paSequences[pseqdesc->seqgroup].data = Mem_Alloc( com_studiocache, filesize ); + + paSequences[pseqdesc->seqgroup].data = Mem_Calloc( com_studiocache, filesize ); memcpy( paSequences[pseqdesc->seqgroup].data, buf, filesize ); Mem_Free( buf ); } @@ -1070,7 +1070,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) // give space for textures and skinrefs size1 = thdr->numtextures * sizeof( mstudiotexture_t ); size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short ); - mod->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length + size1 + size2 ); + mod->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length + size1 + size2 ); memcpy( loadmodel->cache.data, buffer, phdr->length ); // copy main mdl buffer phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr phdr->numskinfamilies = thdr->numskinfamilies; @@ -1089,7 +1089,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) else { // NOTE: don't modify source buffer because it's used for CRC computing - loadmodel->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length ); + loadmodel->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length ); memcpy( loadmodel->cache.data, buffer, phdr->length ); phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr Mod_StudioLoadTextures( mod, phdr ); @@ -1202,4 +1202,4 @@ Returns to default callbacks void Mod_ResetStudioAPI( void ) { pBlendAPI = &gBlendAPI; -} \ No newline at end of file +} diff --git a/engine/common/model.c b/engine/common/model.c index ea480fcb..59cfe5a9 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -31,6 +31,7 @@ static int mod_numknown = 0; byte *com_studiocache; // cache for submodels convar_t *mod_studiocache; convar_t *r_wadtextures; +convar_t *r_showhull; model_t *loadmodel; /* @@ -145,6 +146,7 @@ void Mod_Init( void ) com_studiocache = Mem_AllocPool( "Studio Cache" ); mod_studiocache = Cvar_Get( "r_studiocache", "1", FCVAR_ARCHIVE, "enables studio cache for speedup tracing hitboxes" ); r_wadtextures = Cvar_Get( "r_wadtextures", "0", 0, "completely ignore textures in the bsp-file if enabled" ); + r_showhull = Cvar_Get( "r_showhull", "0", 0, "draw collision hulls 1-3" ); Cmd_AddCommand( "mapstats", Mod_PrintWorldStats_f, "show stats for currently loaded map" ); Cmd_AddCommand( "modellist", Mod_Modellist_f, "display loaded models list" ); @@ -162,6 +164,7 @@ void Mod_FreeAll( void ) { int i; + Mod_ReleaseHullPolygons(); for( i = 0; i < mod_numknown; i++ ) Mod_FreeModel( &mod_known[i] ); mod_numknown = 0; @@ -409,6 +412,10 @@ static void Mod_PurgeStudioCache( void ) { int i; + // refresh hull data + SetBits( r_showhull->flags, FCVAR_CHANGED ); + Mod_ReleaseHullPolygons(); + // release previois map Mod_FreeModel( mod_known ); // world is stuck on slot #0 always @@ -494,7 +501,7 @@ void *Mod_Calloc( int number, size_t size ) cache_user_t *cu; if( number <= 0 || size <= 0 ) return NULL; - cu = (cache_user_t *)Mem_Alloc( com_studiocache, sizeof( cache_user_t ) + number * size ); + cu = (cache_user_t *)Mem_Calloc( com_studiocache, sizeof( cache_user_t ) + number * size ); cu->data = (void *)cu; // make sure what cu->data is not NULL return cu; @@ -533,7 +540,7 @@ void Mod_LoadCacheFile( const char *filename, cache_user_t *cu ) buf = FS_LoadFile( modname, &size, false ); if( !buf || !size ) Host_Error( "LoadCacheFile: ^1can't load %s^7\n", filename ); - cu->data = Mem_Alloc( com_studiocache, size ); + cu->data = Mem_Malloc( com_studiocache, size ); memcpy( cu->data, buf, size ); Mem_Free( buf ); } diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index d71f69c5..7146241d 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -406,7 +406,7 @@ fragbuf_t *Netchan_AllocFragbuf( void ) { fragbuf_t *buf; - buf = (fragbuf_t *)Mem_Alloc( net_mempool, sizeof( fragbuf_t )); + buf = (fragbuf_t *)Mem_Calloc( net_mempool, sizeof( fragbuf_t )); MSG_Init( &buf->frag_message, "Frag Message", buf->frag_message_buf, sizeof( buf->frag_message_buf )); return buf; @@ -578,7 +578,7 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg ) chunksize = chan->pfnBlockSize( chan->client ); else chunksize = FRAGMENT_MAX_SIZE; // fallback - wait = (fragbufwaiting_t *)Mem_Alloc( net_mempool, sizeof( fragbufwaiting_t )); + wait = (fragbufwaiting_t *)Mem_Calloc( net_mempool, sizeof( fragbufwaiting_t )); if( !LZSS_IsCompressed( MSG_GetData( msg ))) { @@ -588,7 +588,7 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg ) if( pbOut && uCompressedSize > 0 && uCompressedSize < uSourceSize ) { - Con_DPrintf( "Compressing split packet (%d -> %d bytes)\n", uSourceSize, uCompressedSize ); + Con_Reportf( "Compressing split packet (%d -> %d bytes)\n", uSourceSize, uCompressedSize ); memcpy( msg->pData, pbOut, uCompressedSize ); MSG_SeekToBit( msg, uCompressedSize << 3, SEEK_SET ); } @@ -756,7 +756,7 @@ void Netchan_CreateFileFragmentsFromBuffer( netchan_t *chan, const char *filenam if( pbOut ) free( pbOut ); } - wait = (fragbufwaiting_t *)Mem_Alloc( net_mempool, sizeof( fragbufwaiting_t )); + wait = (fragbufwaiting_t *)Mem_Calloc( net_mempool, sizeof( fragbufwaiting_t )); remaining = size; pos = 0; @@ -871,7 +871,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename ) Mem_Free( uncompressed ); } - wait = (fragbufwaiting_t *)Mem_Alloc( net_mempool, sizeof( fragbufwaiting_t )); + wait = (fragbufwaiting_t *)Mem_Calloc( net_mempool, sizeof( fragbufwaiting_t )); remaining = filesize; pos = 0; @@ -1077,7 +1077,7 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg ) p = p->next; } - buffer = Mem_Alloc( net_mempool, nsize + 1 ); + buffer = Mem_Calloc( net_mempool, nsize + 1 ); p = chan->incomingbufs[FRAG_FILE_STREAM]; pos = 0; @@ -1110,7 +1110,7 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg ) if( LZSS_IsCompressed( buffer )) { uint uncompressedSize = LZSS_GetActualSize( buffer ) + 1; - byte *uncompressedBuffer = Mem_Alloc( net_mempool, uncompressedSize ); + byte *uncompressedBuffer = Mem_Calloc( net_mempool, uncompressedSize ); nsize = LZSS_Decompress( buffer, uncompressedBuffer ); Mem_Free( buffer ); diff --git a/engine/common/net_encode.c b/engine/common/net_encode.c index 928c9fc1..49a0e8bd 100644 --- a/engine/common/net_encode.c +++ b/engine/common/net_encode.c @@ -682,7 +682,7 @@ void Delta_ParseTable( char **delta_script, delta_info_t *dt, const char *encode const delta_field_t *pInfo; // allocate the delta-structures - if( !dt->pFields ) dt->pFields = (delta_t *)Z_Malloc( dt->maxFields * sizeof( delta_t )); + if( !dt->pFields ) dt->pFields = (delta_t *)Z_Calloc( dt->maxFields * sizeof( delta_t )); pField = dt->pFields; pInfo = dt->pInfo; diff --git a/engine/common/soundlib/snd_main.c b/engine/common/soundlib/snd_main.c index 3eb5704e..415fd7f0 100644 --- a/engine/common/soundlib/snd_main.c +++ b/engine/common/soundlib/snd_main.c @@ -32,7 +32,7 @@ void Sound_Reset( void ) wavdata_t *SoundPack( void ) { - wavdata_t *pack = Mem_Alloc( host.soundpool, sizeof( wavdata_t )); + wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t )); pack->buffer = sound.wav; pack->width = sound.width; diff --git a/engine/common/soundlib/snd_mp3.c b/engine/common/soundlib/snd_mp3.c index 8b72b17b..b6c27a5b 100644 --- a/engine/common/soundlib/snd_mp3.c +++ b/engine/common/soundlib/snd_mp3.c @@ -102,7 +102,7 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, size_t filesize ) } sound.type = WF_PCMDATA; - sound.wav = (byte *)Mem_Alloc( host.soundpool, sound.size ); + sound.wav = (byte *)Mem_Malloc( host.soundpool, sound.size ); // decompress mpg into pcm wav format while( bytesWrite < sound.size ) @@ -155,7 +155,7 @@ stream_t *Stream_OpenMPG( const char *filename ) if( !file ) return NULL; // at this point we have valid stream - stream = Mem_Alloc( host.soundpool, sizeof( stream_t )); + stream = Mem_Calloc( host.soundpool, sizeof( stream_t )); stream->file = file; stream->pos = 0; diff --git a/engine/common/soundlib/snd_utils.c b/engine/common/soundlib/snd_utils.c index 552d04fb..5c29e51b 100644 --- a/engine/common/soundlib/snd_utils.c +++ b/engine/common/soundlib/snd_utils.c @@ -87,7 +87,7 @@ byte *Sound_Copy( size_t size ) { byte *out; - out = Mem_Alloc( host.soundpool, size ); + out = Mem_Malloc( host.soundpool, size ); memcpy( out, sound.tempbuffer, size ); return out; diff --git a/engine/common/soundlib/snd_wav.c b/engine/common/soundlib/snd_wav.c index e99b2919..7757813b 100644 --- a/engine/common/soundlib/snd_wav.c +++ b/engine/common/soundlib/snd_wav.c @@ -279,7 +279,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, size_t filesize ) // Load the data sound.size = sound.samples * sound.width * sound.channels; - sound.wav = Mem_Alloc( host.soundpool, sound.size ); + sound.wav = Mem_Malloc( host.soundpool, sound.size ); memcpy( sound.wav, buffer + (iff_dataPtr - buffer), sound.size ); @@ -384,7 +384,7 @@ stream_t *Stream_OpenWAV( const char *filename ) sound.samples = ( sound.samples / sound.width ) / sound.channels; // at this point we have valid stream - stream = Mem_Alloc( host.soundpool, sizeof( stream_t )); + stream = Mem_Calloc( host.soundpool, sizeof( stream_t )); stream->file = file; stream->size = sound.samples * sound.width * sound.channels; stream->buffsize = FS_Tell( file ); // header length diff --git a/engine/common/zone.c b/engine/common/zone.c index 8cdde6a8..1fa46dc6 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -15,12 +15,6 @@ GNU General Public License for more details. #include "common.h" -#define MEMUNIT 8 // smallest unit we care about is this many bytes -#define MEMCLUMPSIZE (65536 - 1536) // give malloc padding so we can't waste most of a page at the end -#define MEMBITS (MEMCLUMPSIZE / MEMUNIT) -#define MEMBITINTS (MEMBITS / 32) - -#define MEMCLUMP_SENTINEL 0xABADCAFE #define MEMHEADER_SENTINEL1 0xDEADF00D #define MEMHEADER_SENTINEL2 0xDF @@ -29,7 +23,6 @@ typedef struct memheader_s struct memheader_s *next; // next and previous memheaders in chain belonging to pool struct memheader_s *prev; struct mempool_s *pool; // pool this memheader belongs to - struct memclump_s *clump; // clump this memheader lives in, NULL if not in a clump size_t size; // size of the memory after the header (excluding header and sentinel2) const char *filename; // file name and line where Mem_Alloc was called uint fileline; @@ -38,22 +31,10 @@ typedef struct memheader_s // immediately followed by data, which is followed by a MEMHEADER_SENTINEL2 byte } memheader_t; -typedef struct memclump_s -{ - byte block[MEMCLUMPSIZE];// contents of the clump - uint sentinel1; // should always be MEMCLUMP_SENTINEL - int bits[MEMBITINTS]; // if a bit is on, it means that the MEMUNIT bytes it represents are allocated, otherwise free - uint sentinel2; // should always be MEMCLUMP_SENTINEL - size_t blocksinuse; // if this drops to 0, the clump is freed - size_t largestavailable; // largest block of memory available - struct memclump_s *chain; // next clump in the chain -} memclump_t; - typedef struct mempool_s { uint sentinel1; // should always be MEMHEADER_SENTINEL1 struct memheader_s *chain; // chain of individual memory allocations - struct memclump_s *clumpchain; // chain of clumps (if any) size_t totalsize; // total memory allocated in this pool (inside memheaders) size_t realsize; // total memory allocated in this pool (actual malloc total) size_t lastchecksize; // updated each time the pool is displayed by memlist @@ -66,10 +47,8 @@ typedef struct mempool_s mempool_t *poolchain = NULL; // critical stuff -void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline ) +void *_Mem_Alloc( byte *poolptr, size_t size, qboolean clear, const char *filename, int fileline ) { - int i, j, k, needed, endbit, largest; - memclump_t *clump, **clumpchainpointer; memheader_t *mem; mempool_t *pool = (mempool_t *)poolptr; @@ -77,68 +56,10 @@ void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline if( poolptr == NULL ) Sys_Error( "Mem_Alloc: pool == NULL (alloc at %s:%i)\n", filename, fileline ); pool->totalsize += size; - if( size < 4096 ) - { - // clumping - needed = ( sizeof( memheader_t ) + size + sizeof( int ) + (MEMUNIT - 1)) / MEMUNIT; - endbit = MEMBITS - needed; - for( clumpchainpointer = &pool->clumpchain; *clumpchainpointer; clumpchainpointer = &(*clumpchainpointer)->chain ) - { - clump = *clumpchainpointer; - if( clump->sentinel1 != MEMCLUMP_SENTINEL ) - Sys_Error( "Mem_Alloc: trashed clump sentinel 1 (alloc at %s:%d)\n", filename, fileline ); - if( clump->sentinel2 != MEMCLUMP_SENTINEL ) - Sys_Error( "Mem_Alloc: trashed clump sentinel 2 (alloc at %s:%d)\n", filename, fileline ); - if( clump->largestavailable >= needed ) - { - largest = 0; - for( i = 0; i < endbit; i++ ) - { - if( clump->bits[i>>5] & (1 << (i & 31))) - continue; - k = i + needed; - for( j = i; i < k; i++ ) - if( clump->bits[i>>5] & (1 << (i & 31))) - goto loopcontinue; - goto choseclump; -loopcontinue:; - if( largest < j - i ) - largest = j - i; - } - // since clump falsely advertised enough space (nothing wrong - // with that), update largest count to avoid wasting time in - // later allocations - clump->largestavailable = largest; - } - } - - pool->realsize += sizeof( memclump_t ); - clump = malloc( sizeof( memclump_t )); - if( clump == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline ); - memset( clump, 0, sizeof( memclump_t )); - *clumpchainpointer = clump; - clump->sentinel1 = MEMCLUMP_SENTINEL; - clump->sentinel2 = MEMCLUMP_SENTINEL; - clump->chain = NULL; - clump->blocksinuse = 0; - clump->largestavailable = MEMBITS - needed; - j = 0; -choseclump: - mem = (memheader_t *)((byte *)clump->block + j * MEMUNIT ); - mem->clump = clump; - clump->blocksinuse += needed; - - for( i = j + needed; j < i; j++ ) - clump->bits[j >> 5] |= (1 << (j & 31)); - } - else - { - // big allocations are not clumped - pool->realsize += sizeof( memheader_t ) + size + sizeof( int ); - mem = (memheader_t *)malloc( sizeof( memheader_t ) + size + sizeof( int )); - if( mem == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline ); - mem->clump = NULL; - } + // big allocations are not clumped + pool->realsize += sizeof( memheader_t ) + size + sizeof( int ); + mem = (memheader_t *)malloc( sizeof( memheader_t ) + size + sizeof( int )); + if( mem == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline ); mem->filename = filename; mem->fileline = fileline; @@ -153,7 +74,7 @@ choseclump: mem->prev = NULL; pool->chain = mem; if( mem->next ) mem->next->prev = mem; - memset((void *)((byte *)mem + sizeof( memheader_t )), 0, mem->size ); + if( clear ) memset((void *)((byte *)mem + sizeof( memheader_t )), 0, mem->size ); return (void *)((byte *)mem + sizeof( memheader_t )); } @@ -167,7 +88,7 @@ static const char *Mem_CheckFilename( const char *filename ) if( !COM_CheckString( out )) return dummy; - for( i = 0; i < 128; i++, out++ ) + for( i = 0; i < MAX_OSPATH; i++, out++ ) { if( *out == '\0' ) return filename; // valid name @@ -178,8 +99,6 @@ static const char *Mem_CheckFilename( const char *filename ) static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline ) { - int i, firstblock, endblock; - memclump_t *clump, **clumpchainpointer; mempool_t *pool; if( mem->sentinel1 != MEMHEADER_SENTINEL1 ) @@ -208,50 +127,8 @@ static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline // memheader has been unlinked, do the actual free now pool->totalsize -= mem->size; - if(( clump = mem->clump ) != NULL ) - { - if( clump->sentinel1 != MEMCLUMP_SENTINEL ) - Sys_Error( "Mem_Free: trashed clump sentinel 1 (free at %s:%i)\n", filename, fileline ); - if( clump->sentinel2 != MEMCLUMP_SENTINEL ) - Sys_Error( "Mem_Free: trashed clump sentinel 2 (free at %s:%i)\n", filename, fileline ); - firstblock = ((byte *)mem - (byte *)clump->block ); - if( firstblock & ( MEMUNIT - 1 )) - Sys_Error( "Mem_Free: address not valid in clump (free at %s:%i)\n", filename, fileline ); - firstblock /= MEMUNIT; - endblock = firstblock + ((sizeof( memheader_t ) + mem->size + sizeof( int ) + (MEMUNIT - 1)) / MEMUNIT ); - clump->blocksinuse -= endblock - firstblock; - - // could use &, but we know the bit is set - for( i = firstblock; i < endblock; i++ ) - clump->bits[i >> 5] -= (1 << (i & 31)); - if( clump->blocksinuse <= 0 ) - { - // unlink from chain - for( clumpchainpointer = &pool->clumpchain; *clumpchainpointer; clumpchainpointer = &(*clumpchainpointer)->chain ) - { - if (*clumpchainpointer == clump) - { - *clumpchainpointer = clump->chain; - break; - } - } - - pool->realsize -= sizeof( memclump_t ); - memset( clump, 0xBF, sizeof( memclump_t )); - free( clump ); - } - else - { - // clump still has some allocations - // force re-check of largest available space on next alloc - clump->largestavailable = MEMBITS - clump->blocksinuse; - } - } - else - { - pool->realsize -= sizeof( memheader_t ) + mem->size + sizeof( int ); - free( mem ); - } + pool->realsize -= sizeof( memheader_t ) + mem->size + sizeof( int ); + free( mem ); } void _Mem_Free( void *data, const char *filename, int fileline ) @@ -260,7 +137,7 @@ void _Mem_Free( void *data, const char *filename, int fileline ) Mem_FreeBlock((memheader_t *)((byte *)data - sizeof( memheader_t )), filename, fileline ); } -void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, const char *filename, int fileline ) +void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) { memheader_t *memhdr = NULL; char *nb; @@ -273,7 +150,7 @@ void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, const char *filena if( size == memhdr->size ) return memptr; } - nb = _Mem_Alloc( poolptr, size, filename, fileline ); + nb = _Mem_Alloc( poolptr, size, clear, filename, fileline ); if( memptr ) // first allocate? { @@ -399,20 +276,10 @@ void Mem_CheckHeaderSentinels( void *data, const char *filename, int fileline ) } } -static void Mem_CheckClumpSentinels( memclump_t *clump, const char *filename, int fileline ) -{ - // this isn't really very useful - if( clump->sentinel1 != MEMCLUMP_SENTINEL ) - Sys_Error( "Mem_CheckClumpSentinels: trashed sentinel 1 (sentinel check at %s:%i)\n", filename, fileline ); - if( clump->sentinel2 != MEMCLUMP_SENTINEL ) - Sys_Error( "Mem_CheckClumpSentinels: trashed sentinel 2 (sentinel check at %s:%i)\n", filename, fileline ); -} - void _Mem_Check( const char *filename, int fileline ) { memheader_t *mem; mempool_t *pool; - memclump_t *clump; for( pool = poolchain; pool; pool = pool->next ) { @@ -425,10 +292,6 @@ void _Mem_Check( const char *filename, int fileline ) for( pool = poolchain; pool; pool = pool->next ) for( mem = pool->chain; mem; mem = mem->next ) Mem_CheckHeaderSentinels((void *)((byte *) mem + sizeof(memheader_t)), filename, fileline ); - - for( pool = poolchain; pool; pool = pool->next ) - for( clump = pool->clumpchain; clump; clump = clump->chain ) - Mem_CheckClumpSentinels( clump, filename, fileline ); } void Mem_PrintStats( void ) diff --git a/engine/platform/sdl/vid_sdl.c b/engine/platform/sdl/vid_sdl.c index d4300f22..f0e6f83b 100644 --- a/engine/platform/sdl/vid_sdl.c +++ b/engine/platform/sdl/vid_sdl.c @@ -227,7 +227,7 @@ static void R_InitVideoModes( void ) if( !modes ) return; - vidmodes = Mem_Alloc( host.mempool, modes * sizeof( vidmode_t ) ); + vidmodes = Mem_Malloc( host.mempool, modes * sizeof( vidmode_t ) ); for( i = 0; i < modes; i++ ) { @@ -363,8 +363,6 @@ static void APIENTRY GL_DebugOutput( GLuint source, GLuint type, GLuint id, GLui Con_Printf( S_OPENGL_WARN "%s\n", message ); break; case GL_DEBUG_TYPE_PERFORMANCE_ARB: - if( host_developer.value < DEV_EXTENDED ) - return; Con_Printf( S_OPENGL_NOTE "%s\n", message ); break; case GL_DEBUG_TYPE_OTHER_ARB: @@ -592,9 +590,9 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) // remove MSAA, if it present, because // window creating may fail on GLX visual choose - if( gl_msaa->value || glw_state.safe >= 0 ) + if( gl_wgl_msaa_samples->value || glw_state.safe >= 0 ) { - Cvar_Set( "gl_msaa", "0" ); + Cvar_Set( "gl_wgl_msaa_samples", "0" ); glw_state.safe++; GL_SetupAttributes(); // re-choose attributes @@ -740,13 +738,12 @@ static void GL_SetupAttributes( void ) #endif #elif !defined XASH_GL_STATIC - if( Sys_CheckParm( "-gldebug" ) && host_developer.value >= 1 ) + if( Sys_CheckParm( "-gldebug" ) ) { MsgDev( D_NOTE, "Creating an extended GL context for debug...\n" ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG ); glw_state.extended = true; } - #endif // XASH_GLES SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); @@ -795,13 +792,13 @@ static void GL_SetupAttributes( void ) SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, gl_stencilbits->value ); - switch( (int)gl_msaa->value ) + switch( (int)gl_wgl_msaa_samples->value ) { case 2: case 4: case 8: case 16: - samples = gl_msaa->value; + samples = gl_wgl_msaa_samples->value; break; default: samples = 0; // don't use, because invalid parameter is passed @@ -811,11 +808,15 @@ static void GL_SetupAttributes( void ) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); + + glConfig.max_multisamples = samples; } else { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); + + glConfig.max_multisamples = 0; } } @@ -1037,7 +1038,7 @@ void GL_InitExtensionsBigGL() pglGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig.max_vertex_attribs ); #ifdef _WIN32 // Win32 only drivers? - if( glConfig.hardware_type == GLHW_RADEON ) + if( glConfig.hardware_type == GLHW_RADEON && glConfig.max_vertex_uniforms > 512 ) glConfig.max_vertex_uniforms /= 4; // radeon returns not correct info #endif } @@ -1067,8 +1068,7 @@ void GL_InitExtensionsBigGL() } // enable all the low priority messages - if( host_developer.value >= 2 ) - pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); + pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); } #endif } diff --git a/engine/platform/win32/win_lib.c b/engine/platform/win32/win_lib.c index 49743de4..426b4467 100644 --- a/engine/platform/win32/win_lib.c +++ b/engine/platform/win32/win_lib.c @@ -741,7 +741,7 @@ qboolean LibraryLoadSymbols( dll_user_t *hInst ) goto table_error; } - hInst->ordinals = Mem_Alloc( host.mempool, hInst->num_ordinals * sizeof( word )); + hInst->ordinals = Mem_Malloc( host.mempool, hInst->num_ordinals * sizeof( word )); if( FS_Read( f, hInst->ordinals, hInst->num_ordinals * sizeof( word )) != (hInst->num_ordinals * sizeof( word ))) { @@ -757,7 +757,7 @@ qboolean LibraryLoadSymbols( dll_user_t *hInst ) goto table_error; } - hInst->funcs = Mem_Alloc( host.mempool, hInst->num_ordinals * sizeof( dword )); + hInst->funcs = Mem_Malloc( host.mempool, hInst->num_ordinals * sizeof( dword )); if( FS_Read( f, hInst->funcs, hInst->num_ordinals * sizeof( dword )) != (hInst->num_ordinals * sizeof( dword ))) { @@ -773,7 +773,7 @@ qboolean LibraryLoadSymbols( dll_user_t *hInst ) goto table_error; } - p_Names = Mem_Alloc( host.mempool, hInst->num_ordinals * sizeof( dword )); + p_Names = Mem_Malloc( host.mempool, hInst->num_ordinals * sizeof( dword )); if( FS_Read( f, p_Names, hInst->num_ordinals * sizeof( dword )) != (hInst->num_ordinals * sizeof( dword ))) { diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 10c8adca..55f15eb5 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -342,7 +342,7 @@ void SV_ConnectClient( netadr_t from ) sv.current_client = newcl; newcl->edict = EDICT_NUM( (newcl - svs.clients) + 1 ); newcl->challenge = challenge; // save challenge for checksumming - newcl->frames = (client_frame_t *)Z_Malloc( sizeof( client_frame_t ) * SV_UPDATE_BACKUP ); + newcl->frames = (client_frame_t *)Z_Calloc( sizeof( client_frame_t ) * SV_UPDATE_BACKUP ); newcl->userid = g_userid++; // create unique userid newcl->state = cs_connected; @@ -2263,7 +2263,7 @@ void SV_ParseResourceList( sv_client_t *cl, sizebuf_t *msg ) for( i = 0; i < total; i++ ) { - resource = Z_Malloc( sizeof( resource_t ) ); + resource = Z_Calloc( sizeof( resource_t ) ); Q_strncpy( resource->szFileName, MSG_ReadString( msg ), sizeof( resource->szFileName )); resource->type = MSG_ReadByte( msg ); resource->nIndex = MSG_ReadShort( msg ); diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index bfbe91ce..4c57b59d 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -611,7 +611,7 @@ void SV_RestartDecals( void ) if( !SV_Active( )) return; // g-cont. add space for studiodecals if present - host.decalList = (decallist_t *)Z_Malloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 ); + host.decalList = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 ); host.numdecals = R_CreateDecalList( host.decalList ); // remove decals from map @@ -694,7 +694,7 @@ void SV_WriteEntityPatch( const char *filename ) char *entities = NULL; FS_Seek( f, lumpofs, SEEK_SET ); - entities = (char *)Z_Malloc( lumplen + 1 ); + entities = (char *)Z_Calloc( lumplen + 1 ); FS_Read( f, entities, lumplen ); FS_WriteFile( va( "maps/%s.ent", filename ), entities, lumplen ); Con_Printf( "Write 'maps/%s.ent'\n", filename ); @@ -762,7 +762,7 @@ static char *SV_ReadEntityScript( const char *filename, int *flags ) if( !ents && lumplen >= 32 ) { FS_Seek( f, lumpofs, SEEK_SET ); - ents = Z_Malloc( lumplen + 1 ); + ents = Z_Calloc( lumplen + 1 ); FS_Read( f, ents, lumplen ); } FS_Close( f ); // all done @@ -2013,8 +2013,14 @@ int SV_BuildSoundMsg( sizebuf_t *msg, edict_t *ent, int chan, const char *sample if( sample[0] == '!' && Q_isdigit( sample + 1 )) { - SetBits( flags, SND_SENTENCE ); sound_idx = Q_atoi( sample + 1 ); + + if( sound_idx >= MAX_SOUNDS ) + { + SetBits( flags, SND_SENTENCE|SND_SEQUENCE ); + sound_idx -= MAX_SOUNDS; + } + else SetBits( flags, SND_SENTENCE ); } else if( sample[0] == '#' && Q_isdigit( sample + 1 )) { @@ -2927,7 +2933,7 @@ void *pfnPvAllocEntPrivateData( edict_t *pEdict, long cb ) if( cb > 0 ) { // a poke646 have memory corrupt in somewhere - this is trashed last sixteen bytes :( - pEdict->pvPrivateData = Mem_Alloc( svgame.mempool, (cb + 15) & ~15 ); + pEdict->pvPrivateData = Mem_Calloc( svgame.mempool, (cb + 15) & ~15 ); } return pEdict->pvPrivateData; @@ -2967,7 +2973,7 @@ string_t SV_AllocString( const char *szString ) l = Q_strlen( szString ) + 1; - out = out_p = Mem_Alloc( svgame.stringspool, l ); + out = out_p = Mem_Calloc( svgame.stringspool, l ); for( i = 0; i < l; i++ ) { if( szString[i] == '\\' && i < l - 1 ) @@ -4099,7 +4105,7 @@ void pfnEndSection( const char *pszSection ) { if( !Q_stricmp( "oem_end_credits", pszSection )) Host_Credits (); - else Cbuf_AddText( va( "endgame \"%s\"\n", pszSection )); + else Cbuf_AddText( "\ndisconnect\n" ); } /* @@ -4865,8 +4871,8 @@ qboolean SV_LoadProgs( const char *name ) svgame.globals->maxEntities = GI->max_edicts; svgame.globals->maxClients = svs.maxclients; - svgame.edicts = Mem_Alloc( svgame.mempool, sizeof( edict_t ) * GI->max_edicts ); - svs.baselines = Z_Malloc( sizeof( entity_state_t ) * GI->max_edicts ); + svgame.edicts = Mem_Calloc( svgame.mempool, sizeof( edict_t ) * GI->max_edicts ); + svs.baselines = Z_Calloc( sizeof( entity_state_t ) * GI->max_edicts ); svgame.numEntities = svs.maxclients + 1; // clients + world for( i = 0, e = svgame.edicts; i < GI->max_edicts; i++, e++ ) diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 00e39014..a075cf9e 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -1945,7 +1945,7 @@ static char **pfnGetFilesList( const char *pattern, int *numFiles, int gamediron static void *pfnMem_Alloc( size_t cb, const char *filename, const int fileline ) { - return _Mem_Alloc( svgame.mempool, cb, filename, fileline ); + return _Mem_Alloc( svgame.mempool, cb, true, filename, fileline ); } static void pfnMem_Free( void *mem, const char *filename, const int fileline ) @@ -1981,7 +1981,7 @@ const byte *pfnLoadImagePixels( const char *filename, int *width, int *height ) if( !pic ) return NULL; - buffer = Mem_Alloc( svgame.mempool, pic->size ); + buffer = Mem_Malloc( svgame.mempool, pic->size ); if( buffer ) memcpy( buffer, pic->buffer, pic->size ); if( width ) *width = pic->width; if( height ) *height = pic->height; diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index 1f55ff5e..191e3333 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -266,7 +266,7 @@ static void InitEntityTable( SAVERESTOREDATA *pSaveData, int entityCount ) ENTITYTABLE *pTable; int i; - pSaveData->pTable = Mem_Alloc( host.mempool, sizeof( ENTITYTABLE ) * entityCount ); + pSaveData->pTable = Mem_Calloc( host.mempool, sizeof( ENTITYTABLE ) * entityCount ); pSaveData->tableCount = entityCount; // setup entitytable @@ -604,8 +604,8 @@ static SAVERESTOREDATA *SaveInit( int size, int tokenCount ) { SAVERESTOREDATA *pSaveData; - pSaveData = Mem_Alloc( host.mempool, sizeof( SAVERESTOREDATA ) + size ); - pSaveData->pTokens = (char **)Mem_Alloc( host.mempool, tokenCount * sizeof( char* )); + pSaveData = Mem_Calloc( host.mempool, sizeof( SAVERESTOREDATA ) + size ); + pSaveData->pTokens = (char **)Mem_Calloc( host.mempool, tokenCount * sizeof( char* )); pSaveData->tokenCount = tokenCount; pSaveData->pBaseData = (char *)(pSaveData + 1); // skip the save structure); @@ -1108,7 +1108,7 @@ static void SaveClientState( SAVERESTOREDATA *pSaveData, const char *level, int memset( &header, 0, sizeof( header )); // g-cont. add space for studiodecals if present - decalList = (decallist_t *)Z_Malloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 ); + decalList = (decallist_t *)Z_Calloc( sizeof( decallist_t ) * MAX_RENDER_DECALS * 2 ); // initialize client header header.decalCount = R_CreateDecalList( decalList ); @@ -2224,14 +2224,14 @@ int SV_GetSaveComment( const char *savename, char *comment ) return 0; } - pSaveData = (char *)Mem_Alloc( host.mempool, size ); + pSaveData = (char *)Mem_Malloc( host.mempool, size ); FS_Read( f, pSaveData, size ); pData = pSaveData; // allocate a table for the strings, and parse the table if( tokenSize > 0 ) { - pTokenList = Mem_Alloc( host.mempool, tokenCount * sizeof( char* )); + pTokenList = Mem_Calloc( host.mempool, tokenCount * sizeof( char* )); // make sure the token strings pointed to by the pToken hashtable. for( i = 0; i < tokenCount; i++ )