From 9d7ab6acf46a8b71ef119d9c252767865522d21d Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin Date: Sat, 31 Mar 2018 17:09:13 +0500 Subject: [PATCH 01/11] Some fixes for FoV, HUD, egon flare and new compilers. (#52) * Fix warnings. * Merge some fixes from https://github.com/Fograin/hl-subs-mod. --- cl_dll/ev_hldm.cpp | 41 ++++++++++++++++++++++++++++++++++++- cl_dll/health.cpp | 3 ++- cl_dll/hl/hl_objects.cpp | 25 +++++++++++++++++++++- cl_dll/hl/hl_weapons.cpp | 2 ++ cl_dll/hud.cpp | 3 ++- cl_dll/hud.h | 2 +- cl_dll/hud_msg.cpp | 16 ++++++++++++++- cl_dll/input_goldsource.cpp | 2 +- cl_dll/scoreboard.cpp | 2 +- dlls/monsters.cpp | 3 ++- dlls/player.cpp | 18 +++++++++++++--- 11 files changed, 105 insertions(+), 12 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 628b5bfa..08127aa1 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1414,6 +1414,17 @@ enum EGON_FIREMODE BEAM *pBeam; BEAM *pBeam2; +TEMPENTITY *pFlare; // Vit_amiN: egon's beam flare + +void EV_EgonFlareCallback( struct tempent_s *ent, float frametime, float currenttime ) +{ + float delta = currenttime - ent->tentOffset.z; // time past since the last scale + if( delta >= ent->tentOffset.y ) + { + ent->entity.curstate.scale += ent->tentOffset.x * delta; + ent->tentOffset.z = currenttime; + } +} void EV_EgonFire( event_args_t *args ) { @@ -1451,7 +1462,7 @@ void EV_EgonFire( event_args_t *args ) if( EV_IsLocal( idx ) ) gEngfuncs.pEventAPI->EV_WeaponAnimation( g_fireAnims1[gEngfuncs.pfnRandomLong( 0, 3 )], 1 ); - if( iStartup == 1 && EV_IsLocal( idx ) && !pBeam && !pBeam2 && cl_lw->value ) //Adrian: Added the cl_lw check for those lital people that hate weapon prediction. + if( iStartup == 1 && EV_IsLocal( idx ) && !( pBeam || pBeam2 || pFlare ) && cl_lw->value ) //Adrian: Added the cl_lw check for those lital people that hate weapon prediction. { vec3_t vecSrc, vecEnd, angles, forward, right, up; pmtrace_t tr; @@ -1499,8 +1510,16 @@ void EV_EgonFire( event_args_t *args ) pBeam->flags |= ( FBEAM_SINENOISE ); pBeam2 = gEngfuncs.pEfxAPI->R_BeamEntPoint( idx | 0x1000, tr.endpos, iBeamModelIndex, 99999, 5.0, 0.08, 0.7, 25, 0, 0, r, g, b ); + + // Vit_amiN: egon beam flare + pFlare = gEngfuncs.pEfxAPI->R_TempSprite( tr.endpos, vec3_origin, 1.0, gEngfuncs.pEventAPI->EV_FindModelIndex( EGON_FLARE_SPRITE ), kRenderGlow, kRenderFxNoDissipation, 1.0, 99999, FTENT_SPRCYCLE | FTENT_PERSIST ); } } + + if( pFlare ) // Vit_amiN: store the last mode for EV_EgonStop() + { + pFlare->tentOffset.x = ( iFireMode == FIRE_WIDE ) ? 1.0f : 0.0f; + } } void EV_EgonStop( event_args_t *args ) @@ -1529,6 +1548,26 @@ void EV_EgonStop( event_args_t *args ) pBeam2->die = 0.0; pBeam2 = NULL; } + + if( pFlare ) // Vit_amiN: egon beam flare + { + pFlare->die = gEngfuncs.GetClientTime(); + + if( gEngfuncs.GetMaxClients() == 1 || !(pFlare->flags & FTENT_NOMODEL) ) + { + if( pFlare->tentOffset.x != 0.0f ) // true for iFireMode == FIRE_WIDE + { + pFlare->callback = &EV_EgonFlareCallback; + pFlare->fadeSpeed = 2.0; // fade out will take 0.5 sec + pFlare->tentOffset.x = 10.0; // scaling speed per second + pFlare->tentOffset.y = 0.1; // min time between two scales + pFlare->tentOffset.z = pFlare->die; // the last callback run time + pFlare->flags = FTENT_FADEOUT | FTENT_CLIENTCUSTOM; + } + } + + pFlare = NULL; + } } } //====================== diff --git a/cl_dll/health.cpp b/cl_dll/health.cpp index d4979c35..eebf0eb0 100644 --- a/cl_dll/health.cpp +++ b/cl_dll/health.cpp @@ -231,7 +231,8 @@ int CHudHealth::Draw( float flTime ) int iHeight = gHUD.m_iFontHeight; int iWidth = HealthWidth / 10; - FillRGBA( x, y, iWidth, iHeight, 255, 160, 0, a ); + UnpackRGB( r, g, b, RGB_YELLOWISH ); + FillRGBA( x, y, iWidth, iHeight, r, g, b, a ); } DrawDamage( flTime ); diff --git a/cl_dll/hl/hl_objects.cpp b/cl_dll/hl/hl_objects.cpp index b51ee693..55822dcb 100644 --- a/cl_dll/hl/hl_objects.cpp +++ b/cl_dll/hl/hl_objects.cpp @@ -29,6 +29,7 @@ extern BEAM *pBeam; extern BEAM *pBeam2; +extern TEMPENTITY *pFlare; // Vit_amiN: egon's energy flare void HUD_GetLastOrg( float *org ); void UpdateBeams( void ) @@ -75,6 +76,28 @@ void UpdateBeams( void ) pBeam2->target = tr.endpos; pBeam2->die = gEngfuncs.GetClientTime() + 0.1; // We keep it alive just a little bit forward in the future, just in case. } + + if( pFlare ) // Vit_amiN: beam flare + { + pFlare->entity.origin = tr.endpos; + pFlare->die = gEngfuncs.GetClientTime() + 0.1; // We keep it alive just a little bit forward in the future, just in case. + + if( gEngfuncs.GetMaxClients() != 1 ) // Singleplayer always draws the egon's energy beam flare + { + pFlare->flags |= FTENT_NOMODEL; + + if( !( tr.allsolid || tr.ent <= 0 || tr.fraction == 1.0 ) ) // Beam hit some non-world entity + { + physent_t *pEntity = gEngfuncs.pEventAPI->EV_GetPhysent( tr.ent ); + + // Not the world, let's assume that we hit something organic ( dog, cat, uncle joe, etc ) + if( pEntity && !( pEntity->solid == SOLID_BSP || pEntity->movetype == MOVETYPE_PUSHSTEP ) ) + { + pFlare->flags &= ~FTENT_NOMODEL; + } + } + } + } } /* @@ -86,6 +109,6 @@ Add game specific, client-side objects here */ void Game_AddObjects( void ) { - if( pBeam && pBeam2 ) + if( pBeam || pBeam2 || pFlare ) // Vit_amiN: egon flare added UpdateBeams(); } diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index 75161a9e..b2c1d7b3 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -34,6 +34,7 @@ extern globalvars_t *gpGlobals; extern int g_iUser1; +extern bool g_hasPredictedFOV; // Vit_amiN: from HUD // Pool of client side entities/entvars_t static entvars_t ev[32]; @@ -881,6 +882,7 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm to->client.fuser2 = player.m_flNextAmmoBurn; to->client.fuser3 = player.m_flAmmoStartCharge; to->client.maxspeed = player.pev->maxspeed; + g_hasPredictedFOV = true; // Vit_amiN: ready //HL Weapons to->client.vuser1[0] = player.ammo_9mm; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 05bda284..195dfa5a 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -413,6 +413,7 @@ int CHud::MsgFunc_Logo( const char *pszName, int iSize, void *pbuf ) } float g_lastFOV = 0.0; +bool g_hasPredictedFOV = false; // Vit_amiN: it'll became true after the first prediction /* ============ @@ -514,7 +515,7 @@ int CHud::MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf ) int def_fov = CVAR_GET_FLOAT( "default_fov" ); //Weapon prediction already takes care of changing the fog. ( g_lastFOV ). - if( cl_lw && cl_lw->value ) + if( g_hasPredictedFOV ) return 1; g_lastFOV = newfov; diff --git a/cl_dll/hud.h b/cl_dll/hud.h index decfa917..f3e1ed85 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -230,7 +230,7 @@ public: void InitHUDData( void ); int VidInit( void ); int Draw( float flTime ); - int DrawPlayers( int xoffset, float listslot, int nameoffset = 0, char *team = NULL ); // returns the ypos where it finishes drawing + int DrawPlayers( int xoffset, float listslot, int nameoffset = 0, const char *team = NULL ); // returns the ypos where it finishes drawing void UserCmd_ShowScores( void ); void UserCmd_HideScores( void ); int MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ); diff --git a/cl_dll/hud_msg.cpp b/cl_dll/hud_msg.cpp index 47f8bc92..b435a85c 100644 --- a/cl_dll/hud_msg.cpp +++ b/cl_dll/hud_msg.cpp @@ -25,6 +25,10 @@ extern BEAM *pBeam; extern BEAM *pBeam2; +extern TEMPENTITY *pFlare; // Vit_amiN + +extern float g_lastFOV; // Vit_amiN +extern bool g_hasPredictedFOV; // Vit_amiN /// USER-DEFINED SERVER MESSAGE HANDLERS @@ -48,6 +52,11 @@ int CHud::MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf ) // reset concussion effect m_iConcussionEffect = 0; + // Vit_amiN: reset the FOV + m_iFOV = 0; // default_fov + g_lastFOV = 0.0f; + g_hasPredictedFOV = false; + return 1; } @@ -72,6 +81,7 @@ void CHud::MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf ) //Probably not a good place to put this. pBeam = pBeam2 = NULL; + pFlare = NULL; // Vit_amiN: clear egon's beam flare } int CHud::MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf ) @@ -107,10 +117,14 @@ int CHud::MsgFunc_Damage( const char *pszName, int iSize, void *pbuf ) int CHud::MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ) { + int r, g, b; BEGIN_READ( pbuf, iSize ); m_iConcussionEffect = READ_BYTE(); if( m_iConcussionEffect ) - this->m_StatusIcons.EnableIcon( "dmg_concuss", 255, 160, 0 ); + { + UnpackRGB( r, g, b, RGB_YELLOWISH ); // Vit_amiN: fixed + this->m_StatusIcons.EnableIcon( "dmg_concuss", r, g, b ); + } else this->m_StatusIcons.DisableIcon( "dmg_concuss" ); return 1; diff --git a/cl_dll/input_goldsource.cpp b/cl_dll/input_goldsource.cpp index bd997784..c45841cb 100644 --- a/cl_dll/input_goldsource.cpp +++ b/cl_dll/input_goldsource.cpp @@ -1368,7 +1368,7 @@ void IN_JoyMove ( float frametime, usercmd_t *cmd ) // y=ax^b; where a = 300 and b = 1.3 // also x values are in increments of 800 (so this is factored out) // then bounds check result to level out excessively high spin rates - fTemp = 300.0 * pow(abs(fAxisValue) / 800.0, 1.3); + fTemp = 300.0 * pow(fabs(fAxisValue) / 800.0, 1.3); if (fTemp > 14000.0) fTemp = 14000.0; // restore direction information diff --git a/cl_dll/scoreboard.cpp b/cl_dll/scoreboard.cpp index 0f26c6f2..5d52787c 100644 --- a/cl_dll/scoreboard.cpp +++ b/cl_dll/scoreboard.cpp @@ -337,7 +337,7 @@ int CHudScoreboard::Draw( float fTime ) extern float *GetClientColor( int client ); // returns the ypos where it finishes drawing -int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, char *team ) +int CHudScoreboard::DrawPlayers( int xpos_rel, float list_slot, int nameoffset, const char *team ) { int can_show_packetloss = 0; int FAR_RIGHT; diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index 1e1d3de3..953d1a69 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -2118,7 +2118,8 @@ void CBaseMonster::StartMonster( void ) SetThink( &CBaseMonster::CallMonsterThink ); pev->nextthink += RANDOM_FLOAT( 0.1, 0.4 ); // spread think times. - if( !FStringNull( pev->targetname ) )// wait until triggered + // Vit_amiN: fixed -- now it doesn't touch any scripted_sequence target + if( !FStringNull( pev->targetname ) && !m_pCine )// wait until triggered { SetState( MONSTERSTATE_IDLE ); // UNDONE: Some scripted sequence monsters don't have an idle? diff --git a/dlls/player.cpp b/dlls/player.cpp index bbd668ba..b1d28e67 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -1860,6 +1860,7 @@ void CBasePlayer::PreThink( void ) { CBaseEntity *pTrain = CBaseEntity::Instance( pev->groundentity ); float vel; + int iGearId; // Vit_amiN: keeps the train control HUD in sync if( !pTrain ) { @@ -1900,10 +1901,12 @@ void CBasePlayer::PreThink( void ) pTrain->Use( this, this, USE_SET, (float)vel ); } - if( vel ) + iGearId = TrainSpeed( pTrain->pev->speed, pTrain->pev->impulse ); + + if( iGearId != ( m_iTrain & 0x0F ) ) // Vit_amiN: speed changed { - m_iTrain = TrainSpeed( (int)pTrain->pev->speed, pTrain->pev->impulse ); - m_iTrain |= TRAIN_ACTIVE|TRAIN_NEW; + m_iTrain = iGearId; + m_iTrain |= TRAIN_ACTIVE | TRAIN_NEW; } } else if( m_iTrain & TRAIN_ACTIVE ) @@ -2919,6 +2922,8 @@ void CBasePlayer::Precache( void ) if( gInitHUD ) m_fInitHUD = TRUE; + + pev->fov = m_iFOV; // Vit_amiN: restore the FOV on level change or map/saved game load } int CBasePlayer::Save( CSave &save ) @@ -3326,6 +3331,8 @@ void CBasePlayer::ForceClientDllUpdate( void ) { m_iClientHealth = -1; m_iClientBattery = -1; + m_iClientHideHUD = -1; // Vit_amiN: forcing to update + m_iClientFOV = -1; // Vit_amiN: force client weapons to be sent m_iTrain |= TRAIN_NEW; // Force new train message. m_fWeapon = FALSE; // Force weapon send m_fKnownItem = FALSE; // Force weaponinit messages. @@ -3890,6 +3897,11 @@ void CBasePlayer::UpdateClientData( void ) WRITE_BYTE( m_iFlashBattery ); MESSAGE_END(); + // Vit_amiN: the geiger state could run out of sync, too + MESSAGE_BEGIN( MSG_ONE, gmsgGeigerRange, NULL, pev ); + WRITE_BYTE( 0 ); + MESSAGE_END(); + InitStatusBar(); } From f6ffc92d5d17c0d52ddceacff08193bd320b60a0 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 1 Apr 2018 20:38:56 +0300 Subject: [PATCH 02/11] Always update gHUD.m_iFOV on SetFOV message. Fix #53 --- cl_dll/hl/hl_weapons.cpp | 2 -- cl_dll/hud.cpp | 5 ----- cl_dll/hud_msg.cpp | 2 -- 3 files changed, 9 deletions(-) diff --git a/cl_dll/hl/hl_weapons.cpp b/cl_dll/hl/hl_weapons.cpp index b2c1d7b3..75161a9e 100644 --- a/cl_dll/hl/hl_weapons.cpp +++ b/cl_dll/hl/hl_weapons.cpp @@ -34,7 +34,6 @@ extern globalvars_t *gpGlobals; extern int g_iUser1; -extern bool g_hasPredictedFOV; // Vit_amiN: from HUD // Pool of client side entities/entvars_t static entvars_t ev[32]; @@ -882,7 +881,6 @@ void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cm to->client.fuser2 = player.m_flNextAmmoBurn; to->client.fuser3 = player.m_flAmmoStartCharge; to->client.maxspeed = player.pev->maxspeed; - g_hasPredictedFOV = true; // Vit_amiN: ready //HL Weapons to->client.vuser1[0] = player.ammo_9mm; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 195dfa5a..3ef72889 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -413,7 +413,6 @@ int CHud::MsgFunc_Logo( const char *pszName, int iSize, void *pbuf ) } float g_lastFOV = 0.0; -bool g_hasPredictedFOV = false; // Vit_amiN: it'll became true after the first prediction /* ============ @@ -514,10 +513,6 @@ int CHud::MsgFunc_SetFOV( const char *pszName, int iSize, void *pbuf ) int newfov = READ_BYTE(); int def_fov = CVAR_GET_FLOAT( "default_fov" ); - //Weapon prediction already takes care of changing the fog. ( g_lastFOV ). - if( g_hasPredictedFOV ) - return 1; - g_lastFOV = newfov; if( newfov == 0 ) diff --git a/cl_dll/hud_msg.cpp b/cl_dll/hud_msg.cpp index b435a85c..7cc2fbad 100644 --- a/cl_dll/hud_msg.cpp +++ b/cl_dll/hud_msg.cpp @@ -28,7 +28,6 @@ extern BEAM *pBeam2; extern TEMPENTITY *pFlare; // Vit_amiN extern float g_lastFOV; // Vit_amiN -extern bool g_hasPredictedFOV; // Vit_amiN /// USER-DEFINED SERVER MESSAGE HANDLERS @@ -55,7 +54,6 @@ int CHud::MsgFunc_ResetHUD( const char *pszName, int iSize, void *pbuf ) // Vit_amiN: reset the FOV m_iFOV = 0; // default_fov g_lastFOV = 0.0f; - g_hasPredictedFOV = false; return 1; } From 0c515e34649dc7ce9e5be5fabfd71c61b0db04f0 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Apr 2018 23:54:10 +0300 Subject: [PATCH 03/11] Update mobility interface --- engine/mobility_int.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/engine/mobility_int.h b/engine/mobility_int.h index 88f63315..d8b6120a 100644 --- a/engine/mobility_int.h +++ b/engine/mobility_int.h @@ -34,7 +34,7 @@ extern "C" { #define TOUCH_FL_DEF_HIDE (1U << 6) #define TOUCH_FL_DRAW_ADDITIVE (1U << 7) #define TOUCH_FL_STROKE (1U << 8) -#define TOUCH_FL_PRECISION (1U << 9) +#define TOUCH_FL_PRECISION (1U << 9) typedef struct mobile_engfuncs_s { @@ -65,13 +65,21 @@ typedef struct mobile_engfuncs_s void (*pfnTouchSetClientOnly)( unsigned char state ); // Clean defaults list - void (*pfnTouchResetDefaultButtons)(); + void (*pfnTouchResetDefaultButtons)( void ); + // Draw scaled font for client + int (*pfnDrawScaledCharacter)( int x, int y, int number, int r, int g, int b, float scale ); + + void (*pfnSys_Warn)( const char *format, ... ); + + // Get native object for current platform. + // Pass NULL to arguments to receive an array of available objects or NULL if nothing + void *(*pfnGetNativeObject)( const char *obj ); + + void (*pfnSetCustomClientID)( const char *id ); // To be continued... } mobile_engfuncs_t; -extern mobile_engfuncs_t *gMobileEngfuncs; - // function exported from client // returns 0 on no error otherwise error typedef int (*pfnMobilityInterface)( mobile_engfuncs_t *gMobileEngfuncs ); From cec6d7a1bc6383a81cdbb7622e6e4a1ec9ec1b07 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Apr 2018 23:56:01 +0300 Subject: [PATCH 04/11] Add HUD_MessageBox. Rename isXashFWGS to IsXashFWGS --- cl_dll/cdll_int.cpp | 17 ++++++++++++++++- cl_dll/cl_util.h | 3 ++- cl_dll/hud_redraw.cpp | 2 +- cl_dll/input_mouse.cpp | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index fec09792..dc9199ba 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -376,7 +376,22 @@ void DLLEXPORT HUD_MobilityInterface( mobile_engfuncs_t *gpMobileEngfuncs ) gMobileEngfuncs = gpMobileEngfuncs; } -bool isXashFWGS() +bool HUD_MessageBox( const char *msg ) +{ + gEngfuncs.Con_Printf( msg ); // just in case + + if( IsXashFWGS() ) + { + gMobileEngfuncs->pfnSys_Warn( msg ); + return true; + } + + // TODO: Load SDL2 and call ShowSimpleMessageBox + + return false; +} + +bool IsXashFWGS() { return gMobileEngfuncs != NULL; } diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index 23f12230..0cb65f32 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -181,5 +181,6 @@ inline void UnpackRGB( int &r, int &g, int &b, unsigned long ulRGB )\ HSPRITE LoadSprite( const char *pszName ); -bool isXashFWGS(); +bool HUD_MessageBox( const char *msg ); +bool IsXashFWGS(); #endif diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index 06b25a33..4a46a519 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -235,7 +235,7 @@ int CHud::DrawHudString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int DrawUtfString( int xpos, int ypos, int iMaxX, const char *szIt, int r, int g, int b ) { - if (isXashFWGS()) + if (IsXashFWGS()) { // xash3d: reset unicode state gEngfuncs.pfnVGUI2DrawCharacterAdditive( 0, 0, 0, 0, 0, 0, 0 ); diff --git a/cl_dll/input_mouse.cpp b/cl_dll/input_mouse.cpp index 8d57091b..3233d797 100644 --- a/cl_dll/input_mouse.cpp +++ b/cl_dll/input_mouse.cpp @@ -69,7 +69,7 @@ void IN_Shutdown( void ) void IN_Init( void ) { #ifdef SUPPORT_GOLDSOURCE_INPUT - if (isXashFWGS()) { + if (IsXashFWGS()) { gEngfuncs.Con_Printf( "FWGS Xash3D input is in use\n" ); currentInput = &fwgsInput; } else { From 6e5062b39e2118ccb967015265ce81df57dd1e08 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 2 Apr 2018 23:56:26 +0300 Subject: [PATCH 05/11] Check for bad game data(missing or invalid hud.txt) --- cl_dll/hud.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 3ef72889..62c32b41 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -381,6 +381,18 @@ void CHud::VidInit( void ) // assumption: number_1, number_2, etc, are all listed and loaded sequentially m_HUD_number_0 = GetSpriteIndex( "number_0" ); + if( m_HUD_number_0 == -1 ) + { + const char *msg = "There is something wrong with your game data! Please, reinstall\n"; + + if( HUD_MessageBox( msg ) ) + { + gEngfuncs.pfnClientCmd( "quit\n" ); + } + + return; + } + m_iFontHeight = m_rgrcRects[m_HUD_number_0].bottom - m_rgrcRects[m_HUD_number_0].top; m_Ammo.VidInit(); From 71f55bb119c7ec4d0c5dd6dc0c29dee5aa9bcda7 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Tue, 3 Apr 2018 21:39:07 +0300 Subject: [PATCH 06/11] Add mingw support to CMakeLists.txt. Add crosscompiling instructions to README.md --- CMakeLists.txt | 5 +++++ README.md | 8 ++++++++ cl_dll/CMakeLists.txt | 5 ++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bd7fe664..64c48928 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,11 @@ else() message(STATUS "Building for 32 Bit") endif() +if (MINGW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--add-stdcall-alias") +endif() + # add_compile_options for older cmake versions if(${CMAKE_VERSION} VERSION_LESS "3.0.2") macro(add_compile_options) diff --git a/README.md b/README.md index a57d94b5..be0a5fa8 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ Half-Life SDK for Xash3D & GoldSource with some fixes. cmake ../ make +Crosscompiling using mingw: + + mkdir build-mingw && cd build-mingw + TOOLCHAIN_PREFIX=i686-w64-mingw32 # check up the actual mingw prefix of your mingw installation + cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER="$TOOLCHAIN_PREFIX-gcc" -DCMAKE_CXX_COMPILER="$TOOLCHAIN_PREFIX-g++" + You may enable or disable some build options by -Dkey=value. All available build options are defined in CMakeLists.txt at root directory. See below if you want to build the GoldSource compatible libraries. @@ -68,6 +74,8 @@ or when using make without cmake: Unlike original client by Valve the resulting client library will not depend on vgui or SDL2 just like the one that's used in FWGS Xash3d. +Note for **Windows**: it's not possible to create GoldSource compatible libraries using mingw, only msvc builds will work. + Note for **Linux**: GoldSource requires libraries (both client and server) to be compiled with libstdc++ bundled with g++ of major version 4 (versions from 4.6 to 4.9 should work). If your Linux distribution does not provide compatible g++ version you have several options. diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index b848aa6c..323d156f 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -32,7 +32,10 @@ if(NOT MSVC) add_compile_options(-fno-exceptions) # GCC/Clang flag add_compile_options(-Wno-write-strings) # GCC/Clang flag add_definitions(-D_LINUX -DLINUX) # It seems enough for all non-Win32 systems - add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf ) + add_definitions(-Dstricmp=strcasecmp -Dstrnicmp=strncasecmp) + if(NOT MINGW) + add_definitions(-D_snprintf=snprintf -D_vsnprintf=vsnprintf) + endif() else() add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) endif() From d112f720ad305db4266fc39ed89add34d575ec92 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Tue, 3 Apr 2018 23:17:56 +0300 Subject: [PATCH 07/11] Test building with mingw on travis --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9e165b81..fecd6f5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,9 @@ os: sudo: true before_script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install gcc-multilib g++-multilib; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then sudo apt-get install mingw-w64-i686-dev binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686; fi script: - mkdir -p build && cd build - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=0 && make -j3 && rm -rf * - - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=1 && make -j3 && rm -rf * \ No newline at end of file + - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=1 && make -j3 && rm -rf * + - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then cd ..; mkdir build-mingw; cd build-mingw; cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++; make -j3; fi From ec6afbe86d311a4679c282611efd53b0aea53d5a Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 4 Apr 2018 17:30:53 +0300 Subject: [PATCH 08/11] Fix addressing variables in travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fecd6f5b..01d2ba27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,9 @@ os: sudo: true before_script: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install gcc-multilib g++-multilib; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then sudo apt-get install mingw-w64-i686-dev binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "gcc" ]]; then sudo apt-get install mingw-w64-i686-dev binutils-mingw-w64-i686 gcc-mingw-w64-i686 g++-mingw-w64-i686; fi script: - mkdir -p build && cd build - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=0 && make -j3 && rm -rf * - cmake ../ -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DUSE_VOICEMGR=1 && make -j3 && rm -rf * - - if [[ "$TRAVIS_OS_NAME" == "linux" && "CC" == "gcc" ]]; then cd ..; mkdir build-mingw; cd build-mingw; cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++; make -j3; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "gcc" ]]; then cd ..; mkdir build-mingw; cd build-mingw; cmake ../ -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ && make -j3; fi From d17387c61ffe0a81b2ae6c6737bc7f08d7040ab3 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Sat, 7 Apr 2018 04:21:16 +0300 Subject: [PATCH 09/11] Some fixes for PM_InitTextureTypes() from ReGameDLL_CS --- pm_shared/pm_shared.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pm_shared/pm_shared.c b/pm_shared/pm_shared.c index abe7b317..ace56595 100644 --- a/pm_shared/pm_shared.c +++ b/pm_shared/pm_shared.c @@ -168,24 +168,23 @@ void PM_InitTextureTypes() char buffer[512]; int i, j; byte *pMemFile; - int fileSize, filePos; + int fileSize, filePos = 0; static qboolean bTextureTypeInit = false; if( bTextureTypeInit ) return; - memset(&( grgszTextureName[0][0] ), 0, CTEXTURESMAX * CBTEXTURENAMEMAX ); - memset( grgchTextureType, 0, CTEXTURESMAX ); + memset(&( grgszTextureName[0][0] ), 0, sizeof( grgszTextureName ) ); + memset( grgchTextureType, 0, sizeof( grgchTextureType ) ); gcTextures = 0; - fileSize = pmove->COM_FileSize( "sound/materials.txt" ); - pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, NULL ); + pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, &fileSize ); if( !pMemFile ) return; - memset( buffer, 0, 512 ); - filePos = 0; + memset( buffer, 0, sizeof( buffer ) ); + // for each line in the file... while( pmove->memfgets( pMemFile, fileSize, &filePos, buffer, 511 ) != NULL && (gcTextures < CTEXTURESMAX ) ) { From 75bc5105e786fef7ad865fee5226fbf88906541a Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Sun, 8 Apr 2018 19:59:11 +0300 Subject: [PATCH 10/11] Remove old TEXTURETYPE code --- dlls/sound.cpp | 84 ++------------------------------------------------ dlls/world.cpp | 3 -- 2 files changed, 3 insertions(+), 84 deletions(-) diff --git a/dlls/sound.cpp b/dlls/sound.cpp index 31d0b7aa..30c44326 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -1454,14 +1454,6 @@ void EMIT_GROUPNAME_SUIT( edict_t *entity, const char *groupname ) // texture name to a material type. Play footstep sound based // on material type. -int fTextureTypeInit = FALSE; - -#define CTEXTURESMAX 512 // max number of textures loaded - -int gcTextures = 0; -char grgszTextureName[CTEXTURESMAX][CBTEXTURENAMEMAX]; // texture names -char grgchTextureType[CTEXTURESMAX]; // parallel array of texture types - // open materials.txt, get size, alloc space, // save in array. Only works first time called, // ignored on subsequent calls. @@ -1513,87 +1505,17 @@ static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer return NULL; } -void TEXTURETYPE_Init() -{ - char buffer[512]; - int i, j; - byte *pMemFile; - int fileSize, filePos = 0; - - if( fTextureTypeInit ) - return; - - memset( &( grgszTextureName[0][0] ), 0, CTEXTURESMAX * CBTEXTURENAMEMAX ); - memset( grgchTextureType, 0, CTEXTURESMAX ); - - gcTextures = 0; - - pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/materials.txt", &fileSize ); - if( !pMemFile ) - return; - - memset( buffer, 0, 512 ); - // for each line in the file... - while( memfgets( pMemFile, fileSize, filePos, buffer, 511 ) != NULL && ( gcTextures < CTEXTURESMAX) ) - { - // skip whitespace - i = 0; - while( buffer[i] && isspace( buffer[i] ) ) - i++; - - if( !buffer[i] ) - continue; - - // skip comment lines - if( buffer[i] == '/' || !isalpha( buffer[i] ) ) - continue; - - // get texture type - grgchTextureType[gcTextures] = toupper( buffer[i++] ); - - // skip whitespace - while( buffer[i] && isspace( buffer[i] ) ) - i++; - - if( !buffer[i] ) - continue; - - // get sentence name - j = i; - while( buffer[j] && !isspace( buffer[j] ) ) - j++; - - if( !buffer[j] ) - continue; - - // null-terminate name and save in sentences array - j = Q_min( j, CBTEXTURENAMEMAX - 1 + i ); - buffer[j] = 0; - strcpy( &( grgszTextureName[gcTextures++][0] ), &( buffer[i] ) ); - } - - g_engfuncs.pfnFreeFile( pMemFile ); - - fTextureTypeInit = TRUE; -} - // given texture name, find texture type // if not found, return type 'concrete' // NOTE: this routine should ONLY be called if the // current texture under the player changes! +extern "C" char PM_FindTextureType( char *name ); + char TEXTURETYPE_Find( char *name ) { - // CONSIDER: pre-sort texture names and perform faster binary search here - - for( int i = 0; i < gcTextures; i++ ) - { - if( !strnicmp( name, &( grgszTextureName[i][0] ), CBTEXTURENAMEMAX - 1 ) ) - return grgchTextureType[i]; - } - - return CHAR_TEX_CONCRETE; + return PM_FindTextureType(name); } // play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the diff --git a/dlls/world.cpp b/dlls/world.cpp index 3b9a1f1e..ae5a41bc 100644 --- a/dlls/world.cpp +++ b/dlls/world.cpp @@ -500,9 +500,6 @@ void CWorld::Precache( void ) // ok to call this multiple times, calls after first are ignored. SENTENCEG_Init(); - // init texture type array from materials.txt - TEXTURETYPE_Init(); - // the area based ambient sounds MUST be the first precache_sounds // player precaches W_Precache(); // get weapon precaches From b63c1753a142e98598a86deac9e64276997261c8 Mon Sep 17 00:00:00 2001 From: Night Owl Date: Wed, 11 Apr 2018 04:48:42 +0500 Subject: [PATCH 11/11] Do not break motd(Revert old changes). --- dlls/multiplay_gamerules.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 7922d413..de91ac6e 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -1650,8 +1650,8 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) { // read from the MOTD.txt file int length, char_count = 0; - const char *pFileList; - const char *aFileList = pFileList = (const char*)LOAD_FILE_FOR_ME( CVAR_GET_STRING( "motdfile" ), &length ); + char *pFileList; + char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( CVAR_GET_STRING( "motdfile" ), &length ); // send the server name MESSAGE_BEGIN( MSG_ONE, gmsgServerName, NULL, client ); @@ -1679,10 +1679,10 @@ void CHalfLifeMultiplay::SendMOTDToClient( edict_t *client ) if( char_count < MAX_MOTD_LENGTH ) pFileList = aFileList + char_count; else - pFileList = 0; + *pFileList = 0; MESSAGE_BEGIN( MSG_ONE, gmsgMOTD, NULL, client ); - WRITE_BYTE( pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come + WRITE_BYTE( *pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come WRITE_STRING( chunk ); MESSAGE_END(); }