From 0b8d2dbde0b572ab1a77de0a076df3b310766194 Mon Sep 17 00:00:00 2001 From: g-cont Date: Mon, 5 Jan 2009 00:00:00 +0300 Subject: [PATCH] 05 Jan 2009 --- client/global/enginecallback.h | 14 +-- client/hud/hud.cpp | 21 +++- client/hud/hud.h | 4 +- client/hud/hud_ammo.cpp | 2 +- client/hud/hud_health.cpp | 2 +- client/hud/hud_iface.h | 17 +++- client/hud/hud_msg.cpp | 26 +++-- client/hud/hud_utils.cpp | 158 ++++++++++++++++-------------- client/hud/hud_warhead.cpp | 64 +++++++------ client/hud/hud_zoom.cpp | 11 +-- common/ripper/conv_image.c | 20 ++++ common/ripper/conv_main.c | 5 +- common/ripper/conv_sprite.c | 3 + common/ripper/ripper.h | 1 + debug.bat | 2 +- engine/client/cl_frame.c | 17 +++- engine/client/cl_game.c | 28 ++---- engine/client/cl_main.c | 1 + engine/client/cl_parse.c | 5 +- engine/client/cl_scrn.c | 4 +- engine/client/cl_view.c | 5 +- engine/client/client.h | 2 + engine/common/con_utils.c | 45 ++++++++- engine/common/engfuncs.c | 2 +- engine/server/server.h | 1 + engine/server/sv_frame.c | 7 +- engine/server/sv_game.c | 71 ++++++-------- engine/server/sv_init.c | 7 ++ engine/server/sv_world.c | 102 ++++++++++++++++++++ launch/imagelib/imagelib.h | 4 +- launch/imagelib/img_bmp.c | 1 + launch/imagelib/img_utils.c | 21 ++++ launch/launch.h | 1 + launch/memlib.c | 2 +- launch/system.c | 1 + launch/utils.c | 96 ++++++++++--------- public/clgame_api.h | 3 +- public/launch_api.h | 4 +- public/render_api.h | 2 +- render/r_draw.c | 10 +- render/r_local.h | 4 +- render/r_main.c | 103 +++++++++++++------- render/r_model.c | 4 +- render/r_studio.c | 57 +++-------- server/ents/baseentity.h | 10 +- server/ents/basefx.cpp | 65 +++++++------ server/ents/baseitem.cpp | 1 + server/ents/baseother.cpp | 26 ++--- server/ents/baserockets.cpp | 45 +++++---- server/ents/basetrigger.cpp | 23 +++-- server/ents/baseweapon.cpp | 66 +++++++------ server/global/client.cpp | 16 ++-- server/global/utils.cpp | 170 +++++++++++++++------------------ server/global/utils.h | 10 +- server/global/vector.h | 1 + server/monsters/player.cpp | 18 ++-- server/monsters/player.h | 4 +- todo.log | 13 ++- 58 files changed, 841 insertions(+), 587 deletions(-) diff --git a/client/global/enginecallback.h b/client/global/enginecallback.h index ef7afec7..3039174c 100644 --- a/client/global/enginecallback.h +++ b/client/global/enginecallback.h @@ -13,7 +13,6 @@ // screen handlers #define LOAD_SHADER (*g_engfuncs.pfnLoadShader) -#define DrawImage (*g_engfuncs.pfnDrawImage) #define DrawImageExt (*g_engfuncs.pfnDrawImageExt) #define SetColor (*g_engfuncs.pfnSetColor) #define SetParms (*g_engfuncs.pfnSetParms) @@ -55,7 +54,7 @@ inline void CL_PlaySound( int iSound, float flVolume, Vector &pos ) #define CenterPrint (*g_engfuncs.pfnCenterPrint) #define DrawChar (*g_engfuncs.pfnDrawCharacter) #define DrawString (*g_engfuncs.pfnDrawString) -#define GetImageSize (*g_engfuncs.pfnGetImageSize) +#define GetParms (*g_engfuncs.pfnGetParms) #define GetViewAngles (*g_engfuncs.pfnGetViewAngles) #define GetEntityByIndex (*g_engfuncs.pfnGetEntityByIndex) #define GetLocalPlayer (*g_engfuncs.pfnGetLocalPlayer) @@ -82,15 +81,4 @@ inline void TextMessageDrawChar( int xpos, int ypos, int number, int r, int g, i DrawChar( xpos, ypos, SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, number ); } -inline void FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a ) -{ - Vector RGB; - - RGB.x = (float)(r / 255.0f); - RGB.y = (float)(g / 255.0f); - RGB.z = (float)(b / 255.0f); - - g_engfuncs.pfnFillRGBA( x, y, width, height, RGB, (float)(a / 255.0f)); -} - #endif//ENGINECALLBACKS_H \ No newline at end of file diff --git a/client/hud/hud.cpp b/client/hud/hud.cpp index 59ca60e9..53d9d01b 100644 --- a/client/hud/hud.cpp +++ b/client/hud/hud.cpp @@ -76,8 +76,19 @@ void CHud :: VidInit( void ) Draw_VidInit(); // setup screen info - m_scrinfo.iWidth = CVAR_GET_FLOAT( "width" ); - m_scrinfo.iHeight = CVAR_GET_FLOAT( "height" ); + m_scrinfo.iRealWidth = CVAR_GET_FLOAT( "width" ); + m_scrinfo.iRealHeight = CVAR_GET_FLOAT( "height" ); + + if( CVAR_GET_FLOAT( "hud_scale" )) + { + m_scrinfo.iWidth = SCREEN_WIDTH; + m_scrinfo.iHeight = SCREEN_HEIGHT; + } + else + { + m_scrinfo.iWidth = CVAR_GET_FLOAT( "width" ); + m_scrinfo.iHeight = CVAR_GET_FLOAT( "height" ); + } // TODO: build real table of fonts widthInChars for( int i = 0; i < 256; i++ ) @@ -166,10 +177,10 @@ void CHud :: Think( void ) } // think about default fov - if( m_iFOV == 0 ) + if( m_flFOV == 0 ) { // only let players adjust up in fov, and only if they are not overriden by something else - m_iFOV = max( CVAR_GET_FLOAT( "default_fov" ), 90 ); + m_flFOV = max( CVAR_GET_FLOAT( "default_fov" ), 90 ); } } @@ -186,7 +197,7 @@ int CHud :: UpdateClientData( ref_params_t *cdata, float time ) Think(); - cdata->fov_x = m_iFOV; + cdata->fov_x = m_flFOV; cdata->iKeyBits = m_iKeyBits; cdata->v_idlescale = m_iConcussionEffect; diff --git a/client/hud/hud.h b/client/hud/hud.h index a2687a01..73474bcc 100644 --- a/client/hud/hud.h +++ b/client/hud/hud.h @@ -569,7 +569,7 @@ public: float m_vecAngles[3]; int m_iKeyBits; int m_iHideHUDDisplay; - int m_iFOV; + float m_flFOV; int m_Teamplay; int m_iRes; Vector m_vecSkyPos; @@ -656,6 +656,8 @@ public: { byte charWidths[256]; int iCharHeight; + int iRealWidth; + int iRealHeight; int iWidth; int iHeight; } m_scrinfo; diff --git a/client/hud/hud_ammo.cpp b/client/hud/hud_ammo.cpp index 3138c1f5..29c33a36 100644 --- a/client/hud/hud_ammo.cpp +++ b/client/hud/hud_ammo.cpp @@ -565,7 +565,7 @@ int CHudAmmo::MsgFunc_CurWeapon( const char *pszName, int iSize, void *pbuf ) m_pWeapon = pWeapon; - if( gHUD.m_iFOV >= 90 ) + if( gHUD.m_flFOV >= 90 ) { // normal crosshairs if( fOnTarget && m_pWeapon->hAutoaim ) diff --git a/client/hud/hud_health.cpp b/client/hud/hud_health.cpp index d8c28531..6929540a 100644 --- a/client/hud/hud_health.cpp +++ b/client/hud/hud_health.cpp @@ -160,7 +160,7 @@ int CHudHealth :: Draw( float flTime ) return 1; if( !m_hSprite ) - m_hSprite = LOAD_SHADER( PAIN_NAME ); + m_hSprite = SPR_Load( PAIN_NAME ); // has health changed? Flash the health # if( m_fFade ) diff --git a/client/hud/hud_iface.h b/client/hud/hud_iface.h index 1c0020dc..4cd20740 100644 --- a/client/hud/hud_iface.h +++ b/client/hud/hud_iface.h @@ -73,11 +73,16 @@ typedef struct dllfunction_s #define bound( min, num, max ) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min)) -// ScreenHeight returns the height of the screen, in pixels +// ScreenHeight returns the virtual height of the screen, in pixels #define ScreenHeight (gHUD.m_scrinfo.iHeight) -// ScreenWidth returns the width of the screen, in pixels +// ScreenWidth returns the virtual width of the screen, in pixels #define ScreenWidth (gHUD.m_scrinfo.iWidth) +// ScreenHeight returns the height of the screen, in pixels +#define ActualHeight (gHUD.m_scrinfo.iRealHeight) +// ScreenWidth returns the width of the screen, in pixels +#define ActualWidth (gHUD.m_scrinfo.iRealWidth) + inline void UnpackRGB( int &r, int &g, int &b, dword ulRGB ) { r = (ulRGB & 0xFF0000) >>16;\ @@ -152,19 +157,23 @@ extern int SPR_Width( HSPRITE hPic, int frame ); extern client_sprite_t *SPR_GetList( const char *name, int *count ); extern void ParseHudSprite( const char **pfile, char *psz, client_sprite_t *result ); extern void SPR_Set( HSPRITE hPic, int r, int g, int b ); +extern void SPR_Set( HSPRITE hPic, int r, int g, int b, int a ); extern void SPR_Draw( int frame, int x, int y, const wrect_t *prc ); extern void SPR_Draw( int frame, int x, int y, int width, int height ); extern void SPR_DrawHoles( int frame, int x, int y, const wrect_t *prc ); extern void SPR_DrawHoles( int frame, int x, int y, int width, int height ); +extern void SPR_DrawTransColor( int frame, int x, int y, int width, int height ); +extern void SPR_DrawTransColor( int frame, int x, int y, const wrect_t *prc ); extern void SPR_DrawAdditive( int frame, int x, int y, const wrect_t *prc ); extern void SPR_DrawAdditive( int frame, int x, int y, int width, int height ); +extern void FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a ); extern void SetCrosshair( HSPRITE hspr, wrect_t rc, int r, int g, int b ); extern void DrawCrosshair( void ); extern void DrawPause( void ); extern void SetScreenFade( Vector fadeColor, float alpha, float duration, float holdTime, int fadeFlags ); extern void DrawScreenFade( void ); -extern void DrawImageBar( float percent, HSPRITE hImage, int w, int h ); -extern void DrawImageBar( float percent, HSPRITE hImage, int x, int y, int w, int h ); +extern void DrawImageBar( float percent, const char *szSpriteName ); +extern void DrawImageBar( float percent, const char *szSpriteName, int x, int y ); extern void DrawGenericBar( float percent, int w, int h ); extern void DrawGenericBar( float percent, int x, int y, int w, int h ); extern void Draw_VidInit( void ); diff --git a/client/hud/hud_msg.cpp b/client/hud/hud_msg.cpp index 99210884..907d2cc1 100644 --- a/client/hud/hud_msg.cpp +++ b/client/hud/hud_msg.cpp @@ -70,13 +70,17 @@ int CHud :: InitMessages( void ) viewEntityIndex = 0; // trigger_viewset stuff viewFlags = 0; - m_iFOV = 0; - m_iHUDColor = RGB_YELLOWISH; // 255,160,0 + m_flFOV = 0; + m_iHUDColor = RGB_YELLOWISH; // 255, 160, 0 CVAR_REGISTER( "zoom_sensitivity_ratio", "1.2", 0, "mouse sensitivity when zooming" ); CVAR_REGISTER( "default_fov", "90", 0, "default client fov" ); CVAR_REGISTER( "hud_draw", "1", CVAR_ARCHIVE, "hud drawing modes" ); + // UNDONE: replace all coord variables with float not int + // FIXME: remove jitter for moving objects (flashlight beam etc) + CVAR_REGISTER( "hud_scale", "0", CVAR_ARCHIVE|CVAR_LATCH, "scale hud at current resolution" ); + // clear any old HUD list if( m_pHudList ) { @@ -159,26 +163,26 @@ int CHud::MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf ) { BEGIN_READ( pszName, iSize, pbuf ); - int newfov = READ_BYTE(); - int def_fov = CVAR_GET_FLOAT( "default_fov" ); + float newfov = READ_FLOAT(); + float def_fov = CVAR_GET_FLOAT( "default_fov" ); - if( newfov == 0 ) + if( newfov == 0.0f ) { - m_iFOV = def_fov; + m_flFOV = def_fov; } else { - m_iFOV = newfov; + m_flFOV = newfov; } - if( m_iFOV == def_fov ) + if( m_flFOV == def_fov ) { m_flMouseSensitivity = 0; } else { // set a new sensitivity that is proportional to the change from the FOV default - m_flMouseSensitivity = CVAR_GET_FLOAT( "sensitivity" ) * ( (float)newfov / (float)def_fov ); + m_flMouseSensitivity = CVAR_GET_FLOAT( "sensitivity" ) * ( newfov / def_fov ); m_flMouseSensitivity *= CVAR_GET_FLOAT( "zoom_sensitivity_ratio" ); // apply zoom factor } END_READ(); @@ -318,7 +322,11 @@ int CHud :: MsgFunc_WeaponAnim( const char *pszName, int iSize, void *pbuf ) edict_t *viewmodel = GetViewModel(); viewmodel->v.sequence = READ_BYTE(); + viewmodel->v.body = READ_BYTE(); + viewmodel->v.framerate = READ_BYTE() * 0.0625; viewmodel->v.effects |= EF_ANIMATE; + viewmodel->v.frame = -1; // force to start new sequence + viewmodel->v.scale = 1.0f; END_READ(); diff --git a/client/hud/hud_utils.cpp b/client/hud/hud_utils.cpp index e1729bfc..70c1ea83 100644 --- a/client/hud/hud_utils.cpp +++ b/client/hud/hud_utils.cpp @@ -186,15 +186,18 @@ static screenfade_t sf; int SPR_Frames( HSPRITE hPic ) { - // FIXME: engfuncs GetImageFrames - return 1; + int Frames; + + GetParms( NULL, NULL, &Frames, 0, hPic ); + + return Frames; } int SPR_Height( HSPRITE hPic, int frame ) { int Height; - GetImageSize( NULL, &Height, frame, hPic ); + GetParms( NULL, &Height, NULL, frame, hPic ); return Height; } @@ -203,7 +206,7 @@ int SPR_Width( HSPRITE hPic, int frame ) { int Width; - GetImageSize( &Width, NULL, frame, hPic ); + GetParms( &Width, NULL, NULL, frame, hPic ); return Width; } @@ -337,12 +340,23 @@ void SPR_Set( HSPRITE hPic, int r, int g, int b ) SetColor((r / 255.0f), (g / 255.0f), (b / 255.0f), 1.0f ); } -inline static void SPR_DrawGeneric( int frame, int x, int y, int width, int height, const wrect_t *prc ) +void SPR_Set( HSPRITE hPic, int r, int g, int b, int a ) +{ + ds.hSprite = hPic; + SetColor((r / 255.0f), (g / 255.0f), (b / 255.0f), (a / 255.0f)); +} + +inline static void SPR_DrawGeneric( int frame, float x, float y, float width, float height, const wrect_t *prc ) { float s1, s2, t1, t2; if( width == -1 && height == -1 ) - GetImageSize( &width, &height, frame, ds.hSprite ); + { + int w, h; + GetParms( &w, &h, NULL, frame, ds.hSprite ); + width = w; + height = h; + } if( prc ) { @@ -360,9 +374,42 @@ inline static void SPR_DrawGeneric( int frame, int x, int y, int width, int heig s2 = t2 = 1.0f; } + float xscale, yscale; + + // scale for screen sizes + xscale = gHUD.m_scrinfo.iRealWidth / (float)gHUD.m_scrinfo.iWidth; + yscale = gHUD.m_scrinfo.iRealHeight / (float)gHUD.m_scrinfo.iHeight; + + x *= xscale; + y *= yscale; + width *= xscale; + height *= yscale; + DrawImageExt( ds.hSprite, x, y, width, height, s1, t1, s2, t2 ); } +void FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a ) +{ + Vector RGB; + + RGB.x = (float)(r / 255.0f); + RGB.y = (float)(g / 255.0f); + RGB.z = (float)(b / 255.0f); + + float xscale, yscale; + + // scale for screen sizes + xscale = gHUD.m_scrinfo.iRealWidth / (float)gHUD.m_scrinfo.iWidth; + yscale = gHUD.m_scrinfo.iRealHeight / (float)gHUD.m_scrinfo.iHeight; + + x *= xscale; + y *= yscale; + width *= xscale; + height *= yscale; + + g_engfuncs.pfnFillRGBA( x, y, width, height, RGB, (float)(a / 255.0f)); +} + void SPR_Draw( int frame, int x, int y, const wrect_t *prc ) { SetParms( ds.hSprite, kRenderNormal, frame ); @@ -375,6 +422,18 @@ void SPR_Draw( int frame, int x, int y, int width, int height ) SPR_DrawGeneric( frame, x, y, width, height, NULL ); } +void SPR_DrawTransColor( int frame, int x, int y, const wrect_t *prc ) +{ + SetParms( ds.hSprite, kRenderTransColor, frame ); + SPR_DrawGeneric( frame, x, y, -1, -1, prc ); +} + +void SPR_DrawTransColor( int frame, int x, int y, int width, int height ) +{ + SetParms( ds.hSprite, kRenderTransColor, frame ); + SPR_DrawGeneric( frame, x, y, width, height, NULL ); +} + void SPR_DrawHoles( int frame, int x, int y, const wrect_t *prc ) { SetParms( ds.hSprite, kRenderTransAlpha, frame ); @@ -428,77 +487,40 @@ void DrawPause( void ) if( !CVAR_GET_FLOAT( "paused" ) || !CVAR_GET_FLOAT( "scr_showpause" )) return; - if( !ds.hPause ) ds.hPause = LOAD_SHADER( "gfx/shell/m_pause" ); - DrawImage( ds.hPause, (SCREEN_WIDTH - 128) / 2, (SCREEN_HEIGHT - 32) / 2, 128, 32 ); + DrawImageBar( 100, "m_pause" ); // HACKHACK } void DrawImageRectangle( HSPRITE hImage ) { - DrawImage( hImage, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ); + DrawImageExt( hImage, 0, 0, ActualWidth, ActualHeight, 0, 0, 1, 1 ); } -void DrawImageBar( float percent, HSPRITE hImage, int w, int h ) +void DrawImageBar( float percent, const char *szSpriteName ) { - DrawImageBar( percent, hImage, (SCREEN_WIDTH - w)/2, (SCREEN_HEIGHT - h)/2, w, h ); + int m_loading = gHUD.GetSpriteIndex( szSpriteName ); + wrect_t rcSize = gHUD.GetSpriteRect( m_loading ); + + int w = rcSize.right - rcSize.left; + int h = rcSize.bottom - rcSize.top; + DrawImageBar( percent, szSpriteName, (ScreenWidth - w)/2, (ScreenHeight - h)/2 ); } -void DrawImageBar( float percent, HSPRITE hImage, int x, int y, int w, int h ) +void DrawImageBar( float percent, const char *szSpriteName, int x, int y ) { - HSPRITE hFilled; - float progress; - int width1, width2, height; + int m_loading = gHUD.GetSpriteIndex( szSpriteName ); + HSPRITE hLoading = gHUD.GetSprite( m_loading ); + wrect_t rcBar, rcBack; + float step; - hFilled = LOAD_SHADER( "gfx/shell/fill_rect" ); - progress = bound( 0.0, percent * 0.01, 100.0 ); + rcBar = rcBack = gHUD.GetSpriteRect( m_loading ); + step = (float)(rcBack.right - rcBack.left) / 100; + rcBar.right = rcBar.left + (int)ceil(percent * step); - width2 = w * progress; - width1 = bound( 64.0, w, 512.0 ); - height = bound( 16.0, h, 64.0 ); + SPR_Set( hLoading, 128, 128, 128 ); + SPR_DrawAdditive( 0, x, y, &rcBack ); // background - DrawImage( hImage, x, y, width1, height ); // background - - SetColor( 1.0f, 1.0f, 1.0f, 0.5f ); - DrawImage( hFilled, x, y, width2, height ); // progress bar -} - -void DrawGenericBar( float percent, int w, int h ) -{ - DrawGenericBar( percent, (SCREEN_WIDTH - w)/2, (SCREEN_HEIGHT - h)/2, w, h ); -} - -void DrawGenericBar( float percent, int x, int y, int w, int h ) -{ - HSPRITE hFill, hBack; - float progress; - int width1, width2, height1, height2; - int width3, height3, pos_x, pos_y, pos2_x, pos2_y; - - hFill = LOAD_SHADER( "gfx/shell/bar_load" ); - hBack = LOAD_SHADER( "gfx/shell/bar_back" ); - progress = bound( 0.0f, percent * 0.01f, 100.0f ); - - // filling area size - width1 = bound( 64.0, w, 512.0 ); - height1 = bound( 16.0, h, 64.0 ); - - // background size - width2 = width1 - 2; - height2 = height1 - 2; - - // bar size - width3 = width2 * progress; - height3 = height2; - - pos_x = x; - pos_y = y; - pos2_x = x + 1; - pos2_y = y + 1; - - FillRGBA( pos_x, pos_y, width1, height1, 255, 255, 255, 255 ); - DrawImage( hBack, pos2_x, pos2_y, width2, height2 ); - - SetColor( 1.0f, 1.0f, 1.0f, 0.5f ); - DrawImage( hFill, pos2_x, pos2_y, width3, height3 ); + SPR_Set( hLoading, 255, 160, 0 ); + SPR_DrawAdditive( 0, x, y, &rcBar ); // progress bar } // @@ -507,21 +529,17 @@ void DrawGenericBar( float percent, int x, int y, int w, int h ) void V_RenderPlaque( void ) { const char *levelshot; - HSPRITE hDownload; levelshot = CVAR_GET_STRING( "cl_levelshot_name" ); if( !strcmp( levelshot, "" )) levelshot = ""; // logo that shows up while upload next level DrawImageRectangle( LOAD_SHADER( levelshot )); - DrawImageBar( CVAR_GET_FLOAT( "scr_loading" ), LOAD_SHADER( "gfx/shell/m_loading" ), 128, 32 ); + DrawImageBar( CVAR_GET_FLOAT( "scr_loading" ), "m_loading" ); if( !CVAR_GET_FLOAT( "scr_download" )) return; - // FIXME: replace with picture "m_download" - hDownload = LOAD_SHADER( "gfx/shell/m_loading" ); - - DrawImageBar( CVAR_GET_FLOAT( "scr_download" ), hDownload, (SCREEN_WIDTH-128)/2, 420, 128, 32 ); + DrawImageBar( CVAR_GET_FLOAT( "scr_download" ), "m_download", (ScreenWidth-128)/2, ScreenHeight-60 ); } void V_RenderSplash( void ) diff --git a/client/hud/hud_warhead.cpp b/client/hud/hud_warhead.cpp index 0adf8744..17adb227 100644 --- a/client/hud/hud_warhead.cpp +++ b/client/hud/hud_warhead.cpp @@ -9,7 +9,7 @@ #include "hud.h" #define GUIDE_S SPR_Width( m_hCrosshair, 0 ) -#define READOUT_S 128 +#define READOUT_S 192 DECLARE_MESSAGE( m_Redeemer, WarHUD ) int CHudRedeemer::Init( void ) @@ -63,26 +63,33 @@ int CHudRedeemer :: Draw( float flTime ) SPR_Set( m_hCrosshair, 255, 128, 128 ); SPR_DrawAdditive( 0, y, x, NULL); - int yOffset = ((int)(flTime * 850) % READOUT_S) - READOUT_S; + int yOffset = ScreenHeight; + yOffset -= ((int)(flTime * 650) % READOUT_S) - READOUT_S; SPR_Set( m_hSprite, 255, 128, 128 ); - for( ; yOffset < ScreenHeight; yOffset += READOUT_S ) - SPR_DrawAdditive( 0, 0, yOffset, NULL ); + while( yOffset > -READOUT_S ) + { + SPR_DrawAdditive( 0, 0, yOffset, READOUT_S>>1, READOUT_S ); + yOffset -= READOUT_S; + } SetScreenFade( Vector( 1, 0, 0 ), 0.25, 0, 0, FFADE_STAYOUT ); // enable red fade } else if( m_iHudMode == 2 ) // draw alpha noise { - SPR_Set(m_hStatic, 255, 255, 255 ); - // play at 15fps frame = (int)(flTime * 15) % SPR_Frames( m_hStatic ); y = x = 0; - w = SPR_Width( m_hStatic, 0); - h = SPR_Height( m_hStatic, 0); + w = SPR_Width( m_hStatic, 0 ); + h = SPR_Height( m_hStatic, 0 ); - for( y = -(rand() % h); y < ScreenHeight; y += h ) - for( x = -(rand() % w); x < ScreenWidth; x += w ) - SPR_DrawAdditive ( frame, x, y, NULL ); + for( y = -(rand() % h); y < ScreenHeight; y += h ) + { + for( x = -(rand() % w); x < ScreenWidth; x += w ) + { + SPR_Set( m_hStatic, 255, 255, 255, 100 ); + SPR_DrawAdditive( frame, x, y, NULL ); + } + } y = (ScreenWidth - GUIDE_S) / 2; x = (ScreenHeight - GUIDE_S) / 2; @@ -90,48 +97,47 @@ int CHudRedeemer :: Draw( float flTime ) SPR_Set( m_hCrosshair, 255, 128, 128 ); SPR_DrawAdditive( 0, y, x, NULL ); - int yOffset = ((int)(flTime * 850) % READOUT_S) - READOUT_S; - SPR_Set(m_hSprite, 255, 128, 128 ); - for( ; yOffset < ScreenHeight; yOffset += READOUT_S ) - SPR_DrawAdditive( 0, 0, yOffset, NULL ); + int yOffset = ScreenHeight; + yOffset -= ((int)(flTime * 650) % READOUT_S) - READOUT_S; + SPR_Set( m_hSprite, 255, 128, 128 ); + while( yOffset > -READOUT_S ) + { + SPR_DrawAdditive( 0, 0, yOffset, READOUT_S>>1, READOUT_S ); + yOffset -= READOUT_S; + } SetScreenFade( Vector( 1, 0, 0 ), 0.25, 0, 0, FFADE_STAYOUT ); // enable red fade } else if( m_iHudMode == 3 ) // draw static noise { - // play at 25fps - frame = (int)(flTime * 25) % SPR_Frames( m_hStatic ); + // play at 15fps + frame = (int)(flTime * 15) % SPR_Frames( m_hStatic ); SPR_Set( m_hStatic, 255, 255, 255 ); - SPR_Draw( frame, 0, 0, &rc ); + SPR_Draw( frame, 0, 0, ScreenWidth, ScreenHeight ); // disable fade SetScreenFade( Vector( 1, 1, 1 ), 0, 0, 0, FFADE_OUT ); } - else if( m_iHudMode == 4 ) // draw videocamera screen + else if( m_iHudMode == 1 ) // draw videocamera screen { // play at 15fps frame = (int)(flTime * 1.5f) % SPR_Frames( m_hCamRec ); // draw interlaces - SPR_Set( m_hCamera, 16, 96, 16 ); //, 64 ); // give this value from breaklight.bsp (xash03) - SPR_DrawAdditive( frame, 0, 0, &rc ); + SPR_Set( m_hCamera, 16, 96, 16, 64 ); // give this value from breaklight.bsp (xash03) + SPR_DrawAdditive( frame, 0, 0, ScreenWidth, ScreenHeight ); // draw recorder icon - SPR_Set( m_hCamRec, 255, 0, 0 ); //, 255 ); // give this value from breaklight.bsp (xash03) + SPR_Set( m_hCamRec, 255, 0, 0, 255 ); // give this value from breaklight.bsp (xash03) float scale = 2.5f; // REC[*] sprite scale - wrect_t m_rcCamRec; - // calculating pos with different resolutions + // calculating pos for different resolutions w = SPR_Width( m_hCamRec, 0 ) * scale; h = SPR_Height( m_hCamRec, 0 ) * scale; x = ScreenWidth - (w * 1.5f); y = w * 0.4f; - m_rcCamRec.left = x; - m_rcCamRec.right = x + w; - m_rcCamRec.top = y; - m_rcCamRec.bottom = y + h; - SPR_DrawAdditive( frame, 0, 0, &m_rcCamRec ); + SPR_DrawAdditive( frame, x, y, w, h ); // disable fade SetScreenFade( Vector( 1, 1, 1 ), 0, 0, 0, FFADE_OUT ); diff --git a/client/hud/hud_zoom.cpp b/client/hud/hud_zoom.cpp index 53416773..d425737f 100644 --- a/client/hud/hud_zoom.cpp +++ b/client/hud/hud_zoom.cpp @@ -58,22 +58,17 @@ int CHudZoom :: Draw( float flTime ) if( !m_hLines || !m_hCrosshair ) return 0; if( !m_iHudMode ) return 0; // draw scope - float left = (ScreenWidth - ScreenHeight)/2; + float left = (float)(ScreenWidth - ScreenHeight) / 2; float right = left + ScreenHeight; - float centerx = ScreenWidth / 2; - float centery = ScreenHeight / 2; // draw crosshair SPR_Set( m_hCrosshair, 255, 255, 255 ); - SPR_DrawHoles( 0, left, 0, centerx, centery); - SPR_DrawHoles( 1, centerx, 0, right, centery); - SPR_DrawHoles( 2, centerx, centery, right, ScreenHeight); - SPR_DrawHoles( 3, left, centery, centerx, ScreenHeight); + SPR_DrawTransColor( 0, left, 0, ScreenHeight, ScreenHeight ); // draw side-lines SPR_Set( m_hLines, 255, 255, 255 ); SPR_Draw( 0, 0, 0, left, ScreenHeight ); - SPR_Draw( 0, right, 0, ScreenWidth, ScreenHeight ); + SPR_Draw( 0, right, 0, left, ScreenHeight ); return 1; } diff --git a/common/ripper/conv_image.c b/common/ripper/conv_image.c index f186bb8a..8052c597 100644 --- a/common/ripper/conv_image.c +++ b/common/ripper/conv_image.c @@ -64,6 +64,26 @@ bool ConvJPG( const char *name, byte *buffer, size_t filesize, const char *ext ) return false; } +/* +============= +ConvBMP +============= +*/ +bool ConvBMP( const char *name, byte *buffer, size_t filesize, const char *ext ) +{ + rgbdata_t *pic = FS_LoadImage( va( "#%s.bmp", name ), buffer, filesize ); + + if( pic ) + { + FS_SaveImage( va("%s/%s.%s", gs_gamedir, name, ext ), pic ); + Conv_CreateShader( name, pic, ext, NULL, 0, 0 ); + Msg( "%s.bmp\n", name, ext ); // echo to console + FS_FreeImage( pic ); + return true; + } + return false; +} + /* ============= ConvPCX diff --git a/common/ripper/conv_main.c b/common/ripper/conv_main.c index bca1c027..e8a69759 100644 --- a/common/ripper/conv_main.c +++ b/common/ripper/conv_main.c @@ -40,9 +40,10 @@ convformat_t convert_formats[] = convformat_t convert_formats32[] = { {"%s.%s", "spr", ConvSPR, "tga" }, // quake1/half-life sprite - {"%s.%s","spr32",ConvSPR, "tga" }, // spr32 sprite - {"%s.%s", "sp2", ConvSPR, "tga" }, // quake2 sprite + {"%s.%s","spr32",ConvSPR, "dds" }, // spr32 sprite + {"%s.%s", "sp2", ConvSPR, "dds" }, // quake2 sprite {"%s.%s", "jpg", ConvJPG, "png" }, // quake3 textures + {"%s.%s", "bmp", ConvBMP, "dds" }, // 8-bit maps with alpha-cnahnel {"%s.%s", "pcx", ConvPCX, "png" }, // quake2 pics {"%s.%s", "flt", ConvFLT, "png" }, // doom1 textures {"%s.%s", "flp", ConvFLP, "png" }, // doom1 menu pics diff --git a/common/ripper/conv_sprite.c b/common/ripper/conv_sprite.c index f12deee3..ec7c853b 100644 --- a/common/ripper/conv_sprite.c +++ b/common/ripper/conv_sprite.c @@ -212,6 +212,9 @@ void *SPR_ConvertFrame( const char *name, const char *ext, void *pin, int framen spr.frame[framenum].height = (float)LittleLong(pinframe->height); } + if( FS_CheckParm( "-force32" ) && spr.texFormat == SPR_INDEXALPHA ) + pix->flags &= ~IMAGE_HAS_ALPHA; + FS_SaveImage( va("%s/sprites/%s.%s", gs_gamedir, framename, ext ), pix ); FS_FreeImage( pix ); // free image diff --git a/common/ripper/ripper.h b/common/ripper/ripper.h index 18627f9d..d38bece9 100644 --- a/common/ripper/ripper.h +++ b/common/ripper/ripper.h @@ -63,6 +63,7 @@ bool ConvPCX( const char *name, byte *buffer, size_t filesize, const char *ext ) bool ConvFLT( const char *name, byte *buffer, size_t filesize, const char *ext );// Doom1 flat images (textures) bool ConvFLP( const char *name, byte *buffer, size_t filesize, const char *ext );// Doom1 flat images (menu pics) bool ConvJPG( const char *name, byte *buffer, size_t filesize, const char *ext );// Quake3 textures +bool ConvBMP( const char *name, byte *buffer, size_t filesize, const char *ext );// 8-bit maps with alpha-channel bool ConvMIP( const char *name, byte *buffer, size_t filesize, const char *ext );// Quake1, Half-Life wad textures bool ConvLMP( const char *name, byte *buffer, size_t filesize, const char *ext );// Quake1, Half-Life lump images bool ConvFNT( const char *name, byte *buffer, size_t filesize, const char *ext );// Half-Life system fonts diff --git a/debug.bat b/debug.bat index ac598918..bb29ac58 100644 --- a/debug.bat +++ b/debug.bat @@ -72,5 +72,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg echo Build succeeded! echo Please wait. Xash is now loading cd D:\Xash3D\ -quake.exe -game tmpQuArK -log -debug -dev 3 +map dm_qstyle +quake.exe -game tmpQuArK -log -debug -dev 3 +map qctest :done \ No newline at end of file diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index 25e4d429..1906f498 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -23,9 +23,9 @@ void CL_UpdateEntityFields( edict_t *ent ) // copy state to progs ent->v.classname = cl.edict_classnames[ent->pvClientData->current.classname]; ent->v.modelindex = ent->pvClientData->current.model.index; + ent->v.weaponmodel = ent->pvClientData->current.pmodel.index; ent->v.ambient = ent->pvClientData->current.soundindex; ent->v.model = MAKE_STRING( cl.configstrings[CS_MODELS+ent->pvClientData->current.model.index] ); - ent->v.weaponmodel = MAKE_STRING( cl.configstrings[CS_MODELS+ent->pvClientData->current.pmodel.index] ); ent->v.frame = ent->pvClientData->current.model.frame; ent->v.sequence = ent->pvClientData->current.model.sequence; ent->v.gaitsequence = ent->pvClientData->current.model.gaitsequence; @@ -83,7 +83,11 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t if( unchanged ) *state = *old; else MSG_ReadDeltaEntity( msg, old, state, newnum ); - if( state->number == -1 ) return; // entity was delta removed + if( state->number == -1 ) + { + CL_FreeEdict( ent ); + return; // entity was delta removed + } cl.parse_entities++; frame->num_entities++; @@ -156,6 +160,8 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram if( msg->readcount > msg->cursize ) Host_Error("CL_ParsePacketEntities: end of message[%d > %d]\n", msg->readcount, msg->cursize ); + while( newnum >= clgame.numEntities ) CL_AllocEdict(); + while( oldnum < newnum ) { // one or more entities from the old packet are unchanged @@ -193,8 +199,9 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram if( oldnum > newnum ) { - // delta from baseline + // delta from baseline ? edict_t *ent = EDICT_NUM( newnum ); + if( ent->free ) CL_InitEdict( ent ); // FIXME: get rid of this CL_DeltaEntity( msg, newframe, newnum, &ent->pvClientData->baseline, false ); continue; } @@ -218,6 +225,8 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram oldnum = oldstate->number; } } + + for( ; EDICT_NUM( clgame.numEntities - 1 )->free; clgame.numEntities-- ); } /* @@ -357,9 +366,7 @@ void CL_AddViewWeapon( entity_state_t *ps ) if( ps->fov > 135 ) return; if( !ps->viewmodel ) return; - cl.viewent.v.scale = 1.0f; cl.viewent.serialnumber = -1; - cl.viewent.v.framerate = 1.0f; cl.viewent.v.effects |= EF_MINLIGHT; cl.viewent.v.modelindex = ps->viewmodel; VectorCopy( cl.refdef.vieworg, cl.viewent.v.origin ); diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 69a634b9..6eba5574 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -222,6 +222,7 @@ void CL_ParseUserMessage( sizebuf_t *net_buffer, int svc_num ) void CL_InitEdict( edict_t *pEdict ) { Com_Assert( pEdict == NULL ); + Com_Assert( pEdict->pvClientData != NULL ); pEdict->v.pContainingEntity = pEdict; // make cross-links for consistency pEdict->pvClientData = (cl_priv_t *)Mem_Alloc( cls.mempool, sizeof( cl_priv_t )); @@ -256,7 +257,7 @@ edict_t *CL_AllocEdict( void ) for( i = 0; i < clgame.numEntities; i++ ) { pEdict = EDICT_NUM( i ); - // the first couple seconds of server time can involve a lot of + // the first couple seconds of client time can involve a lot of // freeing and allocating, so relax the replacement policy if( pEdict->free && ( pEdict->freetime < 2.0f || ((cl.time * 0.001f) - pEdict->freetime) > 0.5f )) { @@ -353,23 +354,6 @@ void pfnFillRGBA( int x, int y, int width, int height, const float *color, float re->SetColor( NULL ); } -/* -============= -pfnDrawImage - -============= -*/ -void pfnDrawImage( shader_t shader, int x, int y, int width, int height ) -{ - if( shader == -1 ) - { - MsgDev( D_ERROR, "CL_DrawImage: invalid shader handle\n" ); - return; - } - SCR_DrawPic( x, y, width, height, shader ); - if( re ) re->SetColor( NULL ); -} - /* ============= pfnDrawImageExt @@ -711,13 +695,14 @@ pfnGetImageSize ============= */ -void pfnGetImageSize( int *w, int *h, int frame, shader_t shader ) +void pfnGetDrawParms( int *w, int *h, int *f, int frame, shader_t shader ) { - if( re ) re->DrawGetPicSize( w, h, frame, shader ); + if( re ) re->GetParms( w, h, f, frame, shader ); else { if( w ) *w = 0; if( h ) *h = 0; + if( f ) *f = 1; } } @@ -875,7 +860,6 @@ static cl_enginefuncs_t gEngfuncs = pfnMemFree, pfnLoadShader, pfnFillRGBA, - pfnDrawImage, pfnDrawImageExt, pfnSetColor, pfnRegisterVariable, @@ -898,7 +882,7 @@ static cl_enginefuncs_t gEngfuncs = pfnCenterPrint, pfnDrawCharacter, pfnDrawString, - pfnGetImageSize, + pfnGetDrawParms, pfnSetDrawParms, pfnGetViewAngles, CL_GetEdictByIndex, diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 4e2c45b8..19cf7603 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -1195,6 +1195,7 @@ void CL_Frame( dword time ) return; // decide the simulation time + cl.oldtime = cl.time; cl.time += time; // can be merged by cl.frame.servertime cls.realtime += time; cls.frametime = time * 0.001; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index ce71066c..00fa2931 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -284,6 +284,7 @@ void CL_ParseBaseline( sizebuf_t *msg ) while( newnum >= clgame.numEntities ) CL_AllocEdict(); ent = EDICT_NUM( newnum ); + Com_Assert( ent->pvClientData == NULL ); MSG_ReadDeltaEntity( msg, &nullstate, &ent->pvClientData->baseline, newnum ); } @@ -298,9 +299,9 @@ void CL_ParseConfigString( sizebuf_t *msg ) i = MSG_ReadShort( msg ); if( i < 0 || i >= MAX_CONFIGSTRINGS ) - Host_Error("configstring > MAX_CONFIGSTRINGS\n"); + Host_Error( "configstring > MAX_CONFIGSTRINGS\n" ); com.strcpy( cl.configstrings[i], MSG_ReadString( msg )); - + // do something apropriate if( i == CS_SKYNAME && cl.video_prepped ) { diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index ba01c5ac..3982f92c 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -76,11 +76,11 @@ void SCR_DrawPic( float x, float y, float width, float height, string_t shader ) // get original size if( width == -1 || height == -1 ) { - re->DrawGetPicSize( &w, &h, 0, shader ); + re->GetParms( &w, &h, NULL, 0, shader ); width = w, height = h; } SCR_AdjustSize( &x, &y, &width, &height ); - re->DrawStretchPic (x, y, width, height, 0, 0, 1, 1, shader ); + re->DrawStretchPic( x, y, width, height, 0, 0, 1, 1, shader ); } /* diff --git a/engine/client/cl_view.c b/engine/client/cl_view.c index 8e431033..570e42bf 100644 --- a/engine/client/cl_view.c +++ b/engine/client/cl_view.c @@ -176,8 +176,9 @@ void V_RenderView( void ) cl.refdef.areabits = cl.frame.areabits; cl.refdef.rdflags = cl.frame.ps.renderfx; cl.refdef.fov_y = V_CalcFov( cl.refdef.fov_x, cl.refdef.viewport[2], cl.refdef.viewport[3] ); - cl.refdef.time = cl.time * 0.001f; // cl.time for right lerping - cl.refdef.oldtime = (cl.time * 0.001f) - 0.005; // frametime + cl.refdef.oldtime = (cl.oldtime * 0.001f); + cl.refdef.time = (cl.time * 0.001f); // cl.time for right lerping + cl.refdef.frametime = cls.frametime; if( cl.refdef.rdflags & RDF_UNDERWATER ) { diff --git a/engine/client/client.h b/engine/client/client.h index d6aa775a..2f38b7f7 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -106,6 +106,7 @@ typedef struct vec3_t viewangles; dword time; // this is the time value that the client + dword oldtime; // cl.oldtime // is rendering at. always <= cls.realtime ref_params_t refdef; // shared refdef edict_t viewent; // viewmodel @@ -470,6 +471,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num ); void CL_LinkUserMessage( char *pszName, const int svc_num ); void CL_SortUserMessages( void ); edict_t *CL_AllocEdict( void ); +void CL_InitEdict( edict_t *pEdict ); void CL_FreeEdict( edict_t *pEdict ); string_t CL_AllocString( const char *szValue ); const char *CL_GetString( string_t iString ); diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index 98e00bcf..55c0a547 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -186,7 +186,7 @@ bool Cmd_GetDemoList( const char *s, char *completedname, int length ) /* ===================================== -Cmd_GetSourceList +Cmd_GetProgsList Prints or complete vm source folder name ===================================== @@ -230,7 +230,7 @@ bool Cmd_GetProgsList( const char *s, char *completedname, int length ) /* ===================================== -Cmd_GetProgsList +Cmd_GetSourceList Prints or complete vm progs name ===================================== @@ -411,6 +411,44 @@ bool Cmd_GetSoundList( const char *s, char *completedname, int length ) return true; } +bool Cmd_GetStringTablesList( const char *s, char *completedname, int length ) +{ + int i, numtables; + string tables[MAX_STRING_TABLES]; + string matchbuf; + const char *name; + + // compare gamelist with current keyword + for( i = 0, numtables = 0; i < MAX_STRING_TABLES; i++ ) + { + name = StringTable_GetName( i ); + if( name && ( *s == '*' || !com.strnicmp( name, s, com.strlen( s )))) + com.strcpy( tables[numtables++], name ); + } + if( !numtables ) return false; + + com.strncpy( matchbuf, tables[0], MAX_STRING ); + if( completedname && length ) com.strncpy( completedname, matchbuf, length ); + if( numtables == 1 ) return true; + + for( i = 0; i < numtables; i++ ) + { + com.strncpy( matchbuf, tables[i], MAX_STRING ); + Msg("%16s\n", matchbuf ); + } + Msg( "\n^3 %i stringtables found.\n", numtables ); + + // cut shortestMatch to the amount common with s + if( completedname && length ) + { + for( i = 0; matchbuf[i]; i++ ) + { + if( com.tolower( completedname[i]) != com.tolower( matchbuf[i] )) + completedname[i] = 0; + } + } + return true; +} /* ===================================== @@ -428,7 +466,7 @@ bool Cmd_GetGamesList( const char *s, char *completedname, int length ) // compare gamelist with current keyword for( i = 0, numgamedirs = 0; i < GI->numgamedirs; i++ ) { - if(!com.strnicmp(GI->gamedirs[i], s, com.strlen(s))) + if(( *s == '*' ) || !com.strnicmp(GI->gamedirs[i], s, com.strlen( s ))) com.strcpy( gamedirs[numgamedirs++], GI->gamedirs[i] ); } @@ -551,6 +589,7 @@ autocomplete_list_t cmd_list[] = { "prvm_printfucntion", Cmd_GetProgsList }, { "prvm_edictcount", Cmd_GetProgsList }, { "prvm_globalset", Cmd_GetProgsList }, +{ "stringlist", Cmd_GetStringTablesList }, { "prvm_edictset", Cmd_GetProgsList }, { "prvm_profile", Cmd_GetProgsList }, { "prvm_globals", Cmd_GetProgsList }, diff --git a/engine/common/engfuncs.c b/engine/common/engfuncs.c index 63a7fb73..b59a8e61 100644 --- a/engine/common/engfuncs.c +++ b/engine/common/engfuncs.c @@ -1416,7 +1416,7 @@ void VM_getimagesize( void ) p = PRVM_G_STRING(OFS_PARM0); shader = re->RegisterShader( p, SHADER_NOMIP ); - re->DrawGetPicSize( &w, &h, 0, shader ); + re->GetParms( &w, &h, NULL, 0, shader ); VectorSet(PRVM_G_VECTOR(OFS_RETURN), w, h, 0 ); } diff --git a/engine/server/server.h b/engine/server/server.h index fb4a4b61..5905df8d 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -314,6 +314,7 @@ void SV_InitGame (void); void SV_Map( char *levelstring, char *savename ); void SV_SpawnServer( const char *server, const char *savename ); int SV_FindIndex (const char *name, int start, int end, bool create); +void SV_ClassifyEdict( edict_t *ent ); // // sv_phys.c diff --git a/engine/server/sv_frame.c b/engine/server/sv_frame.c index 309079a9..15603ae6 100644 --- a/engine/server/sv_frame.c +++ b/engine/server/sv_frame.c @@ -52,13 +52,15 @@ void SV_UpdateEntityState( edict_t *ent ) ent->pvServerData->s.number = ent->serialnumber; ent->pvServerData->s.solid = ent->pvServerData->solid; + if( !ent->pvServerData->s.classname ) + ent->pvServerData->s.classname = SV_ClassIndex( STRING( ent->v.classname )); + VectorCopy (ent->v.origin, ent->pvServerData->s.origin); VectorCopy (ent->v.angles, ent->pvServerData->s.angles); ent->pvServerData->s.model.index = ent->v.modelindex; ent->pvServerData->s.health = ent->v.health; ent->pvServerData->s.model.skin = ent->v.skin; // studio model skin ent->pvServerData->s.model.body = ent->v.body; // studio model submodel - ent->pvServerData->s.model.gaitsequence = ent->v.gaitsequence;// player sequence, that will be playing on client ent->pvServerData->s.effects = ent->v.effects; // shared client and render flags ent->pvServerData->s.renderfx = ent->v.renderfx; // renderer flags ent->pvServerData->s.rendermode = ent->v.rendermode; // rendering mode @@ -108,6 +110,8 @@ void SV_UpdateEntityState( edict_t *ent ) ent->pvServerData->s.aiment = NUM_FOR_EDICT( ent->v.aiment ); else ent->pvServerData->s.aiment = 0; + // playermodel sequence, that will be playing on a client + ent->pvServerData->s.model.gaitsequence = ent->v.gaitsequence; ent->pvServerData->s.weapons = ent->v.weapons; } else if( ent->pvServerData->s.ed_type == ED_AMBIENT ) @@ -280,6 +284,7 @@ static void SV_AddEntitiesToPacket( vec3_t origin, client_frame_t *frame, sv_ent { case ED_MOVER: case ED_NORMAL: + case ED_MONSTER: case ED_AMBIENT: case ED_BSPBRUSH: case ED_RIGIDBODY: break; diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 4659e427..473fecdb 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -12,31 +12,6 @@ #define EOFS( x ) (int)&(((entvars_t *)0)->x) -const char *ed_name[] = -{ - "unknown", - "world", - "static", - "ambient", - "normal", - "brush", - "player", - "monster", - "tempent", - "beam", - "mover", - "viewmodel", - "item", - "ragdoll", - "physbody", - "trigger", - "portal", - "missile", - "decal", - "vehicle", - "error", -}; - void Sys_FsGetString( file_t *f, char *str ) { char ch; @@ -667,8 +642,7 @@ void SV_InitEdict( edict_t *pEdict ) pEdict->v.pContainingEntity = pEdict; // make cross-links for consistency pEdict->pvServerData = (sv_priv_t *)Mem_Alloc( svgame.mempool, sizeof( sv_priv_t )); pEdict->pvPrivateData = NULL; // will be alloced later by pfnAllocPrivateData - pEdict->serialnumber = pEdict->pvServerData->s.number = NUM_FOR_EDICT( pEdict ); - pEdict->pvServerData->s.ed_type = ED_SPAWNED; + pEdict->serialnumber = NUM_FOR_EDICT( pEdict ); pEdict->free = false; } @@ -1346,13 +1320,12 @@ pfnFindEntityByString */ edict_t* pfnFindEntityByString( edict_t *pStartEdict, const char *pszField, const char *pszValue ) { - int e, f; + int f, e = 0; edict_t *ed; const char *t; - if( !pStartEdict ) e = 0; - else e = NUM_FOR_EDICT( pStartEdict ); - if( !pszValue || !*pszValue ) return pStartEdict; + if( pStartEdict ) e = NUM_FOR_EDICT( pStartEdict ); + if( !pszValue || !*pszValue ) return NULL; // FIXME: make table with hints if( !com.strcmp( pszField, "classname" )) @@ -1382,7 +1355,7 @@ edict_t* pfnFindEntityByString( edict_t *pStartEdict, const char *pszField, cons if( !com.strcmp( t, pszValue )) return ed; } - return EDICT_NUM( 0 ); + return NULL; } /* @@ -1593,18 +1566,31 @@ pfnCreateNamedEntity */ edict_t* pfnCreateNamedEntity( string_t className ) { - edict_t *ed; + edict_t *ent; const char *pszClassName; + LINK_ENTITY_FUNC SpawnEdict; pszClassName = STRING( className ); - ed = pfnCreateEntity(); - ed->v.classname = className; - pszClassName = STRING( className ); + ent = pfnCreateEntity(); + ent->v.classname = className; + + // allocate edict private memory (passed by dlls) + SpawnEdict = (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, pszClassName ); + if( !SpawnEdict ) + { + // attempt to create custom entity + if( svgame.dllFuncs.pfnCreate( ent, pszClassName ) == -1 ) + { + MsgDev( D_ERROR, "No spawn function for %s\n", pszClassName ); + return ent; // this edict needs to be alloced pvPrivateData + } + } + else SpawnEdict( &ent->v ); // also register classname to send for client - ed->pvServerData->s.classname = SV_ClassIndex( pszClassName ); + ent->pvServerData->s.classname = SV_ClassIndex( pszClassName ); - return ed; + return ent; } /* @@ -2286,7 +2272,7 @@ pfnWriteAngle void pfnWriteAngle( float flValue ) { _MSG_WriteBits( &sv.multicast, flValue, svgame.msg_name, NET_ANGLE, __FILE__, __LINE__ ); - svgame.msg_realsize += 4; + svgame.msg_realsize += 2; } /* @@ -2676,17 +2662,16 @@ classify edict for render and network usage */ void pfnClassifyEdict( edict_t *pEdict, int class ) { - if( pEdict->free ) + if( !pEdict || pEdict->free ) { MsgDev( D_ERROR, "SV_ClassifyEdict: can't modify free entity\n" ); return; } if( !pEdict->pvServerData ) return; - pEdict->pvServerData->s.ed_type = class; - // or leave unclassified, wait for next SV_LinkEdict... - Msg( "%s: <%s>\n", STRING( pEdict->v.classname ), ed_name[class] ); + pEdict->pvServerData->s.ed_type = class; + MsgDev( D_NOTE, "%s: <%s>\n", STRING( pEdict->v.classname ), ed_name[class] ); } /* diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 706fddff..73393aff 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -114,6 +114,13 @@ void SV_CreateBaseline( void ) svs.baselines[entnum] = svent->pvServerData->s; } + + // classify edicts for quick network sorting + for( entnum = 0; entnum < svgame.globals->numEntities; entnum++ ) + { + svent = EDICT_NUM( entnum ); + SV_ClassifyEdict( svent ); + } } /* diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index 4fd780fb..ea5bc279 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -39,6 +39,31 @@ typedef struct area_s int type; } area_t; +const char *ed_name[] = +{ + "unknown", + "world", + "static", + "ambient", + "normal", + "brush", + "player", + "monster", + "tempent", + "beam", + "mover", + "viewmodel", + "item", + "ragdoll", + "physbody", + "trigger", + "portal", + "missile", + "decal", + "vehicle", + "error", +}; + areanode_t sv_areanodes[AREA_NODES]; int sv_numareanodes; @@ -142,6 +167,78 @@ void SV_ClearWorld( void ) SV_CreateAreaNode( 0, world->mins, world->maxs ); } +/* +================= +SV_ClassifyEdict + +sorting edict by type +================= +*/ +void SV_ClassifyEdict( edict_t *ent ) +{ + sv_priv_t *sv_ent; + const char *classname; + + sv_ent = ent->pvServerData; + if( !sv_ent || sv_ent->s.ed_type != ED_SPAWNED ) + return; + + // update baseline for new entity + if( !sv_ent->s.number ) + { + // take current state as baseline + SV_UpdateEntityState( ent ); + svs.baselines[ent->serialnumber] = ent->pvServerData->s; + } + classname = STRING( ent->v.classname ); + + if( !com.strnicmp( "worldspawn", classname, 10 )) + { + sv_ent->s.ed_type = ED_WORLDSPAWN; + return; + } + // first pass: determine type by explicit parms + if( ent->v.solid == SOLID_TRIGGER ) + { + if( sv_ent->s.soundindex ) + sv_ent->s.ed_type = ED_AMBIENT; // e.g. trigger_teleport + else sv_ent->s.ed_type = ED_TRIGGER; // never sending to client + } + else if( ent->v.movetype == MOVETYPE_PHYSIC ) + sv_ent->s.ed_type = ED_RIGIDBODY; + else if( ent->v.solid == SOLID_BSP || VectorIsNull( ent->v.origin )) + { + if( ent->v.movetype == MOVETYPE_CONVEYOR ) + sv_ent->s.ed_type = ED_MOVER; + else if( ent->v.flags & FL_WORLDBRUSH ) + sv_ent->s.ed_type = ED_BSPBRUSH; + else if( ent->v.movetype == MOVETYPE_PUSH ) + sv_ent->s.ed_type = ED_MOVER; + else if( ent->v.movetype == MOVETYPE_NONE ) + sv_ent->s.ed_type = ED_BSPBRUSH; + } + else if( ent->v.flags & FL_MONSTER ) + sv_ent->s.ed_type = ED_MONSTER; + else if( ent->v.flags & FL_CLIENT ) + sv_ent->s.ed_type = ED_CLIENT; + else if( !sv_ent->s.model.index && !sv_ent->s.aiment ) + { + if( sv_ent->s.soundindex ) + sv_ent->s.ed_type = ED_AMBIENT; + else sv_ent->s.ed_type = ED_STATIC; // never sending to client + } + + if( sv_ent->s.ed_type == ED_SPAWNED ) + { + // mark as normal + if( sv_ent->s.model.index || sv_ent->s.soundindex ) + sv_ent->s.ed_type = ED_NORMAL; + } + + // or leave unclassified, wait for next SV_LinkEdict... + // Msg( "%s: <%s>\n", STRING( ent->v.classname ), ed_name[sv_ent->s.ed_type] ); +} + /* =============== SV_UnlinkEdict @@ -174,10 +271,15 @@ void SV_LinkEdict( edict_t *ent ) sv_ent = ent->pvServerData; + if( !sv_ent ) return; if( sv_ent->area.prev ) SV_UnlinkEdict( ent ); // unlink from old position if( ent == EDICT_NUM( 0 )) return; // don't add the world if( ent->free ) return; + // trying to classify unclassified edicts + if( sv.state == ss_active && sv_ent->s.ed_type == ED_SPAWNED ) + SV_ClassifyEdict( ent ); + // set the size VectorSubtract( ent->v.maxs, ent->v.mins, ent->v.size ); diff --git a/launch/imagelib/imagelib.h b/launch/imagelib/imagelib.h index a7f00ebf..3b43f730 100644 --- a/launch/imagelib/imagelib.h +++ b/launch/imagelib/imagelib.h @@ -485,7 +485,8 @@ enum LUMP_NORMAL = 0, LUMP_TRANSPARENT, LUMP_DECAL, - LUMP_QFONT + LUMP_QFONT, + LUMP_EXTENDED // bmp images have extened palette with alpha-channel }; extern imglib_t image; @@ -509,6 +510,7 @@ void Image_ConvertPalTo24bit( rgbdata_t *pic ); void Image_DecompressDDS( const byte *buffer, uint target ); void Image_GetPaletteLMP( const byte *pal, int rendermode ); void Image_GetPalettePCX( const byte *pal ); +void Image_GetPaletteBMP( const byte *pal ); void Image_CopyPalette24bit( void ); void Image_CopyPalette32bit( void ); bool Image_ForceDecompress( void ); diff --git a/launch/imagelib/img_bmp.c b/launch/imagelib/img_bmp.c index 87eab1bc..56ba5048 100644 --- a/launch/imagelib/img_bmp.c +++ b/launch/imagelib/img_bmp.c @@ -128,6 +128,7 @@ bool Image_LoadBMP( const char *name, const byte *buffer, size_t filesize ) pb += biTrueWidth; image.num_layers = image.num_mips = 1; image.type = PF_INDEXED_32; // 32 bit palette + Image_GetPaletteBMP( image.palette ); // scan for transparency for( i = 0; i < image.width * image.height; i++ ) diff --git a/launch/imagelib/img_utils.c b/launch/imagelib/img_utils.c index 6d760201..4ede77a6 100644 --- a/launch/imagelib/img_utils.c +++ b/launch/imagelib/img_utils.c @@ -442,6 +442,16 @@ void Image_SetPalette( const byte *pal, uint *d_table ) d_table[i] = BuffBigLong( rgba ); } break; + case LUMP_EXTENDED: + for (i = 0; i < 256; i++) + { + rgba[3] = pal[i*4+0]; + rgba[2] = pal[i*4+1]; + rgba[1] = pal[i*4+2]; + rgba[0] = pal[i*4+3]; + d_table[i] = BuffBigLong( rgba ); + } + break; } } @@ -504,6 +514,17 @@ void Image_GetPalettePCX( const byte *pal ) else Image_GetPaletteQ2(); } +void Image_GetPaletteBMP( const byte *pal ) +{ + image.d_rendermode = LUMP_EXTENDED; + + if( pal ) + { + Image_SetPalette( pal, d_8to24table ); + image.d_currentpal = d_8to24table; + } +} + void Image_GetPaletteLMP( const byte *pal, int rendermode ) { image.d_rendermode = rendermode; diff --git a/launch/launch.h b/launch/launch.h index 258e405f..d80d5aa6 100644 --- a/launch/launch.h +++ b/launch/launch.h @@ -509,6 +509,7 @@ string_t StringTable_SetString( int handle, const char *string ); const char *StringTable_GetString( int handle, string_t index ); int StringTable_LoadSystem( wfile_t *wad, const char *name ); bool StringTable_SaveSystem( int h, wfile_t *wad ); +const char *StringTable_GetName( int handle ); void StringTable_DeleteSystem( int handle ); void StringTable_ClearSystem( int handle ); void StringTable_Info_f( void ); diff --git a/launch/memlib.c b/launch/memlib.c index 4adb8ae0..937535e4 100644 --- a/launch/memlib.c +++ b/launch/memlib.c @@ -1459,5 +1459,5 @@ void Memory_Shutdown( void ) void Memory_Init_Commands( void ) { Cmd_AddCommand( "memlist", MemList_f, "prints memory pool information (or if used as memlist 5 lists individual allocations of 5K or larger, 0 lists all allocations)"); - Cmd_AddCommand( "stinfo", StringTable_Info_f, "prints StringTable system names or contained strings" ); + Cmd_AddCommand( "stringlist", StringTable_Info_f, "prints all known strings for selected StringTable" ); } \ No newline at end of file diff --git a/launch/system.c b/launch/system.c index 26292b22..f50d16a8 100644 --- a/launch/system.c +++ b/launch/system.c @@ -252,6 +252,7 @@ void Sys_GetStdAPI( void ) com.st_getstring = StringTable_GetString; com.st_setstring = StringTable_SetString; com.st_load = StringTable_LoadSystem; + com.st_getname = StringTable_GetName; com.st_save = StringTable_SaveSystem; com.st_clear = StringTable_ClearSystem; com.st_remove = StringTable_DeleteSystem; diff --git a/launch/utils.c b/launch/utils.c index 534172d8..f65e9ec9 100644 --- a/launch/utils.c +++ b/launch/utils.c @@ -223,8 +223,8 @@ float sse_sqrt( float x ) return root; } - -#define MAX_STRINGTABLE_SYSTEMS 8 // seperately stringsystems +#define ST_STATIC_ALLOCATE // comment this to use realloc +// (all pointers to real strings will be invalid after another calling SetString, but it - memory economy mode ) typedef struct stringtable_s { @@ -239,18 +239,20 @@ typedef struct stringtable_s size_t maxstrings; // current system limit } stringtable_t; -stringtable_t *dstring[MAX_STRINGTABLE_SYSTEMS]; +stringtable_t *dstring[MAX_STRING_TABLES]; -bool StringTable_CheckHandle( int handle ) +bool StringTable_CheckHandle( int handle, bool silent ) { - if( handle < 0 || handle > MAX_STRINGTABLE_SYSTEMS ) + if( handle < 0 || handle > MAX_STRING_TABLES ) { - MsgDev( D_ERROR, "StringTable_CheckHandle: invalid system handle %d\n", handle ); + if( !silent ) + MsgDev( D_ERROR, "StringTable_CheckHandle: invalid system handle %d\n", handle ); return false; } if( !dstring[handle] ) { - MsgDev( D_ERROR, "StringTable_CheckHandle: system with handle %d inactive\n", handle ); + if( !silent ) + MsgDev( D_ERROR, "StringTable_CheckHandle: system with handle %d inactive\n", handle ); return false; } return true; @@ -258,7 +260,7 @@ bool StringTable_CheckHandle( int handle ) bool StringTable_CheckString( int handle, string_t str ) { - if(!StringTable_CheckHandle( handle )) + if(!StringTable_CheckHandle( handle, true )) return false; if( str < 0 || str >= dstring[handle]->numstrings ) @@ -269,12 +271,19 @@ bool StringTable_CheckString( int handle, string_t str ) return true; } +const char *StringTable_GetName( int handle ) +{ + if( !StringTable_CheckHandle( handle, true )) + return NULL; + return dstring[handle]->name; +} + int StringTable_CreateNewSystem( const char *name, size_t max_strings ) { int i; // fisrt, find free stringtable system - for( i = 0; i < MAX_STRINGTABLE_SYSTEMS; i++ ) + for( i = 0; i < MAX_STRING_TABLES; i++ ) { if( !dstring[i] ) { @@ -282,7 +291,13 @@ int StringTable_CreateNewSystem( const char *name, size_t max_strings ) dstring[i] = Mem_Alloc( Sys.basepool, sizeof( stringtable_t )); dstring[i]->mempool = Mem_AllocPool( va( "StringTable_%s", name )); com.strncpy( dstring[i]->name, name, MAX_STRING ); + dstring[i]->maxdatasize = max_strings * 8; dstring[i]->maxstrings = max_strings; +#ifdef ST_STATIC_ALLOCATE + // create static arrays + dstring[i]->data = (char *)Mem_Alloc( dstring[i]->mempool, dstring[i]->maxdatasize ); + dstring[i]->table = (int *)Mem_Alloc( dstring[i]->mempool, dstring[i]->maxstrings ); +#endif StringTable_SetString( i, "" ); // make iNullString return i; @@ -295,7 +310,7 @@ int StringTable_CreateNewSystem( const char *name, size_t max_strings ) void StringTable_DeleteSystem( int handle ) { - if( !StringTable_CheckHandle( handle )) + if( !StringTable_CheckHandle( handle, false )) return; // now free stringtable @@ -306,14 +321,18 @@ void StringTable_DeleteSystem( int handle ) void StringTable_ClearSystem( int handle ) { - if( !StringTable_CheckHandle( handle )) + if( !StringTable_CheckHandle( handle, false )) return; Mem_EmptyPool( dstring[handle]->mempool ); dstring[handle]->datasize = dstring[handle]->numstrings = 0; +#ifdef ST_STATIC_ALLOCATE + dstring[handle]->data = (char *)Mem_Alloc( dstring[handle]->mempool, dstring[handle]->maxdatasize ); + dstring[handle]->table = (int *)Mem_Alloc( dstring[handle]->mempool, dstring[handle]->maxstrings ); +#else dstring[handle]->table = NULL; dstring[handle]->data = NULL; - +#endif StringTable_SetString( handle, "" ); // make iNullString } @@ -327,7 +346,7 @@ string_t StringTable_SetString( int handle, const char *string ) { int i, len, table_size, data_size; - if( !StringTable_CheckHandle( handle )) + if( !StringTable_CheckHandle( handle, false )) return -1; for( i = 0; i < dstring[handle]->numstrings; i++ ) @@ -341,15 +360,15 @@ string_t StringTable_SetString( int handle, const char *string ) table_size = sizeof(string_t) * (dstring[handle]->numstrings + 1); data_size = dstring[handle]->datasize + len + 1; - if( table_size >= dstring[handle]->maxstrings ) + if( table_size >= dstring[handle]->maxstrings || data_size >= dstring[handle]->maxdatasize ) { MsgDev( D_ERROR, "StringTable_SetString: string table %s limit exeeded\n", dstring[handle]->name ); return -1; } - +#ifndef ST_STATIC_ALLOCATE dstring[handle]->table = Mem_Realloc( dstring[handle]->mempool, dstring[handle]->table, table_size ); dstring[handle]->data = Mem_Realloc( dstring[handle]->mempool, dstring[handle]->data, data_size ); - +#endif com.strcpy( &dstring[handle]->data[dstring[handle]->datasize], string ); dstring[handle]->table[dstring[handle]->numstrings] = dstring[handle]->datasize; dstring[handle]->datasize += len + 1; // null terminator @@ -362,7 +381,7 @@ bool StringTable_SaveSystem( int h, wfile_t *wad ) { int table_size; - if(!StringTable_CheckHandle( h )) + if(!StringTable_CheckHandle( h, false )) return false; if(!W_SaveLump( wad, "stringdata", dstring[h]->data, dstring[h]->datasize, TYPE_STRDATA, CMP_ZLIB )) return false; @@ -390,33 +409,24 @@ void StringTable_Info_f( void ) { int i, j; - switch(Cmd_Argc( )) + if( Cmd_Argc() != 2 ) { - case 1: - // display list of all actuve StringTable Systems - for( i = 0; i < MAX_STRINGTABLE_SYSTEMS; i++ ) - { - if( dstring[i] ) Msg( "%s\n", dstring[i]->name ); - } - break; - case 2: - // print all symbols in selected StringTable - for( i = 0; i < MAX_STRINGTABLE_SYSTEMS; i++ ) - { - if( dstring[i] ) - { - if( !com.stricmp( dstring[i]->name, Cmd_Argv( 1 ))) - { - for( j = 0; j < dstring[i]->numstrings; j++ ) - Msg( "%s ", StringTable_GetString( i, j )); - Msg( "\n" ); - break; - } - } - } - break; - default: Msg( "Usage: stinfo \n" ); - break; + return; + } + + // print all strings in selected StringTable + for( i = 0; i < MAX_STRING_TABLES; i++ ) + { + if( !dstring[i] ) continue; + + if( !com.stricmp( dstring[i]->name, Cmd_Argv( 1 ))) + { + Msg( "------------- %i strings -------------\n", dstring[i]->numstrings ); + for( j = 0; j < dstring[i]->numstrings; j++ ) + Msg( "%s ", StringTable_GetString( i, j )); + Msg( "\n ^3total %s used\n", com_pretifymem( dstring[i]->datasize, 3 )); + break; + } } } \ No newline at end of file diff --git a/public/clgame_api.h b/public/clgame_api.h index 50c693f7..e05073f0 100644 --- a/public/clgame_api.h +++ b/public/clgame_api.h @@ -160,7 +160,6 @@ typedef struct cl_enginefuncs_s // screen handlers HSPRITE (*pfnLoadShader)( const char *szShaderName ); void (*pfnFillRGBA)( int x, int y, int width, int height, const float *color, float alpha ); - void (*pfnDrawImage)( HSPRITE shader, int x, int y, int width, int height ); void (*pfnDrawImageExt)( HSPRITE shader, int x, int y, int w, int h, float s1, float t1, float s2, float t2 ); void (*pfnSetColor)( float r, float g, float b, float a ); @@ -193,7 +192,7 @@ typedef struct cl_enginefuncs_s void (*pfnCenterPrint)( const char *text, int y, int charWidth ); int (*pfnDrawCharacter)( int x, int y, int width, int height, int number ); void (*pfnDrawString)( int x, int y, int width, int height, const char *text ); - void (*pfnGetImageSize)( int *w, int *h, int frame, shader_t shader ); + void (*pfnGetParms)( int *w, int *h, int *frames, int frame, shader_t shader ); void (*pfnSetParms)( shader_t handle, kRenderMode_t rendermode, int frame ); // local client handlers diff --git a/public/launch_api.h b/public/launch_api.h index 91b430af..5482b3a4 100644 --- a/public/launch_api.h +++ b/public/launch_api.h @@ -19,7 +19,7 @@ #define IsColorString(p) ( p && *(p) == STRING_COLOR_TAG && *((p)+1) && *((p)+1) != STRING_COLOR_TAG ) #define bound(min, num, max) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min)) #define DLLEXPORT __declspec( dllexport ) - +#define MAX_STRING_TABLES 8 // seperately stringsystems #ifndef __cplusplus #define bool BOOL // sizeof( int ) #endif @@ -634,6 +634,7 @@ typedef struct stdilib_api_s const char *(*st_getstring)( int handle, string_t index ); string_t (*st_setstring)( int handle, const char *string ); int (*st_load)( wfile_t *wad, const char *name ); + const char *(*st_getname)( int handle ); bool (*st_save)( int h, wfile_t *wad ); void (*st_clear)( int handle ); void (*st_remove)( int handle ); @@ -896,6 +897,7 @@ misc utils #define StringTable_Clear com.st_clear #define StringTable_GetString com.st_getstring #define StringTable_SetString com.st_setstring +#define StringTable_GetName com.st_getname #define StringTable_Load com.st_load #define StringTable_Save com.st_save #define Com_Assert( x ) if( x ) com.abort( "assert failed at %s:%i\n", __FILE__, __LINE__ ); diff --git a/public/render_api.h b/public/render_api.h index 6b681928..24bd1d2e 100644 --- a/public/render_api.h +++ b/public/render_api.h @@ -59,6 +59,7 @@ typedef struct render_exp_s // misc utilities void (*SetColor)( const float *rgba ); void (*SetParms)( shader_t handle, kRenderMode_t rendermode, int frame ); + void (*GetParms)( int *w, int *h, int *frames, int frame, shader_t shader ); bool (*ScrShot)( const char *filename, int shot_type ); // write screenshot with same name bool (*EnvShot)( const char *filename, uint size, bool skyshot ); // write envshot with same name void (*LightForPoint)( const vec3_t point, vec3_t ambientLight ); @@ -66,7 +67,6 @@ typedef struct render_exp_s void (*DrawStretchRaw)( int x, int y, int w, int h, int cols, int rows, byte *data, bool redraw ); void (*DrawStretchPic)( float x, float y, float w, float h, float s1, float t1, float s2, float t2, shader_t shader ); void (*ImpactMark)( vec3_t org, vec3_t dir, float rot, float radius, vec4_t mod, bool fade, shader_t s, bool tmp ); - void (*DrawGetPicSize)( int *w, int *h, int frame, shader_t shader ); } render_exp_t; diff --git a/render/r_draw.c b/render/r_draw.c index 9626e538..91be8557 100644 --- a/render/r_draw.c +++ b/render/r_draw.c @@ -12,16 +12,17 @@ R_GetPicSize this is needed by some client drawing functions ================= */ -void R_GetPicSize( int *w, int *h, int frame, shader_t handle ) +void R_DrawGetParms( int *w, int *h, int *f, int frame, shader_t handle ) { ref_shader_t *shader; int cur = 0; - if( !w && !h ) return; + if( !w && !h && !f ) return; // assume error if( w ) *w = 0; if( h ) *h = 0; + if( f ) *f = 1; if( handle < 0 || handle > MAX_SHADERS || !(shader = &r_shaders[handle])) return; @@ -34,6 +35,7 @@ void R_GetPicSize( int *w, int *h, int frame, shader_t handle ) if( w ) *w = (int)shader->stages[0]->bundles[0]->textures[cur]->srcWidth; if( h ) *h = (int)shader->stages[0]->bundles[0]->textures[cur]->srcHeight; + if( f ) *f = (int)shader->stages[0]->bundles[0]->numTextures; } /* @@ -60,8 +62,8 @@ void R_DrawSetParms( shader_t handle, kRenderMode_t rendermode, int frame ) break; case kRenderTransColor: shader->stages[0]->flags |= SHADERSTAGE_BLENDFUNC; - shader->stages[0]->blendFunc.src = GL_SRC_COLOR; - shader->stages[0]->blendFunc.dst = GL_ZERO; + shader->stages[0]->blendFunc.src = GL_ZERO; + shader->stages[0]->blendFunc.dst = GL_SRC_COLOR; break; case kRenderTransTexture: shader->stages[0]->flags |= SHADERSTAGE_BLENDFUNC; diff --git a/render/r_local.h b/render/r_local.h index c2779efa..f6cc33f6 100644 --- a/render/r_local.h +++ b/render/r_local.h @@ -568,7 +568,6 @@ typedef struct ref_entity_s float rotation; // what the hell ??? } ref_entity_t; -const char *R_GetStringFromTable( int index ); leaf_t *R_PointInLeaf( const vec3_t p ); byte *R_ClusterPVS( int cluster ); @@ -577,6 +576,7 @@ void R_StudioInit( void ); void R_StudioShutdown( void ); bool R_StudioComputeBBox( vec3_t bbox[8] ); // for drawing bounds void R_StudioResetSequenceInfo( ref_entity_t *ent, dstudiohdr_t *hdr ); +float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval ); void R_StudioSetupModel( int body, int bodypart ); void R_InitModels( void ); void R_ShutdownModels( void ); @@ -825,7 +825,7 @@ void R_DrawFill( float x, float y, float w, float h ); void R_DrawSetParms( shader_t handle, kRenderMode_t rendermode, int frame ); void R_DrawStretchRaw( int x, int y, int w, int h, int width, int height, const byte *raw, bool dirty ); void R_DrawStretchPic( float x, float y, float w, float h, float sl, float tl, float sh, float th, shader_t shader ); -void R_GetPicSize( int *w, int *h, int frame, shader_t shader ); +void R_DrawGetParms( int *w, int *h, int *f, int frame, shader_t shader ); // r_utils.c (test) void MatrixGL_MultiplyFast (const gl_matrix m1, const gl_matrix m2, gl_matrix out); // FIXME: remove diff --git a/render/r_main.c b/render/r_main.c index 3c6fb4bd..ce2d8f85 100644 --- a/render/r_main.c +++ b/render/r_main.c @@ -316,6 +316,7 @@ static void R_AddEntitiesToList( void ) case ED_MOVER: case ED_NORMAL: case ED_CLIENT: + case ED_MONSTER: case ED_BSPBRUSH: case ED_VIEWMODEL: case ED_RIGIDBODY: @@ -1037,6 +1038,7 @@ static bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, float lerpfrac case ED_MOVER: case ED_CLIENT: case ED_NORMAL: + case ED_MONSTER: case ED_BSPBRUSH: case ED_RIGIDBODY: case ED_VIEWMODEL: break; @@ -1052,11 +1054,31 @@ static bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, float lerpfrac refent->body = pRefEntity->v.body; refent->scale = pRefEntity->v.scale; refent->colormap = pRefEntity->v.colormap; - refent->framerate = pRefEntity->v.framerate; refent->effects = pRefEntity->v.effects; if( VectorIsNull( pRefEntity->v.rendercolor )) VectorSet( refent->rendercolor, 1.0f, 1.0f, 1.0f ); else VectorDivide( pRefEntity->v.rendercolor, 255.0f, refent->rendercolor ); + refent->model = cl_models[pRefEntity->v.modelindex]; + refent->movetype = pRefEntity->v.movetype; + refent->framerate = pRefEntity->v.framerate; + refent->prev.sequencetime = refent->animtime - refent->prev.animtime; + + // check model + if( !refent->model ) return false; + switch( refent->model->type ) + { + case mod_brush: break; + case mod_studio: + if( !refent->model->phdr ) + return false; + break; + case mod_sprite: + if( !refent->model->extradata ) + return false; + break; + case mod_bad: // let the render drawing null model + break; + } // setup latchedvars VectorCopy( pRefEntity->v.oldorigin, refent->prev.origin ); @@ -1066,43 +1088,54 @@ static bool R_AddEntityToScene( edict_t *pRefEntity, int ed_type, float lerpfrac for( i = 0; i < 3; i++ ) refent->origin[i] = LerpPoint( pRefEntity->v.oldorigin[i], pRefEntity->v.origin[i], lerpfrac ); - if( ed_type != ED_VIEWMODEL ) - { - refent->frame = pRefEntity->v.frame; - refent->movetype = pRefEntity->v.movetype; - refent->sequence = pRefEntity->v.sequence; - refent->animtime = pRefEntity->v.animtime; + refent->skin = pRefEntity->v.skin; + refent->renderfx = pRefEntity->v.renderfx; - /* FIXME - refent->prev.animtime = pRefEntity->v.animtime; - refent->prev.sequencetime = pRefEntity->v.animtime - s2->model.animtime; - refent->prev.frame = s2->v.frame; - refent->prev.sequence = s2->model.sequence; - */ - } + // do animate + if( refent->effects & EF_ANIMATE ) + { + switch( refent->model->type ) + { + case mod_studio: + if( pRefEntity->v.frame == -1 ) + { + pRefEntity->v.frame = refent->frame = 0; + refent->sequence = pRefEntity->v.sequence; + R_StudioResetSequenceInfo( refent, refent->model->phdr ); + } + else + { + R_StudioFrameAdvance( refent, 0 ); + + if( refent->m_fSequenceFinished ) + { + if( refent->m_fSequenceLoops ) + pRefEntity->v.frame = -1; + // hold at last frame + } + else + { + // copy current frame back to let user grab it on a client-side + pRefEntity->v.frame = refent->frame; + } + } + break; + case mod_sprite: + case mod_brush: + break; + } + } else { - if( !refent->model || !refent->model->phdr ) - return false; - - // update sequence only if finished or not equal current - if( pRefEntity->v.effects & EF_ANIMATE ) - { - Msg("SetSequence: %i\n", pRefEntity->v.sequence ); - refent->sequence = pRefEntity->v.sequence; - R_StudioResetSequenceInfo( refent, refent->model->phdr ); - pRefEntity->v.effects &= ~EF_ANIMATE; - } + refent->prev.frame = refent->frame; + refent->frame = pRefEntity->v.frame; + refent->prev.sequence = refent->sequence; + refent->prev.animtime = refent->animtime; + refent->animtime = pRefEntity->v.animtime; + refent->sequence = pRefEntity->v.sequence; } - // set skin - refent->skin = pRefEntity->v.skin; - refent->model = cl_models[pRefEntity->v.modelindex]; - refent->renderfx = pRefEntity->v.renderfx; - - // FIXME: - // refent->weaponmodel = cl_models[pRefEntity->v.modelindex]; - + refent->weaponmodel = cl_models[pRefEntity->v.weaponmodel]; if( refent->ent_type == ED_MOVER || refent->ent_type == ED_BSPBRUSH ) { @@ -1475,6 +1508,7 @@ render_exp_t DLLEXPORT *CreateAPI(stdlib_api_t *input, render_imp_t *engfuncs ) re.EndFrame = R_EndFrame; re.SetColor = GL_SetColor; + re.GetParms = R_DrawGetParms; re.SetParms = R_DrawSetParms; re.ScrShot = VID_ScreenShot; re.EnvShot = VID_CubemapShot; @@ -1484,8 +1518,5 @@ render_exp_t DLLEXPORT *CreateAPI(stdlib_api_t *input, render_imp_t *engfuncs ) re.DrawStretchPic = R_DrawStretchPic; re.ImpactMark = R_ImpactMark; - // get rid of this - re.DrawGetPicSize = R_GetPicSize; - return &re; } \ No newline at end of file diff --git a/render/r_model.c b/render/r_model.c index 5bc16623..5a937a2c 100644 --- a/render/r_model.c +++ b/render/r_model.c @@ -1166,6 +1166,8 @@ rmodel_t *Mod_ForName( const char *name, bool crash ) FS_Read( file, &hdr, sizeof( uint )); FS_Close( file ); + MsgDev( D_LOAD, "%s\n", mod->name ); + // call the apropriate loader switch( LittleLong( hdr )) { @@ -1297,7 +1299,7 @@ void R_ModelList_f( void ) Msg( "\n" ); Msg( "-----------------------------------\n" ); - for( i = 0; i < r_nummodels, mod = r_models; i++, mod++ ) + for( i = 0, mod = r_models; i < r_nummodels; i++, mod++ ) { if( !mod->name[0] ) continue; // free slot Msg( "%s%s\n", mod->name, (mod->type == mod_bad) ? " (DEFAULTED)" : "" ); diff --git a/render/r_studio.c b/render/r_studio.c index 78052fa3..8cf6490f 100644 --- a/render/r_studio.c +++ b/render/r_studio.c @@ -308,35 +308,15 @@ R_StudioGetSequenceInfo used for client animation ==================== */ -void R_StudioGetSequenceInfo( dstudiohdr_t *hdr, ref_entity_t *ent, float *pflFrameRate, float *pflGroundSpeed ) +float R_StudioSequenceDuration( dstudiohdr_t *hdr, ref_entity_t *ent ) { dstudioseqdesc_t *pseqdesc; - if( !hdr ) return; - - if( ent->sequence >= hdr->numseq ) - { - if( pflFrameRate ) *pflFrameRate = 0.0; - if( pflGroundSpeed ) *pflGroundSpeed = 0.0; - return; - } + if( !hdr || ent->sequence >= hdr->numseq ) + return 0.0f; pseqdesc = (dstudioseqdesc_t *)((byte *)hdr + hdr->seqindex) + ent->sequence; - - if( pseqdesc->numframes > 1 ) - { - if( pflFrameRate ) *pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1); - if( pflGroundSpeed ) - { - *pflGroundSpeed = VectorLength( pseqdesc->linearmovement ); - *pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1); - } - } - else - { - if( pflFrameRate ) *pflFrameRate = 256.0; - if( pflGroundSpeed ) *pflGroundSpeed = 0.0; - } + return pseqdesc->numframes / pseqdesc->fps; } int R_StudioGetSequenceFlags( dstudiohdr_t *hdr, ref_entity_t *ent ) @@ -350,7 +330,7 @@ int R_StudioGetSequenceFlags( dstudiohdr_t *hdr, ref_entity_t *ent ) return pseqdesc->flags; } -float R_StudioFrameAdvance( ref_entity_t *ent, float framerate, float flInterval ) +float R_StudioFrameAdvance( ref_entity_t *ent, float flInterval ) { if( flInterval == 0.0 ) { @@ -363,8 +343,8 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float framerate, float flInterval } if( !ent->animtime ) flInterval = 0.0; - ent->frame += flInterval * framerate * ent->framerate; - ent->animtime = r_refdef.time; + ent->frame += flInterval * ent->framerate; + //ent->animtime = r_refdef.time; if( ent->frame < 0.0 || ent->frame >= 256.0 ) { @@ -378,16 +358,14 @@ float R_StudioFrameAdvance( ref_entity_t *ent, float framerate, float flInterval void R_StudioResetSequenceInfo( ref_entity_t *ent, dstudiohdr_t *hdr ) { - float m_flFrameRate; - if( !ent || !hdr ) return; - R_StudioGetSequenceInfo( hdr, ent, &m_flFrameRate, NULL ); ent->m_fSequenceLoops = ((R_StudioGetSequenceFlags( hdr, ent ) & STUDIO_LOOPING) != 0 ); - // if custom framerate not specified, use default value from studiomodel - ent->framerate = m_flFrameRate; - ent->animtime = r_refdef.time; + // calc anim time + if( !ent->animtime ) ent->animtime = r_refdef.time; + ent->prev.animtime = ent->animtime; + ent->animtime = r_refdef.time + R_StudioSequenceDuration( hdr, ent ); ent->m_fSequenceFinished = FALSE; } @@ -891,9 +869,9 @@ float R_StudioEstimateFrame( dstudioseqdesc_t *pseqdesc ) { double dfdt, f; - if ( m_fDoInterp ) + if( m_fDoInterp ) { - if ( r_refdef.time < m_pCurrentEntity->animtime ) dfdt = 0; + if( r_refdef.time < m_pCurrentEntity->animtime ) dfdt = 0; else dfdt = (r_refdef.time - m_pCurrentEntity->animtime) * m_pCurrentEntity->framerate * pseqdesc->fps; } else dfdt = 0; @@ -1732,7 +1710,7 @@ void R_StudioSetupRender( int passnum ) m_pvlightvalues = &g_lightvalues[0]; // misc info - m_fDoInterp = r_interpolate->integer; + m_fDoInterp = (m_pCurrentEntity->effects & EF_NOINTERP) ? false : true; m_PassNum = passnum; } @@ -1751,13 +1729,6 @@ bool R_StudioDrawModel( int pass, int flags ) { if( /*mirror_render ||*/ r_lefthand->value == 2 ) return 0; - - // viewmodel animate on client - //if( !m_pCurrentEntity->m_fSequenceFinished ) - R_StudioFrameAdvance( m_pCurrentEntity, 1.0f, 0 ); - - //if( m_pCurrentEntity->m_fSequenceFinished && m_pCurrentEntity->m_fSequenceLoops ) - // R_StudioResetSequenceInfo( m_pCurrentEntity, m_pStudioHeader ); } R_StudioSetupRender( pass ); diff --git a/server/ents/baseentity.h b/server/ents/baseentity.h index 451a5270..4e6cd175 100644 --- a/server/ents/baseentity.h +++ b/server/ents/baseentity.h @@ -130,9 +130,8 @@ public: } else if( pev->solid == SOLID_TRIGGER ) { - if( pev->modelindex == 0 ) - SetObjectClass( ED_TRIGGER ); // never sending to client - else SetObjectClass( ED_NORMAL ); + if( pev->ambient ) SetObjectClass( ED_NORMAL ); + else SetObjectClass( ED_TRIGGER ); // never sending to client } else if( pev->movetype == MOVETYPE_PHYSIC ) { @@ -155,8 +154,7 @@ public: SetObjectClass( ED_CLIENT ); else if( !pev->modelindex && !pev->weaponmodel ) { - if( pev->noise1 || pev->noise2 || pev->noise3 ) - SetObjectClass( ED_AMBIENT ); + if( pev->ambient ) SetObjectClass( ED_AMBIENT ); else SetObjectClass( ED_STATIC ); // never sending to client } @@ -164,7 +162,7 @@ public: if( m_iClassType == ED_SPAWNED ) { // mark as normal - if( pev->modelindex || pev->noise1 || pev->noise2 || pev->noise3 ) + if( pev->modelindex || pev->ambient ) SetObjectClass( ED_NORMAL ); } } diff --git a/server/ents/basefx.cpp b/server/ents/basefx.cpp index 62365867..963804ca 100644 --- a/server/ents/basefx.cpp +++ b/server/ents/basefx.cpp @@ -357,7 +357,7 @@ void CFade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType //======================================================================= class CEnvZoom : public CBaseLogic { - void Spawn (void ){ if(!pev->button) pev->button = CVAR_GET_FLOAT( "default_fov" ); } + void Spawn (void ){ if( !pev->frags ) pev->frags = CVAR_GET_FLOAT( "default_fov" ); } void EXPORT Think( void ); void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); void KeyValue( KeyValueData* pkvd ); @@ -368,14 +368,14 @@ LINK_ENTITY_TO_CLASS( env_zoom, CEnvZoom ); void CEnvZoom::KeyValue( KeyValueData* pkvd ) { - if (FStrEq(pkvd->szKeyName, "duration")) + if( FStrEq( pkvd->szKeyName, "duration" )) { - pev->takedamage = atof(pkvd->szValue); + pev->takedamage = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } - else if (FStrEq(pkvd->szKeyName, "fov")) + else if ( FStrEq( pkvd->szKeyName, "fov" )) { - pev->button = atoi(pkvd->szValue); + pev->frags = atof( pkvd->szValue ); pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue( pkvd ); @@ -383,64 +383,67 @@ void CEnvZoom::KeyValue( KeyValueData* pkvd ) void CEnvZoom::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { - if ( !pActivator || !pActivator->IsPlayer()) pActivator = UTIL_PlayerByIndex( 1 ); - m_hActivator = pActivator; //save activator + if( !pActivator || !pActivator->IsPlayer()) + pActivator = UTIL_PlayerByIndex( 1 ); + m_hActivator = pActivator; // save activator - if (m_iState == STATE_ON) return; - if (useType == USE_TOGGLE || useType == USE_ON) SetFadeTime(); - else if (useType == USE_OFF)((CBasePlayer *)pActivator)->m_iFOV = CVAR_GET_FLOAT( "default_fov" ); - else if (useType == USE_SHOWINFO) + if( m_iState == STATE_ON ) return; + if( useType == USE_TOGGLE || useType == USE_ON ) SetFadeTime(); + else if( useType == USE_OFF ) + ((CBasePlayer *)pActivator)->m_flFOV = CVAR_GET_FLOAT( "default_fov" ); + else if( useType == USE_SHOWINFO ) { DEBUGHEAD; - Msg("State: %s, Fade time %.00f\n", GetStringForState( GetState()), pev->takedamage); - Msg("Current FOV: %d, Final FOV: %d\n", ((CBasePlayer *)pActivator)->m_iFOV, pev->button); + ALERT( at_console, "State: %s, Fade time %.00f\n", GetStringForState( GetState()), pev->takedamage ); + ALERT( at_console, "Current FOV: %g, Final FOV: %g\n", ((CBasePlayer *)pActivator)->m_flFOV, pev->button ); } } void CEnvZoom::SetFadeTime( void ) { - int CurFOV; - int Length; + float CurFOV; + float Length; - if( pev->takedamage == 0) //instant apply fov + if( pev->takedamage == 0 ) // instant apply fov { - ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_iFOV = pev->button; + ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV = pev->frags; return; } else { - CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_iFOV; - if(CurFOV == 0) CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_iFOV = CVAR_GET_FLOAT( "default_fov" ); + CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV; + if( CurFOV == 0.0f ) + CurFOV = ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV = CVAR_GET_FLOAT( "default_fov" ); - if(CurFOV > pev->button) Length = CurFOV - pev->button; - else if (CurFOV < pev->button) + if( CurFOV > pev->frags ) Length = CurFOV - pev->frags; + else if( CurFOV < pev->frags ) { - Length = pev->button - CurFOV; - pev->body = 1;//increment fov + Length = pev->frags - CurFOV; + pev->body = 1; // increment fov } - else return;//no change + else return; // no change pev->health = pev->takedamage / Length; SetNextThink ( pev->health ); } } -void CEnvZoom::Think ( void ) +void CEnvZoom::Think( void ) { - if( ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_iFOV == pev->button ) + if( Q_rint(((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV ) == Q_rint( pev->frags )) { - //calculate fov is over + // time is expired SetThink( NULL ); DontThink(); m_iState = STATE_OFF; - //fire target after finished //transfer fov - UTIL_FireTargets( pev->target, m_hActivator, this, USE_TOGGLE, pev->button ); + // fire target after finished // transmit final fov + UTIL_FireTargets( pev->target, m_hActivator, this, USE_TOGGLE, pev->frags ); return; } else { - if(pev->body ) ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_iFOV++; - else ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_iFOV--; + if( pev->body ) ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV += gpGlobals->frametime; + else ((CBasePlayer *)(CBaseEntity *)m_hActivator)->m_flFOV -= gpGlobals->frametime; } m_iState = STATE_ON; SetNextThink ( pev->health ); diff --git a/server/ents/baseitem.cpp b/server/ents/baseitem.cpp index b614e932..54cd788a 100644 --- a/server/ents/baseitem.cpp +++ b/server/ents/baseitem.cpp @@ -28,6 +28,7 @@ void CItem::Spawn( void ) UTIL_SetOrigin( this, pev->origin ); UTIL_SetSize(pev, g_vecZero, g_vecZero ); + SetObjectClass( ED_NORMAL ); SetTouch( ItemTouch ); SetThink( ItemFall ); diff --git a/server/ents/baseother.cpp b/server/ents/baseother.cpp index e65a245d..acf85d7a 100644 --- a/server/ents/baseother.cpp +++ b/server/ents/baseother.cpp @@ -195,24 +195,26 @@ LINK_ENTITY_TO_CLASS( floorent, CFloorEnt ); CLaserSpot *CLaserSpot::CreateSpot( void ) { CLaserSpot *pSpot = GetClassPtr( (CLaserSpot *)NULL ); + pSpot->pev->classname = MAKE_STRING( "misc_laserdot" ); pSpot->Spawn(); - pSpot->pev->classname = MAKE_STRING("laserspotent"); return pSpot; } void CLaserSpot::Precache( void ) { - UTIL_PrecacheModel("sprites/glow02.spr"); - UTIL_PrecacheSound("weapons/spot_on.wav"); - UTIL_PrecacheSound("weapons/spot_off.wav"); + UTIL_PrecacheModel( "sprites/laserdot.spr" ); + UTIL_PrecacheSound( "weapons/spot_on.wav" ); + UTIL_PrecacheSound( "weapons/spot_off.wav" ); } void CLaserSpot::Spawn( void ) { Precache( ); - //laser dot settings + SetObjectClass( ED_NORMAL ); + + // laser dot settings pev->movetype = MOVETYPE_FLY; pev->solid = SOLID_NOT; pev->scale = 1.0; @@ -220,7 +222,7 @@ void CLaserSpot::Spawn( void ) pev->renderfx = kRenderFxNoDissipation; pev->renderamt = 255; pev->rendercolor = Vector( 200, 12, 12 ); - UTIL_SetModel(ENT(pev), "sprites/glow02.spr" ); + UTIL_SetModel( ENT( pev ), "sprites/laserdot.spr" ); UTIL_SetOrigin( this, pev->origin ); } @@ -229,7 +231,7 @@ void CLaserSpot::Suspend( float flSuspendTime ) pev->effects |= EF_NODRAW; // -1 means suspend indefinitely - if (flSuspendTime == -1) SetThink( NULL ); + if( flSuspendTime == -1 ) SetThink( NULL ); else { SetThink( Revive ); @@ -249,9 +251,9 @@ void CLaserSpot::Update( CBasePlayer *m_pPlayer ) UTIL_MakeVectors( m_pPlayer->pev->v_angle ); UTIL_TraceLine( m_pPlayer->GetGunPosition(), m_pPlayer->GetGunPosition() + gpGlobals->v_forward * 8192, dont_ignore_monsters, ENT(m_pPlayer->pev), &tr ); - UTIL_SetOrigin( this, tr.vecEndPos ); + UTIL_SetOrigin( this, tr.vecEndPos + tr.vecPlaneNormal * 10 ); - if( UTIL_PointContents( tr.vecEndPos ) & CONTENTS_SKY && VARS(tr.pHit)->solid == SOLID_BSP ) + if( UTIL_PointContents( tr.vecEndPos ) & CONTENTS_SKY && VARS( tr.pHit )->solid == SOLID_BSP ) { pev->renderamt = 33; pev->effects |= EF_NODRAW; @@ -261,11 +263,11 @@ void CLaserSpot::Update( CBasePlayer *m_pPlayer ) pev->effects &= ~EF_NODRAW; float SpotDistance = (tr.vecEndPos - m_pPlayer->GetGunPosition()).Length(); - int brightness = (1 / log(SpotDistance / 0.3)) * 1300; - pev->scale = SpotDistance / 2500 + RANDOM_FLOAT(0.01, SpotDistance/2750); + int brightness = (1 / log( SpotDistance / 0.3 )) * 1300; + pev->scale = SpotDistance / 2500 + RANDOM_FLOAT( 0.01, SpotDistance / 2750 ); if(pev->renderamt >= 255) pev->renderamt = brightness + RANDOM_LONG(1, SpotDistance/400); else pev->renderamt += 5; } } -LINK_ENTITY_TO_CLASS( laserspotent, CLaserSpot ); \ No newline at end of file +LINK_ENTITY_TO_CLASS( misc_laserdot, CLaserSpot ); \ No newline at end of file diff --git a/server/ents/baserockets.cpp b/server/ents/baserockets.cpp index 8d70571d..c9bf3aff 100644 --- a/server/ents/baserockets.cpp +++ b/server/ents/baserockets.cpp @@ -338,14 +338,17 @@ IMPLEMENT_SAVERESTORE( CRpgRocket, CGrenade ); void CRpgRocket :: Spawn( void ) { Precache( ); + + SetObjectClass( ED_NORMAL ); + // motor pev->movetype = MOVETYPE_BOUNCE; pev->solid = SOLID_BBOX; - UTIL_SetModel(ENT(pev), "models/rpgrocket.mdl"); + UTIL_SetModel(ENT(pev), "models/props/rocket.mdl"); UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0)); UTIL_SetOrigin( this, pev->origin ); - pev->classname = MAKE_STRING("rpg_rocket"); + pev->classname = MAKE_STRING( "rpg_rocket" ); SetThink( IgniteThink ); SetTouch( ExplodeTouch ); @@ -383,11 +386,11 @@ void CRpgRocket::Detonate( void ) void CRpgRocket :: Precache( void ) { - UTIL_PrecacheModel("models/rpgrocket.mdl"); - UTIL_PrecacheSound ("weapons/rpg/rocket1.wav"); - UTIL_PrecacheSound ("weapons/rpg/beep.wav"); - UTIL_PrecacheSound ("weapons/rpg/beep2.wav"); - m_iTrail = UTIL_PrecacheModel("sprites/smoke.spr"); + UTIL_PrecacheModel( "models/props/rocket.mdl" ); + UTIL_PrecacheSound( "weapons/rpg/rocket1.wav" ); + UTIL_PrecacheSound( "weapons/rpg/beep.wav" ); + UTIL_PrecacheSound( "weapons/rpg/beep2.wav" ); + m_iTrail = UTIL_PrecacheModel( "sprites/smoke.spr" ); } void CRpgRocket :: IgniteThink( void ) @@ -429,7 +432,7 @@ void CRpgRocket :: FollowThink( void ) vecTarget = gpGlobals->v_forward; flMax = 4096; // Examine all entities within a reasonable radius - while ((pOther = UTIL_FindEntityByClassname( pOther, "laserspotent" )) != NULL) + while ((pOther = UTIL_FindEntityByClassname( pOther, "misc_laserdot" )) != NULL) { UTIL_TraceLine ( pev->origin, pOther->pev->origin, dont_ignore_monsters, ENT(pev), &tr ); // Msg( "%f\n", tr.flFraction ); @@ -591,6 +594,7 @@ CNukeExplode *CNukeExplode::Create ( Vector vecOrigin, CBaseEntity *pOwner ) void CNukeExplode :: Spawn( void ) { + SetObjectClass( ED_NORMAL ); Precache(); UTIL_SetModel(ENT(pev), "models/nexplode.mdl"); TraceResult tr; @@ -617,10 +621,10 @@ void CNukeExplode :: Spawn( void ) void CNukeExplode :: Precache( void ) { - m_usExplodeSprite = UTIL_PrecacheModel("sprites/warhead01.spr"); - m_usExplodeSprite2 = UTIL_PrecacheModel("sprites/warhead02.spr"); - UTIL_PrecacheModel("models/nexplode.mdl"); - UTIL_PrecacheSound("weapons/warhead/whexplode.wav"); + m_usExplodeSprite = UTIL_PrecacheModel("sprites/war_explo01.spr"); + m_usExplodeSprite2 = UTIL_PrecacheModel("sprites/war_exlpo02.spr"); + UTIL_PrecacheModel( "models/nexplode.mdl" ); + UTIL_PrecacheSound( "weapons/warhead/whexplode.wav" ); } void CNukeExplode :: ExplodeThink( void ) @@ -628,8 +632,8 @@ void CNukeExplode :: ExplodeThink( void ) pev->renderamt -= 1.5; pev->scale += .2; - if(pev->scale >= 8 && pev->scale < 8.2)//create second explode sprite - SFX_Explode( m_usExplodeSprite2, pev->oldorigin, 100, TE_EXPLFLAG_NOPARTICLES | TE_EXPLFLAG_NOSOUND ); + if(pev->scale >= 8 && pev->scale < 8.2 ) // create second explode sprite + SFX_Explode( m_usExplodeSprite2, pev->oldorigin, 100, TE_EXPLFLAG_NOPARTICLES|TE_EXPLFLAG_NOSOUND ); entvars_t *pevOwner; if ( pev->owner ) pevOwner = VARS( pev->owner ); @@ -675,12 +679,13 @@ void CWHRocket :: Spawn( void ) { Precache( ); + SetObjectClass( ED_NORMAL ); m_pPlayer = (CBasePlayer*)CBasePlayer::Instance( pev->owner ); - if(!m_pPlayer)//leveldesigner may put rocket on a map + if( !m_pPlayer ) // leveldesigner may put rocket on a map { - if(!IsMultiplayer()) + if( !IsMultiplayer()) { - Msg("Warning! Player pointer is not valid\n"); + ALERT( at_warning, "player pointer is not valid\n" ); m_pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( 1 ); } else @@ -693,10 +698,10 @@ void CWHRocket :: Spawn( void ) pev->solid = SOLID_SLIDEBOX; pev->takedamage = DAMAGE_YES; pev->health = 10; - pev->speed = WARHEAD_SPEED;//set initial speed + pev->speed = WARHEAD_SPEED; // set initial speed - UTIL_SetModel(ENT(pev), "models/whrocket.mdl"); - EMIT_SOUND( ENT(pev), CHAN_WEAPON, "weapons/warhead/launch.wav", 1, 0.5 ); + UTIL_SetModel(ENT( pev ), "models/whrocket.mdl"); + EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "weapons/warhead/launch.wav", 1, 0.5 ); UTIL_SetOrigin( this, pev->origin ); pev->colormap = ENTINDEX(edict());//manually save our index into colormap diff --git a/server/ents/basetrigger.cpp b/server/ents/basetrigger.cpp index fef556af..98383cad 100644 --- a/server/ents/basetrigger.cpp +++ b/server/ents/basetrigger.cpp @@ -10,9 +10,9 @@ //======================================================================= // func_trigger - volume, that fire target when player in or out //======================================================================= -#define SF_TRIGGER_ALLOWMONSTERS 1// monsters allowed to fire this trigger -#define SF_TRIGGER_NOCLIENTS 2// players not allowed to fire this trigger -#define SF_TRIGGER_PUSHABLES 4// only pushables can fire this trigger +#define SF_TRIGGER_ALLOWMONSTERS 1 // monsters allowed to fire this trigger +#define SF_TRIGGER_NOCLIENTS 2 // players not allowed to fire this trigger +#define SF_TRIGGER_PUSHABLES 4 // only pushables can fire this trigger class CBaseTrigger; class CInOutRegister : public CPointEntity @@ -157,15 +157,16 @@ void CBaseTrigger :: Spawn( void ) pev->solid = SOLID_TRIGGER; pev->movetype = MOVETYPE_NONE; pev->takedamage = DAMAGE_NO; - UTIL_SetModel(ENT(pev), pev->model ); // set size and link into world - SetBits( pev->effects, EF_NODRAW ); + UTIL_SetModel( ENT( pev ), pev->model ); // set size and link into world + SetObjectClass( ED_TRIGGER ); // create a null-terminator for the registry - m_pRegister = GetClassPtr( (CInOutRegister*)NULL ); + m_pRegister = GetClassPtr(( CInOutRegister *)NULL ); m_pRegister->m_hValue = NULL; m_pRegister->m_pNext = NULL; m_pRegister->m_pField = this; m_pRegister->pev->classname = MAKE_STRING("zoneent"); + m_pRegister->SetObjectClass( ED_STATIC ); SetThink( Update ); } @@ -917,11 +918,13 @@ void CChangeLevel :: KeyValue( KeyValueData *pkvd ) void CChangeLevel :: Spawn( void ) { - if ( FStringNull( pev->netname)) Msg( "a % doesn't have a map", STRING(pev->classname) ); - if ( FStringNull( pev->message)) Msg( "trigger_changelevel to %s doesn't have a landmark", STRING(pev->netname) ); + if( FStringNull( pev->netname )) + ALERT( at_error, "a % doesn't have a map\n", STRING( pev->classname )); + if( FStringNull( pev->message )) + ALERT( at_error, "trigger_changelevel to %s doesn't have a landmark\n", STRING( pev->netname )); - //determine work style - if (FStringNull ( pev->targetname )) SetUse( NULL ); + // determine work style + if( FStringNull( pev->targetname )) SetUse( NULL ); else SetTouch( NULL ); pev->solid = SOLID_TRIGGER; diff --git a/server/ents/baseweapon.cpp b/server/ents/baseweapon.cpp index aa1eaf15..5711e1e2 100644 --- a/server/ents/baseweapon.cpp +++ b/server/ents/baseweapon.cpp @@ -15,7 +15,7 @@ #include "gamerules.h" #include "defaults.h" -//base defines +// base defines extern int gEvilImpulse101; ItemInfo CBasePlayerWeapon::ItemInfoArray[MAX_WEAPONS]; AmmoInfo CBasePlayerWeapon::AmmoInfoArray[MAX_AMMO_SLOTS]; @@ -24,6 +24,8 @@ int ID[MAX_WEAPONS]; int GlobalID = 0; int g_iSwing; +// replacement table for classic half-life weapons +// add animation names if we need const char *NAME_VM_PUMP[] = { "pump", }; const char *NAME_VM_IDLE1[] = { "idle", "idle1", }; const char *NAME_VM_IDLE2[] = { "fidget", "fidget1", }; @@ -154,7 +156,7 @@ CBaseEntity* CBasePlayerWeapon::Respawn( void ) pent = CREATE_NAMED_ENTITY( pev->classname ); if ( FNullEnt( pent ) ) { - //it's a custom weapon! + // it's a custom weapon! pent = CREATE_NAMED_ENTITY( MAKE_STRING( "weapon_generic" )); } pNewWeapon = Instance( pent ); @@ -275,19 +277,21 @@ void CBasePlayerWeapon :: Spawn( void ) pev->movetype = MOVETYPE_TOSS; pev->solid = SOLID_BBOX; - pev->sequence = 1;//set world animation + pev->sequence = 1; // set world animation UTIL_SetOrigin( this, pev->origin ); - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0) );//pointsize until it lands on the ground. + UTIL_SetModel( ENT( pev ), iWorldModel( )); + SetObjectClass( ED_NORMAL ); SetTouch( DefaultTouch ); SetThink( FallThink ); - UTIL_SetModel(ENT(pev), iWorldModel()); + // pointsize until it lands on the ground. + UTIL_SetSize( pev, Vector( 0, 0, 0 ), Vector( 0, 0, 0 )); m_iSpot = 0; pev->animtime = gpGlobals->time + 0.1; - b_restored = TRUE; //already restored + b_restored = TRUE; // already restored SetNextThink( 0.1 ); } @@ -862,25 +866,31 @@ int CBasePlayerWeapon :: SetAnimation( Activity activity, float fps ) //========================================================= void CBasePlayerWeapon :: SendWeaponAnim( int sequence, float fps ) { - dstudiohdr_t *pstudiohdr; - dstudioseqdesc_t *pseqdesc; - pstudiohdr = (dstudiohdr_t *)GET_MODEL_PTR( ENT(pev) ); + float framerate = 1.0f; // fps multiplier + + if( fps ) + { + dstudiohdr_t *pstudiohdr = (dstudiohdr_t *)GET_MODEL_PTR( ENT( pev )); + if( pstudiohdr ) + { + dstudioseqdesc_t *pseqdesc; + + pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence; + framerate = fps / pseqdesc->fps; + } + } // calculate additional body for special effects pev->body = (pev->body % NUM_HANDS) + NUM_HANDS * m_iBody; MESSAGE_BEGIN( MSG_ONE, gmsg.WeaponAnim, NULL, m_pPlayer->pev ); WRITE_BYTE( sequence ); + WRITE_BYTE( pev->body ); + WRITE_BYTE( framerate * 16 ); MESSAGE_END(); - if( pstudiohdr ) - { - pseqdesc = (dstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)sequence; - if(fps) pseqdesc->fps = fps; - } - m_pPlayer->pev->weaponanim = sequence; - SetNextIdle(SequenceDuration()); + SetNextIdle( SequenceDuration( )); } //========================================================= @@ -1564,30 +1574,30 @@ void CBasePlayerWeapon::ZoomUpdate( void ) { if((iAttack1() == ZOOM && m_pPlayer->pev->button & IN_ATTACK) || (iAttack2() == ZOOM && m_pPlayer->pev->button & IN_ATTACK2)) { - if(m_iZoom == 0) + if( m_iZoom == 0 ) { if (m_flHoldTime > UTIL_WeaponTimeBase()) return; m_iZoom = 1; EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/zoom.wav", 1, ATTN_NORM); m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.8; } - if(m_iZoom == 1) + if( m_iZoom == 1 ) { - m_pPlayer->m_iFOV = 50; + m_pPlayer->m_flFOV = 50.0f; m_pPlayer->pev->viewmodel = NULL; - m_iZoom = 2;//ready to zooming, wait for 0.8 secs + m_iZoom = 2; // ready to zooming, wait for 0.8 secs } - if (m_iZoom == 2 && m_pPlayer->m_iFOV > MAX_ZOOM) + if( m_iZoom == 2 && m_pPlayer->m_flFOV > MAX_ZOOM ) { - if (m_flTimeUpdate < UTIL_WeaponTimeBase()) + if( m_flTimeUpdate < UTIL_WeaponTimeBase( )) { - m_pPlayer->m_iFOV--; - m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.02; + m_pPlayer->m_flFOV -= 1.2;//gpGlobals->frametime; + m_flTimeUpdate = UTIL_WeaponTimeBase() + 0.002; } } - if(m_iZoom == 3) ZoomReset(); + if( m_iZoom == 3 ) ZoomReset(); } - else if(m_iZoom > 1) m_iZoom = 3; + else if( m_iZoom > 1 ) m_iZoom = 3; MESSAGE_BEGIN( MSG_ONE, gmsg.ZoomHUD, NULL, m_pPlayer->pev ); WRITE_BYTE( m_iZoom ); @@ -1601,7 +1611,7 @@ void CBasePlayerWeapon::ZoomReset( void ) { m_pPlayer->pev->viewmodel = iViewModel(); m_flHoldTime = UTIL_WeaponTimeBase() + 0.5; - m_pPlayer->m_iFOV = 90; + m_pPlayer->m_flFOV = 90; m_iZoom = 0; // clear zoom MESSAGE_BEGIN( MSG_ONE, gmsg.ZoomHUD, NULL, m_pPlayer->pev ); WRITE_BYTE( m_iZoom ); @@ -1840,7 +1850,7 @@ int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) } // if the ammo, state, or fov has changed, update the weapon - if( m_iClip != m_iClientClip || state != m_iClientWeaponState || pPlayer->m_iFOV != pPlayer->m_iClientFOV ) + if( m_iClip != m_iClientClip || state != m_iClientWeaponState || pPlayer->m_flFOV != pPlayer->m_flClientFOV ) { bSend = TRUE; } diff --git a/server/global/client.cpp b/server/global/client.cpp index 46bfaa8c..66cb1505 100644 --- a/server/global/client.cpp +++ b/server/global/client.cpp @@ -536,7 +536,7 @@ void ClientCommand( edict_t *pEntity ) { GetClassPtr((CBasePlayer *)pev)->ForceClientDllUpdate(); } - else if ( FStrEq(pcmd, "give" ) ) + else if( FStrEq( pcmd, "give" )) { if ( g_flWeaponCheat != 0.0) { @@ -550,15 +550,15 @@ void ClientCommand( edict_t *pEntity ) // player is dropping an item. GetClassPtr((CBasePlayer *)pev)->DropPlayerItem((char *)CMD_ARGV(1)); } - else if ( FStrEq(pcmd, "fov" ) ) + else if( FStrEq( pcmd, "fov" )) { - if( g_flWeaponCheat && CMD_ARGC() > 1) + if( g_flWeaponCheat && CMD_ARGC() > 1 ) { - GetClassPtr((CBasePlayer *)pev)->m_iFOV = atoi( CMD_ARGV(1) ); + GetClassPtr((CBasePlayer *)pev)->m_flFOV = atof( CMD_ARGV( 1 )); } else { - ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "\"fov\" is \"%d\"\n", (int)GetClassPtr((CBasePlayer *)pev)->m_iFOV ) ); + ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "\"fov\" is \"%g\"\n", (int)GetClassPtr((CBasePlayer *)pev)->m_flFOV ) ); } } else if ( FStrEq(pcmd, "use" ) ) @@ -1044,8 +1044,8 @@ void LinkUserMessages( void ) gmsg.ItemPickup = REG_USER_MSG( "ItemPickup", -1 ); gmsg.RoomType = REG_USER_MSG( "RoomType", 2 ); gmsg.HideWeapon = REG_USER_MSG( "HideWeapon", 1 ); - gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 1 ); - gmsg.SetFOV = REG_USER_MSG( "SetFOV", 1 ); + gmsg.WeaponAnim = REG_USER_MSG( "WeaponAnim", 3 ); + gmsg.SetFOV = REG_USER_MSG( "SetFOV", 4 ); gmsg.ShowMenu = REG_USER_MSG( "ShowMenu", -1 ); gmsg.Shake = REG_USER_MSG("ScreenShake", 13 ); gmsg.Fade = REG_USER_MSG("ScreenFade", sizeof(ScreenFade)); @@ -1067,7 +1067,7 @@ void LinkUserMessages( void ) gmsg.AddPortal = REG_USER_MSG( "AddPortal", 1); gmsg.HudText = REG_USER_MSG( "HudText", -1 ); gmsg.ShowGameTitle = REG_USER_MSG("GameTitle", 1); - gmsg.TempEntity = REG_USER_MSG( "TempEntity", 1); // FIXME + gmsg.TempEntity = REG_USER_MSG( "TempEntity", -1); gmsg.SetFog = REG_USER_MSG("SetFog", 7 ); gmsg.SetSky = REG_USER_MSG( "SetSky", 13 ); gmsg.Particle = REG_USER_MSG( "Particle", -1); diff --git a/server/global/utils.cpp b/server/global/utils.cpp index f8276e49..4c9872e9 100644 --- a/server/global/utils.cpp +++ b/server/global/utils.cpp @@ -1007,7 +1007,7 @@ void UTIL_SetAvelocity ( CBaseEntity *pEnt, const Vector vecSet ) // Precache and set resources - add check for present or invalid name // NOTE: game will not crashed if model not specified, this code is legacy //======================================================================== -void UTIL_SetModel( edict_t *e, string_t s, char *c ) // set default model if not found +void UTIL_SetModel( edict_t *e, string_t s, const char *c ) // set default model if not found { if( FStringNull( s )) UTIL_SetModel( e, c ); else UTIL_SetModel( e, s ); @@ -1057,49 +1057,44 @@ void UTIL_SetModel( edict_t *e, const char *model ) } } -int UTIL_PrecacheModel( string_t s, char *e )//precache default model if not found +int UTIL_PrecacheModel( string_t s, const char *e ) // precache default model if not found { - if (FStringNull( s )) + if( FStringNull( s )) return UTIL_PrecacheModel( e ); return UTIL_PrecacheModel( s ); } -int UTIL_PrecacheModel( string_t s ){ return UTIL_PrecacheModel( (char*)STRING(s)); } -int UTIL_PrecacheModel( char* s ) + +int UTIL_PrecacheModel( string_t s ){ return UTIL_PrecacheModel( STRING( s )); } +int UTIL_PrecacheModel( const char* s ) { - if(!s || !*s) + if( !s || !*s ) { - ALERT(at_console,"Warning: modelname not specified\n"); - return g_sModelIndexNullModel; //set null model - } - //no need to precacahe brush - if (s[0] == '*') return 0; - - //verify file exists - byte *data = LOAD_FILE(s, NULL); - if (data) - { - FREE_FILE( data ); - return g_engfuncs.pfnPrecacheModel(s); + ALERT( at_warning, "modelname not specified\n" ); + return g_sModelIndexNullModel; // set null model } - int namelen = strlen(s) - 1; - if (s[namelen] == 'l') + // no need to precache brush + if( s[0] == '*' ) return 0; + + if( FILE_EXISTS( s )) { - //this is model - ALERT(at_console,"Warning: model \"%s\" not found!\n",s); + return g_engfuncs.pfnPrecacheModel( s ); + } + + if( !strcmp( UTIL_FileExtension( s ), "mdl" )) + { + ALERT( at_warning, "model \"%s\" not found!\n", s ); return g_sModelIndexErrorModel; } - else if (s[namelen] == 'r') + else if( !strcmp( UTIL_FileExtension( s ), "spr" )) { - //this is sprite - ALERT(at_console,"Warning: sprite \"%s\" not found!\n",s); + ALERT( at_warning, "sprite \"%s\" not found!\n", s ); return g_sModelIndexErrorSprite; } else { - //unknown format - ALERT(at_console,"Warning: invalid name \"%s\"!\n",s); - return g_sModelIndexNullModel; //set null model + ALERT( at_error, "invalid name \"%s\"!\n", s ); + return g_sModelIndexNullModel; } } @@ -1128,7 +1123,7 @@ void AddAmmoName( string_t iAmmoName ) //======================================================================== // Precaches entity from other entity //======================================================================== -void UTIL_PrecacheEntity( string_t szClassname ) { UTIL_PrecacheEntity( (char *)STRING(szClassname) ); } +void UTIL_PrecacheEntity( string_t szClassname ) { UTIL_PrecacheEntity( STRING( szClassname )); } void UTIL_PrecacheEntity( const char *szClassname ) { edict_t *pent; @@ -1137,47 +1132,45 @@ void UTIL_PrecacheEntity( const char *szClassname ) // check for virtual entities if( FUNCTION_FROM_NAME( szClassname )) { - pent = CREATE_NAMED_ENTITY(istr); - if ( FNullEnt( pent )) return; + pent = CREATE_NAMED_ENTITY( istr ); + if( FNullEnt( pent )) return; } else if( !strncmp( szClassname, "weapon_", 7 )) { //may be this a weapon_generic entity? - pent = CREATE_NAMED_ENTITY(MAKE_STRING("weapon_generic")); + pent = CREATE_NAMED_ENTITY( MAKE_STRING( "weapon_generic" )); if ( FNullEnt( pent )) return; //this never gonna called anymore. just in case pent->v.netname = istr; } - else //unknown error + else // unknown error { - Msg("can't create %s\n", szClassname ); + ALERT( at_error, "can't create %s\n", szClassname ); return; } - CBaseEntity *pEntity = CBaseEntity::Instance (VARS( pent )); - if (pEntity) pEntity->Precache(); + CBaseEntity *pEntity = CBaseEntity::Instance( VARS( pent )); + if( pEntity ) pEntity->Precache(); REMOVE_ENTITY(pent); } //======================================================================== // Precaches aurora particle and set it //======================================================================== -int UTIL_PrecacheAurora( string_t s ) { return UTIL_PrecacheAurora( (char *)STRING(s)); } +int UTIL_PrecacheAurora( string_t s ) { return UTIL_PrecacheAurora( STRING( s )); } int UTIL_PrecacheAurora( const char *s ) { - char path[128]; //path length - sprintf(path, "scripts/aurora/%s.aur", s); + char path[256]; + sprintf( path, "scripts/aurora/%s.aur", s ); - byte *data = LOAD_FILE(path, NULL); - if (data) + if( FILE_EXISTS( path )) { - FREE_FILE( data ); - return ALLOC_STRING(path); + return ALLOC_STRING( path ); } - else //otherwise + else // otherwise { - if(!s || !*s)Msg( "Warning: Aurora not specified!\n", s); - else Msg( "Warning: Aurora %s not found!\n", s); - return ALLOC_STRING( "scripts/aurora/error.aur"); + if( !s || !*s )Msg( "Warning: Aurora not specified!\n", s); + else ALERT( at_warning, "aurora %s not found!\n", s ); + return MAKE_STRING( "scripts/aurora/error.aur" ); } } @@ -1195,86 +1188,81 @@ void UTIL_SetBeams( char *szFile, CBaseEntity *pStart, CBaseEntity *pEnd ) { MESSAGE_BEGIN( MSG_ALL, gmsg.Beams ); WRITE_STRING( szFile ); - WRITE_BYTE( pStart->entindex());//beam start entity - WRITE_BYTE( pEnd->entindex() );//beam end entity + WRITE_BYTE( pStart->entindex()); // beam start entity + WRITE_BYTE( pEnd->entindex() ); // beam end entity MESSAGE_END(); } //======================================================================== // Precaches and play sound //======================================================================== -int UTIL_PrecacheSound( string_t s, char *e )//precache default model if not found +int UTIL_PrecacheSound( string_t s, const char *e ) // precache default model if not found { if (FStringNull( s )) return UTIL_PrecacheSound( e ); return UTIL_PrecacheSound( s ); } -int UTIL_PrecacheSound( string_t s ){ return UTIL_PrecacheSound( (char*)STRING(s)); } -int UTIL_PrecacheSound( char* s ) +int UTIL_PrecacheSound( string_t s ){ return UTIL_PrecacheSound( STRING( s )); } +int UTIL_PrecacheSound( const char* s ) { - if(!s || !*s) return MAKE_STRING("common/null.wav"); //set null sound - if(*s == '!') return MAKE_STRING(s); //sentence - just make string + if( !s || !*s ) return MAKE_STRING( "common/null.wav" ); // set null sound + if( *s == '!' ) return MAKE_STRING( s ); // sentence - just make string - //LOAD_FILE_FOR_ME will cause problems for some users. Disabled - g_engfuncs.pfnPrecacheSound(s); - return MAKE_STRING(s); - - //NOTE: Engine function as predicted for sound folder - //But LOAD_FILE don't known about this. Set it manualy + char path[256]; + sprintf( path, "sound/%s", s ); - char path[256]; //path size - sprintf(path, "sound/%s", s); - - //verify file exists - byte *data = LOAD_FILE(path, NULL); - if (data) + // check file for existing + if( FILE_EXISTS( path )) { - FREE_FILE( data ); - g_engfuncs.pfnPrecacheSound(s); - return MAKE_STRING(s); + g_engfuncs.pfnPrecacheSound( s ); + return MAKE_STRING( s ); } - int namelen = strlen(s) - 1; - if (s[namelen] == 'v') + + if( !strcmp( UTIL_FileExtension( s ), "wav" )) { - //this is sound - ALERT(at_console,"Warning: sound \"%s\" not found!\n",s); - g_engfuncs.pfnPrecacheSound("common/null.wav"); - return MAKE_STRING("common/null.wav"); //set null sound + // this is sound + ALERT( at_warning, "sound \"%s\" not found!\n", s ); + } + else if( !strcmp( UTIL_FileExtension( s ), "ogg" )) + { + // this is sound + ALERT( at_warning, "sound \"%s\" not found!\n", s ); } else { - //unknown format - ALERT(at_console,"Warning: invalid name \"%s\"!\n",s); - g_engfuncs.pfnPrecacheSound("common/null.wav"); - return MAKE_STRING("common/null.wav"); //set null sound + // unknown format + ALERT( at_error, "invalid name \"%s\"!\n", s ); } + + g_engfuncs.pfnPrecacheSound("common/null.wav"); + return MAKE_STRING( "common/null.wav" ); } -int UTIL_LoadSoundPreset( string_t pString ) { return UTIL_LoadSoundPreset( (char*)STRING(pString) ); } +int UTIL_LoadSoundPreset( string_t pString ) { return UTIL_LoadSoundPreset( STRING( pString )); } int UTIL_LoadSoundPreset( const char *pString ) { - //try to load direct sound path - //so we supported 99 presets... - int m_sound, namelen = strlen(pString) - 1; + // try to load direct sound path + // so we supported 99 presets... + int m_sound, namelen = strlen( pString ) - 1; - if(namelen > 2)//yes, it's sound path + if( namelen > 2 ) // yes, it's sound path m_sound = ALLOC_STRING( pString ); - else if(pString[0] == '!')//sentence + else if( pString[0] == '!' ) // sentence m_sound = ALLOC_STRING( pString ); - else m_sound = atoi(pString);//no, it's preset + else m_sound = atoi( pString ); // no, it's preset return m_sound; } -int UTIL_LoadDecalPreset( string_t pString ) { return UTIL_LoadDecalPreset( (char*)STRING(pString) ); } +int UTIL_LoadDecalPreset( string_t pString ) { return UTIL_LoadDecalPreset( STRING( pString )); } int UTIL_LoadDecalPreset( const char *pString ) { - //try to load direct sound path - //so we supported 9 decal groups... + // try to load direct sound path + // so we supported 9 decal groups... int m_decal, namelen = strlen(pString) - 1; - if(namelen > 1)//yes, it's decal name + if( namelen > 1 ) // yes, it's decal name m_decal = ALLOC_STRING( pString ); - else m_decal = atoi(pString);//no, it's preset + else m_decal = atoi( pString ); // no, it's preset return m_decal; } diff --git a/server/global/utils.h b/server/global/utils.h index 92d40889..3f9a038d 100644 --- a/server/global/utils.h +++ b/server/global/utils.h @@ -666,13 +666,13 @@ void UTIL_SetView( int ViewEntity = 0, int flags = 0 ); void UTIL_SetView( CBaseEntity *pActivator, int ViewEntity = 0, int flags = 0 ); void UTIL_SetView( CBaseEntity *pActivator, CBaseEntity *pViewEnt = 0, int flags = 0 ); -void UTIL_SetModel( edict_t *e, string_t s, char *c ); +void UTIL_SetModel( edict_t *e, string_t s, const char *c ); void UTIL_SetModel( edict_t *e, const char *model ); void UTIL_SetModel( edict_t *e, string_t model ); -int UTIL_PrecacheModel( char* s ); -int UTIL_PrecacheModel( string_t s, char *e ); -int UTIL_PrecacheSound( char* s ); -int UTIL_PrecacheSound( string_t s, char *e ); +int UTIL_PrecacheModel( const char* s ); +int UTIL_PrecacheModel( string_t s, const char *e ); +int UTIL_PrecacheSound( const char* s ); +int UTIL_PrecacheSound( string_t s, const char *e ); int UTIL_PrecacheModel( string_t s ); int UTIL_PrecacheSound( string_t s ); void UTIL_PrecacheEntity( const char *szClassname ); diff --git a/server/global/vector.h b/server/global/vector.h index 89b1181f..429e967d 100644 --- a/server/global/vector.h +++ b/server/global/vector.h @@ -62,6 +62,7 @@ public: #define nanmask (255<<23) #define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) +#define Q_rint(x) ((x) > 0 ? (int)((x) + 0.5) : (int)((x) - 0.5)) inline float DotProduct(const Vector2D& a, const Vector2D& b) { return( a.x*b.x + a.y*b.y ); } inline Vector2D operator*(float fl, const Vector2D& v) { return v * fl; } diff --git a/server/monsters/player.cpp b/server/monsters/player.cpp index 4bffbc30..5b5dbe80 100644 --- a/server/monsters/player.cpp +++ b/server/monsters/player.cpp @@ -123,7 +123,7 @@ TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] = DEFINE_FIELD( CBasePlayer, m_pTank, FIELD_EHANDLE ), // NB: this points to a CFuncTank*Controls* now. --LRC DEFINE_FIELD( CBasePlayer, m_pMonitor, FIELD_EHANDLE ), DEFINE_FIELD( CBasePlayer, m_iHideHUD, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iFOV, FIELD_INTEGER ), + DEFINE_FIELD( CBasePlayer, m_flFOV, FIELD_FLOAT ), DEFINE_FIELD( CBasePlayer, pViewEnt, FIELD_CLASSPTR), DEFINE_FIELD( CBasePlayer, viewFlags, FIELD_INTEGER), DEFINE_FIELD( CBasePlayer, m_iSndRoomtype, FIELD_INTEGER ), @@ -897,7 +897,7 @@ void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) MESSAGE_END(); // reset FOV - m_iFOV = m_iClientFOV = 90; + m_flFOV = m_flClientFOV = 90.0f; pViewEnt = 0; viewFlags = 0; @@ -3276,8 +3276,8 @@ void CBasePlayer::Spawn( void ) Rain_nextFadeUpdate = 0; GiveOnlyAmmo = FALSE; - m_iFOV = 90;// init field of view. - m_iClientFOV = -1; // make sure fov reset is sent + m_flFOV = 90.0f;// init field of view. + m_flClientFOV = -1; // make sure fov reset is sent //m_iAcessLevel = 2; m_flNextDecalTime = 0; // let this player decal as soon as he spawns. @@ -4250,10 +4250,10 @@ void CBasePlayer :: UpdateClientData( void ) m_iClientHideHUD = m_iHideHUD; } - if ( m_iFOV != m_iClientFOV ) + if ( m_flFOV != m_flClientFOV ) { MESSAGE_BEGIN( MSG_ONE, gmsg.SetFOV, NULL, pev ); - WRITE_BYTE( m_iFOV ); + WRITE_FLOAT( m_flFOV ); MESSAGE_END(); // cache FOV change at end of function, so weapon updates can see that FOV has changed @@ -4635,10 +4635,10 @@ void CBasePlayer :: UpdateClientData( void ) // Cache and client weapon change m_pClientActiveItem = m_pActiveItem; - m_iClientFOV = m_iFOV; + m_flClientFOV = m_flFOV; - // Update Status Bar - if ( m_flNextSBarUpdateTime < gpGlobals->time ) + // update Status Bar + if( m_flNextSBarUpdateTime < gpGlobals->time ) { UpdateStatusBar(); m_flNextSBarUpdateTime = gpGlobals->time + 0.2; diff --git a/server/monsters/player.h b/server/monsters/player.h index 03e671dd..af47b6ae 100644 --- a/server/monsters/player.h +++ b/server/monsters/player.h @@ -172,8 +172,8 @@ public: int m_iClientBattery; // the Battery currently known by the client. If this changes, send a new int m_iHideHUD; // the players hud weapon info is to be hidden int m_iClientHideHUD; - int m_iFOV; // field of view - int m_iClientFOV; // client's known FOV + float m_flFOV; // field of view + float m_flClientFOV; // client's known FOV // usable player items CBasePlayerWeapon *m_rgpPlayerItems[MAX_ITEM_TYPES]; diff --git a/todo.log b/todo.log index fcf5b9ef..e2e8fc11 100644 --- a/todo.log +++ b/todo.log @@ -32,13 +32,16 @@ Beta 13.12.08 11.Load server.dll and client.dll only once OK 12.v_refdef interactions OK 13.hud_scale factor OK -14.move "loading" and "pause" into CHUD -15.Get Rid Of DrawImage +14.move "loading" and "pause" into CHUD OK +15.Get Rid Of DrawImage OK 16.Copy Resources OK 17.тормоза на больших картах -18.weapon pickup & drawing -19.AddRefEntity uses edict_t instead entity state -20.render custom models +18.weapon pickup & drawing OK +19.AddRefEntity uses edict_t instead entity state OK +20.render custom models OK +21.zoom_hud and warhead hud OK +22.entity_state_t revision 4 +23.entvars_t revision 1 entity_state_t невидима для пользователя