From 84c95482c0f246e2d0b8f2c29bb76f766d090fff Mon Sep 17 00:00:00 2001 From: g-cont Date: Thu, 24 Mar 2011 00:00:00 +0300 Subject: [PATCH] 24 Mar 2011 --- engine/client/cl_game.c | 2 +- engine/client/cl_main.c | 6 +- engine/client/cl_menu.c | 7 +- engine/client/cl_pmove.c | 7 +- engine/client/cl_scrn.c | 5 - engine/client/cl_tent.c | 3 +- engine/client/gl_rmain.c | 7 +- engine/client/gl_rsurf.c | 2 + engine/client/gl_sprite.c | 37 ++- engine/client/gl_studio.c | 28 +- engine/client/gl_vidnt.c | 2 +- engine/client/gl_warp.c | 4 +- engine/client/vgui/vgui_draw.c | 2 +- engine/common/imagelib/imagelib.h | 58 ++++ engine/common/imagelib/img_jpg.c | 498 +++++++++++++++++++++++++++++ engine/common/imagelib/img_utils.c | 1 + engine/engine.dsp | 4 + engine/server/sv_client.c | 48 ++- engine/server/sv_game.c | 3 + engine/server/sv_pmove.c | 7 +- game_launch/game.dsp | 10 +- game_launch/game.ncb | Bin 41984 -> 0 bytes game_launch/game.opt | Bin 52736 -> 0 bytes mainui/ui_title_anim.cpp | 12 +- mainui/utils.cpp | 8 +- 25 files changed, 695 insertions(+), 66 deletions(-) create mode 100644 engine/common/imagelib/img_jpg.c delete mode 100644 game_launch/game.ncb delete mode 100644 game_launch/game.opt diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index cd80097e..4e72fd54 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -3017,7 +3017,7 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame ) if( psprite->texFormat == SPR_ALPHTEST ) { pglEnable( GL_ALPHA_TEST ); - pglAlphaFunc( GL_GEQUAL, 0.5f ); + pglAlphaFunc( GL_GREATER, 0.0f ); } GL_Bind( GL_TEXTURE0, gl_texturenum ); diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index bc49be28..251966b0 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -33,7 +33,6 @@ convar_t *cl_solid_players; convar_t *cl_draw_beams; convar_t *cl_showmiss; convar_t *cl_cmdrate; -convar_t *userinfo; // // userinfo @@ -541,6 +540,9 @@ void CL_WritePacket( void ) // update download/upload slider. Netchan_UpdateProgress( &cls.netchan ); + + // make sure what menu and CL_WritePacket catch changes + userinfo->modified = false; } /* @@ -1486,7 +1488,6 @@ void CL_InitLocal( void ) topcolor = Cvar_Get( "topcolor", "0", CVAR_USERINFO|CVAR_ARCHIVE, "player top color" ); bottomcolor = Cvar_Get( "bottomcolor", "0", CVAR_USERINFO|CVAR_ARCHIVE, "player bottom color" ); rate = Cvar_Get( "rate", "25000", CVAR_USERINFO|CVAR_ARCHIVE, "player network rate" ); - userinfo = Cvar_Get( "@userinfo", "0", CVAR_READ_ONLY, "" ); // use ->modified value only cl_showfps = Cvar_Get( "cl_showfps", "1", CVAR_ARCHIVE, "show client fps" ); cl_smooth = Cvar_Get ("cl_smooth", "0", CVAR_ARCHIVE, "smooth up stair climbing and interpolate position in multiplayer" ); cl_cmdbackup = Cvar_Get( "cl_cmdbackup", "10", CVAR_ARCHIVE, "how many additional history commands are sent" ); @@ -1498,6 +1499,7 @@ void CL_InitLocal( void ) Cvar_Get( "hud_scale", "0", CVAR_ARCHIVE|CVAR_LATCH, "scale hud at current resolution" ); Cvar_Get( "skin", "", CVAR_USERINFO, "player skin" ); // XDM 3.3 want this cvar Cvar_Get( "spectator", "0", CVAR_USERINFO|CVAR_ARCHIVE, "1 is enable spectator mode" ); + Cvar_Get( "cl_updaterate", "60", CVAR_USERINFO|CVAR_ARCHIVE, "refresh rate of server messages" ); // server commands Cmd_AddCommand ("noclip", NULL, "enable or disable no clipping mode" ); diff --git a/engine/client/cl_menu.c b/engine/client/cl_menu.c index 058bb7b7..d04def1d 100644 --- a/engine/client/cl_menu.c +++ b/engine/client/cl_menu.c @@ -46,9 +46,12 @@ void UI_SetActiveMenu( qboolean fActive ) { movie_state_t *cin_state; - // don't touch menu state when video is restarted - if( !menu.hInstance )//|| host.state == HOST_RESTART ) + if( !menu.hInstance ) + { + if( !fActive ) + Key_SetKeyDest( key_game ); return; + } menu.drawLogo = fActive; menu.dllFuncs.pfnSetActiveMenu( fActive ); diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index 3a13c955..d5053410 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -532,7 +532,12 @@ void CL_InitClientMove( void ) // enumerate client hulls for( i = 0; i < 4; i++ ) - clgame.dllFuncs.pfnGetHullBounds( i, clgame.player_mins[i], clgame.player_maxs[i] ); + { + if( clgame.dllFuncs.pfnGetHullBounds( i, clgame.player_mins[i], clgame.player_maxs[i] )) + MsgDev( D_INFO, "CL: hull%i, player_mins: %g %g %g, player_maxs: %g %g %g\n", i, + clgame.player_mins[i][0], clgame.player_mins[i][1], clgame.player_mins[i][2], + clgame.player_maxs[i][0], clgame.player_maxs[i][1], clgame.player_maxs[i][2] ); + } Q_memcpy( clgame.pmove->player_mins, clgame.player_mins, sizeof( clgame.player_mins )); Q_memcpy( clgame.pmove->player_maxs, clgame.player_maxs, sizeof( clgame.player_maxs )); diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 96e07ce1..5b7e7a04 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -281,11 +281,6 @@ void SCR_UpdateScreen( void ) } V_PostRender(); } - - if( !clgame.hInstance ) return; - - // make sure what menu and CL_WritePacket catch changes - userinfo->modified = false; } static void SCR_LoadCreditsFont( void ) diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index b07a616e..a4bae74e 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -282,8 +282,7 @@ void CL_AddTempEnts( void ) double ft = cl.time - cl.oldtime; float gravity = clgame.movevars.gravity; - clgame.dllFuncs.pfnTempEntUpdate( ft, cl.time, gravity, &cl_free_tents, &cl_active_tents, - CL_TEntAddEntity, CL_TEntPlaySound ); // callbacks + clgame.dllFuncs.pfnTempEntUpdate( ft, cl.time, gravity, &cl_free_tents, &cl_active_tents, CL_TEntAddEntity, CL_TEntPlaySound ); // callbacks } /* diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 5f9bcbeb..344b133d 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -804,7 +804,9 @@ void R_DrawEntitiesOnList( void ) } CL_DrawBeams( false ); - clgame.dllFuncs.pfnDrawNormalTriangles(); + + if( RI.drawWorld ) + clgame.dllFuncs.pfnDrawNormalTriangles(); // NOTE: some mods with custom renderer may generate glErrors // so we clear it here @@ -846,7 +848,8 @@ void R_DrawEntitiesOnList( void ) } } - clgame.dllFuncs.pfnDrawTransparentTriangles (); + if( RI.drawWorld ) + clgame.dllFuncs.pfnDrawTransparentTriangles (); CL_DrawBeams( true ); CL_DrawParticles(); diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index d84fc94f..c388a70e 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -1033,6 +1033,8 @@ void R_DrawBrushModel( cl_entity_t *e ) e->curstate.rendercolor.b, e->curstate.renderamt ); break; case kRenderTransAlpha: + // NOTE: brushes can't change renderamt for 'Solid' mode + pglAlphaFunc( GL_GEQUAL, 0.5f ); default: pglColor4ub( 255, 255, 255, 255 ); break; diff --git a/engine/client/gl_sprite.c b/engine/client/gl_sprite.c index 09073029..a9adecf4 100644 --- a/engine/client/gl_sprite.c +++ b/engine/client/gl_sprite.c @@ -806,6 +806,30 @@ static void R_DrawSpriteQuad( mspriteframe_t *frame, vec3_t org, vec3_t v_right, pglEnd(); } +static _inline qboolean R_SpriteHasLightmap( cl_entity_t *e, int texFormat ) +{ + if( !r_lighting_extended->integer ) + return false; + + if( texFormat != SPR_ALPHTEST ) + return false; + + if( e->curstate.renderamt != 255 ) + return false; + + switch( e->curstate.rendermode ) + { + case kRenderNormal: + case kRenderTransAlpha: + case kRenderTransTexture: + break; + default: + return false; + } + + return true; +} + /* ================= R_DrawSpriteModel @@ -856,10 +880,9 @@ void R_DrawSpriteModel( cl_entity_t *e ) if( psprite->texFormat == SPR_ALPHTEST && e->curstate.rendermode != kRenderTransAdd ) { - if( glState.drawTrans ) - pglDepthMask( GL_TRUE ); pglEnable( GL_ALPHA_TEST ); - pglAlphaFunc( GL_GEQUAL, 0.5f ); + if( alpha != 1.0f ) pglAlphaFunc( GL_GREATER, 0.0f ); + else pglAlphaFunc( GL_GEQUAL, 0.5f ); } if( e->curstate.rendermode == kRenderGlow ) @@ -896,7 +919,7 @@ void R_DrawSpriteModel( cl_entity_t *e ) color[1] = (float)e->curstate.rendercolor.g * ( 1.0f / 255.0f ); color[2] = (float)e->curstate.rendercolor.b * ( 1.0f / 255.0f ); - if( psprite->texFormat == SPR_ALPHTEST && r_lighting_extended->integer && e->curstate.rendermode != kRenderTransAdd ) + if( R_SpriteHasLightmap( e, psprite->texFormat )) { color24 lightColor; qboolean invLight; @@ -992,7 +1015,7 @@ void R_DrawSpriteModel( cl_entity_t *e ) } // draw the sprite 'lightmap' :-) - if( psprite->texFormat == SPR_ALPHTEST && r_lighting_extended->integer && e->curstate.rendermode != kRenderTransAdd ) + if( R_SpriteHasLightmap( e, psprite->texFormat )) { pglEnable( GL_BLEND ); pglDepthFunc( GL_EQUAL ); @@ -1012,11 +1035,7 @@ void R_DrawSpriteModel( cl_entity_t *e ) pglEnable( GL_DEPTH_TEST ); if( psprite->texFormat == SPR_ALPHTEST && e->curstate.rendermode != kRenderTransAdd ) - { - if( glState.drawTrans ) - pglDepthMask( GL_FALSE ); pglDisable( GL_ALPHA_TEST ); - } pglDisable( GL_BLEND ); pglDepthFunc( GL_LEQUAL ); diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index b16ac42d..bb5183f3 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -44,6 +44,7 @@ typedef struct studiolight_s convar_t *r_studio_lerping; convar_t *r_studio_lambert; convar_t *r_drawviewmodel; +convar_t *r_customdraw_playermodel; convar_t *cl_himodels; char model_name[64]; static r_studio_interface_t *pStudioDraw; @@ -93,6 +94,7 @@ void R_StudioInit( void ) r_studio_lerping = Cvar_Get( "r_studio_lerping", "1", CVAR_ARCHIVE, "enables studio animation lerping" ); r_drawviewmodel = Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" ); cl_himodels = Cvar_Get( "cl_himodels", "1", CVAR_ARCHIVE, "draw high-resolution player models in multiplayer" ); + r_customdraw_playermodel = Cvar_Get( "r_customdraw_playermodel", "0", CVAR_ARCHIVE, "allow to drawing playermodel in menu with client renderer" ); // recalc software X and Y alias scale (this stuff is used only by HL software renderer but who knews...) pixelAspect = ((float)scr_height->integer / (float)scr_width->integer); @@ -1362,8 +1364,8 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo ) plight->lightcolor[2] = ambient.b * (1.0f / 255.0f); VectorCopy( plight->lightcolor, lightinfo->color ); - lightinfo->ambientlight = (ambient.r + ambient.g + ambient.b) / 3; - lightinfo->shadelight = (ambient.r + ambient.g + ambient.b); + lightinfo->shadelight = (ambient.r + ambient.g + ambient.b) / 3; + lightinfo->ambientlight = lightinfo->shadelight * 0.1f; if( !ent || !ent->model || !r_dynamic->integer ) return; @@ -2016,6 +2018,10 @@ static void R_StudioSetupRenderer( int rendermode ) { g_iRenderMode = bound( 0, rendermode, kRenderTransInverse ); pglShadeModel( GL_SMOOTH ); // enable gouraud shading + pglDisable( GL_BLEND ); + pglDepthFunc( GL_LEQUAL ); + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); + pglColor4ub( 255, 255, 255, 255 ); } /* @@ -2557,10 +2563,20 @@ void R_DrawStudioModel( cl_entity_t *e ) m_fDoInterp = (e->curstate.effects & EF_NOINTERP) ? false : true; else m_fDoInterp = false; - // select the properly method - if( e->player ) - result = pStudioDraw->StudioDrawPlayer( flags, &e->curstate ); - else result = pStudioDraw->StudioDrawModel( flags ); + // prevent to crash some mods like HLFX in menu Customize + if( !RI.drawWorld && !r_customdraw_playermodel->integer ) + { + if( e->player ) + result = R_StudioDrawPlayer( flags, &e->curstate ); + else result = R_StudioDrawModel( flags ); + } + else + { + // select the properly method + if( e->player ) + result = pStudioDraw->StudioDrawPlayer( flags, &e->curstate ); + else result = pStudioDraw->StudioDrawModel( flags ); + } } /* diff --git a/engine/client/gl_vidnt.c b/engine/client/gl_vidnt.c index 2f6d5536..0a59754a 100644 --- a/engine/client/gl_vidnt.c +++ b/engine/client/gl_vidnt.c @@ -1327,7 +1327,7 @@ static void GL_SetDefaults( void ) pglDisable( GL_BLEND ); pglDisable( GL_ALPHA_TEST ); pglDisable( GL_POLYGON_OFFSET_FILL ); - pglAlphaFunc( GL_GEQUAL, 0.5f ); + pglAlphaFunc( GL_GREATER, 0.0f ); pglEnable( GL_TEXTURE_2D ); pglShadeModel( GL_FLAT ); diff --git a/engine/client/gl_warp.c b/engine/client/gl_warp.c index f3f908f8..05a5bad3 100644 --- a/engine/client/gl_warp.c +++ b/engine/client/gl_warp.c @@ -55,12 +55,12 @@ float r_turbsin[] = static qboolean CheckSkybox( const char *name ) { - const char *skybox_ext[2] = { "tga", "bmp" }; + const char *skybox_ext[3] = { "tga", "bmp", "jpg" }; int i, j, num_checked_sides; const char *sidename; // search for skybox images - for( i = 0; i < 2; i++ ) + for( i = 0; i < 3; i++ ) { num_checked_sides = 0; for( j = 0; j < 6; j++ ) diff --git a/engine/client/vgui/vgui_draw.c b/engine/client/vgui/vgui_draw.c index fb4220d1..87dffd09 100644 --- a/engine/client/vgui/vgui_draw.c +++ b/engine/client/vgui/vgui_draw.c @@ -154,7 +154,7 @@ void VGUI_SetupDrawingImage( int *pColor ) { pglEnable( GL_BLEND ); pglEnable( GL_ALPHA_TEST ); - pglAlphaFunc( GL_GEQUAL, 0.5f ); + pglAlphaFunc( GL_GREATER, 0.0f ); pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); diff --git a/engine/common/imagelib/imagelib.h b/engine/common/imagelib/imagelib.h index dc1300b9..0d29bdf0 100644 --- a/engine/common/imagelib/imagelib.h +++ b/engine/common/imagelib/imagelib.h @@ -138,6 +138,63 @@ typedef struct tga_s } tga_t; #pragma pack( ) +/* +======================================================================== + +.JPG image format + +======================================================================== +*/ +typedef struct huffman_table_s +{ + // Huffman coding tables + byte bits[16]; + byte hval[256]; + byte size[256]; + word code[256]; +} huffman_table_t; + +typedef struct jpg_s +{ + // not a real header + file_t *file; // file + byte *buffer; // jpg buffer + + int width; // width image + int height; // height image + byte *data; // image + int data_precision; // bit per component + int num_components; // number component + int restart_interval; // restart interval + qboolean progressive_mode; // progressive format + + struct + { + int id; // identifier + int h; // horizontal sampling factor + int v; // vertical sampling factor + int t; // quantization table selector + int td; // DC table selector + int ta; // AC table selector + } component_info[3]; // RGB (alpha not supported) + + huffman_table_t hac[4]; // AC table + huffman_table_t hdc[4]; // DC table + + int qtable[4][64]; // quantization table + + struct + { + int ss,se; // progressive jpeg spectral selection + int ah,al; // progressive jpeg successive approx + } scan; + + int dc[3]; + int curbit; + byte curbyte; + +} jpg_t; + // imagelib definitions #define IMAGE_MAXWIDTH 4096 #define IMAGE_MAXHEIGHT 4096 @@ -195,6 +252,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, size_t filesize ); qboolean Image_LoadFNT( const char *name, const byte *buffer, size_t filesize ); qboolean Image_LoadLMP( const char *name, const byte *buffer, size_t filesize ); qboolean Image_LoadPAL( const char *name, const byte *buffer, size_t filesize ); +qboolean Image_LoadJPG( const char *name, const byte *buffer, size_t filesize ); // // formats save diff --git a/engine/common/imagelib/img_jpg.c b/engine/common/imagelib/img_jpg.c new file mode 100644 index 00000000..aafd2e2c --- /dev/null +++ b/engine/common/imagelib/img_jpg.c @@ -0,0 +1,498 @@ +//======================================================================= +// Copyright XashXT Group 2007 © +// img_jpg.c - jpg format load & save +//======================================================================= + +#include "imagelib.h" +#include "mathlib.h" + +jpg_t jpg_file; // jpeg read struct + +int jpeg_read_byte( void ) +{ + // read byte + jpg_file.curbyte = *jpg_file.buffer++; + jpg_file.curbit = 0; + return jpg_file.curbyte; +} + +int jpeg_read_word( void ) +{ + // read word + word i = (jpg_file.buffer[1]<<8)|jpg_file.buffer[0]; + i = ((i << 8) & 0xFF00) + ((i >> 8) & 0x00FF); + jpg_file.buffer += 2; + + return i; +} + +int jpeg_read_bit( void ) +{ + // read bit + register int i; + if( jpg_file.curbit == 0 ) + { + jpeg_read_byte(); + if( jpg_file.curbyte == 0xFF ) + { + while( jpg_file.curbyte == 0xFF ) jpeg_read_byte(); + if( jpg_file.curbyte >= 0xD0 && jpg_file.curbyte <= 0xD7 ) + Q_memset( jpg_file.dc, 0, sizeof(int) * 3 ); + if( jpg_file.curbyte == 0 ) jpg_file.curbyte = 0xFF; + else jpeg_read_byte(); + } + } + + i = (jpg_file.curbyte >> (7 - jpg_file.curbit++)) & 0x01; + if( jpg_file.curbit == 8 ) jpg_file.curbit = 0; + + return i; +} + +int jpeg_read_bits( int num ) +{ + // read num bit + register int i, j; + + for(i = 0, j = 0; i < num; i++) + { + j <<= 1; + j |= jpeg_read_bit(); + } + return j; +} + +int jpeg_bit2int( int bit, int i ) +{ + // convert bit code to int + if((i & (1 << (bit - 1))) > 0) return i; + return -(i ^ ((1 << bit) - 1)); +} + +int jpeg_huffmancode( huffman_table_t *table ) +{ + // get Huffman code + register int i,size,code; + for(size = 1, code = 0, i = 0; size < 17; size++) + { + code <<= 1; + code |= jpeg_read_bit(); + while(table->size[i] <= size) + { + if( table->code[i] == code ) + return table->hval[i]; + i++; + } + } + return code; +} + +void jpeg_idct( float *data ) +{ + // aa&n algorithm inverse DCT + float t0, t1, t2, t3, t4, t5, t6, t7; + float t10, t11, t12, t13; + float z5, z10, z11, z12, z13; + float *dataptr; + int i; + + dataptr = data; + + for(i = 0; i < 8; i++) + { + t0 = dataptr[8 * 0]; + t1 = dataptr[8 * 2]; + t2 = dataptr[8 * 4]; + t3 = dataptr[8 * 6]; + + t10 = t0 + t2; + t11 = t0 - t2; + t13 = t1 + t3; + t12 = - t13 + (t1 - t3) * 1.414213562;//?? + + t0 = t10 + t13; + t3 = t10 - t13; + t1 = t11 + t12; + t2 = t11 - t12; + t4 = dataptr[8 * 1]; + t5 = dataptr[8 * 3]; + t6 = dataptr[8 * 5]; + t7 = dataptr[8 * 7]; + + z13 = t6 + t5; + z10 = t6 - t5; + z11 = t4 + t7; + z12 = t4 - t7; + + t7 = z11 + z13; + t11 = (z11 - z13) * 1.414213562; + z5 = (z10 + z12) * 1.847759065; + t10 = - z5 + z12 * 1.082392200; + t12 = z5 - z10 * 2.613125930; + t6 = t12 - t7; + t5 = t11 - t6; + t4 = t10 + t5; + + dataptr[8 * 0] = t0 + t7; + dataptr[8 * 7] = t0 - t7; + dataptr[8 * 1] = t1 + t6; + dataptr[8 * 6] = t1 - t6; + dataptr[8 * 2] = t2 + t5; + dataptr[8 * 5] = t2 - t5; + dataptr[8 * 4] = t3 + t4; + dataptr[8 * 3] = t3 - t4; + dataptr++; + } + + dataptr = data; + + for(i = 0; i < 8; i++) + { + t10 = dataptr[0] + dataptr[4]; + t11 = dataptr[0] - dataptr[4]; + t13 = dataptr[2] + dataptr[6]; + t12 = - t13 + (dataptr[2] - dataptr[6]) * 1.414213562;//?? + + t0 = t10 + t13; + t3 = t10 - t13; + t1 = t11 + t12; + t2 = t11 - t12; + + z13 = dataptr[5] + dataptr[3]; + z10 = dataptr[5] - dataptr[3]; + z11 = dataptr[1] + dataptr[7]; + z12 = dataptr[1] - dataptr[7]; + + t7 = z11 + z13; + t11 = (z11 - z13) * 1.414213562; + z5 = (z10 + z12) * 1.847759065; + t10 = - z5 + z12 * 1.082392200; + t12 = z5 - z10 * 2.613125930; + + t6 = t12 - t7; + t5 = t11 - t6; + t4 = t10 + t5; + + dataptr[0] = t0 + t7; + dataptr[7] = t0 - t7; + dataptr[1] = t1 + t6; + dataptr[6] = t1 - t6; + dataptr[2] = t2 + t5; + dataptr[5] = t2 - t5; + dataptr[4] = t3 + t4; + dataptr[3] = t3 - t4; + dataptr += 8;//move ptr + } +} + +int jpeg_readmarkers( void ) +{ + // read jpeg markers + int marker, length, i, j, k, l, m; + huffman_table_t *hptr; + + while( 1 ) + { + marker = jpeg_read_byte(); + if( marker != 0xFF ) return 0; + + marker = jpeg_read_byte(); + if( marker != 0xD8 ) + { + length = jpeg_read_word(); + length -= 2; + + switch( marker ) + { + case 0xC0: // baseline + jpg_file.data_precision = jpeg_read_byte(); + jpg_file.height = jpeg_read_word(); + jpg_file.width = jpeg_read_word(); + jpg_file.num_components = jpeg_read_byte(); + if(length - 6 != jpg_file.num_components * 3) return 0; + + for(i = 0; i < jpg_file.num_components; i++) + { + jpg_file.component_info[i].id = jpeg_read_byte(); + j = jpeg_read_byte(); + jpg_file.component_info[i].h = (j >> 4) & 0x0F; + jpg_file.component_info[i].v = j & 0x0F; + jpg_file.component_info[i].t = jpeg_read_byte(); + } + break; + case 0xC1: // extended sequetial, Huffman + case 0xC2: // progressive, Huffman + case 0xC3: // lossless, Huffman + case 0xC5: // differential sequential, Huffman + case 0xC6: // differential progressive, Huffman + case 0xC7: // differential lossless, Huffman + case 0xC8: // reserved for JPEG extensions + case 0xC9: // extended sequential, arithmetic + case 0xCA: // progressive, arithmetic + case 0xCB: // lossless, arithmetic + case 0xCD: // differential sequential, arithmetic + case 0xCE: // differential progressive, arithmetic + case 0xCF: // differential lossless, arithmetic + return 0; // not supported yet + case 0xC4: // huffman table + while( length > 0 ) + { + k = jpeg_read_byte(); + if(k & 0x10) hptr = &jpg_file.hac[k & 0x0F]; + else hptr = &jpg_file.hdc[k & 0x0F]; + for(i = 0, j = 0; i < 16; i++) + { + hptr->bits[i] = jpeg_read_byte(); + j += hptr->bits[i]; + } + length -= 17; + for(i = 0; i < j; i++) hptr->hval[i] = jpeg_read_byte(); + length -= j; + + for(i = 0, k = 0, l = 0; i < 16; i++) + { + for(j = 0; j < hptr->bits[i]; j++, k++) + { + hptr->size[k] = i + 1; + hptr->code[k] = l++; + } + l <<= 1; + } + } + break; + case 0xDB: // quantization table + while( length > 0 ) + { + j = jpeg_read_byte(); + k = (j >> 4) & 0x0F; + for(i = 0; i < 64; i++) + { + if( k )jpg_file.qtable[j][i] = jpeg_read_word(); + else jpg_file.qtable[j][i] = jpeg_read_byte(); + } + length -= 65; + if( k )length -= 64; + } + break; + case 0xD9: // end of image (EOI) + return 0; + case 0xDA: // start of scan (SOS) + j = jpeg_read_byte(); + for(i = 0; i < j; i++) + { + k = jpeg_read_byte(); + m = jpeg_read_byte(); + for( l = 0; l < jpg_file.num_components; l++ ) + { + if( jpg_file.component_info[l].id == k ) + { + jpg_file.component_info[l].td = (m >> 4) & 0x0F; + jpg_file.component_info[l].ta = m & 0x0F; + } + } + } + jpg_file.scan.ss = jpeg_read_byte(); + jpg_file.scan.se = jpeg_read_byte(); + k = jpeg_read_byte(); + jpg_file.scan.ah = (k >> 4) & 0x0F; + jpg_file.scan.al = k & 0x0F; + return 1; + case 0xDD: // restart interval + jpg_file.restart_interval = jpeg_read_word(); + break; + default: + jpg_file.buffer += length; // move ptr + break; + } + } + } +} + + +void jpeg_decompress( void ) +{ + // decompress jpeg file (baseline algorithm) + register int x, y, i, j, k, l, c; + int X, Y, H, V, plane, scaleh[3], scalev[3]; + static float vector[64], dct[64]; + + static const int jpeg_zigzag[64] = + { + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63 + }; + + // 1.0, k = 0; cos(k * PI / 16) * sqrt(2), k = 1...7 + static const float aanscale[8] = + { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; + + scaleh[0] = 1; + scalev[0] = 1; + + if( jpg_file.num_components == 3 ) + { + scaleh[1] = jpg_file.component_info[0].h / jpg_file.component_info[1].h; + scalev[1] = jpg_file.component_info[0].v / jpg_file.component_info[1].v; + scaleh[2] = jpg_file.component_info[0].h / jpg_file.component_info[2].h; + scalev[2] = jpg_file.component_info[0].v / jpg_file.component_info[2].v; + } + + Q_memset( jpg_file.dc, 0, sizeof(int) * 3 ); + + for( Y = 0; Y < jpg_file.height; Y += jpg_file.component_info[0].v << 3 ) + { + if( jpg_file.restart_interval > 0 ) jpg_file.curbit = 0; + for( X = 0; X < jpg_file.width; X += jpg_file.component_info[0].h << 3 ) + { + for(plane = 0; plane < jpg_file.num_components; plane++) + { + for(V = 0; V < jpg_file.component_info[plane].v; V++) + { + for(H = 0; H < jpg_file.component_info[plane].h; H++) + { + i = jpeg_huffmancode(&jpg_file.hdc[jpg_file.component_info[plane].td]); + i &= 0x0F; + vector[0] = jpg_file.dc[plane] + jpeg_bit2int(i,jpeg_read_bits(i)); + jpg_file.dc[plane] = vector[0]; + i = 1; + + while(i < 64) + { + j = jpeg_huffmancode(&jpg_file.hac[jpg_file.component_info[plane].ta]); + if(j == 0) while(i < 64) vector[i++] = 0; + else + { + k = i + ((j >> 4) & 0x0F); + while(i < k) vector[i++] = 0; + j &= 0x0F; + vector[i++] = jpeg_bit2int(j,jpeg_read_bits(j)); + } + } + + k = jpg_file.component_info[plane].t; + for(y = 0, i = 0; y < 8; y++) + { + for(x = 0; x < 8; x++, i++) + { + j = jpeg_zigzag[i]; + dct[i] = vector[j] * jpg_file.qtable[k][j] * aanscale[x] * aanscale[y]; + } + } + + jpeg_idct(dct); + for(y = 0; y < 8; y++) + { + for(x = 0; x < 8; x++) + { + c = ((int)dct[(y << 3) + x] >> 3) + 128; + if(c < 0) c = 0; + else if(c > 255) c = 255; + + if(scaleh[plane] == 1 && scalev[plane] == 1) + { + i = X + x + (H << 3); + j = Y + y + (V << 3); + if(i < jpg_file.width && j < jpg_file.height) + jpg_file.data[((j * jpg_file.width + i) << 2) + plane] = c; + } + else for(l = 0; l < scalev[plane]; l++)//else for, heh... + { + for(k = 0; k < scaleh[plane]; k++) + { + i = X + (x + (H << 3)) * scaleh[plane] + k; + j = Y + (y + (V << 3)) * scalev[plane] + l; + if(i < jpg_file.width && j < jpg_file.height) + jpg_file.data[((j * jpg_file.width + i) << 2) + plane] = c; + } + } + } + } + } + } + } + } + } +} + +void jpeg_ycbcr2rgba( void ) +{ + int i, Y, Cb, Cr, R, G, B; + + // convert YCbCr image to RGBA + for( i = 0; i < jpg_file.width * jpg_file.height << 2; i += 4 ) + { + Y = jpg_file.data[i+0]; + Cb = jpg_file.data[i+1] - 128; + Cr = jpg_file.data[i+2] - 128; + + R = Y + 1.40200 * Cr; + G = Y - 0.34414 * Cb - 0.71414 * Cr; + B = Y + 1.77200 * Cb; + + // bound colors + R = bound( 0, R, 255 ); + G = bound( 0, G, 255 ); + B = bound( 0, B, 255 ); + + jpg_file.data[i+0] = R; + jpg_file.data[i+1] = G; + jpg_file.data[i+2] = B; + jpg_file.data[i+3] = 0xff; // no alpha channel + } + image.flags |= IMAGE_HAS_COLOR; +} + +void jpeg_gray2rgba( void ) +{ + int i, j; + + // grayscale image to RGBA + for(i = 0; i < jpg_file.width * jpg_file.height << 2; i += 4) + { + j = jpg_file.data[i]; + jpg_file.data[i+0] = j; + jpg_file.data[i+1] = j; + jpg_file.data[i+2] = j; + jpg_file.data[i+3] = 0xff; + } +} + + +/* +============= +Image_LoadJPG +============= +*/ +qboolean Image_LoadJPG( const char *name, const byte *buffer, size_t filesize ) +{ + Q_memset( &jpg_file, 0, sizeof( jpg_file )); + jpg_file.buffer = (byte *)buffer; + + if(!jpeg_readmarkers( )) + return false; // it's not a jpg file, just skip it + + image.width = jpg_file.width; + image.height = jpg_file.height; + if(!Image_ValidSize( name )) return false; + + image.size = jpg_file.width * jpg_file.height * 4; + jpg_file.data = Mem_Alloc( host.imagepool, image.size ); + + jpeg_decompress(); + if( jpg_file.num_components == 1 ) jpeg_gray2rgba(); + if( jpg_file.num_components == 3 ) jpeg_ycbcr2rgba(); + + image.rgba = jpg_file.data; + image.type = PF_RGBA_32; + + return true; +} \ No newline at end of file diff --git a/engine/common/imagelib/img_utils.c b/engine/common/imagelib/img_utils.c index 67cb6a8f..09b3c2e6 100644 --- a/engine/common/imagelib/img_utils.c +++ b/engine/common/imagelib/img_utils.c @@ -87,6 +87,7 @@ static const loadpixformat_t load_game[] = { { "%s%s.%s", "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus { "%s%s.%s", "bmp", Image_LoadBMP, IL_HINT_NO }, // hl skyboxes +{ "%s%s.%s", "jpg", Image_LoadJPG, IL_HINT_NO }, // hl skyboxes { "%s%s.%s", "mip", Image_LoadMIP, IL_HINT_NO }, // hl textures from wad or buffer { "%s%s.%s", "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins { "%s%s.%s", "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames diff --git a/engine/engine.dsp b/engine/engine.dsp index 70383746..09fa7182 100644 --- a/engine/engine.dsp +++ b/engine/engine.dsp @@ -286,6 +286,10 @@ SOURCE=.\common\imagelib\img_bmp.c # End Source File # Begin Source File +SOURCE=.\common\imagelib\img_jpg.c +# End Source File +# Begin Source File + SOURCE=.\common\imagelib\img_main.c # End Source File # Begin Source File diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 5f66f19c..4bf248df 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -888,9 +888,7 @@ void SV_PutClientInServer( edict_t *ent ) } else { - if( sv_maxclients->integer > 1 ) - ent->v.netname = MAKE_STRING( Info_ValueForKey( client->userinfo, "name" )); - else ent->v.netname = MAKE_STRING( "player" ); + ent->v.netname = MAKE_STRING( Info_ValueForKey( client->userinfo, "name" )); // fisrt entering svgame.globals->time = sv.time; @@ -1551,40 +1549,40 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo ) // msg command val = Info_ValueForKey( cl->userinfo, "msg" ); - if( Q_strlen( val )) - cl->messagelevel = Q_atoi( val ); + if( Q_strlen( val )) cl->messagelevel = Q_atoi( val ); cl->local_weapons = Q_atoi( Info_ValueForKey( cl->userinfo, "cl_lw" )) ? true : false; cl->lag_compensation = Q_atoi( Info_ValueForKey( cl->userinfo, "cl_lc" )) ? true : false; - if( SV_IsValidEdict( ent )) - { - if( sv_maxclients->integer > 1 ) - { - const char *model = Info_ValueForKey( cl->userinfo, "model" ); + val = Info_ValueForKey( cl->userinfo, "cl_updaterate" ); - // apply custom playermodel - if( Q_strlen( model ) && Q_stricmp( model, "player" )) - { - const char *path = va( "models/player/%s/%s.mdl", model, model ); - Mod_RegisterModel( path, SV_ModelIndex( path )); // register model - SV_SetModel( ent, path ); - cl->modelindex = ent->v.modelindex; - } - else cl->modelindex = 0; + if( Q_strlen( val )) + { + int i = bound( 10, Q_atoi( val ), 300 ); + cl->cl_updaterate = 1.0f / i; + } + + if( sv_maxclients->integer > 1 ) + { + const char *model = Info_ValueForKey( cl->userinfo, "model" ); + + // apply custom playermodel + if( Q_strlen( model ) && Q_stricmp( model, "player" )) + { + const char *path = va( "models/player/%s/%s.mdl", model, model ); + Mod_RegisterModel( path, SV_ModelIndex( path )); // register model + SV_SetModel( ent, path ); + cl->modelindex = ent->v.modelindex; } else cl->modelindex = 0; } + else cl->modelindex = 0; // call prog code to allow overrides svgame.dllFuncs.pfnClientUserInfoChanged( cl->edict, cl->userinfo ); - if( SV_IsValidEdict( ent )) - { - if( sv_maxclients->integer > 1 ) - ent->v.netname = MAKE_STRING(Info_ValueForKey( cl->userinfo, "name" )); - else ent->v.netname = 0; - } + ent->v.netname = MAKE_STRING( Info_ValueForKey( cl->userinfo, "name" )); + if( cl->state >= cs_connected ) cl->sendinfo = true; // needs for update client info } diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 458cf1f6..003894ab 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -2223,7 +2223,10 @@ void pfnMessageBegin( int msg_dest, int msg_num, const float *pOrigin, edict_t * svgame.msg_index = -1; // this is a system message if( msg_num == svc_temp_entity ) + { + svgame.msg_name = "TempEntity"; iSize = -1; // temp entity have variable size + } else iSize = 0; } else diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index eea2d5b0..08bef99e 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -457,7 +457,12 @@ void SV_InitClientMove( void ) // enumerate client hulls for( i = 0; i < 4; i++ ) - svgame.dllFuncs.pfnGetHullBounds( i, svgame.player_mins[i], svgame.player_maxs[i] ); + { + if( svgame.dllFuncs.pfnGetHullBounds( i, svgame.player_mins[i], svgame.player_maxs[i] )) + MsgDev( D_INFO, "SV: hull%i, player_mins: %g %g %g, player_maxs: %g %g %g\n", i, + svgame.player_mins[i][0], svgame.player_mins[i][1], svgame.player_mins[i][2], + svgame.player_maxs[i][0], svgame.player_maxs[i][1], svgame.player_maxs[i][2] ); + } Q_memcpy( svgame.pmove->player_mins, svgame.player_mins, sizeof( svgame.player_mins )); Q_memcpy( svgame.pmove->player_maxs, svgame.player_maxs, sizeof( svgame.player_maxs )); diff --git a/game_launch/game.dsp b/game_launch/game.dsp index 8392fc84..c3550707 100644 --- a/game_launch/game.dsp +++ b/game_launch/game.dsp @@ -50,7 +50,15 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /opt:nowin98 -# ADD LINK32 msvcrt.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /opt:nowin98 /nodefaultlib:"libc.lib" /out:"hl.exe" +# ADD LINK32 msvcrt.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /out:"hl.exe" /opt:nowin98 +# Begin Custom Build +InputPath=.\hl.exe +SOURCE="$(InputPath)" + +"D:\Xash3D\hl.exe" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + copy hl.exe "D:\Xash3D\hl.exe" + +# End Custom Build # Begin Target # Name "game - Win32 Release" diff --git a/game_launch/game.ncb b/game_launch/game.ncb deleted file mode 100644 index 25a4c713acb69747fbc07395361d364e54287403..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41984 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 diff --git a/mainui/ui_title_anim.cpp b/mainui/ui_title_anim.cpp index bc26cb22..af306270 100644 --- a/mainui/ui_title_anim.cpp +++ b/mainui/ui_title_anim.cpp @@ -28,8 +28,8 @@ void UI_PopPButtonStack() { if( hold_button_stack ) return; - UI_SetTitleAnim( AS_TO_BUTTON, ButtonStack[ButtonStackDepth] ); - ButtonStackDepth--; + if ( ButtonStack[ButtonStackDepth] ) UI_SetTitleAnim( AS_TO_BUTTON, ButtonStack[ButtonStackDepth] ); + if ( ButtonStackDepth ) ButtonStackDepth--; } void UI_PushPButtonStack( menuPicButton_s *button ) @@ -103,8 +103,14 @@ void UI_SetTitleAnim( int anim_state, menuPicButton_s *button ) // replace cancel\done button with button which called this menu if( PreClickDepth > uiStatic.menuDepth && anim_state == AS_TO_TITLE ) + { anim_state = AS_TO_BUTTON; - + + // HACK HACK HACK + if ( ButtonStack[ButtonStackDepth + 1] ) + button = ButtonStack[ButtonStackDepth+1]; + } + // don't reset anim if dialog buttons pressed if( button->generic.id == 130 || button->generic.id == 131 ) return; diff --git a/mainui/utils.cpp b/mainui/utils.cpp index c54d3d65..e5f20bf4 100644 --- a/mainui/utils.cpp +++ b/mainui/utils.cpp @@ -1126,6 +1126,7 @@ const char *UI_CheckBox_Key( menuCheckBox_s *cb, int key, int down ) break; case K_ENTER: case K_KP_ENTER: + if( !down ) return sound; if( cb->generic.flags & QMF_MOUSEONLY ) break; sound = uiSoundGlow; @@ -1682,6 +1683,7 @@ const char *UI_Action_Key( menuAction_s *a, int key, int down ) break; case K_ENTER: case K_KP_ENTER: + if( !down ) return sound; if( a->generic.flags & QMF_MOUSEONLY ) break; sound = uiSoundLaunch; @@ -1821,6 +1823,7 @@ const char *UI_Bitmap_Key( menuBitmap_s *b, int key, int down ) break; case K_ENTER: case K_KP_ENTER: + if( !down ) return sound; if( b->generic.flags & QMF_MOUSEONLY ) break; sound = uiSoundLaunch; @@ -1868,9 +1871,9 @@ void UI_Bitmap_Draw( menuBitmap_s *b ) { // don't draw banners until transition is done #ifdef TA_ALT_MODE - if (UI_GetTitleTransFraction()!=10) return; + if ( UI_GetTitleTransFraction() != 10 ) return; #else - if (UI_GetTitleTransFraction()<0.9) return; + if ( UI_GetTitleTransFraction() < 1.0f ) return; #endif } @@ -1973,6 +1976,7 @@ const char *UI_PicButton_Key( menuPicButton_s *b, int key, int down ) break; case K_ENTER: case K_KP_ENTER: + if( !down ) return sound; if( b->generic.flags & QMF_MOUSEONLY ) break; sound = uiSoundLaunch;