06 Feb 2018

This commit is contained in:
g-cont 2018-02-06 00:00:00 +03:00 committed by Alibek Omarov
parent 70d9efc3ac
commit 83bee9ddb6
36 changed files with 3323 additions and 4233 deletions

View File

@ -96,6 +96,7 @@ BRUSH MODELS
#define MAX_MAP_MIPTEX 0x2000000 // 32 Mb internal textures data
#define MAX_MAP_LIGHTING 0x2000000 // 32 Mb lightmap raw data (can contain deluxemaps)
#define MAX_MAP_VISIBILITY 0x1000000 // 16 Mb visdata
#define MAX_MAP_FACEINFO 8192 // can be increased but not needs
#define MAX_TOTAL_CLIPNODES 524288
// quake lump ordering
@ -217,7 +218,7 @@ typedef struct
float maxs[3];
int firstface;
int numfaces; // counting both sides
} dnode2_t;
} dnode32_t;
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
// all other leafs need visibility info
@ -247,7 +248,7 @@ typedef struct
int nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} dleaf2_t;
} dleaf32_t;
typedef struct
{
@ -259,7 +260,7 @@ typedef struct
{
int planenum;
int children[2]; // negative numbers are contents
} dclipnode2_t;
} dclipnode32_t;
typedef struct
{
@ -278,7 +279,7 @@ typedef struct
} dfaceinfo_t;
typedef word dmarkface_t; // leaf marksurfaces indexes
typedef int dmarkface2_t; // leaf marksurfaces indexes
typedef int dmarkface32_t; // leaf marksurfaces indexes
typedef int dsurfedge_t; // map surfedges
@ -292,7 +293,7 @@ typedef struct
typedef struct
{
int v[2]; // vertex numbers
} dedge2_t;
} dedge32_t;
typedef struct
{
@ -320,6 +321,6 @@ typedef struct
// lighting info
byte styles[LM_STYLES];
int lightofs; // start of [numstyles*surfsize] samples
} dface2_t;
} dface32_t;
#endif//BSPFILE_H

View File

@ -33,8 +33,6 @@ typedef struct IVoiceTweak_s
// Get/set control values.
void (*SetControlFloat)( VoiceTweakControl iControl, float value );
float (*GetControlFloat)( VoiceTweakControl iControl );
int (*GetSpeakingVolume)( void );
} IVoiceTweak;
#endif//IVOICETWEAK_H

View File

@ -226,6 +226,8 @@ typedef struct render_api_s
// find in files
char **(*pfnGetFilesList)( const char *pattern, int *numFiles, int gamedironly );
unsigned long (*pfnFileBufferCRC32)( const void *buffer, const int length );
void* ( *pfnGetModel )( int modelindex );
float (*pfnTime)( void );
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 35
} render_api_t;

View File

@ -34,7 +34,7 @@ typedef struct cldll_func_s
void (*IN_Accumulate)( void );
void (*CL_CreateMove)( float frametime, struct usercmd_s *cmd, int active );
int (*CL_IsThirdPerson)( void );
void (*CL_CameraOffset)( float *ofs );
void (*CL_CameraOffset)( float *ofs ); // unused
void *(*KB_Find)( const char *name );
void (*CAM_Think)( void ); // camera stuff
void (*pfnCalcRefdef)( ref_params_t *pparams );
@ -59,8 +59,6 @@ typedef struct cldll_func_s
void (*pfnDirectorMessage)( int iSize, void *pbuf );
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
void (*pfnChatInputPosition)( int *x, int *y );
int (*pfnGetPlayerTeam)( int playerIndex );
void *(*pfnGetClientFactory)( void );
// Xash3D extension
int (*pfnGetRenderInterface)( int version, render_api_t *renderfuncs, render_interface_t *callback );
void (*pfnClipMoveToEntity)( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );

View File

@ -28,15 +28,6 @@ extern "C" {
#include "const.h"
#define MAX_ALIAS_NAME 32
typedef struct cmdalias_s
{
struct cmdalias_s *next;
char name[MAX_ALIAS_NAME];
char *value;
} cmdalias_t;
// this file is included by both the engine and the client-dll,
// so make sure engine declarations aren't done twice
@ -105,8 +96,6 @@ typedef struct hud_player_info_s
char *model;
short topcolor;
short bottomcolor;
unsigned __int64 m_nSteamID;
} hud_player_info_t;
typedef struct cl_enginefuncs_s
@ -259,44 +248,6 @@ typedef struct cl_enginefuncs_s
void (*pfnGetMousePos)( struct tagPOINT *ppt );
void (*pfnSetMousePos)( int x, int y );
void (*pfnSetMouseEnable)( qboolean fEnable );
// undocumented interface starts here
struct cvar_s* (*pfnGetFirstCvarPtr)( void );
void* (*pfnGetFirstCmdFunctionHandle)( void );
void* (*pfnGetNextCmdFunctionHandle)( void *cmdhandle );
const char* (*pfnGetCmdFunctionName)( void *cmdhandle );
float (*pfnGetClientOldTime)( void );
float (*pfnGetGravity)( void );
struct model_s* (*pfnGetModelByIndex)( int index );
void (*pfnSetFilterMode)( int mode ); // same as gl_texsort in original Quake
void (*pfnSetFilterColor)( float red, float green, float blue );
void (*pfnSetFilterBrightness)( float brightness );
void *(*pfnSequenceGet)( const char *fileName, const char *entryName );
void (*pfnSPR_DrawGeneric)( int frame, int x, int y, const wrect_t *prc, int blendsrc, int blenddst, int width, int height );
void *(*pfnSequencePickSentence)( const char *groupName, int pickMethod, int *entryPicked );
int (*pfnVGUI2_DrawString)( int x, int y, const char *str, int r, int g, int b );
int (*pfnVGUI2_DrawStringReverse)( int x, int y, const char *str, int r, int g, int b );
const char *(*LocalPlayerInfo_ValueForKey)( const char* key );
int (*pfnVGUI2_DrawCharacter)( int x, int y, int ch, unsigned int font );
int (*pfnVGUI2_DrawCharacterAdditive)( int x, int y, int ch, int r, int g, int b, unsigned int font );
unsigned int (*pfnGetApproxWavePlayLen)( char *filename );
void* (*pfnVGUI2_GetCareerGameUI)( void ); // g-cont. !!!! potential crash-point!
void (*Cvar_Set)( char *name, char *value );
int (*pfnVGUI2_IsPlayingCareerMatch)( void );
void (*pfnPlaySoundVoiceByName)( char *szSound, float volume, int pitch );
void (*pfnPrimeMusicStream)( char *filename, int looping );
double (*pfnSys_FloatTime)( void );
// decay funcs
void (*pfnProcessTutorMessageDecayBuffer)( int *buffer, int buflen );
void (*pfnConstructTutorMessageDecayBuffer)( int *buffer, int buflen );
void (*pfnResetTutorMessageDecayData)( void );
void (*pfnPlaySoundByNameAtPitch)( char *szSound, float volume, int pitch );
void (*pfnFillRGBABlend)( int x, int y, int width, int height, int r, int g, int b, int a );
int (*pfnGetAppID)( void );
cmdalias_t *(*pfnGetAliases)( void );
void (*pfnVGUI2_GetMouseDelta)( int *x, int *y );
} cl_enginefunc_t;
#define CLDLL_INTERFACE_VERSION 7

View File

@ -184,7 +184,7 @@ void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func )
ev = clgame.events[lastnum];
// NOTE: ev->index will be set later
Q_strncpy( ev->name, szEvName, CS_SIZE );
Q_strncpy( ev->name, szEvName, MAX_QPATH );
ev->func = func;
}

View File

@ -288,17 +288,14 @@ void CL_ProcessEntityUpdate( cl_entity_t *ent )
CL_UpdatePositions( ent );
}
if( !FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
if( ent->player && !FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
{
// g-cont. it should be done for all the players?
// FIXME: probably this cause problems with flahslight and mirror reflection
// but it's used to reduce player body pitch...
if( ent->player )
{
if( world.has_mirrors && gl_allow_mirrors->value && RP_LOCALCLIENT( ent ) && !cl.local.thirdperson )
ent->curstate.angles[PITCH] /= 3.0f;
else ent->curstate.angles[PITCH] /= -3.0f;
}
if( FBitSet( world.flags, FWORLD_HAS_MIRRORS ) && gl_allow_mirrors->value && RP_LOCALCLIENT( ent ) && !cl.local.thirdperson )
ent->curstate.angles[PITCH] /= 3.0f;
else ent->curstate.angles[PITCH] /= -3.0f;
}
VectorCopy( ent->curstate.origin, ent->origin );
@ -911,7 +908,16 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
// check for adding this entity
if( !clgame.dllFuncs.pfnAddEntity( entityType, ent, ent->model->name ))
return false;
return true;
if( entityType == ET_PLAYER && RP_LOCALCLIENT( ent ))
{
if( !CL_IsThirdPerson( ))
{
if( !gl_allow_mirrors->value || !FBitSet( world.flags, FWORLD_HAS_MIRRORS ))
return false;
}
}
if( entityType == ET_BEAM )
{
@ -986,12 +992,6 @@ void CL_LinkPlayers( frame_t *frame )
if( state->messagenum != cl.parsecount )
continue; // not present this frame
if( !CL_IsThirdPerson() && ( i == cl.viewentity - 1 ))
{
if( !gl_allow_mirrors->value || !world.has_mirrors )
continue;
}
if( !state->modelindex || FBitSet( state->effects, EF_NODRAW ))
continue;

View File

@ -87,7 +87,6 @@ static dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and higher
{ "HUD_VoiceStatus", (void **)&clgame.dllFuncs.pfnVoiceStatus },
{ "HUD_ChatInputPosition", (void **)&clgame.dllFuncs.pfnChatInputPosition },
{ "HUD_GetRenderInterface", (void **)&clgame.dllFuncs.pfnGetRenderInterface }, // Xash3D ext
{ "HUD_GetPlayerTeam", (void **)&clgame.dllFuncs.pfnGetPlayerTeam },
{ "HUD_ClipMoveToEntity", (void **)&clgame.dllFuncs.pfnClipMoveToEntity }, // Xash3D ext
{ NULL, NULL }
};
@ -115,18 +114,6 @@ cl_entity_t *CL_GetEntityByIndex( int index )
return CL_EDICT_NUM( index );
}
/*
====================
CL_GetServerTime
don't clamped time that come from server
====================
*/
float CL_GetServerTime( void )
{
return cl.mtime[0];
}
/*
====================
CL_IsThirdPerson
@ -260,18 +247,6 @@ int CL_PointContents( const vec3_t p )
return cont;
}
/*
====================
StudioEvent
Event callback for studio models
====================
*/
void CL_StudioEvent( struct mstudioevent_s *event, cl_entity_t *pEdict )
{
clgame.dllFuncs.pfnStudioEvent( event, pEdict );
}
/*
=============
CL_AdjustXPos
@ -2675,11 +2650,7 @@ pfnGetMousePos
*/
void pfnGetMousePos( struct tagPOINT *ppt )
{
ASSERT( ppt != NULL );
// find mouse movement
GetCursorPos( ppt );
ScreenToClient( host.hWnd, ppt );
}
/*
@ -2690,79 +2661,17 @@ pfnSetMousePos
*/
void pfnSetMousePos( int mx, int my )
{
POINT pt;
pt.x = mx;
pt.y = my;
ClientToScreen( host.hWnd, &pt );
SetCursorPos( pt.x, pt.y );
SetCursorPos( mx, my );
}
/*
=============
pfnSetMouseEnable
legacy of dinput code
=============
*/
void pfnSetMouseEnable( qboolean fEnable )
{
if( fEnable ) IN_ActivateMouse( false );
else IN_DeactivateMouse();
}
/*
=============
pfnGetServerTime
=============
*/
float pfnGetClientOldTime( void )
{
return cl.oldtime;
}
/*
=============
pfnGetGravity
=============
*/
float pfnGetGravity( void )
{
return clgame.movevars.gravity;
}
/*
=============
pfnEnableTexSort
TODO: implement
=============
*/
void pfnEnableTexSort( int enable )
{
}
/*
=============
pfnSetLightmapColor
TODO: implement
=============
*/
void pfnSetLightmapColor( float red, float green, float blue )
{
}
/*
=============
pfnSetLightmapScale
TODO: implement
=============
*/
void pfnSetLightmapScale( float scale )
{
}
@ -2784,201 +2693,6 @@ char *pfnParseFile( char *data, char *token )
return out;
}
/*
=============
pfnSPR_DrawGeneric
=============
*/
void pfnSPR_DrawGeneric( int frame, int x, int y, const wrect_t *prc, int blendsrc, int blenddst, int width, int height )
{
pglEnable( GL_BLEND );
pglBlendFunc( blendsrc, blenddst ); // g-cont. are params is valid?
SPR_DrawGeneric( frame, x, y, width, height, prc );
}
/*
=============
pfnDrawString
=============
*/
int pfnDrawString( int x, int y, const char *str, int r, int g, int b )
{
// draw the string until we hit the null character or a newline character
for( ; *str != 0 && *str != '\n'; str++ )
x += pfnDrawCharacter( x, y, (byte)*str, r, g, b );
return x;
}
/*
=============
pfnDrawStringReverse
=============
*/
int pfnDrawStringReverse( int x, int y, const char *str, int r, int g, int b )
{
char *szIt;
// find the end of the string
for( szIt = (char *)str; *szIt != 0; szIt++ )
x -= clgame.scrInfo.charWidths[(byte)*szIt];
pfnDrawString( x, y, str, r, g, b );
return x;
}
/*
=============
LocalPlayerInfo_ValueForKey
=============
*/
const char *LocalPlayerInfo_ValueForKey( const char* key )
{
return Info_ValueForKey( cls.userinfo, key );
}
/*
=============
pfnVGUI2DrawCharacter
=============
*/
int pfnVGUI2DrawCharacter( int x, int y, int ch, unsigned int font )
{
return 0;
}
/*
=============
pfnVGUI2DrawCharacterAdditive
=============
*/
int pfnVGUI2DrawCharacterAdditive( int x, int y, int ch, int r, int g, int b, unsigned int font )
{
return 0;
}
/*
=============
GetCareerGameInterface
=============
*/
void *GetCareerGameInterface( void )
{
Msg( "^1Career GameInterface called!\n" );
return NULL;
}
/*
=============
pfnPlaySoundVoiceByName
=============
*/
void pfnPlaySoundVoiceByName( char *filename, float volume, int pitch )
{
int hSound = S_RegisterSound( filename );
S_StartSound( NULL, cl.viewentity, CHAN_AUTO, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING );
}
/*
=============
pfnMP3_InitStream
=============
*/
void pfnMP3_InitStream( char *filename, int looping )
{
if( !filename )
{
S_StopBackgroundTrack();
return;
}
if( looping )
{
S_StartBackgroundTrack( filename, filename, 0 );
}
else
{
S_StartBackgroundTrack( filename, NULL, 0 );
}
}
/*
=============
pfnPlaySoundByNameAtPitch
=============
*/
void pfnPlaySoundByNameAtPitch( char *filename, float volume, int pitch )
{
int hSound = S_RegisterSound( filename );
S_StartSound( NULL, cl.viewentity, CHAN_STATIC, hSound, volume, ATTN_NORM, pitch, SND_STOP_LOOPING );
}
/*
=============
CL_FillRGBABlend
=============
*/
void CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a )
{
r = bound( 0, r, 255 );
g = bound( 0, g, 255 );
b = bound( 0, b, 255 );
a = bound( 0, a, 255 );
SPR_AdjustSize( (float *)&x, (float *)&y, (float *)&w, (float *)&h );
pglDisable( GL_TEXTURE_2D );
pglEnable( GL_BLEND );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglColor4f( r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f );
pglBegin( GL_QUADS );
pglVertex2f( x, y );
pglVertex2f( x + w, y );
pglVertex2f( x + w, y + h );
pglVertex2f( x, y + h );
pglEnd ();
pglColor3f( 1.0f, 1.0f, 1.0f );
pglEnable( GL_TEXTURE_2D );
pglDisable( GL_BLEND );
}
/*
=============
pfnGetAppID
=============
*/
int pfnGetAppID( void )
{
return 130; // borrowed from SDLash3D
}
/*
=============
pfnVguiWrap2_GetMouseDelta
=============
*/
void pfnVguiWrap2_GetMouseDelta( int *x, int *y )
{
if( x ) *x = 0;
if( y ) *y = 0;
}
/*
=================
TriApi implementation
@ -3176,6 +2890,7 @@ void TriCullFace( int mode )
clgame.ds.cullMode = GL_NONE;
break;
}
GL_Cull( clgame.ds.cullMode );
}
@ -3404,23 +3119,6 @@ void NetAPI_InitNetworking( void )
NET_Config( true ); // allow remote
}
int Net_GetPacketLoss( void )
{
int packet_loss = 0;
if( cls.state == ca_active )
{
packet_loss = bound( 0, (int)cls.packet_loss, 100 );
if ( packet_loss < 0 )
packet_loss = 0;
if ( packet_loss > 100 )
packet_loss = 100;
}
return packet_loss;
}
/*
=================
NetAPI_InitNetworking
@ -3660,6 +3358,7 @@ void NetAPI_SetValueForKey( char *s, const char *key, const char *value, int max
=================
IVoiceTweak implementation
TODO: implement
=================
*/
/*
@ -3670,7 +3369,6 @@ Voice_StartVoiceTweakMode
*/
int Voice_StartVoiceTweakMode( void )
{
// TODO: implement
return 0;
}
@ -3682,7 +3380,6 @@ Voice_EndVoiceTweakMode
*/
void Voice_EndVoiceTweakMode( void )
{
// TODO: implement
}
/*
@ -3693,7 +3390,6 @@ Voice_SetControlFloat
*/
void Voice_SetControlFloat( VoiceTweakControl iControl, float value )
{
// TODO: implement
}
/*
@ -3704,22 +3400,9 @@ Voice_GetControlFloat
*/
float Voice_GetControlFloat( VoiceTweakControl iControl )
{
// TODO: implement
return 1.0f;
}
/*
=================
Voice_GetSpeakingVolume
=================
*/
int Voice_GetSpeakingVolume( void )
{
// TODO: implement
return 255;
}
// shared between client and server
triangleapi_t gTriApi =
{
@ -3743,7 +3426,7 @@ triangleapi_t gTriApi =
TriLightAtPoint,
TriColor4fRendermode,
TriFogParams,
R_LightVec,
R_LightVec, // Xash3D added
};
static efx_api_t gEfxApi =
@ -3848,7 +3531,7 @@ static event_api_t gEventApi =
pfnTraceTexture,
pfnStopAllSounds,
pfnKillEvents,
CL_EventIndex,
CL_EventIndex, // Xash3D added
CL_IndexEvent,
CL_PlayerTraceExt,
CL_SoundFromIndex,
@ -3887,7 +3570,6 @@ static IVoiceTweak gVoiceApi =
Voice_EndVoiceTweakMode,
Voice_SetControlFloat,
Voice_GetControlFloat,
Voice_GetSpeakingVolume,
};
// engine callbacks
@ -3994,39 +3676,6 @@ static cl_enginefunc_t gEngfuncs =
pfnGetMousePos,
pfnSetMousePos,
pfnSetMouseEnable,
Cvar_GetListHead,
Cmd_GetFirstFunctionHandle,
Cmd_GetNextFunctionHandle,
Cmd_GetName,
pfnGetClientOldTime,
pfnGetGravity,
Mod_Handle,
pfnEnableTexSort,
pfnSetLightmapColor,
pfnSetLightmapScale,
pfnSequenceGet,
pfnSPR_DrawGeneric,
pfnSequencePickSentence,
pfnDrawString,
pfnDrawStringReverse,
LocalPlayerInfo_ValueForKey,
pfnVGUI2DrawCharacter,
pfnVGUI2DrawCharacterAdditive,
Sound_GetApproxWavePlayLen,
GetCareerGameInterface,
Cvar_Set,
pfnIsCareerMatch,
pfnPlaySoundVoiceByName,
pfnMP3_InitStream,
Sys_DoubleTime,
pfnProcessTutorMessageDecayBuffer,
pfnConstructTutorMessageDecayBuffer,
pfnResetTutorMessageDecayData,
pfnPlaySoundByNameAtPitch,
CL_FillRGBABlend,
pfnGetAppID,
Cmd_AliasGetList,
pfnVguiWrap2_GetMouseDelta,
};
void CL_UnloadProgs( void )
@ -4061,7 +3710,7 @@ qboolean CL_LoadProgs( const char *name )
{
static playermove_t gpMove;
const dllfunc_t *func;
CL_EXPORT_FUNCS F; // export 'F'
CL_EXPORT_FUNCS GetClientAPI; // single export
qboolean critical_exports = true;
if( clgame.hInstance ) CL_UnloadProgs();
@ -4085,12 +3734,12 @@ qboolean CL_LoadProgs( const char *name )
*func->func = NULL;
// trying to get single export named 'F'
if(( F = (void *)Com_GetProcAddress( clgame.hInstance, "F" )) != NULL )
if(( GetClientAPI = (void *)Com_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
{
MsgDev( D_NOTE, "CL_LoadProgs: found single callback export\n" );
// trying to fill interface now
F( &clgame.dllFuncs );
GetClientAPI( &clgame.dllFuncs );
// check critical functions again
for( func = cdll_exports; func && func->name; func++ )
@ -4123,7 +3772,7 @@ qboolean CL_LoadProgs( const char *name )
}
}
// it may be loaded through 'F' so we don't need to clear them
// it may be loaded through 'GetClientAPI' so we don't need to clear them
if( critical_exports )
{
// clear new exports

View File

@ -443,6 +443,10 @@ void CL_ParseMovevars( sizebuf_t *msg )
MSG_ReadDeltaMovevars( msg, &clgame.oldmovevars, &clgame.movevars );
// water alpha is not allowed
if( !FBitSet( world.flags, FWORLD_WATERALPHA ))
clgame.movevars.wateralpha = 1.0f;
// update sky if changed
if( Q_strcmp( clgame.oldmovevars.skyName, clgame.movevars.skyName ) && cl.video_prepped )
R_SetupSky( clgame.movevars.skyName );
@ -1486,45 +1490,6 @@ void CL_ParseScreenFade( sizebuf_t *msg )
}
}
/*
==============
CL_ParseCvarValue
Find the client cvar value
and sent it back to the server
==============
*/
void CL_ParseCvarValue( sizebuf_t *msg )
{
const char *cvarName = MSG_ReadString( msg );
convar_t *cvar = Cvar_FindVar( cvarName );
// build the answer
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue );
MSG_WriteString( &cls.netchan.message, cvar ? cvar->string : "Not Found" );
}
/*
==============
CL_ParseCvarValue2
Find the client cvar value
and sent it back to the server
==============
*/
void CL_ParseCvarValue2( sizebuf_t *msg )
{
int requestID = MSG_ReadLong( msg );
const char *cvarName = MSG_ReadString( msg );
convar_t *cvar = Cvar_FindVar( cvarName );
// build the answer
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue2 );
MSG_WriteLong( &cls.netchan.message, requestID );
MSG_WriteString( &cls.netchan.message, cvarName );
MSG_WriteString( &cls.netchan.message, cvar ? cvar->string : "Not Found" );
}
/*
==============
CL_DispatchUserMessage
@ -1702,8 +1667,6 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
cmd = MSG_ReadServerCmd( msg );
if( cmd == svc_querycvarvalue2 ) Msg( "buffer left: %d bytes\n", MSG_GetNumBytesLeft( msg ));
// record command for debugging spew on parse problem
CL_Parse_RecordCommand( cmd, bufStart );
@ -1903,12 +1866,6 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
case svc_studiodecal:
CL_ParseStudioDecal( msg );
break;
case svc_querycvarvalue:
CL_ParseCvarValue( msg );
break;
case svc_querycvarvalue2:
CL_ParseCvarValue2( msg );
break;
default:
CL_ParseUserMessage( msg, cmd );
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;

View File

@ -238,9 +238,9 @@ typedef struct
int maxclients;
int num_custombeams; // server beams count
char model_precache[MAX_MODELS][CS_SIZE];
char sound_precache[MAX_SOUNDS][CS_SIZE];
char event_precache[MAX_EVENTS][CS_SIZE];
char model_precache[MAX_MODELS][MAX_QPATH];
char sound_precache[MAX_SOUNDS][MAX_QPATH];
char event_precache[MAX_EVENTS][MAX_QPATH];
lightstyle_t lightstyles[MAX_LIGHTSTYLES];
short sound_index[MAX_SOUNDS];
@ -302,7 +302,7 @@ typedef void (*pfnEventHook)( event_args_t *args );
typedef struct
{
char name[CS_SIZE];
char name[MAX_QPATH];
word index; // event index
pfnEventHook func; // user-defined function
} cl_user_event_t;
@ -757,7 +757,6 @@ HSPRITE pfnSPR_Load( const char *szPicName );
HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags );
void PicAdjustSize( float *x, float *y, float *w, float *h );
void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a );
void CL_FillRGBABlend( int x, int y, int width, int height, int r, int g, int b, int a );
void CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr );
void CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr );
void CL_SetTraceHull( int hull );

View File

@ -26,7 +26,7 @@ GNU General Public License for more details.
extern byte *r_temppool;
#define BLOCK_SIZE world.block_size // lightmap blocksize
#define BLOCK_SIZE tr.block_size // lightmap blocksize
#define BLOCK_SIZE_DEFAULT 128 // for keep backward compatibility
#define BLOCK_SIZE_MAX 1024
@ -220,6 +220,7 @@ typedef struct
byte visbytes[(MAX_MAP_LEAFS+7)/8]; // member custom PVS
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
int block_size; // lightmap blocksize
double frametime; // special frametime for multipass rendering (will set to 0 on a nextview)
float blend; // global blend value
@ -450,7 +451,7 @@ void R_AliasInit( void );
//
// gl_warp.c
//
void R_InitSky( struct mip_s *mt, struct texture_s *tx, qboolean custom_palette );
void R_InitSkyClouds( struct mip_s *mt, struct texture_s *tx, qboolean custom_palette );
void R_AddSkyBoxSurface( msurface_t *fa );
void R_ClearSkyBox( void );
void R_DrawSkyBox( void );

View File

@ -565,7 +565,7 @@ Build mirror chains for this frame
*/
void R_FindMirrors( void )
{
if( !world.has_mirrors || RI.drawOrtho || !RI.drawWorld || RI.onlyClientDraw || !cl.worldmodel )
if( !FBitSet( world.flags, FWORLD_HAS_MIRRORS ) || RI.drawOrtho || !RI.drawWorld || RI.onlyClientDraw || !cl.worldmodel )
return;
// NOTE: we already has initial params at this point like vieworg, viewangles

View File

@ -1170,7 +1170,7 @@ static int GL_RenderGetParm( int parm, int arg )
arg = bound( 0, arg, MAX_LIGHTMAPS - 1 );
return tr.lightmapTextures[arg];
case PARM_SKY_SPHERE:
return world.sky_sphere && !world.custom_skybox;
return FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX );
case PARM_WIDESCREEN:
return glState.wideScreen;
case PARM_FULLSCREEN:
@ -1180,7 +1180,7 @@ static int GL_RenderGetParm( int parm, int arg )
case PARM_SCREEN_HEIGHT:
return glState.height;
case PARM_MAP_HAS_MIRRORS:
return world.has_mirrors;
return FBitSet( world.flags, FWORLD_HAS_MIRRORS );
case PARM_CLIENT_INGAME:
return CL_IsInGame();
case PARM_MAX_ENTITIES:
@ -1202,7 +1202,7 @@ static int GL_RenderGetParm( int parm, int arg )
arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 );
return tr.lightstylevalue[arg];
case PARM_MAP_HAS_DELUXE:
return (world.deluxedata != NULL);
return FBitSet( world.flags, FWORLD_HAS_DELUXEMAP );
case PARM_MAX_IMAGE_UNITS:
return GL_MaxTextureUnits();
case PARM_CLIENT_ACTIVE:
@ -1222,7 +1222,7 @@ static int GL_RenderGetParm( int parm, int arg )
case PARM_STENCIL_ACTIVE:
return glState.stencilEnabled;
case PARM_WATER_ALPHA:
return world.water_alpha;
return FBitSet( world.flags, FWORLD_WATERALPHA );
}
return 0;
}
@ -1466,6 +1466,8 @@ static render_api_t gRenderAPI =
R_Mem_Free,
pfnGetFilesList,
pfnFileBufferCRC32,
Mod_Handle,
pfnTime,
};
/*

View File

@ -1265,7 +1265,7 @@ void R_DrawTextureChains( void )
RI.currententity = clgame.entities;
RI.currentmodel = RI.currententity->model;
if( world.sky_sphere && !world.custom_skybox )
if( FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX ))
{
pglDisable( GL_TEXTURE_2D );
pglColor3f( 1.0f, 1.0f, 1.0f );
@ -1275,7 +1275,7 @@ void R_DrawTextureChains( void )
for( s = skychain; s != NULL; s = s->texturechain )
R_AddSkyBoxSurface( s );
if( world.sky_sphere && !world.custom_skybox )
if( FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX ))
{
pglEnable( GL_TEXTURE_2D );
if( skychain )
@ -2147,6 +2147,11 @@ void GL_BuildLightmaps( void )
memset( tr.mirror_entities, 0, sizeof( tr.mirror_entities ));
memset( tr.mirrorTextures, 0, sizeof( tr.mirrorTextures ));
memset( &RI, 0, sizeof( RI ));
// update the lightmap blocksize
if( FBitSet( host.features, ENGINE_LARGE_LIGHTMAPS ))
tr.block_size = BLOCK_SIZE_MAX;
else tr.block_size = BLOCK_SIZE_DEFAULT;
skychain = NULL;

View File

@ -322,7 +322,7 @@ void R_AddSkyBoxSurface( msurface_t *fa )
}
}
if( world.sky_sphere && fa->polys && !world.custom_skybox )
if( FBitSet( world.flags, FWORLD_SKYSPHERE ) && fa->polys && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX ))
{
glpoly_t *p = fa->polys;
@ -366,7 +366,7 @@ void R_UnloadSkybox( void )
tr.skyboxbasenum = 5800; // set skybox base (to let some mods load hi-res skyboxes)
memset( tr.skyboxTextures, 0, sizeof( tr.skyboxTextures ));
world.custom_skybox = false;
ClearBits( world.flags, FWORLD_CUSTOM_SKYBOX );
}
/*
@ -488,7 +488,7 @@ void R_SetupSky( const char *skyboxname )
if( i == 6 )
{
world.custom_skybox = true;
SetBits( world.flags, FWORLD_CUSTOM_SKYBOX );
return; // loaded
}
@ -676,12 +676,12 @@ void R_DrawClouds( void )
/*
=============
R_InitSky
R_InitSkyClouds
A sky texture is 256*128, with the right side being a masked overlay
==============
*/
void R_InitSky( mip_t *mt, texture_t *tx, qboolean custom_palette )
void R_InitSkyClouds( mip_t *mt, texture_t *tx, qboolean custom_palette )
{
rgbdata_t r_temp, *r_sky;
uint *trans, *rgba;
@ -690,6 +690,9 @@ void R_InitSky( mip_t *mt, texture_t *tx, qboolean custom_palette )
int i, j, p;
char texname[32];
if( !glw_state.initialized )
return;
Q_snprintf( texname, sizeof( texname ), "%s%s.mip", ( mt->offsets[0] > 0 ) ? "#" : "", tx->name );
if( mt->offsets[0] > 0 )
@ -709,15 +712,15 @@ void R_InitSky( mip_t *mt, texture_t *tx, qboolean custom_palette )
if( !r_sky || !r_sky->palette || r_sky->type != PF_INDEXED_32 || r_sky->height == 0 )
{
MsgDev( D_ERROR, "R_InitSky: unable to load sky texture %s\n", tx->name );
FS_FreeImage( r_sky );
if( r_sky ) FS_FreeImage( r_sky );
return;
}
// 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 ));
r = g = b = 0;
for( i = 0; i < r_sky->width >> 1; i++ )
{
for( j = 0; j < r_sky->height; j++ )
@ -742,9 +745,9 @@ void R_InitSky( mip_t *mt, texture_t *tx, qboolean custom_palette )
r_temp.height = r_sky->height;
r_temp.type = PF_RGBA_32;
r_temp.flags = IMAGE_HAS_COLOR;
r_temp.palette = NULL;
r_temp.buffer = (byte *)trans;
r_temp.size = r_temp.width * r_temp.height * 4;
r_temp.buffer = (byte *)trans;
r_temp.palette = NULL;
// load it in
tr.solidskyTexture = GL_LoadTextureInternal( "solid_sky", &r_temp, TF_NOMIPMAP, false );
@ -754,6 +757,7 @@ void R_InitSky( mip_t *mt, texture_t *tx, qboolean custom_palette )
for( j = 0; j < r_sky->height; j++ )
{
p = r_sky->buffer[i * r_sky->width + j];
if( p == 0 )
{
trans[(i * r_sky->height) + j] = transpix;

View File

@ -19,20 +19,28 @@ GNU General Public License for more details.
#define MAX_CMD_BUFFER 32768
#define MAX_CMD_LINE 2048
#define MAX_ALIAS_NAME 32
typedef struct cmdalias_s
{
struct cmdalias_s *next;
char name[MAX_ALIAS_NAME];
char *value;
} cmdalias_t;
typedef struct
{
byte *data;
int cursize;
int maxsize;
byte *data;
int cursize;
int maxsize;
} cmdbuf_t;
qboolean cmd_wait;
cmdbuf_t cmd_text;
byte cmd_text_buf[MAX_CMD_BUFFER];
cmdalias_t *cmd_alias;
uint cmd_condition;
int cmd_condlevel;
qboolean cmd_wait;
cmdbuf_t cmd_text;
byte cmd_text_buf[MAX_CMD_BUFFER];
cmdalias_t *cmd_alias;
uint cmd_condition;
int cmd_condlevel;
/*
=============================================================================
@ -73,7 +81,7 @@ void *Cbuf_GetSpace( cmdbuf_t *buf, int length )
{
void *data;
if( buf->cursize + length > buf->maxsize )
if(( buf->cursize + length ) > buf->maxsize )
{
buf->cursize = 0;
Host_Error( "Cbuf_GetSpace: overflow\n" );
@ -96,7 +104,7 @@ void Cbuf_AddText( const char *text )
{
int l = Q_strlen( text );
if( cmd_text.cursize + l >= cmd_text.maxsize )
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
{
MsgDev( D_WARN, "Cbuf_AddText: overflow\n" );
}
@ -118,7 +126,7 @@ void Cbuf_InsertText( const char *text )
{
int l = Q_strlen( text );
if( cmd_text.cursize + l >= cmd_text.maxsize )
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
{
MsgDev( D_WARN, "Cbuf_InsertText: overflow\n" );
}
@ -285,8 +293,8 @@ Cmd_StuffCmds_f
Adds command line parameters as script statements
Commands lead with a +, and continue until a - or another +
xash -dev 3 +map c1a0d
xash -nosound -game bshift
hl.exe -dev 3 +map c1a0d
hl.exe -nosound -game bshift
===============
*/
void Cmd_StuffCmds_f( void )
@ -490,47 +498,6 @@ char *Cmd_Args( void )
return cmd_args;
}
/*
============
Cmd_AliasGetList
============
*/
struct cmdalias_s *Cmd_AliasGetList( void )
{
return cmd_alias;
}
/*
============
Cmd_GetList
============
*/
struct cmd_s *Cmd_GetFirstFunctionHandle( void )
{
return cmd_functions;
}
/*
============
Cmd_GetNext
============
*/
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd )
{
return (cmd) ? cmd->next : NULL;
}
/*
============
Cmd_GetName
============
*/
char *Cmd_GetName( struct cmd_s *cmd )
{
return cmd->name;
}
/*
============
Cmd_TokenizeString

View File

@ -752,6 +752,17 @@ int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCom
return bRet;
}
/*
=============
pfnTime
=============
*/
float pfnTime( void )
{
return (float)Sys_DoubleTime();
}
/*
=============
pfnGetGameDir
@ -762,100 +773,4 @@ void pfnGetGameDir( char *szGetGameDir )
{
if( !szGetGameDir ) return;
Q_sprintf( szGetGameDir, "%s/%s", host.rootdir, GI->gamedir );
}
/*
=============
pfnSequenceGet
used by CS:CZ
=============
*/
void *pfnSequenceGet( const char *fileName, const char *entryName )
{
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
return NULL;
}
/*
=============
pfnSequencePickSentence
used by CS:CZ
=============
*/
void *pfnSequencePickSentence( const char *groupName, int pickMethod, int *picked )
{
Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod );
*picked = 0;
return NULL;
}
/*
=============
pfnIsCareerMatch
used by CS:CZ (client stub)
=============
*/
int pfnIsCareerMatch( void )
{
return 0;
}
/*
=============
pfnRegisterTutorMessageShown
only exists in PlayStation version
=============
*/
void pfnRegisterTutorMessageShown( int mid )
{
}
/*
=============
pfnGetTimesTutorMessageShown
only exists in PlayStation version
=============
*/
int pfnGetTimesTutorMessageShown( int mid )
{
return 0;
}
/*
=============
pfnProcessTutorMessageDecayBuffer
only exists in PlayStation version
=============
*/
void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength )
{
}
/*
=============
pfnConstructTutorMessageDecayBuffer
only exists in PlayStation version
=============
*/
void pfnConstructTutorMessageDecayBuffer( int *buffer, int bufferLength )
{
}
/*
=============
pfnResetTutorMessageDecayData
only exists in PlayStation version
=============
*/
void pfnResetTutorMessageDecayData( void )
{
}

View File

@ -39,6 +39,7 @@ extern "C" {
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
#define MAX_SYSPATH 1024 // system filepath
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Msg or MsgDev
#define MAX_TOKEN 2048 // parse token length
#define MAX_MODS 512 // environment games that engine can keep visible
#define EXPORT __declspec( dllexport )
#define BIT( n ) (1<<( n ))
@ -169,27 +170,27 @@ internal shared gameinfo structure (readonly for engine parts)
typedef struct gameinfo_s
{
// filesystem info
char gamefolder[64]; // used for change game '-game x'
char basedir[64]; // base game directory (like 'id1' for Quake or 'valve' for Half-Life)
char gamedir[64]; // game directory (can be match with basedir, used as game dir and as write path)
char falldir[64]; // used as second basedir
char startmap[64]; // map to start singleplayer game
char trainmap[64]; // map to start hazard course (if specified)
char gamefolder[MAX_QPATH]; // used for change game '-game x'
char basedir[MAX_QPATH]; // base game directory (like 'id1' for Quake or 'valve' for Half-Life)
char gamedir[MAX_QPATH]; // game directory (can be match with basedir, used as game dir and as write path)
char falldir[MAX_QPATH]; // used as second basedir
char startmap[MAX_QPATH];// map to start singleplayer game
char trainmap[MAX_QPATH];// map to start hazard course (if specified)
char title[64]; // Game Main Title
float version; // game version (optional)
// .dll pathes
char dll_path[64]; // e.g. "bin" or "cl_dlls"
char game_dll[64]; // custom path for game.dll
char dll_path[MAX_QPATH]; // e.g. "bin" or "cl_dlls"
char game_dll[MAX_QPATH]; // custom path for game.dll
// .ico path
char iconpath[64]; // "game.ico" by default
char iconpath[MAX_QPATH]; // "game.ico" by default
// about mod info
string game_url; // link to a developer's site
string update_url; // link to updates page
char type[64]; // single, toolkit, multiplayer etc
char date[64];
char type[MAX_QPATH]; // single, toolkit, multiplayer etc
char date[MAX_QPATH];
size_t size;
int gamemode;
@ -199,7 +200,7 @@ typedef struct gameinfo_s
char sp_entity[32]; // e.g. info_player_start
char mp_entity[32]; // e.g. info_player_deathmatch
char ambientsound[NUM_AMBIENTS][64]; // quake ambient sounds
char ambientsound[NUM_AMBIENTS][MAX_QPATH]; // quake ambient sounds
int max_edicts; // min edicts is 600, max edicts is 4096
int max_tents; // min temp ents is 300, max is 2048
@ -273,7 +274,7 @@ typedef struct host_redirect_s
typedef struct
{
char name[64];
char name[MAX_QPATH];
short entnum;
vec3_t origin;
float volume;
@ -311,7 +312,7 @@ typedef struct host_parm_s
uint framecount; // global framecount
// list of unique decal indexes
char draw_decals[MAX_DECALS][CS_SIZE];
char draw_decals[MAX_DECALS][MAX_QPATH];
vec3_t player_mins[MAX_MAP_HULLS]; // 4 hulls allowed
vec3_t player_maxs[MAX_MAP_HULLS]; // 4 hulls allowed
@ -344,7 +345,7 @@ typedef struct host_parm_s
qboolean renderinfo_changed;
char rootdir[256]; // member root directory
char gamefolder[64]; // it's a default gamefolder
char gamefolder[MAX_QPATH]; // it's a default gamefolder
byte *imagepool; // imagelib mempool
byte *soundpool; // soundlib mempool
@ -379,10 +380,8 @@ void FS_DefaultExtension( char *path, const char *extension );
void FS_ExtractFilePath( const char *path, char *dest );
const char *FS_GetDiskPath( const char *name, qboolean gamedironly );
const char *FS_FileWithoutPath( const char *in );
wfile_t *W_Open( const char *filename, const char *mode, int *errorcode );
byte *W_LoadLump( wfile_t *wad, const char *lumpname, size_t *lumpsizeptr, const char type );
void W_Close( wfile_t *wad );
file_t *FS_OpenFile( const char *path, long *filesizeptr, qboolean gamedironly );
byte *FS_LoadFile( const char *path, long *filesizeptr, qboolean gamedironly );
qboolean FS_WriteFile( const char *filename, const void *data, long len );
qboolean COM_ParseVector( char **pfile, float *v, size_t size );
@ -412,7 +411,6 @@ long FS_Tell( file_t *file );
qboolean FS_Eof( file_t *file );
int FS_Close( file_t *file );
int FS_Getc( file_t *file );
qboolean FS_Eof( file_t *file );
long FS_FileLength( file_t *f );
/*
@ -625,7 +623,6 @@ long FS_SetStreamPos( stream_t *stream, long newpos );
long FS_GetStreamPos( stream_t *stream );
void FS_FreeStream( stream_t *stream );
qboolean Sound_Process( wavdata_t **wav, int rate, int width, uint flags );
uint Sound_GetApproxWavePlayLen( const char *filepath );
//
// build.c
@ -708,18 +705,7 @@ void Con_DPrintf( char *fmt, ... );
void Con_Printf( char *szFmt, ... );
int pfnNumberOfEntities( void );
int pfnIsInGame( void );
// CS:CS engfuncs (stubs)
void *pfnSequenceGet( const char *fileName, const char *entryName );
void *pfnSequencePickSentence( const char *groupName, int pickMethod, int *picked );
int pfnIsCareerMatch( void );
// Decay engfuncs (stubs)
int pfnGetTimesTutorMessageShown( int mid );
void pfnRegisterTutorMessageShown( int mid );
void pfnConstructTutorMessageDecayBuffer( int *buffer, int buflen );
void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength );
void pfnResetTutorMessageDecayData( void );
float pfnTime( void );
/*
==============================================================
@ -803,14 +789,12 @@ qboolean CL_IsThirdPerson( void );
qboolean CL_IsIntermission( void );
qboolean CL_Initialized( void );
char *CL_Userinfo( void );
float CL_GetServerTime( void );
float CL_GetLerpFrac( void );
void CL_CharEvent( int key );
qboolean CL_DisableVisibility( void );
int CL_PointContents( const vec3_t point );
char *COM_ParseFile( char *data, char *token );
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength );
void CL_StudioEvent( struct mstudioevent_s *event, struct cl_entity_s *ent );
qboolean CL_GetComment( const char *demoname, char *comment );
void COM_AddAppDirectoryToSearchPath( const char *pszBaseDir, const char *appName );
int COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBufferSize );
@ -890,15 +874,10 @@ void Cmd_AutoComplete( char *complete_string );
void COM_SetRandomSeed( long lSeed );
long COM_RandomLong( long lMin, long lMax );
float COM_RandomFloat( float fMin, float fMax );
void TrimSpace( const char *source, char *dest );
const byte *GL_TextureData( unsigned int texnum );
void GL_FreeImage( const char *name );
void VID_InitDefaultResolution( void );
void UI_SetActiveMenu( qboolean fActive );
struct cmd_s *Cmd_GetFirstFunctionHandle( void );
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
struct cmdalias_s *Cmd_AliasGetList( void );
char *Cmd_GetName( struct cmd_s *cmd );
void Cmd_Null_f( void );
extern const char *svc_strings[256];
extern const char *clc_strings[11];

View File

@ -69,13 +69,13 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
for( i = 0, nummaps = 0; i < t->numfilenames; i++ )
{
char entfilename[CS_SIZE];
int ver = -1, mapver = -1, lumpofs = 0, lumplen = 0;
char entfilename[MAX_QPATH];
const char *ext = FS_FileExtension( t->filenames[i] );
int ver = -1, lumpofs = 0, lumplen = 0;
char *ents = NULL, *pfile;
qboolean validmap = false;
int version = 0;
qboolean gearbox = false;
if( Q_stricmp( ext, "bsp" )) continue;
Q_strncpy( message, "^1error^7", sizeof( message ));
f = FS_Open( t->filenames[i], "rb", con_gamemaps->value );
@ -89,30 +89,17 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
FS_Read( f, buf, sizeof( buf ));
header = (dheader_t *)buf;
ver = header->version;
switch( ver )
// check all the lumps and some other errors
if( Mod_TestBmodelLumps( t->filenames[i], buf, true ))
{
case Q1BSP_VERSION:
case HLBSP_VERSION:
case QBSP2_VERSION:
if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && !(header->lumps[LUMP_ENTITIES].filelen % sizeof(dplane_t)))
{
lumpofs = header->lumps[LUMP_PLANES].fileofs;
lumplen = header->lumps[LUMP_PLANES].filelen;
gearbox = true;
}
else
{
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
gearbox = false;
}
break;
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
ver = header->version;
}
hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader_t ));
if( hdrext->id == IDEXTRAHEADER )
version = hdrext->version;
if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version;
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
FS_StripExtension( entfilename );
@ -132,24 +119,18 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
// means there is no title, so clear the message string now
char token[2048];
message[0] = 0;
message[0] = 0; // remove 'error'
pfile = ents;
while(( pfile = COM_ParseFile( pfile, token )) != NULL )
{
if( !Q_strcmp( token, "{" )) continue;
else if(!Q_strcmp( token, "}" )) break;
else if(!Q_strcmp( token, "message" ))
else if( !Q_strcmp( token, "}" )) break;
else if( !Q_strcmp( token, "message" ))
{
// get the message contents
pfile = COM_ParseFile( pfile, message );
}
else if(!Q_strcmp( token, "mapversion" ))
{
// get the message contents
pfile = COM_ParseFile( pfile, token );
mapver = Q_atoi( token );
}
}
Mem_Free( ents );
}
@ -161,19 +142,19 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
switch( ver )
{
case Q1BSP_VERSION:
if( mapver == 220 ) Q_strncpy( buf, "Half-Life Alpha", sizeof( buf ));
else Q_strncpy( buf, "Quake", sizeof( buf ));
Q_strncpy( buf, "Quake", sizeof( buf ));
break;
case QBSP2_VERSION:
Q_strncpy( buf, "Darkplaces BSP2", sizeof( buf ));
break;
case HLBSP_VERSION:
if( gearbox ) Q_strncpy( buf, "Blue-Shift", sizeof( buf ));
else if( version == 1 ) Q_strncpy( buf, "XashXT old format", sizeof( buf ));
else if( version == 2 ) Q_strncpy( buf, "Paranoia 2: Savior", sizeof( buf ));
else if( version == 3 ) Q_strncpy( buf, "not supported", sizeof( buf ));
else if( version == 4 ) Q_strncpy( buf, "Half-Life extended", sizeof( buf ));
else Q_strncpy( buf, "Half-Life", sizeof( buf ));
switch( version )
{
case 1: Q_strncpy( buf, "XashXT old format", sizeof( buf )); break;
case 2: Q_strncpy( buf, "Paranoia 2: Savior", sizeof( buf )); break;
case 4: Q_strncpy( buf, "Half-Life extended", sizeof( buf )); break;
default: Q_strncpy( buf, "Half-Life", sizeof( buf )); break;
}
break;
default: Q_strncpy( buf, "??", sizeof( buf )); break;
}
@ -706,7 +687,6 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
// mod doesn't contain any maps (probably this is a bot)
return Cmd_CheckMapsList_R( fRefresh, false );
}
return false;
}
@ -715,7 +695,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
for( i = 0; i < t->numfilenames; i++ )
{
char *ents = NULL, *pfile;
int ver = -1, lumpofs = 0, lumplen = 0;
int lumpofs = 0, lumplen = 0;
string mapname, message, entfilename;
if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "bsp" ))
@ -731,27 +711,19 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
memset( buf, 0, MAX_SYSPATH );
FS_Read( f, buf, MAX_SYSPATH );
ver = *(uint *)buf;
switch( ver )
header = (dheader_t *)buf;
// check all the lumps and some other errors
if( !Mod_TestBmodelLumps( t->filenames[i], buf, true ))
{
case Q1BSP_VERSION:
case HLBSP_VERSION:
case QBSP2_VERSION:
header = (dheader_t *)buf;
if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 )
{
lumpofs = header->lumps[LUMP_PLANES].fileofs;
lumplen = header->lumps[LUMP_PLANES].filelen;
}
else
{
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
}
break;
FS_Close( f );
continue;
}
// after call Mod_TestBmodelLumps we gurantee what map is valid
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
FS_StripExtension( entfilename );
FS_DefaultExtension( entfilename, ".ent" );
@ -760,7 +732,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
if( !ents && lumplen >= 10 )
{
FS_Seek( f, lumpofs, SEEK_SET );
ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
ents = Z_Malloc( lumplen + 1 );
FS_Read( f, ents, lumplen );
}
@ -768,7 +740,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
{
// if there are entities to parse, a missing message key just
// means there is no title, so clear the message string now
char token[2048];
char token[MAX_TOKEN];
qboolean worldspawn = true;
Q_strncpy( message, "No Title", MAX_STRING );

View File

@ -229,12 +229,11 @@ qboolean CRC32_File( dword *crcvalue, const char *filename )
qboolean CRC32_MapFile( dword *crcvalue, const char *filename, qboolean multiplayer )
{
file_t *f;
dheader_t *header;
char headbuf[256], buffer[1024];
int i, num_bytes, lumplen;
qboolean blue_shift = false;
int version, hdr_size;
dheader_t *header;
file_t *f;
if( !crcvalue ) return false;
@ -276,18 +275,10 @@ qboolean CRC32_MapFile( dword *crcvalue, const char *filename, qboolean multipla
return false;
}
ASSERT( crcvalue != NULL );
CRC32_Init( crcvalue );
// check for Blue-Shift maps
if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && (header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 )
blue_shift = true;
for( i = 0; i < HEADER_LUMPS; i++ )
for( i = LUMP_PLANES; i < HEADER_LUMPS; i++ )
{
if( blue_shift && i == LUMP_PLANES ) continue;
else if( i == LUMP_ENTITIES ) continue;
lumplen = header->lumps[i].filelen;
FS_Seek( f, header->lumps[i].fileofs, SEEK_SET );

View File

@ -19,16 +19,6 @@ GNU General Public License for more details.
convar_t *cvar_vars; // head of list
convar_t *cmd_scripting;
/*
============
Cvar_GetListHead
============
*/
cvar_t *Cvar_GetListHead( void )
{
return (cvar_t *)cvar_vars;
}
/*
============
Cvar_FindVar

View File

@ -62,7 +62,6 @@ void Cvar_WriteVariables( file_t *f, int group );
void Cvar_Reset( const char *var_name );
void Cvar_SetCheatState( void );
qboolean Cvar_Command( void );
cvar_t *Cvar_GetListHead( void );
void Cvar_Init( void );
void Cvar_Unlink( int group );

View File

@ -79,7 +79,6 @@ typedef struct wfile_s
int infotableofs;
byte *mempool; // W_ReadLump temp buffers
int numlumps;
int mode;
file_t *handle;
dlumpinfo_t *lumps;
time_t filetime;
@ -118,6 +117,7 @@ static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedir
static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const char matchtype );
static dpackfile_t *FS_AddFileToPack( const char* name, pack_t *pack, long offset, long size );
static byte *W_LoadFile( const char *path, long *filesizeptr, qboolean gamedironly );
static wfile_t *W_Open( const char *filename, int *errorcode );
static qboolean FS_SysFileExists( const char *path );
static qboolean FS_SysFolderExists( const char *path );
static long FS_SysFileTime( const char *filename );
@ -313,7 +313,7 @@ static dpackfile_t *FS_AddFileToPack( const char *name, pack_t *pack, long offse
diff = Q_stricmp( pack->files[middle].name, name );
// If we found the file, there's a problem
if( !diff ) MsgDev( D_WARN, "Package %s contains the file %s several times\n", pack->filename, name );
if( !diff ) MsgDev( D_WARN, "package %s contains the file %s several times\n", pack->filename, name );
// If we're too far in the list
if( diff > 0 ) right = middle - 1;
@ -549,7 +549,7 @@ static qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loade
}
if( already_loaded ) *already_loaded = false;
if( !Q_stricmp( ext, "wad" )) wad = W_Open( wadfile, "rb", &errorcode );
if( !Q_stricmp( ext, "wad" )) wad = W_Open( wadfile, &errorcode );
else MsgDev( D_ERROR, "\"%s\" doesn't have a wad extension\n", wadfile );
if( wad )
@ -1904,12 +1904,12 @@ Open a file. The syntax is the same as fopen
*/
file_t *FS_Open( const char *filepath, const char *mode, qboolean gamedironly )
{
if( host.type == HOST_NORMAL || host.type == HOST_DEDICATED )
{
// some stupid mappers used leading '/' or '\' in path to models or sounds
if( filepath[0] == '/' || filepath[0] == '\\' ) filepath++;
if( filepath[0] == '/' || filepath[0] == '\\' ) filepath++;
}
// some stupid mappers used leading '/' or '\' in path to models or sounds
if( filepath[0] == '/' || filepath[0] == '\\' )
filepath++;
if( filepath[0] == '/' || filepath[0] == '\\' )
filepath++;
if( FS_CheckNastyPath( filepath, false ))
return NULL;
@ -2314,25 +2314,6 @@ byte *FS_LoadFile( const char *path, long *filesizeptr, qboolean gamedironly )
return buf;
}
/*
============
FS_OpenFile
Simply version of FS_Open
============
*/
file_t *FS_OpenFile( const char *path, long *filesizeptr, qboolean gamedironly )
{
file_t *file = FS_Open( path, "rb", gamedironly );
if( filesizeptr )
{
if( file ) *filesizeptr = file->real_length;
else *filesizeptr = 0;
}
return file;
}
/*
============
FS_WriteFile
@ -2925,7 +2906,7 @@ void FS_InitMemory( void )
/*
=============================================================================
WADSYSTEM PRIVATE COMMON FUNCTIONS
WADSYSTEM PRIVATE ROUTINES
=============================================================================
*/
@ -3204,36 +3185,6 @@ byte *W_ReadLump( wfile_t *wad, dlumpinfo_t *lump, long *lumpsizeptr )
return buf;
}
/*
===========
W_WriteLump
compress and write lump
===========
*/
qboolean W_WriteLump( wfile_t *wad, dlumpinfo_t *lump, const void *data, size_t datasize )
{
if( !wad || !lump ) return false;
if( !data || !datasize )
{
MsgDev( D_WARN, "W_WriteLump: ignore blank lump %s - nothing to save\n", lump->name );
return false;
}
if( wad->mode == O_RDONLY )
{
MsgDev( D_ERROR, "W_WriteLump: %s opened in readonly mode\n", wad->filename );
return false;
}
lump->size = lump->disksize = datasize;
if( FS_Write( wad->handle, data, datasize ) == datasize )
return true;
return false;
}
/*
=============================================================================
@ -3248,54 +3199,17 @@ W_Open
open the wad for reading & writing
===========
*/
wfile_t *W_Open( const char *filename, const char *mode, int *error )
wfile_t *W_Open( const char *filename, int *error )
{
dwadinfo_t header;
wfile_t *wad = (wfile_t *)Mem_Alloc( fs_mempool, sizeof( wfile_t ));
const char *comment = "Created by Xash3D Engine.\0";
int i, ind, mod, opt, lumpcount;
size_t wadsize, lat_size;
int i, lumpcount;
dlumpinfo_t *srclumps;
// parse the mode string
switch( mode[0] )
{
case 'r':
mod = O_RDONLY;
opt = 0;
break;
case 'w':
mod = O_WRONLY;
opt = O_CREAT|O_TRUNC;
break;
case 'a':
mod = O_WRONLY;
opt = O_CREAT;
break;
default:
MsgDev( D_ERROR, "W_Open(%s, %s): invalid mode\n", filename, mode );
return NULL;
}
for( ind = 1; mode[ind] != '\0'; ind++ )
{
switch( mode[ind] )
{
case '+':
mod = O_RDWR;
break;
case 'b':
opt |= O_BINARY;
break;
default:
MsgDev( D_ERROR, "W_Open: %s: unknown char in mode (%c)\n", filename, mode, mode[ind] );
break;
}
}
size_t lat_size;
dwadinfo_t header;
// NOTE: FS_Open is load wad file from the first pak in the list (while fs_ext_path is false)
if( fs_ext_path ) wad->handle = FS_Open( filename, mode, false );
else wad->handle = FS_Open( FS_FileWithoutPath( filename ), mode, false );
if( fs_ext_path ) wad->handle = FS_Open( filename, "rb", false );
else wad->handle = FS_Open( FS_FileWithoutPath( filename ), "rb", false );
if( wad->handle == NULL )
{
@ -3310,125 +3224,93 @@ wfile_t *W_Open( const char *filename, const char *mode, int *error )
wad->filetime = FS_SysFileTime( filename );
wad->mempool = Mem_AllocPool( filename );
wadsize = FS_FileLength( wad->handle );
// if the file is opened in "write", "append", or "read/write" mode
if( mod == O_WRONLY || !wadsize )
if( FS_Read( wad->handle, &header, sizeof( dwadinfo_t )) != sizeof( dwadinfo_t ))
{
dwadinfo_t hdr;
wad->numlumps = 0; // blank wad
wad->lumps = NULL; //
wad->mode = O_WRONLY;
// save space for header
hdr.ident = IDWAD3HEADER;
hdr.numlumps = wad->numlumps;
hdr.infotableofs = sizeof( dwadinfo_t );
FS_Write( wad->handle, &hdr, sizeof( hdr ));
FS_Write( wad->handle, comment, Q_strlen( comment ) + 1 );
wad->infotableofs = FS_Tell( wad->handle );
MsgDev( D_ERROR, "W_Open: %s can't read header\n", filename );
if( error ) *error = WAD_LOAD_BAD_HEADER;
W_Close( wad );
return NULL;
}
else if( mod == O_RDWR || mod == O_RDONLY )
if( header.ident != IDWAD2HEADER && header.ident != IDWAD3HEADER )
{
if( mod == O_RDWR )
wad->mode = O_APPEND;
else wad->mode = O_RDONLY;
MsgDev( D_ERROR, "W_Open: %s is not a WAD2 or WAD3 file\n", filename );
if( error ) *error = WAD_LOAD_BAD_HEADER;
W_Close( wad );
return NULL;
}
if( FS_Read( wad->handle, &header, sizeof( dwadinfo_t )) != sizeof( dwadinfo_t ))
{
MsgDev( D_ERROR, "W_Open: %s can't read header\n", filename );
if( error ) *error = WAD_LOAD_BAD_HEADER;
W_Close( wad );
return NULL;
}
lumpcount = header.numlumps;
if( header.ident != IDWAD2HEADER && header.ident != IDWAD3HEADER )
{
MsgDev( D_ERROR, "W_Open: %s is not a WAD2 or WAD3 file\n", filename );
if( error ) *error = WAD_LOAD_BAD_HEADER;
W_Close( wad );
return NULL;
}
if( lumpcount >= MAX_FILES_IN_WAD )
{
MsgDev( D_WARN, "W_Open: %s is full (%i lumps)\n", filename, lumpcount );
if( error ) *error = WAD_LOAD_TOO_MANY_FILES;
}
else if( lumpcount <= 0 )
{
MsgDev( D_ERROR, "W_Open: %s has no lumps\n", filename );
if( error ) *error = WAD_LOAD_NO_FILES;
W_Close( wad );
return NULL;
}
else if( error ) *error = WAD_LOAD_OK;
lumpcount = header.numlumps;
wad->infotableofs = header.infotableofs; // save infotableofs position
if( lumpcount >= MAX_FILES_IN_WAD && wad->mode == O_APPEND )
{
MsgDev( D_WARN, "W_Open: %s is full (%i lumps)\n", filename, lumpcount );
if( error ) *error = WAD_LOAD_TOO_MANY_FILES;
wad->mode = O_RDONLY; // set read-only mode
}
else if( lumpcount <= 0 && wad->mode == O_RDONLY )
{
MsgDev( D_ERROR, "W_Open: %s has no lumps\n", filename );
if( error ) *error = WAD_LOAD_NO_FILES;
W_Close( wad );
return NULL;
}
else if( error ) *error = WAD_LOAD_OK;
if( FS_Seek( wad->handle, wad->infotableofs, SEEK_SET ) == -1 )
{
MsgDev( D_ERROR, "W_Open: %s can't find lump allocation table\n", filename );
if( error ) *error = WAD_LOAD_BAD_FOLDERS;
W_Close( wad );
return NULL;
}
wad->infotableofs = header.infotableofs; // save infotableofs position
lat_size = lumpcount * sizeof( dlumpinfo_t );
if( FS_Seek( wad->handle, wad->infotableofs, SEEK_SET ) == -1 )
{
MsgDev( D_ERROR, "W_Open: %s can't find lump allocation table\n", filename );
if( error ) *error = WAD_LOAD_BAD_FOLDERS;
W_Close( wad );
return NULL;
}
// NOTE: lumps table can be reallocated for O_APPEND mode
srclumps = (dlumpinfo_t *)Mem_Alloc( wad->mempool, lat_size );
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 );
if( FS_Read( wad->handle, srclumps, lat_size ) != lat_size )
{
MsgDev( D_ERROR, "W_ReadLumpTable: %s has corrupted lump allocation table\n", wad->filename );
if( error ) *error = WAD_LOAD_CORRUPTED;
Mem_Free( srclumps );
W_Close( wad );
return NULL;
}
// starting to add lumps
wad->lumps = (dlumpinfo_t *)Mem_Alloc( wad->mempool, lat_size );
wad->numlumps = 0;
// sort lumps for binary search
for( i = 0; i < lumpcount; i++ )
{
char name[16];
int k;
// cleanup lumpname
Q_strnlwr( srclumps[i].name, name, sizeof( srclumps[i].name ));
// check for '*' symbol issues (quake1)
k = Q_strlen( Q_strrchr( name, '*' ));
if( k ) name[Q_strlen( name ) - k] = '!';
// check for Quake 'conchars' issues (only lmp loader really allows to read this lame pic)
if( srclumps[i].type == 68 && !Q_stricmp( srclumps[i].name, "conchars" ))
srclumps[i].type = TYP_GFXPIC;
// fixups bad image types (some quake wads)
if( srclumps[i].img_type < 0 || srclumps[i].img_type > IMG_DECAL_COLOR )
srclumps[i].img_type = IMG_DIFFUSE;
W_AddFileToWad( name, wad, &srclumps[i] );
}
// release source lumps
if( FS_Read( wad->handle, srclumps, lat_size ) != lat_size )
{
MsgDev( D_ERROR, "W_ReadLumpTable: %s has corrupted lump allocation table\n", wad->filename );
if( error ) *error = WAD_LOAD_CORRUPTED;
Mem_Free( srclumps );
// if we are in append mode - we need started from infotableofs poisition
// overwrite lumptable as well, we have her copy in wad->lumps
if( wad->mode == O_APPEND )
FS_Seek( wad->handle, wad->infotableofs, SEEK_SET );
W_Close( wad );
return NULL;
}
// starting to add lumps
wad->lumps = (dlumpinfo_t *)Mem_Alloc( wad->mempool, lat_size );
wad->numlumps = 0;
// sort lumps for binary search
for( i = 0; i < lumpcount; i++ )
{
char name[16];
int k;
// cleanup lumpname
Q_strnlwr( srclumps[i].name, name, sizeof( srclumps[i].name ));
// check for '*' symbol issues (quake1)
k = Q_strlen( Q_strrchr( name, '*' ));
if( k ) name[Q_strlen( name ) - k] = '!';
// check for Quake 'conchars' issues (only lmp loader really allows to read this lame pic)
if( srclumps[i].type == 68 && !Q_stricmp( srclumps[i].name, "conchars" ))
srclumps[i].type = TYP_GFXPIC;
// fixups bad image types (some quake wads)
if( srclumps[i].img_type < 0 || srclumps[i].img_type > IMG_DECAL_COLOR )
srclumps[i].img_type = IMG_DIFFUSE;
W_AddFileToWad( name, wad, &srclumps[i] );
}
// release source lumps
Mem_Free( srclumps );
// and leave the file open
return wad;
}
@ -3444,28 +3326,9 @@ void W_Close( wfile_t *wad )
{
if( !wad ) return;
if( wad->handle != NULL && ( wad->mode == O_APPEND || wad->mode == O_WRONLY ))
{
dwadinfo_t hdr;
long ofs;
// write the lumpinfo
ofs = FS_Tell( wad->handle );
FS_Write( wad->handle, wad->lumps, wad->numlumps * sizeof( dlumpinfo_t ));
// write the header
hdr.ident = IDWAD3HEADER;
hdr.numlumps = wad->numlumps;
hdr.infotableofs = ofs;
FS_Seek( wad->handle, 0, SEEK_SET );
FS_Write( wad->handle, &hdr, sizeof( hdr ));
}
Mem_FreePool( &wad->mempool );
if( wad->handle != NULL )
FS_Close( wad->handle );
Mem_Free( wad ); // free himself
}
@ -3476,119 +3339,6 @@ FILESYSTEM IMPLEMENTATION
=============================================================================
*/
/*
===========
W_SaveLump
write new or replace existed lump
===========
*/
size_t W_SaveFile( wfile_t *wad, const char *lump, const void *data, size_t datasize, char type, qboolean replace )
{
dlumpinfo_t *find, newlump;
size_t lat_size, oldpos;
char hint, lumpname[64];
if( !wad || !lump ) return -1;
if( !data || !datasize )
{
MsgDev( D_WARN, "W_SaveLump: ignore blank lump %s - nothing to save\n", lump );
return -1;
}
if( wad->mode == O_RDONLY )
{
MsgDev( D_ERROR, "W_SaveLump: %s opened in readonly mode\n", wad->filename );
return -1;
}
if( wad->numlumps >= MAX_FILES_IN_WAD )
{
MsgDev( D_ERROR, "W_SaveLump: %s is full\n", wad->filename );
return -1;
}
find = W_FindLump( wad, lump, type );
if( find != NULL && replace )
{
if( FBitSet( find->attribs, ATTR_READONLY ))
{
// g-cont. i left this limitation as a protect of the replacement of compressed lumps
MsgDev( D_ERROR, "W_ReplaceLump: %s is read-only\n", find->name );
return -1;
}
if( datasize != find->disksize )
{
MsgDev( D_ERROR, "W_ReplaceLump: %s [%s] should be [%s]\n",
lumpname, Q_memprint( datasize ), Q_memprint( find->disksize ));
return -1;
}
oldpos = FS_Tell( wad->handle ); // don't forget restore original position
if( FS_Seek( wad->handle, find->filepos, SEEK_SET ) == -1 )
{
MsgDev( D_ERROR, "W_ReplaceLump: %s is corrupted\n", find->name );
FS_Seek( wad->handle, oldpos, SEEK_SET );
return -1;
}
if( FS_Write( wad->handle, data, datasize ) != find->disksize )
MsgDev( D_WARN, "W_ReplaceLump: %s probably replaced with errors\n", find->name );
// restore old position
FS_Seek( wad->handle, oldpos, SEEK_SET );
return wad->numlumps;
}
else
{
MsgDev( D_ERROR, "W_SaveLump: %s already exist\n", lump );
return -1;
}
// prepare lump name
Q_strncpy( lumpname, lump, sizeof( lumpname ));
// extract image hint
hint = W_HintFromSuf( lumpname );
if( hint != IMG_DIFFUSE )
lumpname[Q_strlen( lumpname ) - HINT_NAMELEN] = '\0'; // kill the suffix
if( Q_strlen( lumpname ) >= WAD3_NAMELEN )
{
// name is too long
MsgDev( D_ERROR, "W_SaveLump: %s more than %i symbols\n", lumpname, WAD3_NAMELEN );
return -1;
}
lat_size = sizeof( dlumpinfo_t ) * (wad->numlumps + 1);
// reallocate lumptable
wad->lumps = (dlumpinfo_t *)Mem_Realloc( wad->mempool, wad->lumps, lat_size );
memset( &newlump, 0, sizeof( newlump ));
// write header
Q_strnupr( lumpname, newlump.name, WAD3_NAMELEN );
newlump.filepos = FS_Tell( wad->handle );
newlump.attribs = ATTR_NONE;
newlump.img_type = hint;
newlump.type = type;
if( !W_WriteLump( wad, &newlump, data, datasize ))
return -1;
// record entry and re-sort table
W_AddFileToWad( lumpname, wad, &newlump );
return wad->numlumps;
}
/*
===========
W_LoadFile

View File

@ -348,7 +348,7 @@ Host_RegisterDecal
*/
qboolean Host_RegisterDecal( const char *name, int *count )
{
char shortname[CS_SIZE];
char shortname[MAX_QPATH];
int i;
if( !name || !*name )

2990
engine/common/mod_bmodel.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -43,12 +43,14 @@ GNU General Public License for more details.
#define LM_SAMPLE_SIZE 16
#define LM_SAMPLE_EXTRASIZE 8
#define MAX_MAP_WADS 256 // max wads that can be referenced per one map
#define CHECKVISBIT( vis, b ) ((b) >= 0 ? (byte)((vis)[(b) >> 3] & (1 << ((b) & 7))) : (byte)false )
#define SETVISBIT( vis, b )( void ) ((b) >= 0 ? (byte)((vis)[(b) >> 3] |= (1 << ((b) & 7))) : (byte)false )
#define CLEARVISBIT( vis, b )( void ) ((b) >= 0 ? (byte)((vis)[(b) >> 3] &= ~(1 << ((b) & 7))) : (byte)false )
#define REFPVS_RADIUS 2.0f // radius for rendering
#define FATPVS_RADIUS 8.0f // FatPVS use radius smaller than the FatPHS
#define REFPVS_RADIUS 2.0f // radius for rendering
#define FATPVS_RADIUS 8.0f // FatPVS use radius smaller than the FatPHS
#define FATPHS_RADIUS 16.0f
// model flags (stored in model_t->flags)
@ -60,45 +62,28 @@ GNU General Public License for more details.
#define MODEL_CLIENT BIT( 30 ) // client sprite
typedef struct wadlist_s
{
char wadnames[256][32];
int count;
} wadlist_t;
typedef struct leaflist_s
{
int count;
int maxcount;
qboolean overflowed;
short *list;
vec3_t mins, maxs;
int topnode; // for overflows where each leaf can't be stored individually
} leaflist_t;
// goes into world.flags
#define FWORLD_SKYSPHERE BIT( 0 )
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
#define FWORLD_WATERALPHA BIT( 2 )
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
#define FWORLD_HAS_MIRRORS BIT( 4 )
typedef struct
{
int mapversion; // map version (an key-value in worldspawn settings)
uint checksum; // current map checksum
int load_sequence; // increace each map change
msurface_t **draw_surfaces; // used for sorting translucent surfaces
int max_surfaces; // max surfaces per submodel (for all models)
qboolean loading; // true if worldmodel is loading
qboolean sky_sphere; // true when quake sky-sphere is used
qboolean has_mirrors; // one or more brush models contain reflective textures
qboolean custom_skybox; // if sky_sphere is active and custom skybox set
qboolean water_alpha; // allow translucency water
int block_size; // lightmap blocksize
int lightmap_samples; // samples per pixel
color24 *deluxedata; // deluxemap data pointer
byte *shadowdata; // occlusion data pointer
int flags; // misc flags
// mapstats info
char message[2048]; // just for debug
char compiler[256]; // map compiler
dclipnode2_t *clipnodes; // temporary 32-bit array to hold clipnodes
int numclipnodes; // may be exceeds 32768
int numnodes; // worldcount of nodes
// translucent sorted array
msurface_t **draw_surfaces; // used for sorting translucent surfaces
int max_surfaces; // max surfaces per submodel (for all models)
// visibility info
byte *visdata; // uncompressed visdata
@ -106,15 +91,7 @@ typedef struct
size_t fatbytes; // fatpvs size
int visclusters; // num visclusters
// world stats
size_t visdatasize; // actual size of the visdata
size_t litdatasize; // actual size of the lightdata
size_t vecdatasize; // actual size of the deluxdata
size_t occdatasize; // actual size of the shadowdata
size_t entdatasize; // actual size of the entity string
size_t texdatasize; // actual size of the textures lump
size_t clipnodesize; // sizeof dclipnode_t struct
// world bounds
vec3_t mins; // real accuracy world bounds
vec3_t maxs;
vec3_t size;
@ -124,6 +101,7 @@ extern world_static_t world;
extern byte *com_studiocache;
extern model_t *loadmodel;
extern convar_t *mod_studiocache;
extern convar_t *r_wadtextures;
//
// model.c
@ -132,12 +110,10 @@ void Mod_Init( void );
void Mod_ClearAll( qboolean keep_playermodel );
void Mod_Shutdown( void );
void Mod_ClearUserData( void );
void Mod_PrintBSPFileSizes( void );
void Mod_GetBounds( int handle, vec3_t mins, vec3_t maxs );
void Mod_GetFrames( int handle, int *numFrames );
void Mod_LoadWorld( const char *name, uint *checksum, qboolean multiplayer );
int Mod_FrameCount( model_t *mod );
void Mod_FreeUnused( void );
void *Mod_Calloc( int number, size_t size );
void *Mod_CacheCheck( struct cache_user_s *c );
void Mod_LoadCacheFile( const char *path, struct cache_user_s *cu );
@ -147,19 +123,27 @@ model_t *Mod_FindName( const char *name, qboolean create );
model_t *Mod_LoadModel( model_t *mod, qboolean world );
model_t *Mod_ForName( const char *name, qboolean world );
qboolean Mod_RegisterModel( const char *name, int index );
mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node );
modtype_t Mod_GetType( int handle );
model_t *Mod_Handle( int handle );
void Mod_FreeUnused( void );
//
// mod_bmodel.c
//
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean silent );
qboolean Mod_HeadnodeVisible( mnode_t *node, const byte *visbits, int *lastleaf );
int Mod_BoxLeafnums( const vec3_t mins, const vec3_t maxs, short *list, int listsize, int *lastleaf );
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis );
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
int Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize );
mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node );
void Mod_AmbientLevels( const vec3_t p, byte *pvolumes );
int Mod_SampleSizeForFace( msurface_t *surf );
byte *Mod_GetPVSForPoint( const vec3_t p );
modtype_t Mod_GetType( int handle );
model_t *Mod_Handle( int handle );
void Mod_UnloadBrushModel( model_t *mod );
void Mod_PrintWorldStats_f( void );
//
// mod_studio.c

File diff suppressed because it is too large Load Diff

View File

@ -955,7 +955,7 @@ Netchan_CopyFileFragments
qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
{
fragbuf_t *p, *n;
char filename[CS_SIZE];
char filename[MAX_QPATH];
int nsize;
byte *buffer;
int pos;

View File

@ -76,8 +76,8 @@ GNU General Public License for more details.
#define svc_eventindex 54 // [index][eventname]
// reserved
#define svc_resourcelocation 56 // [string]
#define svc_querycvarvalue 57 // [string]
#define svc_querycvarvalue2 58 // [string][long] (context)
// reserved
// reserved
#define svc_lastmsg 58 // start user messages at this point
// client to server
@ -90,8 +90,8 @@ GNU General Public License for more details.
// reserved
#define clc_fileconsistency 7
#define clc_voicedata 8
#define clc_requestcvarvalue 9
#define clc_requestcvarvalue2 10
// reserved
// reserved
#define clc_lastmsg 10 // end client messages
#define MAX_VISIBLE_PACKET_BITS 11 // 2048 visible entities per frame (hl1 has 256)
@ -174,7 +174,7 @@ typedef struct
{
int rescount;
int restype[MAX_RESOURCES];
char resnames[MAX_RESOURCES][CS_SIZE];
char resnames[MAX_RESOURCES][MAX_QPATH];
} resourcelist_t;
#endif//PROTOCOL_H

View File

@ -93,49 +93,6 @@ byte *Sound_Copy( size_t size )
return out;
}
uint Sound_GetApproxWavePlayLen( const char *filepath )
{
file_t *f;
wavehdr_t wav;
size_t filesize;
float seconds;
uint samples;
f = FS_Open( filepath, "rb", false );
if( !f ) return 0;
if( FS_Read( f, &wav, sizeof( wav )) != sizeof( wav ))
{
FS_Close( f );
return 0;
}
filesize = FS_FileLength( f );
filesize -= ( sizeof( wavehdr_t ) + sizeof( chunkhdr_t ));
FS_Close( f );
// is real wav file ?
if( wav.riff_id != RIFFHEADER || wav.wave_id != WAVEHEADER || wav.fmt_id != FORMHEADER )
return 0;
if( wav.wFormatTag != 1 )
return 0;
if( wav.nChannels != 1 && wav.nChannels != 2 )
return 0;
if( wav.nBitsPerSample != 8 && wav.nBitsPerSample != 16 )
return 0;
// calc samplecount
seconds = (float)filesize / wav.nAvgBytesPerSec / wav.nChannels;
samples = (uint)(( wav.nSamplesPerSec * wav.nChannels ) * seconds );
// g-cont. this function returns samplecount or time in milliseconds ???
return (uint)(seconds * 1000);
}
/*
================
Sound_ConvertToSigned

View File

@ -258,21 +258,6 @@ typedef struct enginefuncs_s
qboolean (*pfnVoice_SetClientListening)(int iReceiver, int iSender, qboolean bListen);
const char *(*pfnGetPlayerAuthId) ( edict_t *e );
void *(*pfnSequenceGet)( const char *fileName, const char *entryName );
void *(*pfnSequencePickSentence)( const char *groupName, int pickMethod, int *picked );
int (*pfnGetFileSize)( char *filename );
unsigned int (*pfnGetApproxWavePlayLen)( const char *filepath );
int (*pfnIsCareerMatch)( void );
int (*pfnGetLocalizedStringLength)( const char *label );
void (*pfnRegisterTutorMessageShown)( int mid );
int (*pfnGetTimesTutorMessageShown)( int mid );
void (*pfnProcessTutorMessageDecayBuffer)( int *buffer, int bufferLength );
void (*pfnConstructTutorMessageDecayBuffer)( int *buffer, int bufferLength );
void (*pfnResetTutorMessageDecayData)( void );
void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName );
void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID );
int (*CheckParm)( char *parm, char **ppnext );
} enginefuncs_t;
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138
@ -483,8 +468,6 @@ typedef struct
void (*pfnOnFreeEntPrivateData)( edict_t *pEnt );
void (*pfnGameShutdown)(void);
int (*pfnShouldCollide)( edict_t *pentTouched, edict_t *pentOther );
void (*pfnCvarValue)( const edict_t *pEnt, const char *value );
void (*pfnCvarValue2)( const edict_t *pEnt, int requestID, const char *cvarName, const char *value );
} NEW_DLL_FUNCTIONS;
typedef int (*NEW_DLL_FUNCTIONS_FN)( NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion );

View File

@ -383,6 +383,10 @@ SOURCE=.\common\matrixlib.c
# End Source File
# Begin Source File
SOURCE=.\common\mod_bmodel.c
# End Source File
# Begin Source File
SOURCE=.\common\mod_studio.c
# End Source File
# Begin Source File

View File

@ -137,10 +137,10 @@ typedef struct server_s
double lastchecktime;
int lastcheck; // number of last checked client
char model_precache[MAX_MODELS][CS_SIZE];
char sound_precache[MAX_SOUNDS][CS_SIZE];
char files_precache[MAX_CUSTOM][CS_SIZE];
char event_precache[MAX_EVENTS][CS_SIZE];
char model_precache[MAX_MODELS][MAX_QPATH];
char sound_precache[MAX_SOUNDS][MAX_QPATH];
char files_precache[MAX_CUSTOM][MAX_QPATH];
char event_precache[MAX_EVENTS][MAX_QPATH];
sv_static_entity_t static_entities[MAX_STATIC_ENTITIES];
int num_static_entities;

View File

@ -30,8 +30,6 @@ const char *clc_strings[11] =
"clc_unused6",
"clc_fileconsistency",
"clc_voicedata",
"clc_requestcvarvalue",
"clc_requestcvarvalue2",
};
typedef struct ucmd_s
@ -2367,41 +2365,6 @@ void SV_ParseResourceList( sv_client_t *cl, sizebuf_t *msg )
Netchan_FragSend( &cl->netchan );
}
/*
===================
SV_ParseCvarValue
Parse a requested value from client cvar
===================
*/
void SV_ParseCvarValue( sv_client_t *cl, sizebuf_t *msg )
{
const char *value = MSG_ReadString( msg );
if( svgame.dllFuncs2.pfnCvarValue != NULL )
svgame.dllFuncs2.pfnCvarValue( cl->edict, value );
MsgDev( D_REPORT, "Cvar query response: name:%s, value:%s\n", cl->name, value );
}
/*
===================
SV_ParseCvarValue2
Parse a requested value from client cvar
===================
*/
void SV_ParseCvarValue2( sv_client_t *cl, sizebuf_t *msg )
{
string name, value;
int requestID = MSG_ReadLong( msg );
Q_strcpy( name, MSG_ReadString( msg ));
Q_strcpy( value, MSG_ReadString( msg ));
if( svgame.dllFuncs2.pfnCvarValue2 != NULL )
svgame.dllFuncs2.pfnCvarValue2( cl->edict, requestID, name, value );
MsgDev( D_REPORT, "Cvar query response: name:%s, request ID %d, cvar:%s, value:%s\n", cl->name, requestID, name, value );
}
/*
===================
SV_ExecuteClientMessage
@ -2473,12 +2436,6 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
case clc_resourcelist:
SV_ParseResourceList( cl, msg );
break;
case clc_requestcvarvalue:
SV_ParseCvarValue( cl, msg );
break;
case clc_requestcvarvalue2:
SV_ParseCvarValue2( cl, msg );
break;
default:
MsgDev( D_ERROR, "SV_ReadClientMessage: clc_bad\n" );
SV_DropClient( cl );

View File

@ -576,38 +576,27 @@ void SV_WriteEntityPatch( const char *filename )
dheader_t *header;
int ver = -1, lumpofs = 0, lumplen = 0;
byte buf[MAX_SYSPATH]; // 1 kb
string bspfilename;
file_t *f;
f = FS_Open( va( "maps/%s.bsp", filename ), "rb", false );
Q_strncpy( bspfilename, va( "maps/%s.bsp", filename ), sizeof( bspfilename ));
f = FS_Open( bspfilename, "rb", false );
if( !f ) return;
memset( buf, 0, MAX_SYSPATH );
FS_Read( f, buf, MAX_SYSPATH );
ver = *(uint *)buf;
switch( ver )
header = (dheader_t *)buf;
// check all the lumps and some other errors
if( !Mod_TestBmodelLumps( bspfilename, buf, true ))
{
case Q1BSP_VERSION:
case HLBSP_VERSION:
case QBSP2_VERSION:
header = (dheader_t *)buf;
if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && (header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 )
{
// Blue-Shift ordering
lumpofs = header->lumps[LUMP_PLANES].fileofs;
lumplen = header->lumps[LUMP_PLANES].filelen;
}
else
{
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
}
break;
default:
FS_Close( f );
return;
}
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
if( lumplen >= 10 )
{
char *entities = NULL;
@ -642,7 +631,7 @@ char *SV_ReadEntityScript( const char *filename, int *flags )
*flags = 0;
Q_strncpy( bspfilename, va( "maps/%s.bsp", filename ), sizeof( entfilename ));
Q_strncpy( bspfilename, va( "maps/%s.bsp", filename ), sizeof( bspfilename ));
f = FS_Open( bspfilename, "rb", false );
if( !f ) return NULL;
@ -650,32 +639,20 @@ char *SV_ReadEntityScript( const char *filename, int *flags )
memset( buf, 0, MAX_SYSPATH );
FS_Read( f, buf, MAX_SYSPATH );
ver = *(uint *)buf;
switch( ver )
header = (dheader_t *)buf;
// check all the lumps and some other errors
if( !Mod_TestBmodelLumps( bspfilename, buf, (host.developer <= 2) ? true : false ))
{
case Q1BSP_VERSION:
case HLBSP_VERSION:
case QBSP2_VERSION:
header = (dheader_t *)buf;
if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && (header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 )
{
// Blue-Shift ordering
lumpofs = header->lumps[LUMP_PLANES].fileofs;
lumplen = header->lumps[LUMP_PLANES].filelen;
}
else
{
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
}
break;
default:
*flags |= MAP_INVALID_VERSION;
FS_Close( f );
return NULL;
}
// after call Mod_TestBmodelLumps we gurantee what map is valid
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
// check for entfile too
Q_strncpy( entfilename, va( "maps/%s.ent", filename ), sizeof( entfilename ));
@ -692,7 +669,7 @@ char *SV_ReadEntityScript( const char *filename, int *flags )
if( !ents && lumplen >= 10 )
{
FS_Seek( f, lumpofs, SEEK_SET );
ents = (char *)Z_Malloc( lumplen + 1 );
ents = Z_Malloc( lumplen + 1 );
FS_Read( f, ents, lumplen );
}
@ -3407,17 +3384,6 @@ void pfnSetView( const edict_t *pClient, const edict_t *pViewent )
MSG_WriteWord( &client->netchan.message, NUM_FOR_EDICT( pViewent ));
}
/*
=============
pfnTime
=============
*/
float pfnTime( void )
{
return (float)Sys_DoubleTime();
}
/*
=============
pfnStaticDecal
@ -4362,111 +4328,6 @@ const char *pfnGetPlayerAuthId( edict_t *e )
return result;
}
/*
=============
pfnGetFileSize
returns the filesize in bytes
=============
*/
int pfnGetFileSize( char *filename )
{
return FS_FileSize( filename, false );
}
/*
=============
pfnGetLocalizedStringLength
used by CS:CZ (client stub)
=============
*/
int pfnGetLocalizedStringLength( const char *label )
{
return 0;
}
/*
=============
pfnQueryClientCvarValue
request client cvar value
=============
*/
void pfnQueryClientCvarValue( const edict_t *player, const char *cvarName )
{
sv_client_t *cl;
if( !cvarName || !*cvarName )
{
MsgDev( D_ERROR, "QueryClientCvarValue: NULL cvar name!\n" );
return;
}
if(( cl = SV_ClientFromEdict( player, true )) != NULL )
{
MSG_BeginServerCmd( &cl->netchan.message, svc_querycvarvalue );
MSG_WriteString( &cl->netchan.message, cvarName );
}
else
{
if( svgame.dllFuncs2.pfnCvarValue )
svgame.dllFuncs2.pfnCvarValue( player, "Bad Player" );
MsgDev( D_ERROR, "QueryClientCvarValue: tried to send to a non-client!\n" );
}
}
/*
=============
pfnQueryClientCvarValue2
request client cvar value (bugfixed)
=============
*/
void pfnQueryClientCvarValue2( const edict_t *player, const char *cvarName, int requestID )
{
sv_client_t *cl;
if( !cvarName || !*cvarName )
{
MsgDev( D_ERROR, "QueryClientCvarValue: NULL cvar name!\n" );
return;
}
if(( cl = SV_ClientFromEdict( player, true )) != NULL )
{
MSG_BeginServerCmd( &cl->netchan.message, svc_querycvarvalue2 );
MSG_WriteLong( &cl->netchan.message, requestID );
MSG_WriteString( &cl->netchan.message, cvarName );
}
else
{
if( svgame.dllFuncs2.pfnCvarValue2 )
svgame.dllFuncs2.pfnCvarValue2( player, requestID, cvarName, "Bad Player" );
MsgDev( D_ERROR, "QueryClientCvarValue: tried to send to a non-client!\n" );
}
}
/*
=============
pfnCheckParm
=============
*/
static int pfnCheckParm( char *parm, char **ppnext )
{
int i = Sys_CheckParm( parm );
if( ppnext != NULL )
{
if( i > 0 && i < host.argc - 1 )
*ppnext = (char*)host.argv[i + 1];
else *ppnext = NULL;
}
return i;
}
// engine callbacks
static enginefuncs_t gEngfuncs =
@ -4615,20 +4476,6 @@ static enginefuncs_t gEngfuncs =
pfnVoice_GetClientListening,
pfnVoice_SetClientListening,
pfnGetPlayerAuthId,
pfnSequenceGet,
pfnSequencePickSentence,
pfnGetFileSize,
Sound_GetApproxWavePlayLen,
pfnIsCareerMatch,
pfnGetLocalizedStringLength,
pfnRegisterTutorMessageShown,
pfnGetTimesTutorMessageShown,
pfnProcessTutorMessageDecayBuffer,
pfnConstructTutorMessageDecayBuffer,
pfnResetTutorMessageDecayData,
pfnQueryClientCvarValue,
pfnQueryClientCvarValue2,
pfnCheckParm,
};
/*

View File

@ -241,7 +241,7 @@ hull_t *SV_HullForBsp( edict_t *ent, const vec3_t mins, const vec3_t maxs, vec3_
hull = &model->hulls[COM_RandomLong( 0, 0 )];
#endif
// FIXME: find a better method to detect quake-maps?
if( world.sky_sphere || world.lightmap_samples == 1 )
if( FBitSet( world.flags, FWORLD_SKYSPHERE ))
{
// alternate hull select for quake maps
if( size[0] < 3.0f || ent->v.solid == SOLID_PORTAL )