From a7e63d3fc1f4eed83f4e88b56afe38fea8fdaf69 Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 25 Nov 2025 22:05:31 +0200 Subject: [PATCH 01/96] Fix int to bool compare warning warning C4805: '!=': unsafe mix of type 'const int' and type 'bool' in operation --- src/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp b/src/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp index f806c1e69c..18b94fa05f 100644 --- a/src/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp +++ b/src/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp @@ -14,11 +14,11 @@ static void RecvProxy_ScaleChangeFlag(const CRecvProxyData* pData, void* pStruct, void* pOut) { CNEOPredictedViewModelMuzzleFlash* pViewModel = ((CNEOPredictedViewModelMuzzleFlash*)pStruct); - if (pData->m_Value.m_Int != pViewModel->m_bScaleChangeFlag) + if (static_cast(pData->m_Value.m_Int) != pViewModel->m_bScaleChangeFlag) { // Client side value for m_flModelScale will not be updated correctly, work out the correct scale clientside pViewModel->UpdateMuzzleFlashProperties(GetActiveWeapon()); } - // Chain through to the default recieve proxy ... + // Chain through to the default receive proxy ... RecvProxy_IntToEHandle(pData, pStruct, pOut); } #endif // CLIENT_DLL From 73f4785930b6936b45870aced33b0162bf70166c Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 3 Dec 2025 02:49:53 +0200 Subject: [PATCH 02/96] Fix narrowing conversions --- src/CMakeLists.txt | 10 +++ src/common/neo/narrow_cast.h | 72 +++++++++++++++++++ src/game/client/c_baseentity.cpp | 4 ++ src/game/client/c_point_commentary_node.cpp | 16 +++++ src/game/client/c_rope.cpp | 8 +++ src/game/client/c_sceneentity.cpp | 4 ++ src/game/client/c_soundscape.cpp | 12 ++++ src/game/client/cdll_util.cpp | 8 +++ src/game/client/game_controls/MapOverview.cpp | 8 +++ src/game/client/game_controls/teammenu.cpp | 4 ++ src/game/client/hl2/hud_filmdemo.cpp | 8 +++ src/game/client/hl2/hud_hdrdemo.cpp | 8 +++ src/game/client/hl2/hud_suitpower.cpp | 37 ++++++++++ src/game/client/hud_animationinfo.cpp | 12 ++++ src/game/client/hud_basechat.cpp | 43 ++++++++++- src/game/client/hud_closecaption.cpp | 24 +++++++ src/game/client/hud_lcd.cpp | 4 ++ src/game/client/hud_pdump.cpp | 36 ++++++++++ src/game/client/hud_squadstatus.cpp | 4 ++ src/game/client/hud_voicestatus.cpp | 8 +++ src/game/client/hudelement.h | 6 +- src/game/client/in_main.cpp | 4 ++ src/game/client/mp3player.cpp | 8 +++ src/game/client/mp3player.h | 6 ++ src/game/client/mumble.cpp | 4 ++ src/game/client/neo/ui/neo_hud_ammo.cpp | 2 +- .../client/neo/ui/neo_hud_deathnotice.cpp | 16 ++--- src/game/client/neo/ui/neo_hud_message.cpp | 2 +- src/game/client/neo/ui/neo_root.cpp | 4 +- .../client/neo/ui/neo_root_serverbrowser.cpp | 4 +- src/game/client/neo/ui/neo_root_settings.cpp | 14 ++-- src/game/client/neo/ui/neo_ui.cpp | 10 +-- src/game/server/AI_ResponseSystem.cpp | 16 +++++ src/game/server/EventLog.cpp | 29 ++++++++ src/game/server/TemplateEntities.cpp | 12 ++++ src/game/server/ai_basenpc.cpp | 9 +++ src/game/server/ai_hint.cpp | 4 ++ src/game/server/ai_networkmanager.cpp | 4 ++ src/game/server/ai_schedule.cpp | 4 ++ src/game/server/ai_speech.cpp | 8 +++ src/game/server/baseentity.cpp | 12 ++++ src/game/server/cbase.cpp | 8 +++ src/game/server/client.cpp | 4 ++ src/game/server/env_debughistory.cpp | 8 +++ src/game/server/gameinterface.cpp | 8 +++ src/game/server/nav_area.cpp | 10 +++ src/game/server/nav_file.cpp | 4 ++ src/game/server/neo/bot/neo_bot_profile.cpp | 2 +- src/game/server/sceneentity.cpp | 16 +++++ src/game/shared/GameStats.cpp | 4 ++ src/game/shared/SoundEmitterSystem.cpp | 4 ++ src/game/shared/activitylist.cpp | 4 ++ src/game/shared/ammodef.cpp | 4 ++ src/game/shared/gamerules_register.cpp | 4 ++ src/game/shared/mapentities_shared.cpp | 8 +++ src/game/shared/predictioncopy.cpp | 40 +++++++++++ src/game/shared/props_shared.cpp | 4 ++ src/game/shared/saverestore.cpp | 32 ++++++++- src/public/SoundParametersInternal.cpp | 8 +++ src/public/datamap.h | 8 +-- src/public/dt_recv.h | 12 ++++ src/public/dt_send.h | 8 +++ src/public/tier1/utlmemory.h | 8 +++ src/public/tier1/utlvector.h | 5 ++ src/tier1/CMakeLists.txt | 3 + src/tier1/strtools.cpp | 4 ++ src/tier1/utlstring.cpp | 5 +- 67 files changed, 697 insertions(+), 36 deletions(-) create mode 100644 src/common/neo/narrow_cast.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24f2395684..f9ecb99757 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -115,6 +115,12 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWith ) endif() +add_compile_definitions( + # Whether to validate narrowing conversions done with narrow_cast(...) + # If not, will simply alias narrow_cast to static_cast + $<$:PARANOID_NARROWING> +) + if(NEO_RAD_TELEMETRY_DISABLED) add_compile_definitions(RAD_TELEMETRY_DISABLED) endif() @@ -142,6 +148,10 @@ add_compile_definitions( # NEO NOTE (nullsystem): New defines since 2025-02-18 TF2 SDK Update PLATFORM_64BITS INCLUDED_STEAM2_USERID_STRUCTS + + # NEO NOTE (Rain): Needed to remove platform specific min/max C macro pollution; + # instead you can use the Min/Max templated functions from basetypes.h. + NOMINMAX ) if(OS_WINDOWS) diff --git a/src/common/neo/narrow_cast.h b/src/common/neo/narrow_cast.h new file mode 100644 index 0000000000..771988b2fb --- /dev/null +++ b/src/common/neo/narrow_cast.h @@ -0,0 +1,72 @@ +#pragma once + +#ifndef NOMINMAX +#error Please use Max/Min from basetypes.h instead +#endif +#ifdef max +#error Please use Max from basetypes.h instead +#endif +#ifdef min +#error Please use Min from basetypes.h instead +#endif + +#ifdef PARANOID_NARROWING +#include +#include +#include +#include +#endif // PARANOID_NARROWING + +#ifdef PARANOID_NARROWING +template +concept Numeric = std::is_arithmetic_v> || + std::is_enum_v>; + +template +concept DifferentTypes = (!std::is_same_v); + +// Sanity check narrowing conversions. +// Asserts that value v must fit into type . +template + requires DifferentTypes +constexpr void AssertFitsInto(const Value& input) +{ + using inputType = std::remove_reference_t; + using outputType = std::add_const_t; + static_assert(!std::is_reference_v); + static_assert(!std::is_reference_v); + + [[maybe_unused]] const auto& output = static_cast(input); + static_assert(!std::is_same_v); + + [[maybe_unused]] const auto& roundtrip = static_cast(output); + static_assert(std::is_same_v); + + // Value of type A converted to type B, and then back to type A, should equal the original value. + Assert(roundtrip == input); + + // Value of type A converted to type B, where the signedness of A and B differs, should not underflow. + if (std::is_signed_v != std::is_signed_v) + { + Assert((input < inputType{}) == (output < outputType{})); + } +} +#else +consteval void AssertFitsInto(const auto&) { /* optimized away */ } +#endif // PARANOID_NARROWING + +#ifdef PARANOID_NARROWING +// static_cast for narrowing conversions. +// It will assert to ensure the conversion is valid. +template + requires DifferentTypes +constexpr Container narrow_cast(Value&& v) +{ + AssertFitsInto(v); + return static_cast(std::forward(v)); +} +#else +// Alias for static_cast, for marking narrowing conversions. +// If you want to validate the conversions, toggle the NEO_PARANOID_NARROWING in the main CMakeLists.txt. +#define narrow_cast static_cast +#endif // PARANOID_NARROWING diff --git a/src/game/client/c_baseentity.cpp b/src/game/client/c_baseentity.cpp index fd889800cc..15b2af7afa 100644 --- a/src/game/client/c_baseentity.cpp +++ b/src/game/client/c_baseentity.cpp @@ -5195,7 +5195,11 @@ void C_BaseEntity::AllocateIntermediateData( void ) #if !defined( NO_ENTITY_PREDICTION ) if ( m_pOriginalData ) return; +#ifdef NEO + auto allocsize = GetIntermediateDataSize(); +#else size_t allocsize = GetIntermediateDataSize(); +#endif Assert( allocsize > 0 ); m_pOriginalData = new unsigned char[ allocsize ]; diff --git a/src/game/client/c_point_commentary_node.cpp b/src/game/client/c_point_commentary_node.cpp index 527d5ca0da..a5871f38be 100644 --- a/src/game/client/c_point_commentary_node.cpp +++ b/src/game/client/c_point_commentary_node.cpp @@ -449,7 +449,11 @@ void CHudCommentary::Paint() vgui::surface()->DrawSetTextFont( hFont ); vgui::surface()->DrawSetTextColor( clr ); vgui::surface()->DrawSetTextPos( m_iSpeakersX, m_iSpeakersY ); +#ifdef NEO + vgui::surface()->DrawPrintText( m_szSpeakers, narrow_cast(wcslen(m_szSpeakers)) ); +#else vgui::surface()->DrawPrintText( m_szSpeakers, wcslen(m_szSpeakers) ); +#endif if ( COMMENTARY_BUTTONS & IN_ATTACK ) { @@ -461,7 +465,11 @@ void CHudCommentary::Paint() { UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) ); vgui::surface()->DrawSetTextPos( m_iSpeakersX, iY ); +#ifdef NEO + vgui::surface()->DrawPrintText( wzFinal, narrow_cast(wcslen(wzFinal)) ); +#else vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) ); +#endif } pszText = g_pVGuiLocalize->Find( "#Commentary_SecondaryAttack" ); @@ -471,7 +479,11 @@ void CHudCommentary::Paint() UTIL_ReplaceKeyBindings( pszText, 0, wzFinal, sizeof( wzFinal ) ); vgui::surface()->GetTextSize( hFont, wzFinal, w, h ); vgui::surface()->DrawSetTextPos( m_iBarX + m_iBarWide - w, iY ); +#ifdef NEO + vgui::surface()->DrawPrintText( wzFinal, narrow_cast(wcslen(wzFinal)) ); +#else vgui::surface()->DrawPrintText( wzFinal, wcslen(wzFinal) ); +#endif } } @@ -480,7 +492,11 @@ void CHudCommentary::Paint() int iCountWide, iCountTall; vgui::surface()->GetTextSize( hFont, m_szCount, iCountWide, iCountTall ); vgui::surface()->DrawSetTextPos( wide - m_iCountXFR - iCountWide, m_iCountY ); +#ifdef NEO + vgui::surface()->DrawPrintText( m_szCount, narrow_cast(wcslen(m_szCount)) ); +#else vgui::surface()->DrawPrintText( m_szCount, wcslen(m_szCount) ); +#endif // Draw the icon vgui::surface()->DrawSetColor( Color(255,170,0,GetAlpha()) ); diff --git a/src/game/client/c_rope.cpp b/src/game/client/c_rope.cpp index cbc724e791..2165676e0f 100644 --- a/src/game/client/c_rope.cpp +++ b/src/game/client/c_rope.cpp @@ -187,7 +187,11 @@ class CQueuedRopeMemoryManager m_DeleteOnSwitch[m_nCurrentStack].RemoveAll(); } +#ifdef NEO + inline void *Alloc( unsigned bytes ) +#else inline void *Alloc( size_t bytes ) +#endif { MEM_ALLOC_CREDIT(); void *pReturn = m_QueuedRopeMemory[m_nCurrentStack].Alloc( bytes, false ); @@ -564,7 +568,11 @@ void CRopeManager::DrawRenderCache( bool bShadowDepth ) (iRopeCount * sizeof(C_RopeKeyframe::BuildRopeQueuedData_t)) + (iNodeCount * (sizeof(Vector) * 2)); +#ifdef NEO + void *pMemory = m_QueuedModeMemory.Alloc( narrow_cast(iMemoryNeeded) ); +#else void *pMemory = m_QueuedModeMemory.Alloc( iMemoryNeeded ); +#endif CRopeManager::RopeRenderData_t *pRenderCachesStart = (CRopeManager::RopeRenderData_t *)pMemory; C_RopeKeyframe::BuildRopeQueuedData_t *pBuildRopeQueuedDataStart = (C_RopeKeyframe::BuildRopeQueuedData_t *)(pRenderCachesStart + iRenderCacheCount); diff --git a/src/game/client/c_sceneentity.cpp b/src/game/client/c_sceneentity.cpp index 069819f48a..1918fbcb3d 100644 --- a/src/game/client/c_sceneentity.cpp +++ b/src/game/client/c_sceneentity.cpp @@ -758,7 +758,11 @@ CChoreoScene *C_SceneEntity::LoadScene( const char *filename ) Q_FixSlashes( loadfile ); char *pBuffer = NULL; +#ifdef NEO + const auto bufsize = narrow_cast(scenefilecache->GetSceneBufferSize(loadfile)); +#else size_t bufsize = scenefilecache->GetSceneBufferSize( loadfile ); +#endif if ( bufsize <= 0 ) return NULL; diff --git a/src/game/client/c_soundscape.cpp b/src/game/client/c_soundscape.cpp index b56ff950cf..82586dc02c 100644 --- a/src/game/client/c_soundscape.cpp +++ b/src/game/client/c_soundscape.cpp @@ -430,7 +430,11 @@ static int SoundscapeCompletion( const char *partial, char commands[ COMMAND_COM if ( Q_strstr( partial, cmdname ) && strlen(partial) > strlen(cmdname) + 1 ) { substring = (char *)partial + strlen( cmdname ) + 1; +#ifdef NEO + substringLen = V_strlen(substring); +#else substringLen = strlen(substring); +#endif } int i = 0; @@ -752,7 +756,11 @@ void C_SoundscapeSystem::ProcessPlayLooping( KeyValues *pAmbient, const subsound } else if ( !Q_strcasecmp( pKey->GetName(), "soundlevel" ) ) { +#ifdef NEO + if ( !Q_strncasecmp( pKey->GetString(), "SNDLVL_", sizeof( "SNDLVL_" )-1 ) ) +#else if ( !Q_strncasecmp( pKey->GetString(), "SNDLVL_", strlen( "SNDLVL_" ) ) ) +#endif { soundlevel = TextToSoundLevel( pKey->GetString() ); } @@ -932,7 +940,11 @@ void C_SoundscapeSystem::ProcessPlayRandom( KeyValues *pPlayRandom, const subsou } else if ( !Q_strcasecmp( pKey->GetName(), "soundlevel" ) ) { +#ifdef NEO + if ( !Q_strncasecmp( pKey->GetString(), "SNDLVL_", sizeof( "SNDLVL_" )-1 ) ) +#else if ( !Q_strncasecmp( pKey->GetString(), "SNDLVL_", strlen( "SNDLVL_" ) ) ) +#endif { sound.soundlevel.start = TextToSoundLevel( pKey->GetString() ); sound.soundlevel.range = 0; diff --git a/src/game/client/cdll_util.cpp b/src/game/client/cdll_util.cpp index 6561138b50..5dcc4e65cd 100644 --- a/src/game/client/cdll_util.cpp +++ b/src/game/client/cdll_util.cpp @@ -961,7 +961,11 @@ void UTIL_ReplaceKeyBindings( const wchar_t *inbuf, int inbufsizebytes, OUT_Z_BY outbuf[pos] = '\0'; wcscat( outbuf, token ); +#ifdef NEO + pos += narrow_cast(wcslen(token)); +#else pos += wcslen(token); +#endif } else { @@ -972,7 +976,11 @@ void UTIL_ReplaceKeyBindings( const wchar_t *inbuf, int inbufsizebytes, OUT_Z_BY pos += 1; } wcscat( outbuf, locName ); +#ifdef NEO + pos += narrow_cast(wcslen(locName)); +#else pos += wcslen(locName); +#endif if ( bAddBrackets ) { wcscat( outbuf, L"]" ); diff --git a/src/game/client/game_controls/MapOverview.cpp b/src/game/client/game_controls/MapOverview.cpp index 0deb535cac..ff6215e893 100644 --- a/src/game/client/game_controls/MapOverview.cpp +++ b/src/game/client/game_controls/MapOverview.cpp @@ -699,12 +699,20 @@ bool CMapOverview::DrawIcon( MapObject_t *obj ) // draw black shadow text surface()->DrawSetTextColor( 0, 0, 0, 255 ); surface()->DrawSetTextPos( x+1, y ); +#ifdef NEO + surface()->DrawPrintText( iconText, V_wcslen(iconText) ); +#else surface()->DrawPrintText( iconText, wcslen(iconText) ); +#endif // draw name in color surface()->DrawSetTextColor( textColor->r(), textColor->g(), textColor->b(), 255 ); surface()->DrawSetTextPos( x, y ); +#ifdef NEO + surface()->DrawPrintText( iconText, V_wcslen(iconText) ); +#else surface()->DrawPrintText( iconText, wcslen(iconText) ); +#endif } return true; diff --git a/src/game/client/game_controls/teammenu.cpp b/src/game/client/game_controls/teammenu.cpp index e1adf32ddc..33d32dcd78 100644 --- a/src/game/client/game_controls/teammenu.cpp +++ b/src/game/client/game_controls/teammenu.cpp @@ -185,7 +185,11 @@ void CTeamMenu::Update() void CTeamMenu::LoadMapPage( const char *mapName ) { // Save off the map name so we can re-load the page in ApplySchemeSettings(). +#ifdef NEO + V_strncpy( m_szMapName, mapName, narrow_cast( strlen( mapName ) + 1 ) ); +#else Q_strncpy( m_szMapName, mapName, strlen( mapName ) + 1 ); +#endif char mapRES[ MAX_PATH ]; diff --git a/src/game/client/hl2/hud_filmdemo.cpp b/src/game/client/hl2/hud_filmdemo.cpp index ca21a855f8..c87a072056 100644 --- a/src/game/client/hl2/hud_filmdemo.cpp +++ b/src/game/client/hl2/hud_filmdemo.cpp @@ -114,7 +114,11 @@ void CHudFilmDemo::Paint() iLength += vgui::surface()->GetCharacterWidth( hFont, *wch ); } vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY ); +#ifdef NEO + vgui::surface()->DrawPrintText( tempString, narrow_cast(wcslen(tempString)) ); +#else vgui::surface()->DrawPrintText( tempString, wcslen(tempString) ); +#endif } tempString = g_pVGuiLocalize->Find( m_pRightStringID ); @@ -126,7 +130,11 @@ void CHudFilmDemo::Paint() iLength += vgui::surface()->GetCharacterWidth( hFont, *wch ); } vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY ); +#ifdef NEO + vgui::surface()->DrawPrintText( tempString, narrow_cast(wcslen(tempString)) ); +#else vgui::surface()->DrawPrintText( tempString, wcslen(tempString) ); +#endif } } diff --git a/src/game/client/hl2/hud_hdrdemo.cpp b/src/game/client/hl2/hud_hdrdemo.cpp index eaaaf1fe20..56edd2c8a1 100644 --- a/src/game/client/hl2/hud_hdrdemo.cpp +++ b/src/game/client/hl2/hud_hdrdemo.cpp @@ -110,7 +110,11 @@ void CHudHDRDemo::Paint() iLength += vgui::surface()->GetCharacterWidth( hFont, *wch ); } vgui::surface()->DrawSetTextPos( floor(wide * 0.25) - (iLength / 2), m_iLeftY ); +#ifdef NEO + vgui::surface()->DrawPrintText(tempString, V_wcslen(tempString)); +#else vgui::surface()->DrawPrintText(tempString, wcslen(tempString)); +#endif } // Right Title @@ -123,7 +127,11 @@ void CHudHDRDemo::Paint() iLength += vgui::surface()->GetCharacterWidth( hFont, *wch ); } vgui::surface()->DrawSetTextPos( ceil(wide * 0.75) - (iLength / 2), m_iRightY ); +#ifdef NEO + vgui::surface()->DrawPrintText(tempString, V_wcslen(tempString)); +#else vgui::surface()->DrawPrintText(tempString, wcslen(tempString)); +#endif } } diff --git a/src/game/client/hl2/hud_suitpower.cpp b/src/game/client/hl2/hud_suitpower.cpp index ec849b0fba..6cf70186d1 100644 --- a/src/game/client/hl2/hud_suitpower.cpp +++ b/src/game/client/hl2/hud_suitpower.cpp @@ -26,6 +26,15 @@ DECLARE_HUDELEMENT( CHudSuitPower ); #define SUITPOWER_INIT -1 +#ifdef NEO +template +constexpr void DrawPrintLiteral(const wchar (&literal)[len], vgui::FontDrawType_t drawType=vgui::FONT_DRAW_DEFAULT) +{ + static_assert(len > 0); + surface()->DrawPrintText(&literal[0], ARRAYSIZE(literal) - 1, drawType); +} +#endif + //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- @@ -189,6 +198,12 @@ void CHudSuitPower::Paint() wchar_t *tempString = g_pVGuiLocalize->Find("#Valve_Hud_AUX_POWER"); +#ifdef NEO + if (tempString) + surface()->DrawPrintText(tempString, narrow_cast(wcslen(tempString))); + else + DrawPrintLiteral(L"AUX POWER"); +#else if (tempString) { surface()->DrawPrintText(tempString, wcslen(tempString)); @@ -197,6 +212,7 @@ void CHudSuitPower::Paint() { surface()->DrawPrintText(L"AUX POWER", wcslen(L"AUX POWER")); } +#endif if ( m_iActiveSuitDevices ) { @@ -209,6 +225,12 @@ void CHudSuitPower::Paint() surface()->DrawSetTextPos(text2_xpos, ypos); +#ifdef NEO + if (tempString) + surface()->DrawPrintText(tempString, narrow_cast(wcslen(tempString))); + else + DrawPrintLiteral(L"OXYGEN"); +#else if (tempString) { surface()->DrawPrintText(tempString, wcslen(tempString)); @@ -217,6 +239,7 @@ void CHudSuitPower::Paint() { surface()->DrawPrintText(L"OXYGEN", wcslen(L"OXYGEN")); } +#endif ypos += text2_gap; } @@ -226,6 +249,12 @@ void CHudSuitPower::Paint() surface()->DrawSetTextPos(text2_xpos, ypos); +#ifdef NEO + if (tempString) + surface()->DrawPrintText(tempString, narrow_cast(wcslen(tempString))); + else + DrawPrintLiteral(L"FLASHLIGHT"); +#else if (tempString) { surface()->DrawPrintText(tempString, wcslen(tempString)); @@ -234,6 +263,7 @@ void CHudSuitPower::Paint() { surface()->DrawPrintText(L"FLASHLIGHT", wcslen(L"FLASHLIGHT")); } +#endif ypos += text2_gap; } @@ -243,6 +273,12 @@ void CHudSuitPower::Paint() surface()->DrawSetTextPos(text2_xpos, ypos); +#ifdef NEO + if (tempString) + surface()->DrawPrintText(tempString, narrow_cast(wcslen(tempString))); + else + DrawPrintLiteral(L"SPRINT"); +#else if (tempString) { surface()->DrawPrintText(tempString, wcslen(tempString)); @@ -251,6 +287,7 @@ void CHudSuitPower::Paint() { surface()->DrawPrintText(L"SPRINT", wcslen(L"SPRINT")); } +#endif ypos += text2_gap; } } diff --git a/src/game/client/hud_animationinfo.cpp b/src/game/client/hud_animationinfo.cpp index 27949987d1..788e591d16 100644 --- a/src/game/client/hud_animationinfo.cpp +++ b/src/game/client/hud_animationinfo.cpp @@ -117,12 +117,20 @@ void CHudAnimationInfo::PaintString( int& x, int &y, const char *sz, Color *pLeg surface()->DrawSetTextColor( Color( 0, 0, 0, 0 ) ); } +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); surface()->DrawSetTextColor( m_ItemColor ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif int fontHeight = surface()->GetFontTall( m_ItemFont ); @@ -265,7 +273,11 @@ static int HudElementCompletion( const char *partial, char commands[ COMMAND_COM // Insert into lookup if ( substring[0] ) { +#ifdef NEO + if ( !V_strncasecmp( e->GetName(), substring, V_strlen( substring ) ) ) +#else if ( !Q_strncasecmp( e->GetName(), substring, strlen( substring ) ) ) +#endif { add = true; } diff --git a/src/game/client/hud_basechat.cpp b/src/game/client/hud_basechat.cpp index fc989878f1..7cee13bc15 100644 --- a/src/game/client/hud_basechat.cpp +++ b/src/game/client/hud_basechat.cpp @@ -116,7 +116,11 @@ wchar_t* ConvertCRtoNL( wchar_t *str ) void StripEndNewlineFromString( char *str ) { +#ifdef NEO + int s = narrow_cast( strlen( str ) - 1 ); +#else int s = strlen( str ) - 1; +#endif if ( s >= 0 ) { if ( str[s] == '\n' || str[s] == '\r' ) @@ -126,7 +130,11 @@ void StripEndNewlineFromString( char *str ) void StripEndNewlineFromString( wchar_t *str ) { +#ifdef NEO + int s = narrow_cast( wcslen( str ) - 1 ); +#else int s = wcslen( str ) - 1; +#endif if ( s >= 0 ) { if ( str[s] == L'\n' || str[s] == L'\r' ) @@ -947,7 +955,11 @@ void CBaseHudChat::MsgFunc_TextMsg( bf_read &msg ) case HUD_PRINTNOTIFY: g_pVGuiLocalize->ConstructString_safe( outputBuf, szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) ); +#ifdef NEO + len = narrow_cast(strlen(szString)); +#else len = strlen( szString ); +#endif if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' ) { Q_strncat( szString, "\n", sizeof(szString), 1 ); @@ -958,7 +970,11 @@ void CBaseHudChat::MsgFunc_TextMsg( bf_read &msg ) case HUD_PRINTTALK: g_pVGuiLocalize->ConstructString_safe( outputBuf, szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) ); +#ifdef NEO + len = narrow_cast(strlen(szString)); +#else len = strlen( szString ); +#endif if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' ) { Q_strncat( szString, "\n", sizeof(szString), 1 ); @@ -970,7 +986,11 @@ void CBaseHudChat::MsgFunc_TextMsg( bf_read &msg ) case HUD_PRINTCONSOLE: g_pVGuiLocalize->ConstructString_safe( outputBuf, szBuf[0], 4, szBuf[1], szBuf[2], szBuf[3], szBuf[4] ); g_pVGuiLocalize->ConvertUnicodeToANSI( outputBuf, szString, sizeof(szString) ); +#ifdef NEO + len = narrow_cast(strlen(szString)); +#else len = strlen( szString ); +#endif if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' ) { Q_strncat( szString, "\n", sizeof(szString), 1 ); @@ -1027,7 +1047,11 @@ void CBaseHudChat::MsgFunc_VoiceSubtitle( bf_read &msg ) int len; g_pVGuiLocalize->ConvertUnicodeToANSI( szBuf, szString, sizeof(szString) ); +#ifdef NEO + len = narrow_cast(strlen(szString)); +#else len = strlen( szString ); +#endif if ( len && szString[len-1] != '\n' && szString[len-1] != '\r' ) { Q_strncat( szString, "\n", sizeof(szString), 1 ); @@ -1465,7 +1489,11 @@ void CBaseHudChatLine::InsertAndColorizeText( wchar_t *buf, int clientIndex ) return; wchar_t *txt = m_text; +#ifdef NEO + int lineLen = narrow_cast( wcslen( m_text ) ); +#else int lineLen = wcslen( m_text ); +#endif Color colCustom; if ( m_text[0] == COLOR_PLAYERNAME || m_text[0] == COLOR_LOCATION || m_text[0] == COLOR_NORMAL || m_text[0] == COLOR_ACHIEVEMENT || m_text[0] == COLOR_CUSTOM || m_text[0] == COLOR_HEXCODE || m_text[0] == COLOR_HEXCODE_ALPHA ) @@ -1594,7 +1622,11 @@ void CBaseHudChatLine::InsertAndColorizeText( wchar_t *buf, int clientIndex ) m_textRanges.AddToTail(range); range.start = range.end; +#ifdef NEO + range.end = narrow_cast(wcslen(m_text)); +#else range.end = wcslen(m_text); +#endif range.color = pChat->GetTextColorForClient(COLOR_NORMAL, clientIndex); m_textRanges.AddToTail(range); } @@ -1623,7 +1655,11 @@ void CBaseHudChatLine::InsertAndColorizeText( wchar_t *buf, int clientIndex ) { TextRange range; range.start = 0; +#ifdef NEO + range.end = narrow_cast(wcslen(m_text)); +#else range.end = wcslen( m_text ); +#endif range.color = pChat->GetTextColorForClient( COLOR_NORMAL, clientIndex ); m_textRanges.AddToTail( range ); } @@ -1927,7 +1963,12 @@ void CBaseHudChat::ChatPrintf( int iPlayerIndex, int iFilter, const char *fmt, . engine->GetPlayerInfo( iPlayerIndex, &sPlayerInfo ); } +#ifdef NEO + int bufSize = narrow_cast( (strlen( pmsg ) + 1 ) * sizeof(wchar_t) ); + Assert(bufSize <= sizeof(msg) + 1 + sizeof(wchar_t)); +#else int bufSize = (strlen( pmsg ) + 1 ) * sizeof(wchar_t); +#endif wchar_t *wbuf = static_cast( _alloca( bufSize ) ); if ( wbuf ) { @@ -1964,7 +2005,7 @@ void CBaseHudChat::ChatPrintf( int iPlayerIndex, int iFilter, const char *fmt, . { iNameStart = (nameInString - wbuf); #ifdef NEO - iNameLength = wcslen( wideName ) - 1; + iNameLength = V_wcslen( wideName ) - 1; #else iNameLength = wcslen( wideName ); #endif diff --git a/src/game/client/hud_closecaption.cpp b/src/game/client/hud_closecaption.cpp index d832317013..116e41ee41 100644 --- a/src/game/client/hud_closecaption.cpp +++ b/src/game/client/hud_closecaption.cpp @@ -198,7 +198,11 @@ void CCloseCaptionWorkUnit::SetStream( const wchar_t *stream ) delete[] m_pszStream; m_pszStream = NULL; +#ifdef NEO + int len = narrow_cast( wcslen( stream ) ); +#else int len = wcslen( stream ); +#endif Assert( len < 4096 ); m_pszStream = new wchar_t[ len + 1 ]; wcsncpy( m_pszStream, stream, len ); @@ -1718,7 +1722,11 @@ void CHudCloseCaption::ComputeStreamWork( int available_width, CCloseCaptionItem WorkUnitParams params; const wchar_t *curpos = item->GetStream(); +#ifdef NEO + int streamlen = narrow_cast( wcslen( curpos ) ); +#else int streamlen = wcslen( curpos ); +#endif CUtlVector< Color > colorStack; const wchar_t *most_recent_space = NULL; @@ -1938,7 +1946,11 @@ void CHudCloseCaption::DrawStream( wrect_t &rcText, wrect_t &rcWindow, CCloseCap vgui::surface()->DrawSetTextFont( useF ); vgui::surface()->DrawSetTextPos( rcOut.left, rcOut.top ); vgui::surface()->DrawSetTextColor( useColor ); +#ifdef NEO + vgui::surface()->DrawPrintText( wu->GetStream(), narrow_cast( wcslen( wu->GetStream() ) ) ); +#else vgui::surface()->DrawPrintText( wu->GetStream(), wcslen( wu->GetStream() ) ); +#endif } } @@ -2098,7 +2110,11 @@ class CAsyncCaption for ( int i = 0; i < c; ++i ) { caption_t *caption = m_Tokens[ i ]; +#ifdef NEO + int len = narrow_cast( wcslen( caption->stream ) + 1 ); +#else int len = wcslen( caption->stream ) + 1; +#endif if ( curlen + len >= maxlen ) break; @@ -2259,7 +2275,11 @@ class CAsyncCaption if ( !in ) return; +#ifdef NEO + int len = narrow_cast( wcslen( in ) ); +#else int len = wcslen( in ); +#endif stream = new wchar_t[ len + 1 ]; wcsncpy( stream, in, len + 1 ); } @@ -2682,7 +2702,11 @@ static int EmitCaptionCompletion( const char *partial, char commands[ COMMAND_CO if ( Q_strstr( partial, cmdname ) && strlen(partial) > strlen(cmdname) + 1 ) { substring = (char *)partial + strlen( cmdname ) + 1; +#ifdef NEO + substringLen = narrow_cast(strlen(substring)); +#else substringLen = strlen(substring); +#endif } StringIndex_t i = g_pVGuiLocalize->GetFirstStringIndex(); diff --git a/src/game/client/hud_lcd.cpp b/src/game/client/hud_lcd.cpp index e66f9060e8..3328d7fe99 100644 --- a/src/game/client/hud_lcd.cpp +++ b/src/game/client/hud_lcd.cpp @@ -1259,7 +1259,11 @@ bool CLCD::ExtractArrayIndex( char *str, size_t bufsize, int *index ) Q_strncpy( o, s, left ); Q_strncat( o, pos2 + 1, sizeof( o ), COPY_ALL_CHARACTERS ); +#ifdef NEO + V_strncpy( str, o, narrow_cast(bufsize) ); +#else Q_strncpy( str, o, bufsize ); +#endif return true; } diff --git a/src/game/client/hud_pdump.cpp b/src/game/client/hud_pdump.cpp index fec352e20a..2815e43e14 100644 --- a/src/game/client/hud_pdump.cpp +++ b/src/game/client/hud_pdump.cpp @@ -319,7 +319,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( x[ col ] - 10, y - fonttallBig - 2 ); Q_snprintf( sz, sizeof( sz ), "entity # %i: %s%s%s", ent->entindex(), classprefix, classname, classextra ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif for ( i = 0; i < c; i++ ) { @@ -334,7 +338,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( x[ col ] - 10, y ); Q_snprintf( sz, sizeof( sz ), "%s", slot->classname ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttallMedium-1; Q_strncpy( currentclass, slot->classname, sizeof( currentclass ) ); @@ -349,7 +357,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( x[ col ], y ); Q_snprintf( sz, sizeof( sz ), "%s", slot->fieldstring ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttall; @@ -384,7 +396,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( xpos, y ); Q_strncpy( sz, pFirstAndLongestString, sizeof( sz ) ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttall; @@ -395,7 +411,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( xpos, y ); Q_strncpy( sz, "Networked, not checked", sizeof( sz ) ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttall; @@ -406,7 +426,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( xpos, y ); Q_strncpy( sz, "Networked, error checked", sizeof( sz ) ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttall; @@ -417,7 +441,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( xpos, y ); Q_strncpy( sz, "Differs, but within tolerance", sizeof( sz ) ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttall; @@ -428,7 +456,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( xpos, y ); Q_strncpy( sz, "Differs, but not networked", sizeof( sz ) ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttall; @@ -439,7 +471,11 @@ void CPDumpPanel::Paint() surface()->DrawSetTextPos( xpos, y ); Q_strncpy( sz, "Differs, networked", sizeof( sz ) ); g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted) ); +#ifdef NEO + surface()->DrawPrintText( szconverted, V_wcslen( szconverted ) ); +#else surface()->DrawPrintText( szconverted, wcslen( szconverted ) ); +#endif y += fonttall; } diff --git a/src/game/client/hud_squadstatus.cpp b/src/game/client/hud_squadstatus.cpp index e5d7d2715d..90be52b359 100644 --- a/src/game/client/hud_squadstatus.cpp +++ b/src/game/client/hud_squadstatus.cpp @@ -272,7 +272,11 @@ void CHudSquadStatus::Paint() surface()->DrawSetTextFont(m_hTextFont); surface()->DrawSetTextColor(m_SquadTextColor); surface()->DrawSetTextPos(text_xpos, text_ypos); +#ifdef NEO + surface()->DrawPrintText(text, narrow_cast(wcslen(text))); +#else surface()->DrawPrintText(text, wcslen(text)); +#endif } } diff --git a/src/game/client/hud_voicestatus.cpp b/src/game/client/hud_voicestatus.cpp index 1e396ffef9..b52446012c 100644 --- a/src/game/client/hud_voicestatus.cpp +++ b/src/game/client/hud_voicestatus.cpp @@ -448,7 +448,11 @@ void CHudVoiceStatus::Paint() int iTextSpace = item_wide - text_xpos; // write as much of the name as will fit, truncate the rest and add ellipses +#ifdef NEO + int iNameLength = V_wcslen(szconverted); +#else int iNameLength = wcslen(szconverted); +#endif const wchar_t *pszconverted = szconverted; int iTextWidthCounter = 0; for( int j=0;jDrawPrintText( szconverted, V_wcslen(szconverted) ); +#else surface()->DrawPrintText( szconverted, wcslen(szconverted) ); +#endif ypos -= ( item_spacing + item_tall ); diff --git a/src/game/client/hudelement.h b/src/game/client/hudelement.h index 6954fe2abb..2398876a3d 100644 --- a/src/game/client/hudelement.h +++ b/src/game/client/hudelement.h @@ -84,7 +84,11 @@ class CHudElement : public CGameEventListener void operator delete( void *pMem ) { #if defined( _DEBUG ) - int size = _msize( pMem ); +#ifdef NEO + size_t size = _msize(pMem); +#else + int size = _msize( pMem ); +#endif memset( pMem, 0xcd, size ); #endif free( pMem ); diff --git a/src/game/client/in_main.cpp b/src/game/client/in_main.cpp index bfa0824a79..973b0c2c5b 100644 --- a/src/game/client/in_main.cpp +++ b/src/game/client/in_main.cpp @@ -260,7 +260,11 @@ int KB_ConvertString( char *in, char **ppout ) *pOut = '\0'; +#ifdef NEO + int maxlen = V_strlen( sz ) + 1; +#else int maxlen = strlen( sz ) + 1; +#endif pOut = ( char * )malloc( maxlen ); Q_strncpy( pOut, sz, maxlen ); *ppout = pOut; diff --git a/src/game/client/mp3player.cpp b/src/game/client/mp3player.cpp index 9871a8bc25..e494bd7f57 100644 --- a/src/game/client/mp3player.cpp +++ b/src/game/client/mp3player.cpp @@ -118,7 +118,11 @@ static ConCommand mp3( "mp3", mp3_f, "Show/hide mp3 player UI." ); // albumlen - // Output : static bool //----------------------------------------------------------------------------- +#ifdef NEO +static bool SplitArtistAlbum( char const *relative, char *artist, int artistlen, char *album, int albumlen ) +#else static bool SplitArtistAlbum( char const *relative, char *artist, size_t artistlen, char *album, size_t albumlen ) +#endif { artist[ 0 ] = 0; album[ 0 ] = 0; @@ -1519,7 +1523,11 @@ extern "C" }; #endif //NEO +#ifdef NEO +void CMP3Player::GetLocalCopyOfSong( const MP3File_t &mp3, char *outsong, int outlen ) +#else void CMP3Player::GetLocalCopyOfSong( const MP3File_t &mp3, char *outsong, size_t outlen ) +#endif { outsong[ 0 ] = 0; char fn[ 512 ]; diff --git a/src/game/client/mp3player.h b/src/game/client/mp3player.h index d6c6a78ad9..b19b97cfff 100644 --- a/src/game/client/mp3player.h +++ b/src/game/client/mp3player.h @@ -284,7 +284,13 @@ class CMP3Player : public vgui::Frame #ifdef NEO protected: #endif // NEO + +#ifdef NEO + void GetLocalCopyOfSong( const MP3File_t &mp3, char *outsong, int outlen ); +#else void GetLocalCopyOfSong( const MP3File_t &mp3, char *outsong, size_t outlen ); +#endif + float GetMP3Duration( char const *songname ); void OnNextTrack(); void OnPrevTrack(); diff --git a/src/game/client/mumble.cpp b/src/game/client/mumble.cpp index ecf7d8d4b6..9e2fbae16a 100644 --- a/src/game/client/mumble.cpp +++ b/src/game/client/mumble.cpp @@ -233,7 +233,11 @@ void CMumbleSystem::FireGameEvent( IGameEvent *event ) if ( !Q_strcmp( "server_spawn", eventname ) ) { V_strcpy_safe( m_szSteamIDCurrentServer, event->GetString( "steamid", "" ) ); +#ifdef NEO + m_cubSteamIDCurrentServer = V_strlen( m_szSteamIDCurrentServer ) + 1; +#else m_cubSteamIDCurrentServer = strlen( m_szSteamIDCurrentServer ) + 1; +#endif } #endif // NO_STEAM } diff --git a/src/game/client/neo/ui/neo_hud_ammo.cpp b/src/game/client/neo/ui/neo_hud_ammo.cpp index 7b08a367c6..79aab242a1 100644 --- a/src/game/client/neo/ui/neo_hud_ammo.cpp +++ b/src/game/client/neo/ui/neo_hud_ammo.cpp @@ -242,7 +242,7 @@ void CNEOHud_Ammo::DrawAmmo() const constexpr auto maxBullets = 100; // PZ Mag Size char bullets[maxBullets + 1]; - magSizeMax = min(magSizeMax, sizeof(bullets)-1); + magSizeMax = Min(magSizeMax, narrow_cast(sizeof(bullets) - 1)); int i; for(i = 0; i < magSizeMax; i++) { diff --git a/src/game/client/neo/ui/neo_hud_deathnotice.cpp b/src/game/client/neo/ui/neo_hud_deathnotice.cpp index 08135b456a..f26117cc1d 100644 --- a/src/game/client/neo/ui/neo_hud_deathnotice.cpp +++ b/src/game/client/neo/ui/neo_hud_deathnotice.cpp @@ -796,9 +796,9 @@ void CNEOHud_DeathNotice::AddPlayerDeath(IGameEvent* event) g_pVGuiLocalize->ConvertANSIToUnicode(killer_name, deathMsg.Killer.szName, sizeof(deathMsg.Killer.szName)); g_pVGuiLocalize->ConvertANSIToUnicode(victim_name, deathMsg.Victim.szName, sizeof(deathMsg.Victim.szName)); g_pVGuiLocalize->ConvertANSIToUnicode(assists_name, deathMsg.Assist.szName, sizeof(deathMsg.Assist.szName)); - deathMsg.Killer.iNameLength = wcslen(deathMsg.Killer.szName); - deathMsg.Victim.iNameLength = wcslen(deathMsg.Victim.szName); - deathMsg.Assist.iNameLength = wcslen(deathMsg.Assist.szName); + deathMsg.Killer.iNameLength = V_wcslen(deathMsg.Killer.szName); + deathMsg.Victim.iNameLength = V_wcslen(deathMsg.Victim.szName); + deathMsg.Assist.iNameLength = V_wcslen(deathMsg.Assist.szName); if (const auto killerTeam = GetPlayersTeam(killer)) { deathMsg.Killer.iTeam = killerTeam->GetTeamNumber(); @@ -883,7 +883,7 @@ void CNEOHud_DeathNotice::AddPlayerRankChange(IGameEvent* event) DeathNoticeItem deathMsg; deathMsg.Killer.iEntIndex = playerRankChange; g_pVGuiLocalize->ConvertANSIToUnicode(playerRankChangeName, deathMsg.Killer.szName, sizeof(deathMsg.Killer.szName)); - deathMsg.Killer.iNameLength = wcslen(deathMsg.Killer.szName); + deathMsg.Killer.iNameLength = V_wcslen(deathMsg.Killer.szName); if (const auto playerRankChangeTeam = GetPlayersTeam(playerRankChange)) { deathMsg.Killer.iTeam = playerRankChangeTeam->GetTeamNumber(); @@ -915,7 +915,7 @@ void CNEOHud_DeathNotice::AddPlayerGhostCapture(IGameEvent* event) DeathNoticeItem deathMsg; deathMsg.Killer.iEntIndex = playerCapturedGhost; g_pVGuiLocalize->ConvertANSIToUnicode(playerCapturedGhostName, deathMsg.Killer.szName, sizeof(deathMsg.Killer.szName)); - deathMsg.Killer.iNameLength = wcslen(deathMsg.Killer.szName); + deathMsg.Killer.iNameLength = V_wcslen(deathMsg.Killer.szName); if (const auto playerCapturedGhostTeam = GetPlayersTeam(playerCapturedGhost)) { deathMsg.Killer.iTeam = playerCapturedGhostTeam->GetTeamNumber(); @@ -943,7 +943,7 @@ void CNEOHud_DeathNotice::AddVIPExtract(IGameEvent* event) DeathNoticeItem deathMsg; deathMsg.Killer.iEntIndex = playerExtracted; g_pVGuiLocalize->ConvertANSIToUnicode(playerExtractedName, deathMsg.Killer.szName, sizeof(deathMsg.Killer.szName)); - deathMsg.Killer.iNameLength = wcslen(deathMsg.Killer.szName); + deathMsg.Killer.iNameLength = V_wcslen(deathMsg.Killer.szName); if (const auto playerExtractedTeam = GetPlayersTeam(playerExtracted)) { deathMsg.Killer.iTeam = playerExtractedTeam->GetTeamNumber(); @@ -974,14 +974,14 @@ void CNEOHud_DeathNotice::AddVIPDeath(IGameEvent* event) DeathNoticeItem deathMsg; deathMsg.Victim.iEntIndex = playerKilled; g_pVGuiLocalize->ConvertANSIToUnicode(playerKilledName, deathMsg.Victim.szName, sizeof(deathMsg.Victim.szName)); - deathMsg.Victim.iNameLength = wcslen(deathMsg.Victim.szName); + deathMsg.Victim.iNameLength = V_wcslen(deathMsg.Victim.szName); if (const auto playerKilledTeam = GetPlayersTeam(playerKilled)) { deathMsg.Victim.iTeam = playerKilledTeam->GetTeamNumber(); } deathMsg.Killer.iEntIndex = VIPKiller; g_pVGuiLocalize->ConvertANSIToUnicode(VIPKillerName, deathMsg.Killer.szName, sizeof(deathMsg.Killer.szName)); - deathMsg.Killer.iNameLength = wcslen(deathMsg.Killer.szName); + deathMsg.Killer.iNameLength = V_wcslen(deathMsg.Killer.szName); if (const auto VIPKillerTeam = GetPlayersTeam(VIPKiller)) { deathMsg.Killer.iTeam = VIPKillerTeam->GetTeamNumber(); diff --git a/src/game/client/neo/ui/neo_hud_message.cpp b/src/game/client/neo/ui/neo_hud_message.cpp index 2bd3301a1c..b9dedfc6ed 100644 --- a/src/game/client/neo/ui/neo_hud_message.cpp +++ b/src/game/client/neo/ui/neo_hud_message.cpp @@ -100,7 +100,7 @@ void CNEOHud_Message::DrawNeoHudElement() { surface()->DrawSetTextPos(m_Padding, yOffset); const std::wstring& line = m_Lines[i]; - surface()->DrawPrintText(line.c_str(), line.size()); + surface()->DrawPrintText(line.c_str(), narrow_cast(line.size())); yOffset += m_LineHeights[i] + (int)(2 * m_fScale); } diff --git a/src/game/client/neo/ui/neo_root.cpp b/src/game/client/neo/ui/neo_root.cpp index f436cdfa9c..37961c3955 100644 --- a/src/game/client/neo/ui/neo_root.cpp +++ b/src/game/client/neo/ui/neo_root.cpp @@ -133,7 +133,7 @@ static bool NetAdrIsFavorite(const servernetadr_t &netAdr) nConnPort == netAdr.GetConnectionPort() && nQueryPort == netAdr.GetQueryPort() && (unFlags & k_unFavoriteFlagFavorite) && - nAppID == engine->GetAppID()) + nAppID == narrow_cast(engine->GetAppID())) { return true; } @@ -738,7 +738,7 @@ void CNeoRoot::OnMainLoop(const NeoUI::Mode eMode) surface()->GetTextSize(g_uiCtx.fonts[NeoUI::FONT_NTNORMAL].hdl, BUILD_DISPLAY, textWidth, textHeight); surface()->DrawSetTextPos(g_uiCtx.iMarginX, tall - textHeight - g_uiCtx.iMarginY); - surface()->DrawPrintText(BUILD_DISPLAY, wcslen(BUILD_DISPLAY)); + surface()->DrawPrintText(BUILD_DISPLAY, V_wcslen(BUILD_DISPLAY)); } } diff --git a/src/game/client/neo/ui/neo_root_serverbrowser.cpp b/src/game/client/neo/ui/neo_root_serverbrowser.cpp index 2b1a5b2943..c4f269b530 100644 --- a/src/game/client/neo/ui/neo_root_serverbrowser.cpp +++ b/src/game/client/neo/ui/neo_root_serverbrowser.cpp @@ -157,8 +157,8 @@ void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) switch (sortCtx.col) { case SBLIST_COL_TYPE: - iLeft = static_cast(blLeft.eType); - iRight = static_cast(blRight.eType); + iLeft = narrow_cast(blLeft.eType); + iRight = narrow_cast(blRight.eType); break; case SBLIST_COL_DATETIME: iLeft = blLeft.timeVal; diff --git a/src/game/client/neo/ui/neo_root_settings.cpp b/src/game/client/neo/ui/neo_root_settings.cpp index 6bd3b82efe..7c52296b80 100644 --- a/src/game/client/neo/ui/neo_root_settings.cpp +++ b/src/game/client/neo/ui/neo_root_settings.cpp @@ -260,19 +260,19 @@ void NeoSettingsBackgroundsInit(NeoSettings* ns) ns->backgrounds = new KeyValues( "neo_backgrounds" ); ns->iCBListSize = 0; - constexpr auto allocate = [](NeoSettings *ns, int size) { + constexpr auto allocate = [](NeoSettings *ns, size_t size) { ns->p2WszCBList = (wchar_t **)calloc(sizeof(wchar_t *), ns->iCBListSize); ns->p2WszCBList[0] = (wchar_t *)calloc(sizeof(wchar_t) * size, ns->iCBListSize); }; // Setup Background Map options - int dispSize = Max(sizeof(NEO_FALLBACK_BACKGROUND_DISPLAYNAME), sizeof(NEO_RANDOM_BACKGROUND_NAME) + 1); + auto dispSize = Max(sizeof(NEO_FALLBACK_BACKGROUND_DISPLAYNAME), sizeof(NEO_RANDOM_BACKGROUND_NAME) + 1); if ( !ns->backgrounds->LoadFromFile( g_pFullFileSystem, NEO_BACKGROUNDS_FILENAME, "MOD" ) ) { // File empty or unable to load, set to static and return early Warning( "Unable to load '%s'\n", NEO_BACKGROUNDS_FILENAME ); ns->iCBListSize = 1; allocate(ns, dispSize); - g_pVGuiLocalize->ConvertANSIToUnicode(NEO_FALLBACK_BACKGROUND_DISPLAYNAME, ns->p2WszCBList[0], sizeof(wchar_t) * dispSize); + g_pVGuiLocalize->ConvertANSIToUnicode(NEO_FALLBACK_BACKGROUND_DISPLAYNAME, ns->p2WszCBList[0], narrow_cast(sizeof(wchar_t) * dispSize)); NeoSettingsBackgroundWrite(ns, NEO_FALLBACK_BACKGROUND_FILENAME); return; } @@ -298,17 +298,17 @@ void NeoSettingsBackgroundsInit(NeoSettings* ns) } ns->iCBListSize++; - dispSize = Max(dispSize, (V_strlen(displayName) + 1)); + dispSize = Max(dispSize, (V_strlen(displayName) + 1)); background = background->GetNextKey(); } - const int wDispSize = sizeof(wchar_t) * dispSize; + const int wDispSize = narrow_cast(sizeof(wchar_t) * dispSize); // Random Background Option ns->iCBListSize++; allocate(ns, dispSize); KeyValues* background = ns->backgrounds->GetFirstSubKey(); // iterate through background maps and set their names - for (int i = 0, offset = 0; i < ns->iCBListSize - 1; ++i, offset += dispSize) + for (int i = 0, offset = 0; i < ns->iCBListSize - 1; ++i, offset = narrow_cast(offset+dispSize)) { g_pVGuiLocalize->ConvertANSIToUnicode(background->GetName(), ns->p2WszCBList[0] + offset, wDispSize); ns->p2WszCBList[i] = ns->p2WszCBList[0] + offset; @@ -316,7 +316,7 @@ void NeoSettingsBackgroundsInit(NeoSettings* ns) } // Set last option to random - const int offset = (ns->iCBListSize - 1) * dispSize; + const int offset = narrow_cast((ns->iCBListSize - 1) * dispSize); g_pVGuiLocalize->ConvertANSIToUnicode(ns->iCBListSize == 1 ? NEO_FALLBACK_BACKGROUND_DISPLAYNAME : NEO_RANDOM_BACKGROUND_NAME, ns->p2WszCBList[0] + offset, wDispSize); ns->p2WszCBList[ns->iCBListSize - 1] = ns->p2WszCBList[0] + offset; diff --git a/src/game/client/neo/ui/neo_ui.cpp b/src/game/client/neo/ui/neo_ui.cpp index 151d875173..cc1ca9e6d0 100644 --- a/src/game/client/neo/ui/neo_ui.cpp +++ b/src/game/client/neo/ui/neo_ui.cpp @@ -450,9 +450,9 @@ void EndContext() { const int iTotalSection = c->iSection; int iTally = 0; - for (int i = 0; i < iTotalSection; ++i) + for (decltype(Context::ibfSectionCanActive) i = 0; i < iTotalSection; ++i) { - const uint64_t ibfCmp = (1 << i); + const auto ibfCmp = (decltype(i))1 << i; iTally += (c->ibfSectionCanActive & ibfCmp) && (!bSwitchSectionController || (c->ibfSectionCanController & ibfCmp)); } @@ -470,7 +470,7 @@ void EndContext() c->iActiveSection += iIncr; c->iActiveSection = LoopAroundInArray(c->iActiveSection, iTotalSection); - const uint64_t ibfCmp = (1 << c->iActiveSection); + const auto ibfCmp = (decltype(Context::ibfSectionCanActive))1 << c->iActiveSection; bNextCmp = !((c->ibfSectionCanActive & ibfCmp) && (!bSwitchSectionController || (c->ibfSectionCanController & ibfCmp))); } while (bNextCmp); @@ -846,10 +846,10 @@ GetMouseinFocusedRet BeginWidget(const WidgetFlag eWidgetFlag) // Mark this section this widget under as able to be active if (eWidgetFlag & WIDGETFLAG_MARKACTIVE) { - c->ibfSectionCanActive |= (1 << c->iSection); + c->ibfSectionCanActive |= (decltype(Context::ibfSectionCanActive))1 << c->iSection; if (!(c->iSectionFlags & SECTIONFLAG_EXCLUDECONTROLLER)) { - c->ibfSectionCanController |= (1 << c->iSection); + c->ibfSectionCanController |= (decltype(Context::ibfSectionCanController))1 << c->iSection; } } diff --git a/src/game/server/AI_ResponseSystem.cpp b/src/game/server/AI_ResponseSystem.cpp index 9c849b2d32..f5eedfa55f 100644 --- a/src/game/server/AI_ResponseSystem.cpp +++ b/src/game/server/AI_ResponseSystem.cpp @@ -679,7 +679,11 @@ abstract_class CResponseSystem : public IResponseSystem bool Compare( const char *setValue, Criteria *c, bool verbose = false ); bool CompareUsingMatcher( const char *setValue, Matcher& m, bool verbose = false ); void ComputeMatcher( Criteria *c, Matcher& matcher ); +#ifdef NEO + void ResolveToken( Matcher& matcher, char *token, int bufsize, char const *rawtoken ); +#else void ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ); +#endif float LookupEnumeration( const char *name, bool& found ); int FindBestMatchingRule( const AI_CriteriaSet& set, bool verbose ); @@ -695,7 +699,11 @@ abstract_class CResponseSystem : public IResponseSystem void LoadFromBuffer( const char *scriptfile, const char *buffer, CStringPool &includedFiles ); +#ifdef NEO + void GetCurrentScript( char *buf, int buflen ); +#else void GetCurrentScript( char *buf, size_t buflen ); +#endif int GetCurrentToken() const; void SetCurrentScript( const char *script ); bool IsRootCommand(); @@ -775,7 +783,11 @@ CResponseSystem::~CResponseSystem() // Purpose: // Output : char const //----------------------------------------------------------------------------- +#ifdef NEO +void CResponseSystem::GetCurrentScript( char *buf, int buflen ) +#else void CResponseSystem::GetCurrentScript( char *buf, size_t buflen ) +#endif { Assert( buf ); buf[ 0 ] = 0; @@ -843,7 +855,11 @@ float CResponseSystem::LookupEnumeration( const char *name, bool& found ) // Purpose: // Input : matcher - //----------------------------------------------------------------------------- +#ifdef NEO +void CResponseSystem::ResolveToken( Matcher& matcher, char *token, int bufsize, char const *rawtoken ) +#else void CResponseSystem::ResolveToken( Matcher& matcher, char *token, size_t bufsize, char const *rawtoken ) +#endif { if ( rawtoken[0] != '[' ) { diff --git a/src/game/server/EventLog.cpp b/src/game/server/EventLog.cpp index fa62179d73..626fef6022 100644 --- a/src/game/server/EventLog.cpp +++ b/src/game/server/EventLog.cpp @@ -27,10 +27,38 @@ void CEventLog::FireGameEvent( IGameEvent *event ) PrintEvent ( event ); } +#ifdef NEO +template +constexpr bool cmp(const char* a, const char(&b)[size]) +{ + static_assert(size > 0); + Assert(a); + return V_strncmp(a, &b[0], size - 1) == 0; +} +#endif + bool CEventLog::PrintEvent( IGameEvent *event ) { const char * name = event->GetName(); +#ifdef NEO + if (cmp(name, "server_")) + { + return true; // we don't care about server events (engine does) + } + else if (cmp(name, "player_")) + { + return PrintPlayerEvent( event ); + } + else if (cmp(name, "team_")) + { + return PrintTeamEvent( event ); + } + else if (cmp(name, "game_")) + { + return PrintGameEvent( event ); + } +#else if ( Q_strncmp(name, "server_", strlen("server_")) == 0 ) { return true; // we don't care about server events (engine does) @@ -47,6 +75,7 @@ bool CEventLog::PrintEvent( IGameEvent *event ) { return PrintGameEvent( event ); } +#endif else { return PrintOtherEvent( event ); // bomb_, round_, et al diff --git a/src/game/server/TemplateEntities.cpp b/src/game/server/TemplateEntities.cpp index a50693e460..52fd4bb5cb 100644 --- a/src/game/server/TemplateEntities.cpp +++ b/src/game/server/TemplateEntities.cpp @@ -87,10 +87,18 @@ int Templates_Add(CBaseEntity *pEntity, const char *pszMapData, int nLen) // We may modify the values of the keys in this mapdata chunk later on to fix Entity I/O // connections. For this reason, we need to ensure we have enough memory to do that. int iKeys = MapEntity_GetNumKeysInEntity( pszMapData ); +#ifdef NEO + auto iExtraSpace = (strlen(ENTITYIO_FIXUP_STRING) + 1) * iKeys; +#else int iExtraSpace = (strlen(ENTITYIO_FIXUP_STRING)+1) * iKeys; +#endif // Extra 1 because the mapdata passed in isn't null terminated +#ifdef NEO + pEntData->iMapDataLength = narrow_cast(nLen + iExtraSpace + 1); +#else pEntData->iMapDataLength = nLen + iExtraSpace + 1; +#endif pEntData->pszMapData = (char *)malloc( pEntData->iMapDataLength ); memcpy(pEntData->pszMapData, pszMapData, nLen + 1); pEntData->pszMapData[nLen] = '\0'; @@ -342,7 +350,11 @@ char *Templates_GetEntityIOFixedMapData( int iIndex ) Q_strncpy( g_Templates[iIndex]->pszFixedMapData, g_Templates[iIndex]->pszMapData, g_Templates[iIndex]->iMapDataLength ); } +#ifdef NEO + int iFixupSize = narrow_cast(strlen(ENTITYIO_FIXUP_STRING)); // don't include \0 when copying in the fixup +#else int iFixupSize = strlen(ENTITYIO_FIXUP_STRING); // don't include \0 when copying in the fixup +#endif char *sOurFixup = new char[iFixupSize+1]; // do alloc room here for the null terminator Q_snprintf( sOurFixup, iFixupSize+1, "%c%.4d", ENTITYIO_FIXUP_STRING[0], g_iCurrentTemplateInstance ); diff --git a/src/game/server/ai_basenpc.cpp b/src/game/server/ai_basenpc.cpp index 586ef68127..a6c94bac2c 100644 --- a/src/game/server/ai_basenpc.cpp +++ b/src/game/server/ai_basenpc.cpp @@ -12484,7 +12484,11 @@ int CAI_BaseNPC::WalkMove( const Vector& vecPosition, unsigned int mask ) static void AIMsgGuts( CAI_BaseNPC *pAI, unsigned flags, const char *pszMsg ) { +#ifdef NEO + int len = V_strlen( pszMsg ); +#else int len = strlen( pszMsg ); +#endif const char *pszFmt2 = NULL; if ( len && pszMsg[len-1] == '\n' ) @@ -13875,8 +13879,13 @@ void CAI_BaseNPC::InputForceInteractionWithNPC( inputdata_t &inputdata ) int iInteraction = -1; for ( int i = 0; i < m_ScriptedInteractions.Count(); i++ ) { +#ifdef NEO + if ( Q_strncmp( pszParam, STRING(m_ScriptedInteractions[i].iszInteractionName), V_strlen(pszParam) ) ) + continue; +#else if ( Q_strncmp( pszParam, STRING(m_ScriptedInteractions[i].iszInteractionName), strlen(pszParam) ) ) continue; +#endif // Use sequence? or activity? if ( m_ScriptedInteractions[i].sPhases[SNPCINT_SEQUENCE].iActivity != ACT_INVALID ) diff --git a/src/game/server/ai_hint.cpp b/src/game/server/ai_hint.cpp index de814f38e9..0cf434e60d 100644 --- a/src/game/server/ai_hint.cpp +++ b/src/game/server/ai_hint.cpp @@ -676,7 +676,11 @@ void CAI_HintManager::RemoveHint( CAI_Hint *pHintToRemove ) //----------------------------------------------------------------------------- int CAI_HintManager::GetFlags( const char *token ) { +#ifdef NEO + int len = V_strlen( token ); +#else int len = strlen( token ); +#endif if ( len <= 0 ) { return bits_HINT_NODE_NONE; diff --git a/src/game/server/ai_networkmanager.cpp b/src/game/server/ai_networkmanager.cpp index dcc0647b71..72c9a28481 100644 --- a/src/game/server/ai_networkmanager.cpp +++ b/src/game/server/ai_networkmanager.cpp @@ -236,7 +236,11 @@ void CAI_NetworkManager::SaveNetworkGraph( void ) Q_snprintf( tempFilename, sizeof( tempFilename ), "%s/%s", szNrpFilename, STRING( gpGlobals->mapname ) ); // Remove the filename. +#ifdef NEO + int len = V_strlen( tempFilename ); +#else int len = strlen( tempFilename ); +#endif for ( int i=0; i < len; i++ ) { if ( tempFilename[len-i-1] == '/' || tempFilename[len-i-1] == '\\' ) diff --git a/src/game/server/ai_schedule.cpp b/src/game/server/ai_schedule.cpp index a4389769f9..d060b4d1d3 100644 --- a/src/game/server/ai_schedule.cpp +++ b/src/game/server/ai_schedule.cpp @@ -594,7 +594,11 @@ CAI_Schedule::CAI_Schedule(char *name, int schedule_id, CAI_Schedule *pNext) { m_iScheduleID = schedule_id; +#ifdef NEO + int len = V_strlen(name); +#else int len = strlen(name); +#endif m_pName = new char[len+1]; Q_strncpy(m_pName,name,len+1); diff --git a/src/game/server/ai_speech.cpp b/src/game/server/ai_speech.cpp index c0cc46090b..0620e8f06e 100644 --- a/src/game/server/ai_speech.cpp +++ b/src/game/server/ai_speech.cpp @@ -264,7 +264,11 @@ void CAI_Expresser::TestAllResponses() //----------------------------------------------------------------------------- +#ifdef NEO +static const int LEN_SPECIFIC_SCENE_MODIFIER = V_strlen( AI_SPECIFIC_SCENE_MODIFIER ); +#else static const int LEN_SPECIFIC_SCENE_MODIFIER = strlen( AI_SPECIFIC_SCENE_MODIFIER ); +#endif //----------------------------------------------------------------------------- // Purpose: Searches for a possible response @@ -510,7 +514,11 @@ bool CAI_Expresser::Speak( AIConcept_t aiconcept, const char *modifiers /*= NULL if ( pszOutResponseChosen ) { const char *szResponse = response.GetResponsePtr(); +#ifdef NEO + V_strncpy( pszOutResponseChosen, szResponse, narrow_cast(bufsize) ); +#else Q_strncpy( pszOutResponseChosen, szResponse, bufsize ); +#endif } return spoke; diff --git a/src/game/server/baseentity.cpp b/src/game/server/baseentity.cpp index d1a774fab6..4a52951273 100644 --- a/src/game/server/baseentity.cpp +++ b/src/game/server/baseentity.cpp @@ -794,7 +794,11 @@ struct TimedOverlay_t void CBaseEntity::AddTimedOverlay( const char *msg, int endTime ) { TimedOverlay_t *pNewTO = new TimedOverlay_t; +#ifdef NEO + int len = V_strlen(msg); +#else int len = strlen(msg); +#endif pNewTO->msg = new char[len + 1]; Q_strncpy(pNewTO->msg,msg, len+1); pNewTO->msgEndTime = gpGlobals->curtime + endTime; @@ -3849,14 +3853,22 @@ void *CBaseEntity::operator new( size_t stAllocateBlock ) { // call into engine to get memory Assert( stAllocateBlock != 0 ); +#ifdef NEO + return engine->PvAllocEntPrivateData(narrow_cast(stAllocateBlock)); +#else return engine->PvAllocEntPrivateData(stAllocateBlock); +#endif }; void *CBaseEntity::operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine ) { // call into engine to get memory Assert( stAllocateBlock != 0 ); +#ifdef NEO + return engine->PvAllocEntPrivateData(narrow_cast(stAllocateBlock)); +#else return engine->PvAllocEntPrivateData(stAllocateBlock); +#endif } void CBaseEntity::operator delete( void *pMem ) diff --git a/src/game/server/cbase.cpp b/src/game/server/cbase.cpp index e2c060b967..27a71e9d58 100644 --- a/src/game/server/cbase.cpp +++ b/src/game/server/cbase.cpp @@ -1154,7 +1154,11 @@ void CEventQueue::CancelEventOn( CBaseEntity *pTarget, const char *sInputName ) bool bDelete = false; if (pCur->m_pEntTarget == pTarget) { +#ifdef NEO + if ( !Q_strncmp( STRING(pCur->m_iTargetInput), sInputName, narrow_cast( strlen(sInputName) ) ) ) +#else if ( !Q_strncmp( STRING(pCur->m_iTargetInput), sInputName, strlen(sInputName) ) ) +#endif { // Found a matching event; delete it from the queue. bDelete = true; @@ -1191,7 +1195,11 @@ bool CEventQueue::HasEventPending( CBaseEntity *pTarget, const char *sInputName if ( !sInputName ) return true; +#ifdef NEO + if ( !Q_strncmp( STRING(pCur->m_iTargetInput), sInputName, narrow_cast( strlen(sInputName) ) ) ) +#else if ( !Q_strncmp( STRING(pCur->m_iTargetInput), sInputName, strlen(sInputName) ) ) +#endif return true; } diff --git a/src/game/server/client.cpp b/src/game/server/client.cpp index 12ffbb69b1..88df41aa96 100644 --- a/src/game/server/client.cpp +++ b/src/game/server/client.cpp @@ -297,7 +297,11 @@ void Host_Say( edict_t *pEdict, const CCommand &args, bool teamonly ) Q_snprintf( text, sizeof(text), "%s: ", pszPlayerName ); } +#ifdef NEO + j = narrow_cast(sizeof(text) - 2 - strlen(text)); // -2 for /n and null terminator +#else j = sizeof(text) - 2 - strlen(text); // -2 for /n and null terminator +#endif if ( (int)strlen(p) > j ) p[j] = 0; diff --git a/src/game/server/env_debughistory.cpp b/src/game/server/env_debughistory.cpp index bf249ecf91..e5c144afc3 100644 --- a/src/game/server/env_debughistory.cpp +++ b/src/game/server/env_debughistory.cpp @@ -89,7 +89,11 @@ void CDebugHistory::AddDebugHistoryLine( int iCategory, const char *szLine ) return; const char *pszRemaining = szLine; +#ifdef NEO + int iCharsToWrite = narrow_cast( strlen( pszRemaining ) + 1 ); // Add 1 so that we copy the null terminator +#else int iCharsToWrite = strlen( pszRemaining ) + 1; // Add 1 so that we copy the null terminator +#endif // Clip the line if it's too long. Wasteful doing it this way, but keeps code below nice & simple. char szTmpBuffer[MAX_DEBUG_HISTORY_LINE_LENGTH]; @@ -103,7 +107,11 @@ void CDebugHistory::AddDebugHistoryLine( int iCategory, const char *szLine ) while ( iCharsToWrite ) { +#ifdef NEO + int iCharsLeftBeforeLoop = narrow_cast(sizeof(m_DebugLines[iCategory]) - (m_DebugLineEnd[iCategory] - m_DebugLines[iCategory])); +#else int iCharsLeftBeforeLoop = sizeof(m_DebugLines[iCategory]) - (m_DebugLineEnd[iCategory] - m_DebugLines[iCategory]); +#endif // Write into the buffer int iWrote = MIN( iCharsToWrite, iCharsLeftBeforeLoop ); diff --git a/src/game/server/gameinterface.cpp b/src/game/server/gameinterface.cpp index 88634e5d7d..e61b964ca4 100644 --- a/src/game/server/gameinterface.cpp +++ b/src/game/server/gameinterface.cpp @@ -1797,7 +1797,11 @@ void CServerGameDLL::GetSaveComment( char *text, int maxlength, float flMinutes, // Try to find a matching title comment for this mapname for ( i = 0; i < ARRAYSIZE(gTitleComments) && !pName; i++ ) { +#ifdef NEO + if ( !V_strnicmp( mapname, gTitleComments[i].pBSPName, narrow_cast( strlen(gTitleComments[i].pBSPName) ) ) ) +#else if ( !Q_strnicmp( mapname, gTitleComments[i].pBSPName, strlen(gTitleComments[i].pBSPName) ) ) +#endif { // found one int j; @@ -2163,7 +2167,11 @@ void UpdateChapterRestrictions( const char *mapname ) chapterTitle[0] = 0; for ( int i = 0; i < ARRAYSIZE(gTitleComments); i++ ) { +#ifdef NEO + if ( !V_strnicmp( mapname, gTitleComments[i].pBSPName, narrow_cast( strlen(gTitleComments[i].pBSPName) ) ) ) +#else if ( !Q_strnicmp( mapname, gTitleComments[i].pBSPName, strlen(gTitleComments[i].pBSPName) ) ) +#endif { // found Q_strncpy( chapterTitle, gTitleComments[i].pTitleName, sizeof( chapterTitle ) ); diff --git a/src/game/server/nav_area.cpp b/src/game/server/nav_area.cpp index 5d6c472b4f..80ca961c5f 100644 --- a/src/game/server/nav_area.cpp +++ b/src/game/server/nav_area.cpp @@ -122,8 +122,13 @@ void *CNavVectorNoEditAllocator::Alloc( size_t nSize ) { m_memory.Init( 1024*1024, 0, 0, 4 ); } +#ifdef NEO + m_pCurrent = (int *)m_memory.Alloc( narrow_cast(nSize) ); + m_nBytesCurrent = narrow_cast(nSize); +#else m_pCurrent = (int *)m_memory.Alloc( nSize ); m_nBytesCurrent = nSize; +#endif return m_pCurrent; } @@ -136,8 +141,13 @@ void *CNavVectorNoEditAllocator::Realloc( void *pMem, size_t nSize ) } if ( nSize > (size_t)m_nBytesCurrent ) { +#ifdef NEO + m_memory.Alloc( narrow_cast(nSize - m_nBytesCurrent) ); + m_nBytesCurrent = narrow_cast(nSize); +#else m_memory.Alloc( nSize - m_nBytesCurrent ); m_nBytesCurrent = nSize; +#endif } return m_pCurrent; } diff --git a/src/game/server/nav_file.cpp b/src/game/server/nav_file.cpp index 44c9c924e8..035402972b 100644 --- a/src/game/server/nav_file.cpp +++ b/src/game/server/nav_file.cpp @@ -204,7 +204,11 @@ char *GetBspFilename( const char *navFilename ) Q_snprintf( bspFilename, sizeof( bspFilename ), FORMAT_BSPFILE, STRING( gpGlobals->mapname ) ); +#ifdef NEO + int len = V_strlen( bspFilename ); +#else int len = strlen( bspFilename ); +#endif if (len < 3) return NULL; diff --git a/src/game/server/neo/bot/neo_bot_profile.cpp b/src/game/server/neo/bot/neo_bot_profile.cpp index 87b5bef45c..254af6f16f 100644 --- a/src/game/server/neo/bot/neo_bot_profile.cpp +++ b/src/game/server/neo/bot/neo_bot_profile.cpp @@ -210,7 +210,7 @@ static void SetProfileTempBotCommon(CNEOBotProfile *pProfile, KeyValues *kv) char szInvalids[512] = {}; for (int idxWep = 1; idxWep < NEO_WIDX__TOTAL; ++idxWep) { - if (flagsInvalids & (1 << (idxWep - 1))) + if (flagsInvalids & ((decltype(flagsInvalids))1 << (idxWep - 1))) { V_strcat_safe(szInvalids, " "); V_strcat_safe(szInvalids, WEP_BIT_FLAG_CMP[idxWep - 1].szValue); diff --git a/src/game/server/sceneentity.cpp b/src/game/server/sceneentity.cpp index dcd752ca72..310df8f96e 100644 --- a/src/game/server/sceneentity.cpp +++ b/src/game/server/sceneentity.cpp @@ -39,6 +39,10 @@ #include "npc_alyx_episodic.h" #endif // HL2_EPISODIC +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -209,7 +213,11 @@ bool CopySceneFileIntoMemory( char const *pFilename, void **pBuffer, int *pSize if ( bufSize > 0 ) { *pBuffer = new byte[bufSize]; +#ifdef NEO + *pSize = narrow_cast>(bufSize); +#else *pSize = bufSize; +#endif return scenefilecache->GetSceneData( pFilename, (byte *)(*pBuffer), bufSize ); } @@ -1652,7 +1660,11 @@ bool CSceneEntity::GetSoundNameForPlayer( CChoreoEvent *event, CBasePlayer *play } // Copy the sound name +#ifdef NEO + CopySoundNameWithModifierToken( buf, event->GetParameters(), narrow_cast(buflen), pchToken ); +#else CopySoundNameWithModifierToken( buf, event->GetParameters(), buflen, pchToken ); +#endif // If there was a modifier token, don't change the sound based on CC if ( pchToken[0] != 0 ) @@ -1686,7 +1698,11 @@ bool CSceneEntity::GetSoundNameForPlayer( CChoreoEvent *event, CBasePlayer *play // Master event sounds always play too (master will be the combined .wav) if ( validtoken ) { +#ifdef NEO + V_strncpy( buf, tok, narrow_cast(buflen) ); +#else Q_strncpy( buf, tok, buflen ); +#endif } return true; } diff --git a/src/game/shared/GameStats.cpp b/src/game/shared/GameStats.cpp index c40002119b..a5749cfe48 100644 --- a/src/game/shared/GameStats.cpp +++ b/src/game/shared/GameStats.cpp @@ -453,7 +453,11 @@ bool CBaseGameStats::SaveToFileNOW( bool bForceSyncWrite /* = false */ ) else { // Allocate memory for async system to use (and free afterward!!!) +#ifdef NEO + const auto nBufferSize = buf.TellPut(); +#else size_t nBufferSize = buf.TellPut(); +#endif void *pMem = malloc(nBufferSize); CUtlBuffer statsBuffer( pMem, nBufferSize ); statsBuffer.Put( buf.Base(), nBufferSize ); diff --git a/src/game/shared/SoundEmitterSystem.cpp b/src/game/shared/SoundEmitterSystem.cpp index e5cdad7851..cd1d3961cf 100644 --- a/src/game/shared/SoundEmitterSystem.cpp +++ b/src/game/shared/SoundEmitterSystem.cpp @@ -1097,7 +1097,11 @@ static int GamesoundCompletion( const char *partial, char commands[ COMMAND_COMP if ( Q_strstr( partial, cmdname ) && strlen(partial) > strlen(cmdname) + 1 ) { substring = (char *)partial + strlen( cmdname ) + 1; +#ifdef NEO + substringLen = V_strlen(substring); +#else substringLen = strlen(substring); +#endif } for ( int i = soundemitterbase->GetSoundCount()-1; i >= 0 && current < COMMAND_COMPLETION_MAXITEMS; i-- ) diff --git a/src/game/shared/activitylist.cpp b/src/game/shared/activitylist.cpp index a57513fd31..beda5c86b9 100644 --- a/src/game/shared/activitylist.cpp +++ b/src/game/shared/activitylist.cpp @@ -2541,7 +2541,11 @@ class CActivityDataOps : public CDefSaveRestoreOps AssertOnce( activityIndex == -1 ); // FIXME: whatever activity this was, it's now being saved out as ACT_RESET pActivityName = ActivityList_NameForIndex( 0 ); } +#ifdef NEO + int len = V_strlen(pActivityName) + 1; +#else int len = strlen(pActivityName) + 1; +#endif // Use the high 16-bits of this int to signify this file format // this makes this backwards compatible. diff --git a/src/game/shared/ammodef.cpp b/src/game/shared/ammodef.cpp index 257e8569a0..9c5d4f51a0 100644 --- a/src/game/shared/ammodef.cpp +++ b/src/game/shared/ammodef.cpp @@ -201,7 +201,11 @@ bool CAmmoDef::AddAmmoType(char const* name, int damageType, int tracerType, int if (m_nAmmoIndex == MAX_AMMO_TYPES) return false; +#ifdef NEO + int len = V_strlen(name); +#else int len = strlen(name); +#endif m_AmmoType[m_nAmmoIndex].pName = new char[len+1]; Q_strncpy(m_AmmoType[m_nAmmoIndex].pName, name,len+1); m_AmmoType[m_nAmmoIndex].nDamageType = damageType; diff --git a/src/game/shared/gamerules_register.cpp b/src/game/shared/gamerules_register.cpp index 8f83ec9f40..be9938a50f 100644 --- a/src/game/shared/gamerules_register.cpp +++ b/src/game/shared/gamerules_register.cpp @@ -122,7 +122,11 @@ CGameRulesRegister* CGameRulesRegister::FindByName( const char *pName ) // Make sure the client gets notification to make a new game rules object. Assert( g_StringTableGameRules ); +#ifdef NEO + g_StringTableGameRules->AddString( true, "classname", narrow_cast( strlen( pClassName ) + 1 ), pClassName ); +#else g_StringTableGameRules->AddString( true, "classname", strlen( pClassName ) + 1, pClassName ); +#endif if ( g_pGameRules ) { diff --git a/src/game/shared/mapentities_shared.cpp b/src/game/shared/mapentities_shared.cpp index d76e112aa4..43a42c26a1 100644 --- a/src/game/shared/mapentities_shared.cpp +++ b/src/game/shared/mapentities_shared.cpp @@ -255,7 +255,11 @@ bool CEntityMapData::GetNextKey( char *keyName, char *value ) Q_strncpy( keyName, token, MAPKEY_MAXLENGTH ); // fix up keynames with trailing spaces +#ifdef NEO + int n = V_strlen(keyName); +#else int n = strlen(keyName); +#endif while (n && keyName[n-1] == ' ') { keyName[n-1] = 0; @@ -312,7 +316,11 @@ bool CEntityMapData::SetValue( const char *keyName, char *NewValue, int nKeyInst if ( nCurrKeyInstance > nKeyInstance ) { // Find the start & end of the token we're going to replace +#ifdef NEO + int entLen = V_strlen(m_pEntData); +#else int entLen = strlen(m_pEntData); +#endif char *postData = new char[entLen]; prevData = inputData; inputData = (char*)MapEntity_ParseToken( inputData, token ); // get keyname diff --git a/src/game/shared/predictioncopy.cpp b/src/game/shared/predictioncopy.cpp index d5cb6b8ecb..b8cf6492f7 100644 --- a/src/game/shared/predictioncopy.cpp +++ b/src/game/shared/predictioncopy.cpp @@ -1835,50 +1835,90 @@ void CValueChangeTracker::GetValue( char *buf, size_t bufsize ) break; case FIELD_FLOAT: case FIELD_TIME: +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%f", *(float const *)pInputData ); +#else Q_snprintf( buf, bufsize, "%f", *(float const *)pInputData ); +#endif break; case FIELD_STRING: +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%s", (char const*)pInputData ); +#else Q_snprintf( buf, bufsize, "%s", (char const*)pInputData ); +#endif break; case FIELD_VECTOR: { const Vector *pVec = (const Vector *)pInputData; +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%f %f %f", pVec->x, pVec->y, pVec->z ); +#else Q_snprintf( buf, bufsize, "%f %f %f", pVec->x, pVec->y, pVec->z ); +#endif } break; case FIELD_QUATERNION: { const Quaternion *p = ( const Quaternion * )pInputData; +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%f %f %f %f", p->x, p->y, p->z, p->w ); +#else Q_snprintf( buf, bufsize, "%f %f %f %f", p->x, p->y, p->z, p->w ); +#endif } break; case FIELD_COLOR32: { const Color *color = ( const Color * )pInputData; +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%d %d %d %d", color->r(), color->g(), color->b(), color->a() ); +#else Q_snprintf( buf, bufsize, "%d %d %d %d", color->r(), color->g(), color->b(), color->a() ); +#endif } break; case FIELD_BOOLEAN: +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%s", (*(const bool*)pInputData) ? "true" : "false" ); +#else Q_snprintf( buf, bufsize, "%s", (*(const bool *)pInputData) ? "true" : "false" ); +#endif break; case FIELD_INTEGER: case FIELD_TICK: case FIELD_MODELINDEX: +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%i", *(const int*)pInputData ); +#else Q_snprintf( buf, bufsize, "%i", *(const int*)pInputData ); +#endif break; case FIELD_SHORT: +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%i", (int)*(const short*)pInputData ); +#else Q_snprintf( buf, bufsize, "%i", (int)*(const short*)pInputData ); +#endif break; case FIELD_CHARACTER: +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "%c", *(const char *)pInputData ); +#else Q_snprintf( buf, bufsize, "%c", *(const char *)pInputData ); +#endif break; case FIELD_EHANDLE: +#ifdef NEO + Q_snprintf( buf, narrow_cast(bufsize), "eh 0x%p", (void const *)((const EHANDLE *)pInputData)->Get() ); +#else Q_snprintf( buf, bufsize, "eh 0x%p", (void const *)((const EHANDLE *)pInputData)->Get() ); +#endif break; } } diff --git a/src/game/shared/props_shared.cpp b/src/game/shared/props_shared.cpp index 4c2165609b..f474374ccc 100644 --- a/src/game/shared/props_shared.cpp +++ b/src/game/shared/props_shared.cpp @@ -468,7 +468,11 @@ const char *CPropData::GetRandomChunkModel( const char *pszBreakableSection, int int i; for ( i = 0; i < iCount; i++ ) { +#ifdef NEO + if ( !Q_strncmp( STRING(m_BreakableChunks[i].iszChunkType), pszBreakableSection, V_strlen(pszBreakableSection) ) ) +#else if ( !Q_strncmp( STRING(m_BreakableChunks[i].iszChunkType), pszBreakableSection, strlen(pszBreakableSection) ) ) +#endif break; } if ( i == iCount ) diff --git a/src/game/shared/saverestore.cpp b/src/game/shared/saverestore.cpp index cc8abfcf6d..02e4621185 100644 --- a/src/game/shared/saverestore.cpp +++ b/src/game/shared/saverestore.cpp @@ -354,7 +354,11 @@ void CSave::Log( const char *pName, fieldtype_t fieldType, void *value, int coun } } +#ifdef NEO + int nLength = narrow_cast(strlen(szBuf) + 1); +#else int nLength = strlen( szBuf ) + 1; +#endif filesystem->Write( szBuf, nLength, m_hLogFile ); } @@ -419,7 +423,11 @@ void CSave::WriteData( const char *pdata , int size ) void CSave::WriteString( const char *pstring ) { +#ifdef NEO + BufferData( pstring, narrow_cast(strlen(pstring) + 1) ); +#else BufferData( pstring, strlen(pstring) + 1 ); +#endif } //------------------------------------- @@ -429,7 +437,11 @@ void CSave::WriteString( const string_t *stringId, int count ) for ( int i = 0; i < count; i++ ) { const char *pString = STRING(stringId[i]); +#ifdef NEO + BufferData( pString, narrow_cast(strlen(pString)+1) ); +#else BufferData( pString, strlen(pString)+1 ); +#endif } } @@ -500,20 +512,28 @@ void CSave::WriteFloat( const char *pname, const float *data, int count ) void CSave::WriteString( const char *pname, const char *pdata ) { +#ifdef NEO + BufferField( pname, narrow_cast(strlen(pdata) + 1), pdata ); +#else BufferField( pname, strlen(pdata) + 1, pdata ); +#endif } //------------------------------------- void CSave::WriteString( const char *pname, const string_t *stringId, int count ) { +#ifdef NEO + int i; size_t size; +#else int i, size; +#endif size = 0; for ( i = 0; i < count; i++ ) size += strlen( STRING( stringId[i] ) ) + 1; - WriteHeader( pname, size ); + WriteHeader( pname, narrow_cast(size) ); WriteString( stringId, count ); } @@ -1148,7 +1168,11 @@ void CSave::WriteFunction( datamap_t *pRootMap, const char *pname, inputfunc_t * functionName = "BADFUNCTIONPOINTER"; } +#ifdef NEO + BufferField( pname, V_strlen(functionName) + 1, functionName ); +#else BufferField( pname, strlen(functionName) + 1, functionName ); +#endif } //------------------------------------- @@ -1801,8 +1825,12 @@ int CRestore::ReadData( char *pData, int size, int nBytesAvailable ) void CRestore::ReadString( char *pDest, int nSizeDest, int nBytesAvailable ) { const char *pString = BufferPointer(); - if ( !nBytesAvailable ) + if (!nBytesAvailable) +#ifdef NEO + nBytesAvailable = narrow_cast(strlen(pString) + 1); +#else nBytesAvailable = strlen( pString ) + 1; +#endif BufferSkipBytes( nBytesAvailable ); Q_strncpy(pDest, pString, nSizeDest ); diff --git a/src/public/SoundParametersInternal.cpp b/src/public/SoundParametersInternal.cpp index b408c93825..662627c64f 100644 --- a/src/public/SoundParametersInternal.cpp +++ b/src/public/SoundParametersInternal.cpp @@ -226,7 +226,11 @@ int TextToChannel( const char *name ) return CHAN_AUTO; } +#ifdef NEO + if ( Q_strncasecmp( name, "chan_", V_strlen( "chan_" ) ) ) +#else if ( Q_strncasecmp( name, "chan_", strlen( "chan_" ) ) ) +#endif { return atoi( name ); } @@ -538,7 +542,11 @@ void CSoundParametersInternal::PitchFromString( const char *sz ) void CSoundParametersInternal::SoundLevelFromString( const char *sz ) { +#ifdef NEO + if ( !Q_strncasecmp( sz, "SNDLVL_", V_strlen( "SNDLVL_" ) ) ) +#else if ( !Q_strncasecmp( sz, "SNDLVL_", strlen( "SNDLVL_" ) ) ) +#endif { soundlevel.start = TextToSoundLevel( sz ); soundlevel.range = 0; diff --git a/src/public/datamap.h b/src/public/datamap.h index 0330c85324..d53be0980c 100644 --- a/src/public/datamap.h +++ b/src/public/datamap.h @@ -130,13 +130,13 @@ DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) ) // Normal offset of is invalid on non-array-types, this is dubious as hell. The rest of the codebase converted to the // legit offsetof from the C headers, so we'll use the old impl here to avoid exposing temptation to others +#ifdef NEO +#define _hacky_datamap_offsetof(s,m) narrow_cast(((size_t)&(((s *)0)->m))) +#else #define _hacky_datamap_offsetof(s,m) ((size_t)&(((s *)0)->m)) +#endif -#ifdef NEO // NEO NOTE (nullsystem): warning: narrowing conversion of ... from 'int' to 'size_t' -#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { (size_t)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance } -#else #define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { (int)_hacky_datamap_offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance } -#endif #define DEFINE_FIELD_NULL { FIELD_VOID,0, {0,0},0,0,0,0,0,0} #define DEFINE_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_SAVE, NULL, 0 ) #define DEFINE_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 ) diff --git a/src/public/dt_recv.h b/src/public/dt_recv.h index 1a31e1d9b8..9243d21f0a 100644 --- a/src/public/dt_recv.h +++ b/src/public/dt_recv.h @@ -285,13 +285,25 @@ inline bool RecvTable::IsInMainList() const // Normal offset of is invalid on non-array-types, this is dubious as hell. The rest of the codebase converted to the // legit offsetof from the C headers, so we'll use the old impl here to avoid exposing temptation to others +#ifdef NEO +#define _hacky_dtrecv_offsetof(s,m) ( narrow_cast( (size_t)&(((s *)0x1000000)->m) - 0x1000000u ) ) +#else #define _hacky_dtrecv_offsetof(s,m) ( (size_t)&(((s *)0x1000000)->m) - 0x1000000u ) +#endif +#ifdef NEO +#define RECVINFO(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), narrow_cast(sizeof(((currentRecvDTClass*)0)->varName)) +#else #define RECVINFO(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) +#endif // NEO #define RECVINFO_NAME(varName, remoteVarName) #remoteVarName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) #define RECVINFO_STRING(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), STRINGBUFSIZE(currentRecvDTClass, varName) #define RECVINFO_BASECLASS(tableName) RecvPropDataTable("this", 0, 0, &REFERENCE_RECV_TABLE(tableName)) +#ifdef NEO +#define RECVINFO_ARRAY(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), narrow_cast(sizeof(((currentRecvDTClass*)0)->varName[0])), narrow_cast(sizeof(((currentRecvDTClass*)0)->varName)/sizeof(((currentRecvDTClass*)0)->varName[0])) +#else #define RECVINFO_ARRAY(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName[0]), sizeof(((currentRecvDTClass*)0)->varName)/sizeof(((currentRecvDTClass*)0)->varName[0]) +#endif // Just specify the name and offset. Used for strings and data tables. #define RECVINFO_NOSIZE(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName) diff --git a/src/public/dt_send.h b/src/public/dt_send.h index e8204b7d87..bdd41e6a55 100644 --- a/src/public/dt_send.h +++ b/src/public/dt_send.h @@ -578,7 +578,11 @@ inline void SendTable::SetHasPropsEncodedAgainstTickcount( bool bState ) // Normal offset of is invalid on non-array-types, this is dubious as hell. The rest of the codebase converted to the // legit offsetof from the C headers, so we'll use the old impl here to avoid exposing temptation to others +#ifdef NEO +#define _hacky_dtsend_offsetof(s,m) narrow_cast( ( (size_t)&(((s *)0x1000000)->m) - 0x1000000u ) ) +#else #define _hacky_dtsend_offsetof(s,m) ( (size_t)&(((s *)0x1000000)->m) - 0x1000000u ) +#endif // These can simplify creating the variables. // Note: currentSendDTClass::MakeANetworkVar_##varName equates to currentSendDTClass. It's @@ -599,7 +603,11 @@ inline void SendTable::SetHasPropsEncodedAgainstTickcount( bool bState ) #define SENDINFO_STRUCTARRAYELEM(varName, i)#varName "[" #i "]", _hacky_dtsend_offsetof(currentSendDTClass, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0]) // Use this when you're not using a CNetworkVar to represent the data you're sending. +#ifdef NEO +#define SENDINFO_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName), narrow_cast(sizeof(((currentSendDTClass*)0)->varName)) +#else #define SENDINFO_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName) +#endif #define SENDINFO_STRING_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName) #define SENDINFO_DT(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName) #define SENDINFO_DT_NAME(varName, remoteVarName) #remoteVarName, _hacky_dtsend_offsetof(currentSendDTClass, varName) diff --git a/src/public/tier1/utlmemory.h b/src/public/tier1/utlmemory.h index ff64a79666..ba8c27821d 100644 --- a/src/public/tier1/utlmemory.h +++ b/src/public/tier1/utlmemory.h @@ -22,6 +22,10 @@ #include "tier0/memalloc.h" #include "tier0/memdbgon.h" +#ifdef NEO +#include "../common/neo/narrow_cast.h" +#endif + #pragma warning (disable:4100) #pragma warning (disable:4514) @@ -342,7 +346,11 @@ class CUtlMemoryConservative int NumAllocated() const { +#ifdef NEO + return narrow_cast( AllocSize() / sizeof( T ) ); +#else return AllocSize() / sizeof( T ); +#endif } int Count() const { diff --git a/src/public/tier1/utlvector.h b/src/public/tier1/utlvector.h index 7c6e3d76f4..b2622648fa 100644 --- a/src/public/tier1/utlvector.h +++ b/src/public/tier1/utlvector.h @@ -424,8 +424,13 @@ class CUtlVectorUltraConservative : private A } else { +#ifdef NEO + auto nNeeded = sizeof(Data_t) + ( num * sizeof(T) ); + auto nHave = A::GetSize( m_pData ); +#else int nNeeded = sizeof(Data_t) + ( num * sizeof(T) ); int nHave = A::GetSize( m_pData ); +#endif if ( nNeeded > nHave ) { m_pData = (Data_t *)A::Realloc( m_pData, nNeeded ); diff --git a/src/tier1/CMakeLists.txt b/src/tier1/CMakeLists.txt index 1ff0f6d3bb..5936b3fa58 100644 --- a/src/tier1/CMakeLists.txt +++ b/src/tier1/CMakeLists.txt @@ -15,6 +15,7 @@ target_include_directories(tier1 ${CMAKE_SOURCE_DIR}/public/tier1 PRIVATE ${CMAKE_SOURCE_DIR}/common + ${CMAKE_SOURCE_DIR}/common/neo ${CMAKE_SOURCE_DIR}/public ${CMAKE_SOURCE_DIR}/public/tier0 ) @@ -136,6 +137,8 @@ target_sources_grouped( TARGET tier1 NAME "Header Files" FILES + ${CMAKE_SOURCE_DIR}/common/neo/narrow_cast.h + ${CMAKE_SOURCE_DIR}/public/tier1/bitbuf.h ${CMAKE_SOURCE_DIR}/public/tier1/byteswap.h ${CMAKE_SOURCE_DIR}/public/tier1/callqueue.h diff --git a/src/tier1/strtools.cpp b/src/tier1/strtools.cpp index c46c708b3d..081e0d46f5 100644 --- a/src/tier1/strtools.cpp +++ b/src/tier1/strtools.cpp @@ -282,7 +282,11 @@ char *V_strlower( char *start ) char *V_strnlwr(char *s, size_t count) { // Assert( count >= 0 ); tautology since size_t is unsigned +#ifdef NEO + AssertValidStringPtr( s, narrow_cast(count) ); +#else AssertValidStringPtr( s, count ); +#endif char* pRet = s; if ( !s || !count ) diff --git a/src/tier1/utlstring.cpp b/src/tier1/utlstring.cpp index c5dbb4999e..5cf3e56baf 100644 --- a/src/tier1/utlstring.cpp +++ b/src/tier1/utlstring.cpp @@ -94,8 +94,11 @@ void CUtlString::SetDirect( const char *pValue, int nChars ) AssertMsg( nChars == Q_strlen(m_pString), "CUtlString::SetDirect does not support resizing strings in place." ); return; // Do nothing. Realloc in AllocMemory might move pValue's location resulting in a bad memcpy. } - +#ifdef NEO + Assert( nChars <= Min( narrow_cast(strnlen(pValue, nChars) + 1), nChars ) ); +#else Assert( nChars <= Min( strnlen(pValue, nChars) + 1, nChars ) ); +#endif AllocMemory( nChars ); Q_memcpy( m_pString, pValue, nChars ); } From e874a0703d961e8b7dd9ef8041fa187051f39f2f Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 3 Dec 2025 02:54:15 +0200 Subject: [PATCH 03/96] Fix unused variables --- src/game/client/c_baseplayer.cpp | 2 ++ src/game/client/c_baseviewmodel.cpp | 4 ++++ src/game/client/c_effects.cpp | 4 ++++ src/game/client/c_impact_effects.cpp | 8 ++++++++ src/game/client/c_pixel_visibility.cpp | 2 ++ src/game/client/c_rope.cpp | 2 ++ src/game/client/c_smoke_trail.cpp | 2 ++ src/game/client/c_te.cpp | 4 ++++ src/game/client/c_te_largefunnel.cpp | 2 ++ src/game/client/c_te_legacytempents.cpp | 2 ++ src/game/client/c_te_sprite.cpp | 4 ++++ src/game/client/c_testtraceline.cpp | 4 ++++ src/game/client/camomaterialproxy.cpp | 4 ++++ src/game/client/clientshadowmgr.cpp | 4 ++++ src/game/client/detailobjectsystem.cpp | 2 ++ src/game/client/fx.cpp | 16 ++++++++++++++++ src/game/client/fx_blood.cpp | 4 ++++ src/game/client/fx_explosion.cpp | 2 ++ src/game/client/fx_sparks.cpp | 8 ++++++++ src/game/client/game_controls/SpectatorGUI.cpp | 5 ++++- src/game/client/hl2/c_npc_combinegunship.cpp | 2 ++ src/game/client/hl2/c_strider.cpp | 2 ++ src/game/client/hl2mp/c_hl2mp_player.cpp | 2 ++ src/game/client/neo/ui/neo_hud_round_state.cpp | 1 - src/game/client/neo/ui/neo_loading.cpp | 2 +- src/game/client/neo/ui/neo_root.cpp | 5 ----- src/game/client/neo/ui/neo_ui.cpp | 1 - src/game/client/particlemgr.cpp | 6 ++++++ src/game/client/particles_attractor.cpp | 2 ++ src/game/client/physics_main_client.cpp | 2 ++ src/game/client/studio_stats.cpp | 2 ++ .../server/NextBot/NextBotGroundLocomotion.cpp | 2 +- .../server/NextBot/Path/NextBotPathFollow.cpp | 2 +- src/game/server/ai_basenpc.cpp | 2 ++ src/game/server/ai_basenpc_schedule.cpp | 2 ++ src/game/server/ai_planesolver.cpp | 2 ++ src/game/server/ai_tacticalservices.cpp | 2 ++ src/game/server/basecombatcharacter.cpp | 4 ++++ src/game/server/baseentity.cpp | 2 ++ src/game/server/fish.cpp | 2 ++ src/game/server/genericmonster.cpp | 4 ++++ src/game/server/gib.cpp | 2 ++ src/game/server/h_ai.cpp | 4 ++++ src/game/server/hl2/func_tank.cpp | 8 ++++++++ src/game/server/hl2/npc_BaseZombie.cpp | 2 ++ src/game/server/hl2/npc_antlionguard.cpp | 2 ++ src/game/server/hl2/npc_combine.cpp | 2 ++ src/game/server/hl2/npc_combinecamera.cpp | 4 +++- src/game/server/hl2/npc_combinedropship.cpp | 2 ++ src/game/server/hl2/npc_combinegunship.cpp | 10 ++++++++++ src/game/server/hl2/npc_dog.cpp | 6 +++++- src/game/server/hl2/npc_manhack.cpp | 2 ++ src/game/server/hl2/npc_metropolice.cpp | 2 ++ src/game/server/hl2/npc_rollermine.cpp | 2 ++ src/game/server/hl2/npc_strider.cpp | 2 ++ src/game/server/hl2/npc_turret_ceiling.cpp | 2 ++ src/game/server/hl2/prop_combine_ball.cpp | 2 ++ src/game/server/hl2/proto_sniper.cpp | 4 ++++ src/game/server/nav_area.cpp | 4 ++++ src/game/server/nav_edit.cpp | 2 ++ .../bot/behavior/neo_bot_tactical_monitor.cpp | 2 ++ src/game/server/neo/bot/neo_bot.cpp | 4 ++-- src/game/server/neo/neo_dm_spawn.cpp | 2 +- src/game/server/npc_talker.cpp | 2 ++ src/game/server/physics_prop_ragdoll.cpp | 2 ++ src/game/server/props.cpp | 2 ++ src/game/server/te_projecteddecal.cpp | 2 ++ src/game/server/triggers.cpp | 2 ++ src/game/server/util.cpp | 4 ++++ src/game/shared/gamemovement.cpp | 8 ++++++++ src/game/shared/hl2mp/weapon_rpg.cpp | 8 ++++++++ src/game/shared/particlesystemquery.cpp | 2 ++ src/game/shared/physics_shared.cpp | 2 ++ src/game/shared/ragdoll_shared.cpp | 2 ++ src/game/shared/takedamageinfo.cpp | 2 ++ src/public/ScratchPadUtils.cpp | 4 ++++ src/public/haptics/haptic_utils.cpp | 2 ++ 77 files changed, 236 insertions(+), 16 deletions(-) diff --git a/src/game/client/c_baseplayer.cpp b/src/game/client/c_baseplayer.cpp index 05cb0e8ba9..424c32f067 100644 --- a/src/game/client/c_baseplayer.cpp +++ b/src/game/client/c_baseplayer.cpp @@ -3229,7 +3229,9 @@ void C_BasePlayer::BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vec // Find out where the player's head (driven by the HMD) is in the world. // We can't move this with animations or effects without causing nausea, so we need to move // the whole body so that the animated head is in the right place to match the player-controlled head. +#ifndef NEO Vector vHeadUp; +#endif Vector vRealPivotPoint; if( UseVR() ) { diff --git a/src/game/client/c_baseviewmodel.cpp b/src/game/client/c_baseviewmodel.cpp index c54906dde8..bdcc6de6f7 100644 --- a/src/game/client/c_baseviewmodel.cpp +++ b/src/game/client/c_baseviewmodel.cpp @@ -232,7 +232,11 @@ void C_BaseViewModel::ApplyBoneMatrixTransform( matrix3x4_t& transform ) MatrixInvert( viewMatrixInverse, viewMatrix ); // Transform into view space. +#ifdef NEO + matrix3x4_t temp; +#else matrix3x4_t temp, temp2; +#endif ConcatTransforms( viewMatrix, transform, temp ); // Flip it along X. diff --git a/src/game/client/c_effects.cpp b/src/game/client/c_effects.cpp index 8e87405d1f..ca46397086 100644 --- a/src/game/client/c_effects.cpp +++ b/src/game/client/c_effects.cpp @@ -884,7 +884,9 @@ void CClient_Precipitation::CreateAshParticle( void ) float curTime = gpGlobals->frametime; +#ifndef NEO Vector vPushOrigin; +#endif Vector absmins = WorldAlignMins(); Vector absmaxs = WorldAlignMaxs(); @@ -2078,7 +2080,9 @@ void CSnowFallManager::CreateOutsideVolumeSnowParticles( float flCurrentTime, fl //----------------------------------------------------------------------------- void CSnowFallManager::CreateInsideVolumeSnowParticles( float flCurrentTime, float flRadius, const Vector &vecEyePos, const Vector &vecForward, float flZoomScale ) { +#ifndef NEO Vector vecParticleSpawn; +#endif // Check/Setup for zoom. bool bZoomed = ( flZoomScale > 1.0f ); diff --git a/src/game/client/c_impact_effects.cpp b/src/game/client/c_impact_effects.cpp index 90b9a10ece..6a44385a84 100644 --- a/src/game/client/c_impact_effects.cpp +++ b/src/game/client/c_impact_effects.cpp @@ -184,7 +184,11 @@ static void CreateFleckParticles( const Vector& origin, const Vector &color, tra break; } +#ifdef NEO + Vector dir; +#else Vector dir, end; +#endif float colorRamp; @@ -676,7 +680,11 @@ void FX_AntlionImpact( const Vector &pos, trace_t *trace ) // Setup our collision information fleckEmitter->m_ParticleCollision.Setup( spawnOffset, &shotDir, flAngularSpray, 8.0f, flMaxSpeed, FLECK_GRAVITY, FLECK_DAMPEN ); +#ifdef NEO + Vector dir; +#else Vector dir, end; +#endif Vector color = Vector( 1, 0.9, 0.75 ); float colorRamp; diff --git a/src/game/client/c_pixel_visibility.cpp b/src/game/client/c_pixel_visibility.cpp index 731cd47d54..b581e003b3 100644 --- a/src/game/client/c_pixel_visibility.cpp +++ b/src/game/client/c_pixel_visibility.cpp @@ -51,7 +51,9 @@ const float MIN_PROXY_PIXELS = 25.0f; float PixelVisibility_DrawProxy( IMatRenderContext *pRenderContext, OcclusionQueryObjectHandle_t queryHandle, Vector origin, float scale, float proxyAspect, IMaterial *pMaterial, bool screenspace ) { +#ifndef NEO Vector point; +#endif // don't expand this with distance to fit pixels or the sprite will poke through // only expand the parts perpendicular to the view diff --git a/src/game/client/c_rope.cpp b/src/game/client/c_rope.cpp index 2165676e0f..f7d54891fa 100644 --- a/src/game/client/c_rope.cpp +++ b/src/game/client/c_rope.cpp @@ -900,7 +900,9 @@ void C_RopeKeyframe::CPhysicsDelegate::GetNodeForces( CSimplePhysics::CNode *pNo GetWindspeedAtTime(gpGlobals->curtime, vecWindVel); if ( vecWindVel.LengthSqr() > 0 ) { +#ifndef NEO Vector vecWindAccel; +#endif VectorMA( *pAccel, WIND_FORCE_FACTOR, vecWindVel, *pAccel ); } else diff --git a/src/game/client/c_smoke_trail.cpp b/src/game/client/c_smoke_trail.cpp index 81d5c349ad..743ab6c628 100644 --- a/src/game/client/c_smoke_trail.cpp +++ b/src/game/client/c_smoke_trail.cpp @@ -1507,7 +1507,9 @@ void C_FireTrail::Update( float fTimeDelta ) numPuffs = clamp( numPuffs, 1, 32 ); SimpleParticle *pParticle; +#ifndef NEO Vector offsetColor; +#endif float step = moveLength / numPuffs; //Fill in the gaps diff --git a/src/game/client/c_te.cpp b/src/game/client/c_te.cpp index 842b23e411..aac6ae50d5 100644 --- a/src/game/client/c_te.cpp +++ b/src/game/client/c_te.cpp @@ -599,7 +599,11 @@ class C_TempEntsSystem : public ITempEntsSystem case TE_SMOKE: { +#ifdef NEO + Vector vecOrigin; +#else Vector vecOrigin, vecDirection; +#endif vecOrigin.x = pKeyValues->GetFloat( "originx" ); vecOrigin.y = pKeyValues->GetFloat( "originy" ); vecOrigin.z = pKeyValues->GetFloat( "originz" ); diff --git a/src/game/client/c_te_largefunnel.cpp b/src/game/client/c_te_largefunnel.cpp index 25430db06e..4f37f3c9df 100644 --- a/src/game/client/c_te_largefunnel.cpp +++ b/src/game/client/c_te_largefunnel.cpp @@ -59,7 +59,9 @@ void C_TELargeFunnel::CreateFunnel( void ) SimpleParticle *pParticle; Vector vecDir; +#ifndef NEO Vector vecDest; +#endif float ratio = 0.25; float invratio = 1 / ratio; diff --git a/src/game/client/c_te_legacytempents.cpp b/src/game/client/c_te_legacytempents.cpp index a0b0473487..a7c71a358f 100644 --- a/src/game/client/c_te_legacytempents.cpp +++ b/src/game/client/c_te_legacytempents.cpp @@ -3399,8 +3399,10 @@ void CTempEnts::CSEjectBrass( const Vector &vecPosition, const QAngle &angVeloci Vector forward, right, up; Vector velocity; +#ifndef NEO Vector origin; QAngle angle; +#endif // Add some randomness to the velocity diff --git a/src/game/client/c_te_sprite.cpp b/src/game/client/c_te_sprite.cpp index 36cf6b2e6b..ba66c99728 100644 --- a/src/game/client/c_te_sprite.cpp +++ b/src/game/client/c_te_sprite.cpp @@ -123,7 +123,11 @@ void TE_Sprite( IRecipientFilter& filter, float delay, void TE_Sprite( IRecipientFilter& filter, float delay, KeyValues *pKeyValues ) { +#ifdef NEO + Vector vecOrigin; +#else Vector vecOrigin, vecDirection; +#endif vecOrigin.x = pKeyValues->GetFloat( "originx" ); vecOrigin.y = pKeyValues->GetFloat( "originy" ); vecOrigin.z = pKeyValues->GetFloat( "originz" ); diff --git a/src/game/client/c_testtraceline.cpp b/src/game/client/c_testtraceline.cpp index 47016cc930..f8c69d8d44 100644 --- a/src/game/client/c_testtraceline.cpp +++ b/src/game/client/c_testtraceline.cpp @@ -145,7 +145,11 @@ void C_TestTraceline::DrawCube( Vector& center, unsigned char* pColor ) int C_TestTraceline::DrawModel( int flags ) { trace_t tr; +#ifdef NEO + Vector forward, right, up, endpos; +#else Vector forward, right, up, endpos, hitpos; +#endif AngleVectors (GetAbsAngles(), &forward, &right, &up); endpos = GetAbsOrigin() + forward * MAX_TRACE_LENGTH; diff --git a/src/game/client/camomaterialproxy.cpp b/src/game/client/camomaterialproxy.cpp index 77828c8973..d30f5fe062 100644 --- a/src/game/client/camomaterialproxy.cpp +++ b/src/game/client/camomaterialproxy.cpp @@ -367,14 +367,18 @@ void CCamoMaterialProxy::GenerateCamoTexture( ITexture* pTexture, IVTFTexture *p mins = m_pEnt->WorldAlignMins(); maxs = m_pEnt->WorldAlignMaxs(); +#ifndef NEO Vector traceDirection; Vector traceEnd; trace_t traceResult; +#endif Vector forward, right, up; AngleVectors( entityAngles, &forward, &right, &up ); +#ifndef NEO Vector position, transformedPosition; +#endif Vector maxsMinusMins = maxs - mins; Vector diffuseColor[256]; diff --git a/src/game/client/clientshadowmgr.cpp b/src/game/client/clientshadowmgr.cpp index b5cd266266..b456ab4a4d 100644 --- a/src/game/client/clientshadowmgr.cpp +++ b/src/game/client/clientshadowmgr.cpp @@ -2360,7 +2360,11 @@ void CClientShadowMgr::BuildOrthoShadow( IClientRenderable* pRenderable, worldOrigin.z = (int)(worldOrigin.z / dx) * dx; // NOTE: We gotta use the general matrix because xvec and yvec aren't perp +#ifdef NEO + VMatrix matWorldToTexture; +#else VMatrix matWorldToShadow, matWorldToTexture; +#endif BuildGeneralWorldToShadowMatrix( m_Shadows[handle].m_WorldToShadow, worldOrigin, vecShadowDir, xvec, yvec ); BuildWorldToTextureMatrix( m_Shadows[handle].m_WorldToShadow, size, matWorldToTexture ); Vector2DCopy( size, m_Shadows[handle].m_WorldSize ); diff --git a/src/game/client/detailobjectsystem.cpp b/src/game/client/detailobjectsystem.cpp index 3518fa902b..f8fd300322 100644 --- a/src/game/client/detailobjectsystem.cpp +++ b/src/game/client/detailobjectsystem.cpp @@ -2077,7 +2077,9 @@ int CDetailObjectSystem::SortSpritesBackToFront( int nLeaf, const Vector &viewOr { CDetailModel &model = m_DetailObjects[j]; +#ifndef NEO Vector v; +#endif VectorSubtract( model.GetRenderOrigin(), viewOrigin, vecDelta ); float flSqDist = vecDelta.LengthSqr(); if ( flSqDist >= flMaxSqDist ) diff --git a/src/game/client/fx.cpp b/src/game/client/fx.cpp index a342837f67..f453b9f7ea 100644 --- a/src/game/client/fx.cpp +++ b/src/game/client/fx.cpp @@ -865,7 +865,11 @@ void FX_GunshipMuzzleEffect( const Vector &origin, const QAngle &angles, float s void FX_GunshipTracer( Vector& start, Vector& end, int velocity, bool makeWhiz ) { VPROF_BUDGET( "FX_GunshipTracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); +#ifdef NEO + Vector shotDir; +#else Vector vNear, dStart, dEnd, shotDir; +#endif float totalDist; //Get out shot direction and length @@ -915,7 +919,11 @@ void FX_StriderMuzzleEffect( const Vector &origin, const QAngle &angles, float s void FX_StriderTracer( Vector& start, Vector& end, int velocity, bool makeWhiz ) { VPROF_BUDGET( "FX_StriderTracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); +#ifdef NEO + Vector shotDir; +#else Vector vNear, dStart, dEnd, shotDir; +#endif float totalDist; //Get out shot direction and length @@ -949,7 +957,11 @@ void FX_StriderTracer( Vector& start, Vector& end, int velocity, bool makeWhiz ) void FX_HunterTracer( Vector& start, Vector& end, int velocity, bool makeWhiz ) { VPROF_BUDGET( "FX_HunterTracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); +#ifdef NEO + Vector shotDir; +#else Vector vNear, dStart, dEnd, shotDir; +#endif float totalDist; // Get out shot direction and length @@ -983,7 +995,11 @@ void FX_HunterTracer( Vector& start, Vector& end, int velocity, bool makeWhiz ) void FX_GaussTracer( Vector& start, Vector& end, int velocity, bool makeWhiz ) { VPROF_BUDGET( "FX_GaussTracer", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); +#ifdef NEO + Vector shotDir; +#else Vector vNear, dStart, dEnd, shotDir; +#endif float totalDist; //Get out shot direction and length diff --git a/src/game/client/fx_blood.cpp b/src/game/client/fx_blood.cpp index 820879da8b..3b1bdbf74c 100644 --- a/src/game/client/fx_blood.cpp +++ b/src/game/client/fx_blood.cpp @@ -593,7 +593,11 @@ void HunterDamageCallback( const CEffectData &data ) // Setup our collision information pGlassEmitter->m_ParticleCollision.Setup( data.m_vOrigin, &data.m_vNormal, flAngularSpray, flMinSpeed, flMaxSpeed, 600.0f, 0.2f ); +#ifdef NEO + Vector dir; +#else Vector dir, end; +#endif int numFlecks = 32; diff --git a/src/game/client/fx_explosion.cpp b/src/game/client/fx_explosion.cpp index 2eaffc014f..106e665341 100644 --- a/src/game/client/fx_explosion.cpp +++ b/src/game/client/fx_explosion.cpp @@ -1207,7 +1207,9 @@ void C_WaterExplosionEffect::CreateMisc( void ) int numDrops = 32; float length = 0.1f; +#ifndef NEO Vector vForward, vRight, vUp; +#endif Vector offDir; TrailParticle *tParticle; diff --git a/src/game/client/fx_sparks.cpp b/src/game/client/fx_sparks.cpp index 295c830ab9..1338529d65 100644 --- a/src/game/client/fx_sparks.cpp +++ b/src/game/client/fx_sparks.cpp @@ -1021,7 +1021,11 @@ void FX_MicroExplosion( Vector &position, Vector &normal ) } TrailParticle *pParticle; +#ifdef NEO + Vector dir; +#else Vector dir, vOfs; +#endif float length = 0.2f; //Fast lines @@ -1225,7 +1229,11 @@ void FX_Explosion( Vector& origin, Vector& normal, char materialType ) // Throw some smoke balls out around the normal int numBalls = 12; +#ifdef NEO + Vector vecRight, vecUp; +#else Vector vecRight, vecForward, vecUp; +#endif QAngle vecAngles; VectorAngles( normal, vecAngles ); AngleVectors( vecAngles, NULL, &vecRight, &vecUp ); diff --git a/src/game/client/game_controls/SpectatorGUI.cpp b/src/game/client/game_controls/SpectatorGUI.cpp index 71e99a0587..acf2ff8514 100644 --- a/src/game/client/game_controls/SpectatorGUI.cpp +++ b/src/game/client/game_controls/SpectatorGUI.cpp @@ -714,9 +714,13 @@ void CSpectatorGUI::Update() GetHudSize(wide, tall); m_pTopBar->GetBounds( bx, by, bwide, btall ); +#ifndef NEO IGameResources *gr = GameResources(); +#endif int specmode = GetSpectatorMode(); +#ifndef NEO int playernum = GetSpectatorTarget(); +#endif IViewPortPanel *overview = gViewPortInterface->FindPanelByName( PANEL_OVERVIEW ); @@ -851,7 +855,6 @@ extern ConVar cl_neo_hud_health_mode; void CSpectatorGUI::UpdatePlayerLabel() { IGameResources* gr = GameResources(); - int specmode = GetSpectatorMode(); int playernum = GetSpectatorTarget(); // update player name filed, text & color diff --git a/src/game/client/hl2/c_npc_combinegunship.cpp b/src/game/client/hl2/c_npc_combinegunship.cpp index b42ca04ff5..b277cdc44f 100644 --- a/src/game/client/hl2/c_npc_combinegunship.cpp +++ b/src/game/client/hl2/c_npc_combinegunship.cpp @@ -274,7 +274,9 @@ int C_GunshipFX::DrawModel( int ) ent->GetAttachment( m_attachment, m_worldPosition, angles ); } +#ifndef NEO Vector test; +#endif m_t += gpGlobals->frametime; if ( m_tMax > 0 ) { diff --git a/src/game/client/hl2/c_strider.cpp b/src/game/client/hl2/c_strider.cpp index 3ea3f733ad..06a1fb84a7 100644 --- a/src/game/client/hl2/c_strider.cpp +++ b/src/game/client/hl2/c_strider.cpp @@ -987,7 +987,9 @@ void StriderBlood( const Vector &origin, const Vector &normal, float scale ) PMaterialHandle hMaterial = ParticleMgr()->GetPMaterial( "effects/slime1" ); float length = 0.2f; +#ifndef NEO Vector vForward, vRight, vUp; +#endif Vector offDir; TrailParticle *tParticle; diff --git a/src/game/client/hl2mp/c_hl2mp_player.cpp b/src/game/client/hl2mp/c_hl2mp_player.cpp index 6c60d2b9e0..c1974cb6c9 100644 --- a/src/game/client/hl2mp/c_hl2mp_player.cpp +++ b/src/game/client/hl2mp/c_hl2mp_player.cpp @@ -1585,7 +1585,9 @@ void C_HL2MP_Player::CalculateIKLocks( float currentTime ) for (int i = 0; i < targetCount; i++) { +#ifndef NEO trace_t trace; +#endif CIKTarget *pTarget = &m_pIk->m_target[i]; if (!pTarget->IsActive()) diff --git a/src/game/client/neo/ui/neo_hud_round_state.cpp b/src/game/client/neo/ui/neo_hud_round_state.cpp index 241d73da06..13e531f3f9 100644 --- a/src/game/client/neo/ui/neo_hud_round_state.cpp +++ b/src/game/client/neo/ui/neo_hud_round_state.cpp @@ -533,7 +533,6 @@ void CNEOHud_RoundState::DrawNeoHudElement() m_iRightPlayersTotal = 0; int leftCount = 0; int rightCount = 0; - bool bDMRightSide = false; if (NEORules()->IsTeamplay()) { for (int i = 1; i <= gpGlobals->maxClients; i++) diff --git a/src/game/client/neo/ui/neo_loading.cpp b/src/game/client/neo/ui/neo_loading.cpp index e0b34b96e1..52b5548b51 100644 --- a/src/game/client/neo/ui/neo_loading.cpp +++ b/src/game/client/neo/ui/neo_loading.cpp @@ -148,7 +148,7 @@ void CNeoLoading::FetchGameUIPanels() { const vgui::VPANEL curLoadChPanel = vgui::ipanel()->GetChild(loadingPanel, i); const char *curLoadChPanelName = vgui::ipanel()->GetName(curLoadChPanel); - const char *curLoadChPanelClass = vgui::ipanel()->GetClassName(curLoadChPanel); + [[maybe_unused]] const char *curLoadChPanelClass = vgui::ipanel()->GetClassName(curLoadChPanel); Panel *pPanel = vgui::ipanel()->GetPanel(curLoadChPanel, "GAMEUI"); if (!pPanel) { diff --git a/src/game/client/neo/ui/neo_root.cpp b/src/game/client/neo/ui/neo_root.cpp index 37961c3955..e69887af73 100644 --- a/src/game/client/neo/ui/neo_root.cpp +++ b/src/game/client/neo/ui/neo_root.cpp @@ -819,10 +819,6 @@ void CNeoRoot::MainLoopRoot(const MainLoopParam param) NeoUI::EndSection(); g_uiCtx.bgColor = COLOR_TRANSPARENT; - const int iBtnWide = m_iTitleWidth + iMargin; - const int iRightXPos = iBtnPlaceXMid + (iBtnWide / 2) + iMarginHalf; - int iRightSideYStart = (iTitleMarginTop + (2 * iTitleNHeight)); - // Draw top steam section portion { // Draw title @@ -1926,7 +1922,6 @@ void CNeoRoot::MainLoopSprayPicker(const MainLoopParam param) m_bSprayGalleryRefresh = false; } - const int iGalleryRows = g_iRowsInScreen / 4; const int iNormTall = g_uiCtx.layout.iRowTall; const int iCellTall = iNormTall * 4; diff --git a/src/game/client/neo/ui/neo_ui.cpp b/src/game/client/neo/ui/neo_ui.cpp index cc1ca9e6d0..dd03d98226 100644 --- a/src/game/client/neo/ui/neo_ui.cpp +++ b/src/game/client/neo/ui/neo_ui.cpp @@ -74,7 +74,6 @@ void MultiWidgetHighlighter(const int iTotalWidgets) // Peek-forward what the area of the multiple widgets will cover without modifying the context int iMulLayoutX = c->iLayoutX; - int iMulLayoutY = c->iLayoutY; int iAllXWide = 0; int iMulIdxRowParts = c->iIdxRowParts; diff --git a/src/game/client/particlemgr.cpp b/src/game/client/particlemgr.cpp index 7b6d7701f0..a0d4a335ed 100644 --- a/src/game/client/particlemgr.cpp +++ b/src/game/client/particlemgr.cpp @@ -1633,7 +1633,11 @@ int CParticleMgr::ComputeParticleDefScreenArea( int nInfoCount, RetireInfo_t *pI pInfo[nCollection].m_pCollection = pCollection; pInfo[nCollection].m_bFirstFrame = false; +#ifdef NEO + Vector vecCenter, vecScreenCenter; +#else Vector vecCenter, vecScreenCenter, vecCenterCam; +#endif vecCenter = pCollection->GetControlPointAtCurrentTime( pDef->GetCullControlPoint() ); Vector3DMultiplyPositionProjective( worldToPixels, vecCenter, vecScreenCenter ); @@ -1751,7 +1755,9 @@ bool CParticleMgr::EarlyRetireParticleSystems( int nCount, ParticleSimListEntry_ ppEffects[i].m_pNewParticleEffect->MarkShouldPerformCullCheck( true ); } +#ifndef NEO Vector vecCameraForward; +#endif VMatrix worldToView, viewToProjection, worldToProjection, worldToScreen; render->GetMatricesForView( *pViewSetup, &worldToView, &viewToProjection, &worldToProjection, &worldToScreen ); float flFocalDist = tan( DEG2RAD( pViewSetup->fov * 0.5f ) ); diff --git a/src/game/client/particles_attractor.cpp b/src/game/client/particles_attractor.cpp index 3b52fb58f7..65f9fc7d61 100644 --- a/src/game/client/particles_attractor.cpp +++ b/src/game/client/particles_attractor.cpp @@ -32,7 +32,9 @@ CParticleAttractor *CParticleAttractor::Create( const Vector ¢er, const char void CParticleAttractor::UpdateVelocity( SimpleParticle *pParticle, float timeDelta ) { float speed = VectorNormalize( pParticle->m_vecVelocity ); +#ifndef NEO Vector offset; +#endif Vector dir = ( m_vecAttractorOrigin - pParticle->m_Pos ); VectorNormalize( dir ); diff --git a/src/game/client/physics_main_client.cpp b/src/game/client/physics_main_client.cpp index d00d36a7d1..9720ed0495 100644 --- a/src/game/client/physics_main_client.cpp +++ b/src/game/client/physics_main_client.cpp @@ -84,7 +84,9 @@ void C_BaseEntity::PhysicsPushEntity( const Vector& push, trace_t *pTrace ) Vector prevOrigin; VectorCopy( GetAbsOrigin(), prevOrigin ); +#ifndef NEO trace_t trace; +#endif PhysicsCheckSweep( prevOrigin, push, pTrace ); if ( pTrace->fraction ) diff --git a/src/game/client/studio_stats.cpp b/src/game/client/studio_stats.cpp index a6c3508554..dfbb2b55f5 100644 --- a/src/game/client/studio_stats.cpp +++ b/src/game/client/studio_stats.cpp @@ -101,7 +101,9 @@ void StudioStats_FindClosestEntity( CClientRenderablesList *pClientRenderablesLi return; } +#ifndef NEO trace_t tr; +#endif Vector vecStart, vecEnd; VectorMA( MainViewOrigin(), MAX_TRACE_LENGTH, MainViewForward(), vecEnd ); VectorMA( MainViewOrigin(), 10, MainViewForward(), vecStart ); diff --git a/src/game/server/NextBot/NextBotGroundLocomotion.cpp b/src/game/server/NextBot/NextBotGroundLocomotion.cpp index 27f6a52bf7..14f0758696 100644 --- a/src/game/server/NextBot/NextBotGroundLocomotion.cpp +++ b/src/game/server/NextBot/NextBotGroundLocomotion.cpp @@ -394,7 +394,7 @@ void NextBotGroundLocomotion::ApplyAccumulatedApproach( void ) SetDesiredLean( lean ); */ - Vector newPos; + //Vector newPos; // if we just started a jump, don't snap to the ground - let us get in the air first if ( DidJustJump() || !IsOnGround() ) diff --git a/src/game/server/NextBot/Path/NextBotPathFollow.cpp b/src/game/server/NextBot/Path/NextBotPathFollow.cpp index d6ff825aa4..eff4ba5e33 100644 --- a/src/game/server/NextBot/Path/NextBotPathFollow.cpp +++ b/src/game/server/NextBot/Path/NextBotPathFollow.cpp @@ -1759,7 +1759,7 @@ bool PathFollower::JumpOverGaps( INextBot *bot, const Path::Segment *goal, const return false; } - trace_t result; + //trace_t result; NextBotTraversableTraceFilter filter( bot, ILocomotion::IMMEDIATELY ); const float hullWidth = ( body ) ? body->GetHullWidth() : 1.0f; diff --git a/src/game/server/ai_basenpc.cpp b/src/game/server/ai_basenpc.cpp index a6c94bac2c..e2b3b4fbf5 100644 --- a/src/game/server/ai_basenpc.cpp +++ b/src/game/server/ai_basenpc.cpp @@ -3836,7 +3836,9 @@ void CAI_BaseNPC::SetPlayerAvoidState( void ) //If we are coming out of a script, check if we are stuck inside the player. if ( m_bPerformAvoidance || ( ShouldPlayerAvoid() && bIsMoving ) ) { +#ifndef NEO trace_t trace; +#endif Vector vMins, vMaxs; GetPlayerAvoidBounds( &vMins, &vMaxs ); diff --git a/src/game/server/ai_basenpc_schedule.cpp b/src/game/server/ai_basenpc_schedule.cpp index 45ddec10b5..a5cf0fdce9 100644 --- a/src/game/server/ai_basenpc_schedule.cpp +++ b/src/game/server/ai_basenpc_schedule.cpp @@ -1025,7 +1025,9 @@ float CAI_BaseNPC::CalcReasonableFacing( bool bIgnoreOriginalFacing ) else { // If I'm facing a wall, change my original yaw and try to find a good direction to face. +#ifndef NEO trace_t tr; +#endif Vector forward; QAngle angles( 0, 0, 0 ); diff --git a/src/game/server/ai_planesolver.cpp b/src/game/server/ai_planesolver.cpp index 680195c577..5451f2539e 100644 --- a/src/game/server/ai_planesolver.cpp +++ b/src/game/server/ai_planesolver.cpp @@ -440,7 +440,9 @@ AI_SuggestorResult_t CAI_PlaneSolver::GenerateObstacleSuggestions( const AILocal int nSideProbes = (nProbes - 1) / 2; float yawGoalDir = UTIL_VecToYaw( goal.dir ); +#ifndef NEO Vector probeTarget; +#endif AIMoveTrace_t moveTrace; int i; diff --git a/src/game/server/ai_tacticalservices.cpp b/src/game/server/ai_tacticalservices.cpp index 87399c4f22..4fe559fc90 100644 --- a/src/game/server/ai_tacticalservices.cpp +++ b/src/game/server/ai_tacticalservices.cpp @@ -151,7 +151,9 @@ bool CAI_TacticalServices::FindCoverPos( const Vector &vNearPos, const Vector &v //------------------------------------- bool CAI_TacticalServices::TestLateralCover( const Vector &vecCheckStart, const Vector &vecCheckEnd, float flMinDist ) { +#ifndef NEO trace_t tr; +#endif if ( (vecCheckStart - vecCheckEnd).LengthSqr() > Square(flMinDist) ) { diff --git a/src/game/server/basecombatcharacter.cpp b/src/game/server/basecombatcharacter.cpp index 894717cec0..afe2b114d5 100644 --- a/src/game/server/basecombatcharacter.cpp +++ b/src/game/server/basecombatcharacter.cpp @@ -882,7 +882,9 @@ void CBaseCombatCharacter::UpdateOnRemove( void ) //========================================================= bool CBaseCombatCharacter::CorpseGib( const CTakeDamageInfo &info ) { +#ifndef NEO trace_t tr; +#endif bool gibbed = false; EmitSound( "BaseCombatCharacter.CorpseGib" ); @@ -1793,7 +1795,9 @@ void CBaseCombatCharacter::ThrowDirForWeaponStrip( CBaseCombatWeapon *pWeapon, c VMatrix zRot; MatrixBuildRotateZ( zRot, random->RandomFloat( -60.0f, 60.0f ) ); +#ifndef NEO Vector vecThrow; +#endif Vector3DMultiply( zRot, vecForward, *pVecThrowDir ); pVecThrowDir->z = random->RandomFloat( -0.5f, 0.5f ); diff --git a/src/game/server/baseentity.cpp b/src/game/server/baseentity.cpp index 4a52951273..a6f4995662 100644 --- a/src/game/server/baseentity.cpp +++ b/src/game/server/baseentity.cpp @@ -2779,7 +2779,9 @@ static void CheckPushedEntity( CBaseEntity *pEntity, pushblock_t ¶ms ) pPhysics->GetShadowPosition( &origin, &angles ); float fraction = -1.0f; +#ifndef NEO matrix3x4_t parentDelta; +#endif if ( pEntity == params.pRootParent ) { if ( pEntity->GetLocalAngularVelocity() == vec3_angle ) diff --git a/src/game/server/fish.cpp b/src/game/server/fish.cpp index e66200684e..41c9c0fcb0 100644 --- a/src/game/server/fish.cpp +++ b/src/game/server/fish.cpp @@ -575,7 +575,9 @@ void CFishPool::Spawn() m_waterLevel = UTIL_WaterLevel( GetAbsOrigin(), GetAbsOrigin().z, GetAbsOrigin().z + 1000.0f ); +#ifndef NEO trace_t result; +#endif for( int i=0; i 500) diff --git a/src/game/server/hl2/func_tank.cpp b/src/game/server/hl2/func_tank.cpp index a990d1291e..ad15b3b521 100644 --- a/src/game/server/hl2/func_tank.cpp +++ b/src/game/server/hl2/func_tank.cpp @@ -1728,7 +1728,9 @@ void CFuncTank::AimBarrelAtPlayerCrosshair( QAngle *pAngles ) //----------------------------------------------------------------------------- void CFuncTank::CalcNPCEnemyTarget( Vector *pVecTarget ) { +#ifndef NEO Vector vecTarget; +#endif CAI_BaseNPC *pNPC = m_hController->MyNPCPointer(); // Aim the barrel at the npc's enemy, or where the npc is looking. @@ -3616,8 +3618,10 @@ void CMortarShell::Warn( void ) //--------------------------------------------------------- void CMortarShell::Impact( void ) { +#ifndef NEO // Fire the bullets Vector vecSrc, vecShootDir; +#endif float flRadius = MORTAR_BLAST_RADIUS; @@ -3921,8 +3925,10 @@ void CFuncTankMortar::Fire( int bulletCount, const Vector &barrelEnd, const Vect #define TARGET_SEARCH_DEPTH 100 +#ifndef NEO // find something interesting to shoot at near the projected position. Vector delta; +#endif // Make a really rough approximation of the last half of the mortar trajectory and trace it. // Do this so that mortars fired into windows land on rooftops, and that targets projected @@ -4184,8 +4190,10 @@ void CFuncTankCombineCannon::UpdateBeamThink() return; trace_t trBeam; +#ifndef NEO trace_t trShot; trace_t trBlockLOS; +#endif Vector vecBarrel = WorldBarrelPosition(); Vector vecAim; diff --git a/src/game/server/hl2/npc_BaseZombie.cpp b/src/game/server/hl2/npc_BaseZombie.cpp index 5e81dfd055..a4384f03ea 100644 --- a/src/game/server/hl2/npc_BaseZombie.cpp +++ b/src/game/server/hl2/npc_BaseZombie.cpp @@ -2087,7 +2087,9 @@ void CNPC_BaseZombie::StartTask( const Task_t *pTask ) case TASK_ZOMBIE_GET_PATH_TO_PHYSOBJ: { +#ifndef NEO Vector vecGoalPos; +#endif Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->GetLocalOrigin(); diff --git a/src/game/server/hl2/npc_antlionguard.cpp b/src/game/server/hl2/npc_antlionguard.cpp index faf0099fd9..fb909c0f79 100644 --- a/src/game/server/hl2/npc_antlionguard.cpp +++ b/src/game/server/hl2/npc_antlionguard.cpp @@ -1759,7 +1759,9 @@ void CNPC_AntlionGuard::HandleAnimEvent( animevent_t *pEvent ) if ( HasCondition( COND_ENEMY_UNREACHABLE ) && HasCondition( COND_ENEMY_FACING_ME ) == false ) { // Build an arc around the top of the target that we'll offset our aim by +#ifndef NEO Vector vecOffset; +#endif float flSin, flCos; float flRad = random->RandomFloat( 0, M_PI / 6.0f ); // +/- 30 deg if ( random->RandomInt( 0, 1 ) ) diff --git a/src/game/server/hl2/npc_combine.cpp b/src/game/server/hl2/npc_combine.cpp index 9949cd91c5..296df740c7 100644 --- a/src/game/server/hl2/npc_combine.cpp +++ b/src/game/server/hl2/npc_combine.cpp @@ -2312,8 +2312,10 @@ void CNPC_Combine::OnStartSchedule( int scheduleType ) //========================================================= void CNPC_Combine::HandleAnimEvent( animevent_t *pEvent ) { +#ifndef NEO Vector vecShootDir; Vector vecShootOrigin; +#endif bool handledEvent = false; if (pEvent->type & AE_TYPE_NEWEVENTSYSTEM) diff --git a/src/game/server/hl2/npc_combinecamera.cpp b/src/game/server/hl2/npc_combinecamera.cpp index 26d1f07e63..021462bbd9 100644 --- a/src/game/server/hl2/npc_combinecamera.cpp +++ b/src/game/server/hl2/npc_combinecamera.cpp @@ -722,8 +722,10 @@ void CNPC_CombineCamera::TrackTarget( CBaseEntity *pTarget ) } Vector vecMuzzle, vecMuzzleDir; +#ifndef NEO QAngle vecMuzzleAng; - +#endif + GetAttachment("eyes", vecMuzzle, &vecMuzzleDir); SetIdealActivity((Activity) ACT_COMBINE_CAMERA_OPEN_IDLE); diff --git a/src/game/server/hl2/npc_combinedropship.cpp b/src/game/server/hl2/npc_combinedropship.cpp index 8a2de2f853..7ef929de59 100644 --- a/src/game/server/hl2/npc_combinedropship.cpp +++ b/src/game/server/hl2/npc_combinedropship.cpp @@ -2982,7 +2982,9 @@ void CNPC_CombineDropship::MakeTracer( const Vector &vecTracerSrc, const trace_t { float flTracerDist; Vector vecDir; +#ifndef NEO Vector vecEndPos; +#endif vecDir = tr.endpos - vecTracerSrc; diff --git a/src/game/server/hl2/npc_combinegunship.cpp b/src/game/server/hl2/npc_combinegunship.cpp index 1e868a6277..ae37ada89a 100644 --- a/src/game/server/hl2/npc_combinegunship.cpp +++ b/src/game/server/hl2/npc_combinegunship.cpp @@ -945,7 +945,11 @@ void CNPC_CombineGunship::StartGroundAttack( void ) //----------------------------------------------------------------------------- void CNPC_CombineGunship::ManageWarningBeam( void ) { +#ifdef NEO + Vector vecSrc; +#else Vector vecSrc, vecShootDir; +#endif GetAttachment( "BellyGun", vecSrc, NULL, NULL, NULL ); trace_t tr; @@ -1411,7 +1415,9 @@ void CNPC_CombineGunship::MoveHead( void ) float flDot; Vector vTargetPos, vGunPosition; +#ifndef NEO Vector vecTargetOffset; +#endif QAngle vGunAngles; GetAttachment( "muzzle", vGunPosition, vGunAngles ); @@ -1632,8 +1638,10 @@ bool CNPC_CombineGunship::FireGun( void ) //------------------------------------------------------------------------------ void CNPC_CombineGunship::FireCannonRound( void ) { +#ifndef NEO Vector vecPenetrate; trace_t tr; +#endif Vector vecToEnemy, vecEnemyTarget; Vector vecMuzzle; @@ -2810,7 +2818,9 @@ void CNPC_CombineGunship::MakeTracer( const Vector &vecTracerSrc, const trace_t { float flTracerDist; Vector vecDir; +#ifndef NEO Vector vecEndPos; +#endif vecDir = tr.endpos - vecTracerSrc; diff --git a/src/game/server/hl2/npc_dog.cpp b/src/game/server/hl2/npc_dog.cpp index 6e05cf4d00..9f75b440b1 100644 --- a/src/game/server/hl2/npc_dog.cpp +++ b/src/game/server/hl2/npc_dog.cpp @@ -333,7 +333,9 @@ void CNPC_Dog::SetPlayerAvoidState( void ) //If we are coming out of a script, check if we are stuck inside the player. if ( m_bPerformAvoidance || ( ShouldPlayerAvoid() && bIsMoving ) ) { +#ifndef NEO trace_t trace; +#endif Vector vMins, vMaxs; Vector vWorldMins, vWorldMaxs; Vector vPlayerMins, vPlayerMaxs; @@ -859,8 +861,10 @@ void CNPC_Dog::ThrowObject( const char *pAttachmentName ) } vThrowDirection = vecToss + ( m_hThrowTarget->GetSmoothedVelocity() / 2 ); - + +#ifndef NEO Vector vLinearDrag; +#endif Vector unitVel = vThrowDirection; VectorNormalize( unitVel ); diff --git a/src/game/server/hl2/npc_manhack.cpp b/src/game/server/hl2/npc_manhack.cpp index feef84f8b7..12b78c844a 100644 --- a/src/game/server/hl2/npc_manhack.cpp +++ b/src/game/server/hl2/npc_manhack.cpp @@ -890,7 +890,9 @@ void CNPC_Manhack::OnStateChange( NPC_STATE OldState, NPC_STATE NewState ) //----------------------------------------------------------------------------- void CNPC_Manhack::HandleAnimEvent( animevent_t *pEvent ) { +#ifndef NEO Vector vecNewVelocity; +#endif switch( pEvent->event ) { case MANHACK_AE_START_ENGINE: diff --git a/src/game/server/hl2/npc_metropolice.cpp b/src/game/server/hl2/npc_metropolice.cpp index ea8b2065d1..1175a96130 100644 --- a/src/game/server/hl2/npc_metropolice.cpp +++ b/src/game/server/hl2/npc_metropolice.cpp @@ -4698,7 +4698,9 @@ void CNPC_MetroPolice::RunTask( const Task_t *pTask ) { AutoMovement( ); +#ifndef NEO Vector vecAimPoint; +#endif GetMotor()->SetIdealYawToTargetAndUpdate( m_vecBurstTargetPos, AI_KEEP_YAW_SPEED ); if ( IsActivityFinished() ) diff --git a/src/game/server/hl2/npc_rollermine.cpp b/src/game/server/hl2/npc_rollermine.cpp index d850fe2c5e..81b9e4b10e 100644 --- a/src/game/server/hl2/npc_rollermine.cpp +++ b/src/game/server/hl2/npc_rollermine.cpp @@ -2005,7 +2005,9 @@ void CNPC_RollerMine::ShockTouch( CBaseEntity *pOther ) // jump up at a 30 degree angle away from the guy we hit SetTouch( &CNPC_RollerMine::CloseTouch ); +#ifndef NEO Vector vel; +#endif pPhysics->SetVelocity( &impulse, NULL ); EmitSound( "NPC_RollerMine.Shock" ); // Do a shock effect diff --git a/src/game/server/hl2/npc_strider.cpp b/src/game/server/hl2/npc_strider.cpp index 26acec55c5..1a4471fbe0 100644 --- a/src/game/server/hl2/npc_strider.cpp +++ b/src/game/server/hl2/npc_strider.cpp @@ -2739,7 +2739,9 @@ void CNPC_Strider::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, in { float flTracerDist; Vector vecDir; +#ifndef NEO Vector vecEndPos; +#endif vecDir = tr.endpos - vecTracerSrc; diff --git a/src/game/server/hl2/npc_turret_ceiling.cpp b/src/game/server/hl2/npc_turret_ceiling.cpp index ec8b4207e3..be0b761d8d 100644 --- a/src/game/server/hl2/npc_turret_ceiling.cpp +++ b/src/game/server/hl2/npc_turret_ceiling.cpp @@ -841,9 +841,11 @@ void CNPC_CeilingTurret::Shoot( const Vector &vecSrc, const Vector &vecDirToEnem } else { +#ifndef NEO // Just shoot where you're facing! Vector vecMuzzle, vecMuzzleDir; QAngle vecMuzzleAng; +#endif info.m_vecSrc = vecSrc; info.m_vecDirShooting = vecDirToEnemy; diff --git a/src/game/server/hl2/prop_combine_ball.cpp b/src/game/server/hl2/prop_combine_ball.cpp index b93703498e..d300766b6b 100644 --- a/src/game/server/hl2/prop_combine_ball.cpp +++ b/src/game/server/hl2/prop_combine_ball.cpp @@ -2113,7 +2113,9 @@ void CPointCombineBallLauncher::SpawnBall() pBall->SetRadius( flRadius ); Vector vecAbsOrigin = GetAbsOrigin(); +#ifndef NEO Vector zaxis; +#endif pBall->SetAbsOrigin( vecAbsOrigin ); pBall->SetSpawner( this ); diff --git a/src/game/server/hl2/proto_sniper.cpp b/src/game/server/hl2/proto_sniper.cpp index fe9844ebf7..4db75240fc 100644 --- a/src/game/server/hl2/proto_sniper.cpp +++ b/src/game/server/hl2/proto_sniper.cpp @@ -2476,7 +2476,9 @@ Vector CProtoSniper::LeadTarget( CBaseEntity *pTarget ) //float actualShotDist; Vector vecAdjustedShot; Vector vecTarget; +#ifndef NEO trace_t tr; +#endif /* NDebugOverlay::EntityBounds(pTarget, @@ -2657,10 +2659,12 @@ void CProtoSniper::InputDisableSniper( inputdata_t &inputdata ) //--------------------------------------------------------- bool CProtoSniper::FindFrustratedShot( float flNoise ) { +#ifndef NEO Vector vecForward; Vector vecStart; Vector vecAimAt; Vector vecAim; +#endif if( !GetEnemy() ) { diff --git a/src/game/server/nav_area.cpp b/src/game/server/nav_area.cpp index 80ca961c5f..9a52932b1f 100644 --- a/src/game/server/nav_area.cpp +++ b/src/game/server/nav_area.cpp @@ -2102,7 +2102,9 @@ bool CNavArea::IsFlat( void ) const */ bool CNavArea::IsCoplanar( const CNavArea *area ) const { +#ifndef NEO Vector u, v; +#endif bool isOnDisplacement = ( m_node[ NORTH_WEST ] && m_node[ NORTH_WEST ]->IsOnDisplacement() ) || ( m_node[ NORTH_EAST ] && m_node[ NORTH_EAST ]->IsOnDisplacement() ) || @@ -4535,8 +4537,10 @@ float FindGroundZ( const Vector& original, const Vector& corner1, const Vector& */ void CNavArea::PlaceOnGround( NavCornerType corner, float inset ) { +#ifndef NEO trace_t result; Vector from, to; +#endif Vector nw = m_nwCorner + Vector ( inset, inset, 0 ); Vector se = m_seCorner + Vector ( -inset, -inset, 0 ); diff --git a/src/game/server/nav_edit.cpp b/src/game/server/nav_edit.cpp index 5f2551bdb0..c9997552b0 100644 --- a/src/game/server/nav_edit.cpp +++ b/src/game/server/nav_edit.cpp @@ -163,7 +163,9 @@ void CNavMesh::GetEditVectors( Vector *pos, Vector *forward ) AngleVectors( player->EyeAngles() + player->GetPunchAngle(), forward ); } #else +#ifndef NEO Vector dir; +#endif AngleVectors( player->EyeAngles() + player->GetPunchAngle(), forward ); #endif diff --git a/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp b/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp index 70dca838ee..ae5db90b3a 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_tactical_monitor.cpp @@ -292,7 +292,9 @@ ActionResult< CNEOBot > CNEOBotTacticalMonitor::Update( CNEOBot *me, float inter } } +#if 0 const CKnownEntity *threat = me->GetVisionInterface()->GetPrimaryKnownThreat(); +#endif // check if we need to get to cover QueryResultType shouldRetreat = me->GetIntentionInterface()->ShouldRetreat( me ); diff --git a/src/game/server/neo/bot/neo_bot.cpp b/src/game/server/neo/bot/neo_bot.cpp index 2acda92e56..0178c9d15b 100644 --- a/src/game/server/neo/bot/neo_bot.cpp +++ b/src/game/server/neo/bot/neo_bot.cpp @@ -154,7 +154,6 @@ CON_COMMAND_F(neo_bot_add, "Add a bot.", FCVAR_GAMEDLL) iTeam = numJinrai < numNSF ? TEAM_JINRAI : numNSF < numJinrai ? TEAM_NSF : RandomInt(TEAM_JINRAI, TEAM_NSF); } - char name[MAX_NAME_LENGTH]; int iNumAdded = 0; for (i = 0; i < botCount; ++i) { @@ -1526,10 +1525,11 @@ void CNEOBot::EquipBestWeaponForThreat(const CKnownEntity* threat, const bool bN CNEOBaseCombatWeapon* pChosen = NULL; +#if 0 bool bCanSeeTarget = threat->GetTimeSinceLastSeen() < 0.2f; - // Don't stay in melee if they are far away, or we don't know where they are right now. bool bInMeleeRange = !IsRangeGreaterThan(threat->GetLastKnownPosition(), 127.0f) && bCanSeeTarget; +#endif if (throwable) { diff --git a/src/game/server/neo/neo_dm_spawn.cpp b/src/game/server/neo/neo_dm_spawn.cpp index 945cc09cd6..f6ccfb2b99 100644 --- a/src/game/server/neo/neo_dm_spawn.cpp +++ b/src/game/server/neo/neo_dm_spawn.cpp @@ -195,7 +195,7 @@ void DMSpawnComCallbackLoad([[maybe_unused]] const CCommand &command) return; } - const int version = buf.GetInt(); + /*const int version =*/ (void)buf.GetInt(); const int locsSize = buf.GetInt(); for (int i = 0; i < locsSize && buf.IsValid(); ++i) { diff --git a/src/game/server/npc_talker.cpp b/src/game/server/npc_talker.cpp index 8355fa4154..371f02943a 100644 --- a/src/game/server/npc_talker.cpp +++ b/src/game/server/npc_talker.cpp @@ -314,7 +314,9 @@ CBaseEntity *CNPCSimpleTalker::EnumFriends( CBaseEntity *pPrevious, int listNumb CBaseEntity *pFriend = pPrevious; const char *pszFriend; trace_t tr; +#ifndef NEO Vector vecCheck; +#endif pszFriend = m_szFriends[ FriendNumber(listNumber) ]; while ( pszFriend != NULL && ((pFriend = gEntList.FindEntityByClassname( pFriend, pszFriend )) != NULL) ) diff --git a/src/game/server/physics_prop_ragdoll.cpp b/src/game/server/physics_prop_ragdoll.cpp index 72635ea897..04e4ccd08c 100644 --- a/src/game/server/physics_prop_ragdoll.cpp +++ b/src/game/server/physics_prop_ragdoll.cpp @@ -973,7 +973,9 @@ void CRagdollProp::VPhysicsUpdate( IPhysicsObject *pPhysics ) matrix3x4_t boneToWorld[MAXSTUDIOBONES]; QAngle angles; +#ifndef NEO Vector surroundingMins, surroundingMaxs; +#endif int i; for ( i = 0; i < m_ragdoll.listCount; i++ ) diff --git a/src/game/server/props.cpp b/src/game/server/props.cpp index 02e6220dca..8e60ea965b 100644 --- a/src/game/server/props.cpp +++ b/src/game/server/props.cpp @@ -5038,7 +5038,9 @@ void CPropDoorRotating::ComputeDoorExtent( Extent *extent, unsigned int extentTy if ( extentType & DOOR_EXTENT_CLOSED ) { +#ifndef NEO Extent closedExtent; +#endif CalculateDoorVolume( m_angRotationClosed, m_angRotationClosed, &extent->lo, &extent->hi ); if ( extentType & DOOR_EXTENT_OPEN ) diff --git a/src/game/server/te_projecteddecal.cpp b/src/game/server/te_projecteddecal.cpp index 83e40e1a4d..462e5de88e 100644 --- a/src/game/server/te_projecteddecal.cpp +++ b/src/game/server/te_projecteddecal.cpp @@ -71,7 +71,9 @@ void CTEProjectedDecal::Test( const Vector& current_origin, const QAngle& curren m_vecOrigin = current_origin; m_angRotation = current_angles; +#ifndef NEO Vector vecEnd; +#endif Vector forward; diff --git a/src/game/server/triggers.cpp b/src/game/server/triggers.cpp index 003b9d7412..e46c3bca2c 100644 --- a/src/game/server/triggers.cpp +++ b/src/game/server/triggers.cpp @@ -1607,7 +1607,9 @@ void CChangeLevel::WarnAboutActiveLead( void ) void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) { CBaseEntity *pLandmark; +#ifndef NEO levellist_t levels[16]; +#endif Assert(!FStrEq(m_szMapName, "")); diff --git a/src/game/server/util.cpp b/src/game/server/util.cpp index 3bf653fed0..ba23fa9d08 100644 --- a/src/game/server/util.cpp +++ b/src/game/server/util.cpp @@ -2973,8 +2973,10 @@ void CC_KDTreeTest( const CCommand &args ) int nCount = 0; +#ifndef NEO Vector vecDelta; trace_t trace; +#endif CBaseEntity *pList[1024]; for ( iTest = 0; iTest < NUM_KDTREE_TESTS; ++iTest ) { @@ -2999,7 +3001,9 @@ void CC_KDTreeTest( const CCommand &args ) int nCount = 0; +#ifndef NEO trace_t trace; +#endif CBaseEntity *pList[1024]; for ( iTest = 0; iTest < NUM_KDTREE_TESTS; ++iTest ) { diff --git a/src/game/shared/gamemovement.cpp b/src/game/shared/gamemovement.cpp index d5886fa285..c9f1930e45 100644 --- a/src/game/shared/gamemovement.cpp +++ b/src/game/shared/gamemovement.cpp @@ -2295,7 +2295,11 @@ void CGameMovement::FullObserverMove( void ) Vector wishvel; Vector forward, right, up; +#ifdef NEO + Vector wishdir; +#else Vector wishdir, wishend; +#endif float wishspeed; AngleVectors (mv->m_vecViewAngles, &forward, &right, &up); // Determine movement angles @@ -4352,7 +4356,9 @@ void CGameMovement::FinishUnDuck( void ) Assert(dynamic_cast(player)); int i; +#ifndef NEO trace_t trace; +#endif Vector newOrigin; VectorCopy( mv->GetAbsOrigin(), newOrigin ); @@ -4685,9 +4691,11 @@ void CGameMovement::Duck( void ) HandleDuckingSpeedCrop(); // If the player is holding down the duck button, the player is in duck transition, ducking, or duck-jumping. +#ifndef NEO bool bFirstTimePredicted = true; // Assumes we never rerun commands on the server. #ifdef CLIENT_DLL bFirstTimePredicted = prediction->IsFirstTimePredicted(); +#endif #endif // If the player is holding down the duck button, the player is in duck transition, ducking, or duck-jumping. diff --git a/src/game/shared/hl2mp/weapon_rpg.cpp b/src/game/shared/hl2mp/weapon_rpg.cpp index 1a0b3c239a..ed73873308 100644 --- a/src/game/shared/hl2mp/weapon_rpg.cpp +++ b/src/game/shared/hl2mp/weapon_rpg.cpp @@ -596,7 +596,9 @@ void CMissile::SeekThink( void ) Vector targetPos; float flHomingSpeed; +#ifndef NEO Vector vecLaserDotPosition; +#endif ComputeActualDotPosition( pLaserDot, &targetPos, &flHomingSpeed ); if ( IsSimulatingOnAlternateTicks() ) @@ -1439,8 +1441,10 @@ void CWeaponRPG::PrimaryAttack( void ) if ( GetActivity() == ACT_VM_RELOAD ) return; +#ifndef NEO Vector vecOrigin; Vector vecForward; +#endif m_flNextPrimaryAttack = gpGlobals->curtime + 0.5f; @@ -2005,7 +2009,9 @@ void CWeaponRPG::DrawEffects( void ) color32 color={255,255,255,255}; Vector vecAttachment, vecDir; +#ifndef NEO QAngle angles; +#endif float scale = 8.0f + random->RandomFloat( -2.0f, 2.0f ); @@ -2236,7 +2242,9 @@ int CLaserDot::DrawModel( int flags ) { color32 color={255,255,255,255}; Vector vecAttachment, vecDir; +#ifndef NEO QAngle angles; +#endif float scale; Vector endPos; diff --git a/src/game/shared/particlesystemquery.cpp b/src/game/shared/particlesystemquery.cpp index 9a7332315d..34c7a62e5c 100644 --- a/src/game/shared/particlesystemquery.cpp +++ b/src/game/shared/particlesystemquery.cpp @@ -484,7 +484,9 @@ bool CParticleSystemQuery::IsPointInControllingObjectHitBox( bool bInBBox = false; Vector vecBBoxMin; Vector vecBBoxMax; +#ifndef NEO Vector vecOrigin; +#endif vecBBoxMin = pMoveParent->CollisionProp()->OBBMins(); vecBBoxMax = pMoveParent->CollisionProp()->OBBMaxs(); diff --git a/src/game/shared/physics_shared.cpp b/src/game/shared/physics_shared.cpp index fa90580870..4e064c8927 100644 --- a/src/game/shared/physics_shared.cpp +++ b/src/game/shared/physics_shared.cpp @@ -826,7 +826,9 @@ void PhysComputeSlideDirection( IPhysicsObject *pPhysics, const Vector &inputVel { Vector velocity = inputVelocity; AngularImpulse angVel = inputAngularVelocity; +#ifndef NEO Vector pos; +#endif IPhysicsFrictionSnapshot *pSnapshot = pPhysics->CreateFrictionSnapshot(); while ( pSnapshot->IsValid() ) diff --git a/src/game/shared/ragdoll_shared.cpp b/src/game/shared/ragdoll_shared.cpp index 51376d6f40..2844dfce37 100644 --- a/src/game/shared/ragdoll_shared.cpp +++ b/src/game/shared/ragdoll_shared.cpp @@ -483,7 +483,9 @@ void RagdollApplyAnimationAsVelocity( ragdoll_t &ragdoll, const matrix3x4_t *pBo MatrixAngles( inverse, q, pos ); Vector velocity; +#ifndef NEO AngularImpulse angVel; +#endif float flSpin; Vector localVelocity; diff --git a/src/game/shared/takedamageinfo.cpp b/src/game/shared/takedamageinfo.cpp index d488524f22..6c60b56cf7 100644 --- a/src/game/shared/takedamageinfo.cpp +++ b/src/game/shared/takedamageinfo.cpp @@ -205,9 +205,11 @@ void ClearMultiDamage( void ) //----------------------------------------------------------------------------- void ApplyMultiDamage( void ) { +#ifndef NEO Vector vecSpot1;//where blood comes from Vector vecDir;//direction blood should go trace_t tr; +#endif if ( !g_MultiDamage.GetTarget() ) return; diff --git a/src/public/ScratchPadUtils.cpp b/src/public/ScratchPadUtils.cpp index 92ce68de02..09406e81a2 100644 --- a/src/public/ScratchPadUtils.cpp +++ b/src/public/ScratchPadUtils.cpp @@ -221,7 +221,11 @@ void ScratchPad_DrawLitCone( tri.m_Verts.SetSize( 3 ); float flDot = -vLightDir.Dot( vDir ); +#ifdef NEO + Vector bottomColor; +#else Vector topColor, bottomColor; +#endif VectorLerp( vDarkColor, vBrightColor, RemapVal( -flDot, -1, 1, 0, 1 ), bottomColor ); diff --git a/src/public/haptics/haptic_utils.cpp b/src/public/haptics/haptic_utils.cpp index b9c72b2fb7..ed6050ece2 100644 --- a/src/public/haptics/haptic_utils.cpp +++ b/src/public/haptics/haptic_utils.cpp @@ -221,7 +221,9 @@ void UpdateAvatarEffect(void) Vector vel; Vector vvel; +#ifndef NEO Vector evel; +#endif QAngle eye; C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); if(!pPlayer) From 38214f5b5ddc436a40aefc434d177f9da7e6750b Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 3 Dec 2025 02:55:09 +0200 Subject: [PATCH 04/96] Fix use of incorrect assert format macro --- src/game/client/cdll_client_int.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/client/cdll_client_int.cpp b/src/game/client/cdll_client_int.cpp index dd3bdde603..091d9e1ba2 100644 --- a/src/game/client/cdll_client_int.cpp +++ b/src/game/client/cdll_client_int.cpp @@ -926,7 +926,7 @@ static void RestrictNeoClientCheats() else if (auto* cmd = g_pCVar->FindCommand(cheatName)) cmd->AddFlags(flags); else - AssertMsg(false, "convar or concmd named \"%s\" was not found\n", cheatName); + AssertMsg1(false, "convar or concmd named \"%s\" was not found\n", cheatName); } } #endif From 75c1450bec3cbd034572d69335ee927a15a106d3 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 3 Dec 2025 02:56:30 +0200 Subject: [PATCH 05/96] Remove min/max macros Use the Min/Max templated functions from basetypes.h, instead --- src/game/client/neo/c_neo_player.cpp | 4 ++-- src/game/client/neo/ui/neo_hud_crosshair.cpp | 2 +- .../client/neo/ui/neo_hud_friendly_marker.cpp | 2 +- .../client/neo/ui/neo_hud_ghost_cap_point.cpp | 2 +- .../client/neo/ui/neo_hud_ghost_marker.cpp | 2 +- .../client/neo/ui/neo_hud_worldpos_marker.cpp | 6 +++--- src/game/client/neo/ui/neo_root.cpp | 2 +- src/game/client/neo/ui/neo_ui.cpp | 4 ++-- src/game/client/neo/ui/neo_utils.cpp | 2 +- src/game/shared/basecombatweapon_shared.cpp | 2 +- src/game/shared/neo/neo_gamerules.cpp | 8 ++++---- src/game/shared/neo/neo_player_shared.h | 6 ------ .../shared/neo/neo_predicted_viewmodel.cpp | 2 +- .../weapons/weapon_neobasecombatweapon.cpp | 14 ++++++------- .../shared/sdk/sdk_basegrenade_projectile.cpp | 4 ++-- .../stdshaders/neo_motion_model_dx9.cpp | 2 +- .../stdshaders/neo_thermal_model_dx9.cpp | 2 +- src/mathlib/imagequant.cpp | 20 +++++++++++++++++++ src/mathlib/quantize.cpp | 20 +++++++++++++++++++ src/public/mathlib/mathlib.h | 20 +++++++++++++++++++ src/public/minmax.h | 6 ++++++ src/public/tier0/basetypes.h | 9 +++++++++ src/public/tier0/valve_minmax_off.h | 6 ++++++ src/public/tier0/valve_minmax_on.h | 8 ++++++++ src/public/tier1/utlrange.h | 3 +++ src/vgui2/vgui_controls/Label.cpp | 2 ++ src/vgui2/vgui_controls/ListPanel.cpp | 5 +++++ 27 files changed, 129 insertions(+), 36 deletions(-) diff --git a/src/game/client/neo/c_neo_player.cpp b/src/game/client/neo/c_neo_player.cpp index 4c06c2ff77..97486f3c67 100644 --- a/src/game/client/neo/c_neo_player.cpp +++ b/src/game/client/neo/c_neo_player.cpp @@ -1254,8 +1254,8 @@ void C_NEO_Player::ClientThink(void) auto vel = GetAbsVelocity().Length(); if (this == pLocalPlayer) { - if (vel > 0.5) { m_flTocFactor = min(0.3f, m_flTocFactor + 0.01); } // NEO TODO (Adam) base on time rather than think rate - else { m_flTocFactor = max(0.1f, m_flTocFactor - 0.01); } + if (vel > 0.5) { m_flTocFactor = Min(0.3f, m_flTocFactor + 0.01f); } // NEO TODO (Adam) base on time rather than think rate + else { m_flTocFactor = Max(0.1f, m_flTocFactor - 0.01f); } } else { diff --git a/src/game/client/neo/ui/neo_hud_crosshair.cpp b/src/game/client/neo/ui/neo_hud_crosshair.cpp index aa316d2880..34b7832bc1 100644 --- a/src/game/client/neo/ui/neo_hud_crosshair.cpp +++ b/src/game/client/neo/ui/neo_hud_crosshair.cpp @@ -74,7 +74,7 @@ void PaintCrosshair(const CrosshairInfo &crh, int inaccuracy, const int x, const { if (crh.iESizeType == CROSSHAIR_SIZETYPE_SCREEN && crh.iEDynamicType == CROSSHAIR_DYNAMICTYPE_NONE) { - iSize = (crh.flScrSize * (max(wide, tall) / 2)); + iSize = (crh.flScrSize * (Max(wide, tall) / 2)); } const bool bOdd = ((crh.iThick % 2) == 1); diff --git a/src/game/client/neo/ui/neo_hud_friendly_marker.cpp b/src/game/client/neo/ui/neo_hud_friendly_marker.cpp index 214af06ba2..14ab8aa8e1 100644 --- a/src/game/client/neo/ui/neo_hud_friendly_marker.cpp +++ b/src/game/client/neo/ui/neo_hud_friendly_marker.cpp @@ -233,7 +233,7 @@ void CNEOHud_FriendlyMarker::DrawPlayer(Color teamColor, C_NEO_Player *player, c auto DisplayText = [this, &textSize, x](const char *textASCII, int y, int maxLength) { wchar_t textUTF[MAX_MARKER_STRSIZE]; COMPILE_TIME_ASSERT(sizeof(textUTF) == sizeof(wchar_t) * MAX_MARKER_STRSIZE); - const int numChars = g_pVGuiLocalize->ConvertANSIToUnicode(textASCII, textUTF, min(sizeof(textUTF), sizeof(wchar_t) * maxLength)); + const int numChars = g_pVGuiLocalize->ConvertANSIToUnicode(textASCII, textUTF, narrow_cast(Min(sizeof(textUTF), sizeof(wchar_t) * maxLength))); int textWidth, textHeight; vgui::surface()->GetTextSize(m_hFont, textUTF, textWidth, textHeight); vgui::surface()->DrawSetTextPos(x - (textWidth / 2), y - textHeight); diff --git a/src/game/client/neo/ui/neo_hud_ghost_cap_point.cpp b/src/game/client/neo/ui/neo_hud_ghost_cap_point.cpp index d3d3037fc2..f252720f00 100644 --- a/src/game/client/neo/ui/neo_hud_ghost_cap_point.cpp +++ b/src/game/client/neo/ui/neo_hud_ghost_cap_point.cpp @@ -50,7 +50,7 @@ void CNEOHud_GhostCapPoint::ApplySchemeSettings(vgui::IScheme *pScheme) SetBounds(0, 0, m_iPosX, m_iPosY); // Override CNEOHud_WorldPosMarker's sizing with our own - const int widerAxis = max(m_viewWidth, m_viewHeight); + const int widerAxis = Max(m_viewWidth, m_viewHeight); m_viewCentreSize = widerAxis * (cl_neo_hud_center_ghost_cap_size.GetFloat() / 100.0f); } diff --git a/src/game/client/neo/ui/neo_hud_ghost_marker.cpp b/src/game/client/neo/ui/neo_hud_ghost_marker.cpp index 5bd5727671..b0cff5c79e 100644 --- a/src/game/client/neo/ui/neo_hud_ghost_marker.cpp +++ b/src/game/client/neo/ui/neo_hud_ghost_marker.cpp @@ -76,7 +76,7 @@ void CNEOHud_GhostMarker::ApplySchemeSettings(vgui::IScheme *pScheme) SetBgColor(COLOR_TRANSPARENT); // Override CNEOHud_WorldPosMarker's sizing with our own - const int widerAxis = max(m_viewWidth, m_viewHeight); + const int widerAxis = Max(m_viewWidth, m_viewHeight); m_viewCentreSize = widerAxis * (cl_neo_hud_center_ghost_marker_size.GetFloat() / 100.0f); } diff --git a/src/game/client/neo/ui/neo_hud_worldpos_marker.cpp b/src/game/client/neo/ui/neo_hud_worldpos_marker.cpp index 15ccaa7e14..da281bf1aa 100644 --- a/src/game/client/neo/ui/neo_hud_worldpos_marker.cpp +++ b/src/game/client/neo/ui/neo_hud_worldpos_marker.cpp @@ -30,7 +30,7 @@ void CNEOHud_WorldPosMarker::ApplySchemeSettings(vgui::IScheme* pScheme) m_viewCentreX = m_viewWidth / 2; m_viewCentreY = m_viewHeight / 2; - auto widerAxis = max(m_viewWidth, m_viewHeight); + auto widerAxis = Max(m_viewWidth, m_viewHeight); m_viewCentreSize = widerAxis * (static_cast(cl_neo_hud_centre_size.GetInt()) / 100); BaseClass::ApplySchemeSettings(pScheme); @@ -76,7 +76,7 @@ float CNEOHud_WorldPosMarker::GetFadeValueTowardsScreenCentreInverted(int x, int if(dist <= m_viewCentreSize) { - return max(min, (dist - innerArea) / innerArea); + return Max(min, (dist - innerArea) / innerArea); } return 1; @@ -88,7 +88,7 @@ float CNEOHud_WorldPosMarker::GetFadeValueTowardsScreenCentreInAndOut(int x, int auto dist = DistanceToCentre(x, y); if(dist <= innerArea) { - return max(min, dist / innerArea); + return Max(min, dist / innerArea); } if(dist <= m_viewCentreSize) diff --git a/src/game/client/neo/ui/neo_root.cpp b/src/game/client/neo/ui/neo_root.cpp index e69887af73..803dbd0d66 100644 --- a/src/game/client/neo/ui/neo_root.cpp +++ b/src/game/client/neo/ui/neo_root.cpp @@ -133,7 +133,7 @@ static bool NetAdrIsFavorite(const servernetadr_t &netAdr) nConnPort == netAdr.GetConnectionPort() && nQueryPort == netAdr.GetQueryPort() && (unFlags & k_unFavoriteFlagFavorite) && - nAppID == narrow_cast(engine->GetAppID())) + nAppID == static_cast(engine->GetAppID())) { return true; } diff --git a/src/game/client/neo/ui/neo_ui.cpp b/src/game/client/neo/ui/neo_ui.cpp index dd03d98226..ccea1ea8a2 100644 --- a/src/game/client/neo/ui/neo_ui.cpp +++ b/src/game/client/neo/ui/neo_ui.cpp @@ -1259,7 +1259,7 @@ bool Texture(const char *szTexturePath, const int x, const int y, const int widt } else { - iDispWide = min(width, height); + iDispWide = Min(width, height); iDispTall = iDispWide; } @@ -1618,7 +1618,7 @@ void Slider(const wchar_t *wszLeftLabel, float *flValue, const float flMin, cons wchar_t wszTmpTest[ARRAYSIZE(pSInfo->wszText)]; const int iStrMinLen = V_swprintf_safe(wszTmpTest, wszFormat, flMin); const int iStrMaxLen = V_swprintf_safe(wszTmpTest, wszFormat, flMax); - pSInfo->iMaxStrSize = max(iStrMinLen, iStrMaxLen); + pSInfo->iMaxStrSize = Max(iStrMinLen, iStrMaxLen); pSInfo->bActive = wdgState.bActive; } SliderInfo *pSInfo = &c->htSliders.Element(hdl); diff --git a/src/game/client/neo/ui/neo_utils.cpp b/src/game/client/neo/ui/neo_utils.cpp index d01a6cebcf..afa8601456 100644 --- a/src/game/client/neo/ui/neo_utils.cpp +++ b/src/game/client/neo/ui/neo_utils.cpp @@ -17,7 +17,7 @@ uint8 *NeoUtils::CropScaleTo256(const uint8 *rgba8888Data, int width, int height // Crop to square if (width != height) { - const int targetWH = min(width, height); + const int targetWH = Min(width, height); uint8 *croppedData = (uint8 *)(calloc(targetWH * targetWH, sizeof(uint8) * STRIDE)); const int dstYLines = targetWH * STRIDE; diff --git a/src/game/shared/basecombatweapon_shared.cpp b/src/game/shared/basecombatweapon_shared.cpp index fc75dcd821..327c038dbd 100644 --- a/src/game/shared/basecombatweapon_shared.cpp +++ b/src/game/shared/basecombatweapon_shared.cpp @@ -2949,7 +2949,7 @@ void RecvProxy_m_iClip(const CRecvProxyData* pData, void* pStruct, void* pOut) const float bulletHeatCost = pNeoWeapon->GetNeoWepBits() & (NEO_WEP_SUPA7 | NEO_WEP_AA13) ? 0.5 : 0.1; // NEO TODO (Adam) store this in weapon info text file? constexpr float MAX_WEAPON_TEMPERATURE_WHEN_FIRING = -0.5; - pNeoWeapon->m_flTemperature = max(MAX_WEAPON_TEMPERATURE_WHEN_FIRING, pNeoWeapon->m_flTemperature - (bulletsFired * bulletHeatCost)); + pNeoWeapon->m_flTemperature = Max(MAX_WEAPON_TEMPERATURE_WHEN_FIRING, pNeoWeapon->m_flTemperature - (bulletsFired * bulletHeatCost)); } #endif //CLIENT_DLL #endif // NEO diff --git a/src/game/shared/neo/neo_gamerules.cpp b/src/game/shared/neo/neo_gamerules.cpp index d51b86a563..f48d41d0fc 100644 --- a/src/game/shared/neo/neo_gamerules.cpp +++ b/src/game/shared/neo/neo_gamerules.cpp @@ -2324,8 +2324,8 @@ void CNEORules::CheckChatCommand(CNEO_Player *pNeoCmdPlayer, const char *pSzChat } if (readyPlayers.array[TEAM_JINRAI] < iThres || readyPlayers.array[TEAM_NSF] < iThres) { - const int iNeedJin = max(0, iThres - readyPlayers.array[TEAM_JINRAI]); - const int iNeedNSF = max(0, iThres - readyPlayers.array[TEAM_NSF]); + const int iNeedJin = Max(0, iThres - readyPlayers.array[TEAM_JINRAI]); + const int iNeedNSF = Max(0, iThres - readyPlayers.array[TEAM_NSF]); char szPrintNeed[100]; V_sprintf_safe(szPrintNeed, "Jinrai need %d players and NSF need %d players " "to ready up to start.", iNeedJin, iNeedNSF); @@ -2333,8 +2333,8 @@ void CNEORules::CheckChatCommand(CNEO_Player *pNeoCmdPlayer, const char *pSzChat } else if (readyPlayers.array[TEAM_JINRAI] > iThres || readyPlayers.array[TEAM_NSF] > iThres) { - const int iExtraJin = max(0, readyPlayers.array[TEAM_JINRAI] - iThres); - const int iExtraNSF = max(0, readyPlayers.array[TEAM_NSF] - iThres); + const int iExtraJin = Max(0, readyPlayers.array[TEAM_JINRAI] - iThres); + const int iExtraNSF = Max(0, readyPlayers.array[TEAM_NSF] - iThres); char szPrintNeed[100]; V_sprintf_safe(szPrintNeed, "Jinrai have %d extra players and NSF have %d extra players " "over the %d per team threshold.", iExtraJin, iExtraNSF, iThres); diff --git a/src/game/shared/neo/neo_player_shared.h b/src/game/shared/neo/neo_player_shared.h index 28f2fc4e4f..6e78282b70 100644 --- a/src/game/shared/neo/neo_player_shared.h +++ b/src/game/shared/neo/neo_player_shared.h @@ -7,12 +7,6 @@ #include "tier0/valve_minmax_off.h" #include #include -#ifndef min - #define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef max - #define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif #define USERID2NEOPLAYER(i) ToNEOPlayer( ClientEntityList().GetEnt( engine->GetPlayerForUserID( i ) ) ) diff --git a/src/game/shared/neo/neo_predicted_viewmodel.cpp b/src/game/shared/neo/neo_predicted_viewmodel.cpp index 20b8434be4..95edfc64cc 100644 --- a/src/game/shared/neo/neo_predicted_viewmodel.cpp +++ b/src/game/shared/neo/neo_predicted_viewmodel.cpp @@ -581,7 +581,7 @@ void CNEOPredictedViewModel::CalcViewModelView(CBasePlayer *pOwner, Vector endPos = pOwner->EyePosition() + (vForward * VIEWMODEL_MOVE_DISTANCE); // NEO NOTE (Adam) the hull generated by tracehull is fixed to the axis, using a non square cube shape will give varying results depending on player orientation to the obstacle in front of them (already the case to an extent since not using a sphere) UTIL_TraceHull(startPos, endPos, Vector(-4,-4,-4), Vector(4,4,4), MASK_SOLID &~ CONTENTS_MONSTER, pOwner, COLLISION_GROUP_NONE, &tr); - tr.fraction = max(VIEWMODEL_MOVE_FRACTION_MIN, tr.fraction); // The smallest value tr.fraction can have given the size of the player hull + tr.fraction = Max(VIEWMODEL_MOVE_FRACTION_MIN, tr.fraction); // The smallest value tr.fraction can have given the size of the player hull if (abs(tr.fraction - m_flGunPush) < (maxFractionChange + 0.01)) // float math, don't want the gun to move when in its resting position { diff --git a/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp b/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp index cffca09b1e..6d0a7eea3b 100644 --- a/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp +++ b/src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp @@ -325,13 +325,13 @@ void CNEOBaseCombatWeapon::ClientThink() { if (GetOwner() && m_flTemperature > 0) { - constexpr int DESIRED_TEMPERATURE_WHEN_HELD = 0; - m_flTemperature = max(DESIRED_TEMPERATURE_WHEN_HELD, m_flTemperature - (TICK_INTERVAL / THERMALS_OBJECT_COOL_TIME)); + constexpr float DESIRED_TEMPERATURE_WHEN_HELD = 0; + m_flTemperature = Max(DESIRED_TEMPERATURE_WHEN_HELD, m_flTemperature - (TICK_INTERVAL / THERMALS_OBJECT_COOL_TIME)); } else if (m_flTemperature < 1) { - constexpr int DESIRED_TEMPERATURE_WITHOUT_OWNER = 1; - m_flTemperature = min(DESIRED_TEMPERATURE_WITHOUT_OWNER, m_flTemperature + (TICK_INTERVAL / THERMALS_OBJECT_COOL_TIME)); + constexpr float DESIRED_TEMPERATURE_WITHOUT_OWNER = 1; + m_flTemperature = Min(DESIRED_TEMPERATURE_WITHOUT_OWNER, m_flTemperature + (TICK_INTERVAL / THERMALS_OBJECT_COOL_TIME)); } SetNextClientThink(gpGlobals->curtime + TICK_INTERVAL); } @@ -607,7 +607,7 @@ void CNEOBaseCombatWeapon::ProcessAnimationEvents() { return; } - m_flNextPrimaryAttack = max(gpGlobals->curtime + nextAttackDelay, m_flNextPrimaryAttack); + m_flNextPrimaryAttack = Max(gpGlobals->curtime + nextAttackDelay, m_flNextPrimaryAttack.Get()); m_flNextSecondaryAttack = m_flNextPrimaryAttack; }; @@ -633,7 +633,7 @@ void CNEOBaseCombatWeapon::ProcessAnimationEvents() else if (m_bLowered && gpGlobals->curtime > m_flNextPrimaryAttack) { SetWeaponIdleTime(gpGlobals->curtime + 0.2); - m_flNextPrimaryAttack = max(gpGlobals->curtime + 0.2, m_flNextPrimaryAttack); + m_flNextPrimaryAttack = Max(gpGlobals->curtime + 0.2f, m_flNextPrimaryAttack.Get()); m_flNextSecondaryAttack = m_flNextPrimaryAttack; } } @@ -1033,7 +1033,7 @@ void CNEOBaseCombatWeapon::PrimaryAttack(void) pPlayer->SetSuitUpdate("!HEV_AMO0", FALSE, 0); } - m_flAccuracyPenalty = min( + m_flAccuracyPenalty = Min( GetMaxAccuracyPenalty(), m_flAccuracyPenalty + GetAccuracyPenalty() * sv_neo_accuracy_penalty_scale.GetFloat() ); diff --git a/src/game/shared/sdk/sdk_basegrenade_projectile.cpp b/src/game/shared/sdk/sdk_basegrenade_projectile.cpp index 1252900686..05619d7f17 100644 --- a/src/game/shared/sdk/sdk_basegrenade_projectile.cpp +++ b/src/game/shared/sdk/sdk_basegrenade_projectile.cpp @@ -122,8 +122,8 @@ END_NETWORK_TABLE() void CBaseGrenadeProjectile::ClientThink() { - constexpr int DESIRED_TEMPERATURE_WITHOUT_OWNER = 1; - m_flTemperature = min(DESIRED_TEMPERATURE_WITHOUT_OWNER, m_flTemperature + (TICK_INTERVAL / THERMALS_OBJECT_COOL_TIME)); + constexpr float DESIRED_TEMPERATURE_WITHOUT_OWNER = 1; + m_flTemperature = Min(DESIRED_TEMPERATURE_WITHOUT_OWNER, m_flTemperature + (TICK_INTERVAL / THERMALS_OBJECT_COOL_TIME)); if (m_flTemperature > 0) { SetNextClientThink(gpGlobals->curtime + TICK_INTERVAL); diff --git a/src/materialsystem/stdshaders/neo_motion_model_dx9.cpp b/src/materialsystem/stdshaders/neo_motion_model_dx9.cpp index 0d43f19848..6e1aac46f0 100644 --- a/src/materialsystem/stdshaders/neo_motion_model_dx9.cpp +++ b/src/materialsystem/stdshaders/neo_motion_model_dx9.cpp @@ -63,7 +63,7 @@ BEGIN_VS_SHADER( Neo_Motion_Model_DX9, "Help for motion model shader" ) s_pShaderAPI->GetMatrix(MATERIAL_VIEW, mat.m[0]); MatrixTranspose(mat, mat); s_pShaderAPI->SetPixelShaderConstant(0, mat.m[2], 3); - const float speed = min(1.f, params[SPEED]->GetFloatValue() * 0.02f); + const float speed = Min(1.f, params[SPEED]->GetFloatValue() * 0.02f); s_pShaderAPI->SetPixelShaderConstant(3, &speed); } diff --git a/src/materialsystem/stdshaders/neo_thermal_model_dx9.cpp b/src/materialsystem/stdshaders/neo_thermal_model_dx9.cpp index cdaf210f8b..4d1c9d9a75 100644 --- a/src/materialsystem/stdshaders/neo_thermal_model_dx9.cpp +++ b/src/materialsystem/stdshaders/neo_thermal_model_dx9.cpp @@ -86,7 +86,7 @@ BEGIN_VS_SHADER( Neo_Thermal_Model_DX9, "Help for thermal model shader" ) constexpr float timeForBodyToCoolFully = 5; const float maximumTemperatureOffsetValue = params[MAXTEMPERATUREOFFSET]->GetFloatValue(); const float temperatureValue = params[TEMPERATUREVALUE]->GetFloatValue(); - const float temperatureCoefficient = maximumTemperatureOffsetValue * min(1.f, temperatureValue / timeForBodyToCoolFully); + const float temperatureCoefficient = maximumTemperatureOffsetValue * Min(1.f, temperatureValue / timeForBodyToCoolFully); s_pShaderAPI->SetPixelShaderConstant(3, &temperatureCoefficient); } diff --git a/src/mathlib/imagequant.cpp b/src/mathlib/imagequant.cpp index 830ed557c2..e8645e36a7 100644 --- a/src/mathlib/imagequant.cpp +++ b/src/mathlib/imagequant.cpp @@ -8,6 +8,26 @@ #include #include +#ifdef NEO +namespace { + // Please use "Min" instead. + // Alias for Min, so we don't need to ifdef every single SDK location where this is used. + template< class T > + constexpr T min(T const& val1, T const& val2) + { + return Min(val1, val2); + } + + // Please use "Max" instead. + // Alias for Max, so we don't need to ifdef every single SDK location where this is used. + template< class T > + constexpr T max(T const& val1, T const& val2) + { + return Max(val1, val2); + } +}; +#endif + #define N_EXTRAVALUES 1 #define N_DIMENSIONS (3+N_EXTRAVALUES) diff --git a/src/mathlib/quantize.cpp b/src/mathlib/quantize.cpp index ed8bf8ac71..f5f90217f7 100644 --- a/src/mathlib/quantize.cpp +++ b/src/mathlib/quantize.cpp @@ -22,6 +22,26 @@ #include +#ifdef NEO +namespace { + // Please use "Min" instead. + // Alias for Min, so we don't need to ifdef every single SDK location where this is used. + template< class T > + constexpr T min(T const& val1, T const& val2) + { + return Min(val1, val2); + } + + // Please use "Max" instead. + // Alias for Max, so we don't need to ifdef every single SDK location where this is used. + template< class T > + constexpr T max(T const& val1, T const& val2) + { + return Max(val1, val2); + } +}; +#endif + static int current_ndims; static struct QuantizedValue *current_root; static int current_ssize; diff --git a/src/public/mathlib/mathlib.h b/src/public/mathlib/mathlib.h index 01107d1995..30548a5451 100644 --- a/src/public/mathlib/mathlib.h +++ b/src/public/mathlib/mathlib.h @@ -20,6 +20,26 @@ // For MMX intrinsics #include +#ifdef NEO +namespace { + // Please use "Min" instead. + // Alias for Min, so we don't need to ifdef every single SDK location where this is used. + template< class T > + constexpr T min(T const& val1, T const& val2) + { + return Min(val1, val2); + } + + // Please use "Max" instead. + // Alias for Max, so we don't need to ifdef every single SDK location where this is used. + template< class T > + constexpr T max(T const& val1, T const& val2) + { + return Max(val1, val2); + } +}; +#endif + // XXX remove me #undef clamp diff --git a/src/public/minmax.h b/src/public/minmax.h index c964f1a1ae..5a2a2f25d8 100644 --- a/src/public/minmax.h +++ b/src/public/minmax.h @@ -8,6 +8,10 @@ #ifndef MINMAX_H #define MINMAX_H +#ifdef NEO +// Please use Max/Min from basetypes.h instead +#else + // Remove the MSVC defines #ifdef min #undef min @@ -37,4 +41,6 @@ const T& max(const T& a, const T& b) return (a < b) ? b : a; } +#endif // NEO + #endif // MINMAX_H diff --git a/src/public/tier0/basetypes.h b/src/public/tier0/basetypes.h index 7a2b7fe90d..fdf515e932 100644 --- a/src/public/tier0/basetypes.h +++ b/src/public/tier0/basetypes.h @@ -95,6 +95,9 @@ inline T AlignValue( T val, uintptr_t alignment ) // lower-case) function can generate more expensive code because of the // mixed types involved. template< class T > +#ifdef NEO +constexpr +#endif T Clamp( T const &val, T const &minVal, T const &maxVal ) { if( val < minVal ) @@ -108,6 +111,9 @@ T Clamp( T const &val, T const &minVal, T const &maxVal ) // This is the preferred Min operator. Using the MIN macro can lead to unexpected // side-effects or more expensive code. template< class T > +#ifdef NEO +constexpr +#endif T Min( T const &val1, T const &val2 ) { return val1 < val2 ? val1 : val2; @@ -116,6 +122,9 @@ T Min( T const &val1, T const &val2 ) // This is the preferred Max operator. Using the MAX macro can lead to unexpected // side-effects or more expensive code. template< class T > +#ifdef NEO +constexpr +#endif T Max( T const &val1, T const &val2 ) { return val1 > val2 ? val1 : val2; diff --git a/src/public/tier0/valve_minmax_off.h b/src/public/tier0/valve_minmax_off.h index 633a378094..363cd9c730 100644 --- a/src/public/tier0/valve_minmax_off.h +++ b/src/public/tier0/valve_minmax_off.h @@ -1,7 +1,13 @@ //========= Copyright Valve Corporation, All rights reserved. ============// +#ifdef NEO +// Please use Max/Min from basetypes.h instead +#else + #ifdef min #undef min #endif #ifdef max #undef max #endif + +#endif \ No newline at end of file diff --git a/src/public/tier0/valve_minmax_on.h b/src/public/tier0/valve_minmax_on.h index 738eabc162..d652cc9091 100644 --- a/src/public/tier0/valve_minmax_on.h +++ b/src/public/tier0/valve_minmax_on.h @@ -1,4 +1,10 @@ //========= Copyright Valve Corporation, All rights reserved. ============// +#ifdef NEO +// Please use Max/Min from basetypes.h instead +#undef max +#undef min +#else + #if !defined(POSIX) #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -7,3 +13,5 @@ #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #endif + +#endif // NEO \ No newline at end of file diff --git a/src/public/tier1/utlrange.h b/src/public/tier1/utlrange.h index db218b1240..cf01f1dcd5 100644 --- a/src/public/tier1/utlrange.h +++ b/src/public/tier1/utlrange.h @@ -13,6 +13,9 @@ // This terribleness breaks /numeric_limits on msvc #if defined( min ) || defined( max ) +#ifdef NEO +#error Please use Max/Min from basetypes.h instead +#endif #define UTLRANGE_H_MINMAX_QUIRK #include "valve_minmax_off.h" #endif // defined( min ) || defined( max ) diff --git a/src/vgui2/vgui_controls/Label.cpp b/src/vgui2/vgui_controls/Label.cpp index c3d3da669d..73a16b94d5 100644 --- a/src/vgui2/vgui_controls/Label.cpp +++ b/src/vgui2/vgui_controls/Label.cpp @@ -27,9 +27,11 @@ using namespace vgui; +#ifndef NEO // Please use Max/Min from basetypes.h instead #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif +#endif DECLARE_BUILD_FACTORY_DEFAULT_TEXT( Label, Label ); diff --git a/src/vgui2/vgui_controls/ListPanel.cpp b/src/vgui2/vgui_controls/ListPanel.cpp index 792c0a8869..69e7cfae93 100644 --- a/src/vgui2/vgui_controls/ListPanel.cpp +++ b/src/vgui2/vgui_controls/ListPanel.cpp @@ -43,6 +43,7 @@ enum }; +#ifndef NEO // Please use Max/Min from basetypes.h instead #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif @@ -54,6 +55,10 @@ enum #ifndef clamp #define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) ) #endif +#endif +#ifdef NEO +#define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) ) +#endif //----------------------------------------------------------------------------- // From fc4e6962a739a7e6876d91143b63d13e7776d300 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 3 Dec 2025 02:57:02 +0200 Subject: [PATCH 06/96] Fix MSVC false positive warning --- src/game/client/neo/ui/neo_root_serverbrowser.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/game/client/neo/ui/neo_root_serverbrowser.cpp b/src/game/client/neo/ui/neo_root_serverbrowser.cpp index c4f269b530..b563637f4f 100644 --- a/src/game/client/neo/ui/neo_root_serverbrowser.cpp +++ b/src/game/client/neo/ui/neo_root_serverbrowser.cpp @@ -134,6 +134,9 @@ bool ServerBlacklisted(const gameserveritem_t &server) return false; } +#ifdef _MSC_VER // msvc quirk: we gotta disable the warning before entering the function scope for this to work +#pragma warning( disable : 4701, justification : "iLeft, iRight guaranteed assigned by the previous switch case" ) +#endif void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) { if (g_blacklistedServers.IsEmpty()) @@ -173,6 +176,9 @@ void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) case SBLIST_COL_TYPE: case SBLIST_COL_DATETIME: if (iLeft != iRight) return (sortCtx.bDescending) ? iLeft < iRight : iLeft > iRight; +#ifdef _MSC_VER +#pragma warning( default : 4701 ) // undo warning suppression from start of func +#endif break; default: break; @@ -195,6 +201,9 @@ void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) } } +#ifdef _MSC_VER // msvc quirk: we gotta disable the warning before entering the function scope for this to work +#pragma warning( disable : 4701, justification : "iLeft, iRight guaranteed assigned by the previous switch case" ) +#endif void CNeoServerList::UpdateFilteredList() { if (m_iType == GS_BLACKLIST) @@ -277,6 +286,9 @@ void CNeoServerList::UpdateFilteredList() default: break; } +#ifdef _MSC_VER +#pragma warning( default : 4701 ) // undo warning suppression from start of func +#endif return (m_pSortCtx->bDescending) ? (V_strcmp(szRight, szLeft) > 0) : (V_strcmp(szLeft, szRight) > 0); }); From 79ed9a0839b6f5672a13deef5e28529ac076652b Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 3 Dec 2025 02:57:22 +0200 Subject: [PATCH 07/96] Fix missing includes --- src/game/server/ai_speech.cpp | 4 ++++ src/game/server/baseentity.cpp | 2 ++ src/game/shared/neo/neo_misc.cpp | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/game/server/ai_speech.cpp b/src/game/server/ai_speech.cpp index 0620e8f06e..796ca274cb 100644 --- a/src/game/server/ai_speech.cpp +++ b/src/game/server/ai_speech.cpp @@ -17,6 +17,10 @@ #include "isaverestore.h" #include "sceneentity.h" +#if defined NEO +#include "neo_misc.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include diff --git a/src/game/server/baseentity.cpp b/src/game/server/baseentity.cpp index a6f4995662..2c8aa2cdbb 100644 --- a/src/game/server/baseentity.cpp +++ b/src/game/server/baseentity.cpp @@ -70,7 +70,9 @@ #ifdef NEO #include "neo_player.h" +#include "neo_misc.h" #endif // NEO + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" diff --git a/src/game/shared/neo/neo_misc.cpp b/src/game/shared/neo/neo_misc.cpp index f8cdb3203c..7516656300 100644 --- a/src/game/shared/neo/neo_misc.cpp +++ b/src/game/shared/neo/neo_misc.cpp @@ -11,6 +11,9 @@ extern ConVar sv_neo_comp_name; #define DEMOS_DIRECTORY_NAME "demos" #endif +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + [[nodiscard]] bool InRect(const vgui::IntRect &rect, const int x, const int y) { return IN_BETWEEN_EQ(rect.x0, x, rect.x1) && IN_BETWEEN_EQ(rect.y0, y, rect.y1); From 4567cdc1506b2b2a931df4e9389b7cea73ea4cfe Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 4 Dec 2025 00:53:49 +0200 Subject: [PATCH 08/96] Fix CMake MSVC EH flags Don't need to toggle this on x64 since we currently won't throw from that path --- src/tier1/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tier1/CMakeLists.txt b/src/tier1/CMakeLists.txt index 5936b3fa58..d07e4f0be5 100644 --- a/src/tier1/CMakeLists.txt +++ b/src/tier1/CMakeLists.txt @@ -100,7 +100,10 @@ if(OS_WINDOWS) processor_detect.cpp ) - set_source_files_properties(processor_detect.cpp PROPERTIES COMPILE_FLAGS /EHsc) + # Currently only need exception handling for 32-bit CPU detection code + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set_source_files_properties(processor_detect.cpp PROPERTIES COMPILE_FLAGS /EHsc) + endif() endif() if(OS_LINUX OR OS_MACOS) From 9f6a476367ff722064ace5022c01731a5a23704b Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 4 Dec 2025 01:00:57 +0200 Subject: [PATCH 09/96] Fix usage of str literal without args -Wformat-security --- src/game/client/neo/ui/neo_hud_player_ping.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/game/client/neo/ui/neo_hud_player_ping.cpp b/src/game/client/neo/ui/neo_hud_player_ping.cpp index 83a22819f9..eef1c289e9 100644 --- a/src/game/client/neo/ui/neo_hud_player_ping.cpp +++ b/src/game/client/neo/ui/neo_hud_player_ping.cpp @@ -367,10 +367,7 @@ void CNEOHud_PlayerPing::NotifyPing(const int playerSlot) CBaseHudChat* hudChat = (CBaseHudChat*)GET_HUDELEMENT(CHudChat); if (hudChat) { - char szText[256]; - V_strcpy_safe(szText, pPlayer->GetNeoPlayerName()); - V_strcat_safe(szText, " pinged a location\n"); - hudChat->ChatPrintf(0, CHAT_FILTER_NONE, szText); + hudChat->ChatPrintf(0, CHAT_FILTER_NONE, "%s pinged a location\n", pPlayer->GetNeoPlayerName()); } } From 8b3851e82e29f888d2cdefc2416044350d2f88a9 Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 4 Dec 2025 01:01:53 +0200 Subject: [PATCH 10/96] Fix stray token after endif --- src/game/client/neo/c_neo_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/client/neo/c_neo_player.cpp b/src/game/client/neo/c_neo_player.cpp index 97486f3c67..8613c6ee0a 100644 --- a/src/game/client/neo/c_neo_player.cpp +++ b/src/game/client/neo/c_neo_player.cpp @@ -1521,7 +1521,7 @@ void C_NEO_Player::UpdateGlowEffects(int iNewTeam) } } } -#endif GLOWS_ENABLE +#endif // GLOWS_ENABLE bool C_NEO_Player::IsAllowedToSuperJump(void) { From 100013566e035e528d37cc548e16c7c2010ffafd Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 4 Dec 2025 01:27:53 +0200 Subject: [PATCH 11/96] GCC: suppress -Wstringop-truncation from SDK base func Suppress warning for what is apparently intentional behaviour from the SDK. gcc steamrt3 --- src/public/tier1/utlstring.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/public/tier1/utlstring.h b/src/public/tier1/utlstring.h index 3d41c066ce..6ca831fcf4 100644 --- a/src/public/tier1/utlstring.h +++ b/src/public/tier1/utlstring.h @@ -396,7 +396,24 @@ class StringFuncs public: static char *Duplicate( const char *pValue ) { return strdup( pValue ); } // Note that this function takes a character count, and does not guarantee null-termination. +#ifdef NEO + static void Copy(OUT_CAP(iLengthInChars) char* out_pOut, const char* pIn, int iLengthInChars) + { +#ifdef __GNUC__ +#pragma GCC diagnostic push +#if ((__GNUC__ >= 10) && (__GNUC__ <= 13)) +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#pragma GCC diagnostic ignored "-Wstringop-truncation" +#endif +#endif + strncpy(out_pOut, pIn, iLengthInChars); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + } +#else static void Copy( OUT_CAP(iLengthInChars) char *out_pOut, const char *pIn, int iLengthInChars ) { strncpy( out_pOut, pIn, iLengthInChars ); } +#endif static int Compare( const char *pLhs, const char *pRhs ) { return strcmp( pLhs, pRhs ); } static int CaselessCompare( const char *pLhs, const char *pRhs ) { return Q_strcasecmp( pLhs, pRhs ); } static int Length( const char *pValue ) { return (int)strlen( pValue ); } From 0aa89720f3d8c8b85dbb98952e4ef9110a126d12 Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 4 Dec 2025 02:04:13 +0200 Subject: [PATCH 12/96] Fix buffer underflow for 0 len inputs --- src/game/client/hud_basechat.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/game/client/hud_basechat.cpp b/src/game/client/hud_basechat.cpp index 7cee13bc15..d346a94a5b 100644 --- a/src/game/client/hud_basechat.cpp +++ b/src/game/client/hud_basechat.cpp @@ -117,7 +117,10 @@ wchar_t* ConvertCRtoNL( wchar_t *str ) void StripEndNewlineFromString( char *str ) { #ifdef NEO - int s = narrow_cast( strlen( str ) - 1 ); + const auto len = strlen(str); + if (len == 0) + return; + int s = narrow_cast(len - 1); #else int s = strlen( str ) - 1; #endif @@ -131,7 +134,10 @@ void StripEndNewlineFromString( char *str ) void StripEndNewlineFromString( wchar_t *str ) { #ifdef NEO - int s = narrow_cast( wcslen( str ) - 1 ); + const auto len = wcslen(str); + if (len == 0) + return; + int s = narrow_cast(len - 1); #else int s = wcslen( str ) - 1; #endif From 3458a2f4460eeedc2682153e1de5565237e8f16e Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 4 Dec 2025 02:32:20 +0200 Subject: [PATCH 13/96] Fix CMake warning for C code '-Wno-invalid-offsetof' is valid for C++/ObjC++ but not for C --- src/CMakeLists.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f9ecb99757..736bacc9de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -310,8 +310,10 @@ if(OS_LINUX OR OS_MACOS) #-Wextra # if STEAM_BRANCH #-Wshadow # if STEAM_BRANCH - $<$:-mfpmath=sse> + # Required for SourceMod gamedata generation $<$:-Wno-invalid-offsetof> + + $<$:-mfpmath=sse> $<$:-Wno-overloaded-virtual> $<$:-Wno-reorder> -Wno-multichar @@ -346,9 +348,6 @@ if(OS_LINUX OR OS_MACOS) # Fix for "error: cast from pointer to smaller type 'unsigned int' loses information" #-fms-extensions - - # Required for SourceMod gamedata generation - -Wno-invalid-offsetof ) # Disable option for older compiler in docker From 42ace6abdcae45fcc74046bcb4d7893e02c190d4 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 04:43:28 +0200 Subject: [PATCH 14/96] Remove redundant casts --- src/public/dt_recv.h | 8 -------- src/public/dt_send.h | 4 ---- 2 files changed, 12 deletions(-) diff --git a/src/public/dt_recv.h b/src/public/dt_recv.h index 9243d21f0a..60ae852c7e 100644 --- a/src/public/dt_recv.h +++ b/src/public/dt_recv.h @@ -291,19 +291,11 @@ inline bool RecvTable::IsInMainList() const #define _hacky_dtrecv_offsetof(s,m) ( (size_t)&(((s *)0x1000000)->m) - 0x1000000u ) #endif -#ifdef NEO -#define RECVINFO(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), narrow_cast(sizeof(((currentRecvDTClass*)0)->varName)) -#else #define RECVINFO(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) -#endif // NEO #define RECVINFO_NAME(varName, remoteVarName) #remoteVarName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName) #define RECVINFO_STRING(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), STRINGBUFSIZE(currentRecvDTClass, varName) #define RECVINFO_BASECLASS(tableName) RecvPropDataTable("this", 0, 0, &REFERENCE_RECV_TABLE(tableName)) -#ifdef NEO -#define RECVINFO_ARRAY(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), narrow_cast(sizeof(((currentRecvDTClass*)0)->varName[0])), narrow_cast(sizeof(((currentRecvDTClass*)0)->varName)/sizeof(((currentRecvDTClass*)0)->varName[0])) -#else #define RECVINFO_ARRAY(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName), sizeof(((currentRecvDTClass*)0)->varName[0]), sizeof(((currentRecvDTClass*)0)->varName)/sizeof(((currentRecvDTClass*)0)->varName[0]) -#endif // Just specify the name and offset. Used for strings and data tables. #define RECVINFO_NOSIZE(varName) #varName, _hacky_dtrecv_offsetof(currentRecvDTClass, varName) diff --git a/src/public/dt_send.h b/src/public/dt_send.h index bdd41e6a55..43891c49ee 100644 --- a/src/public/dt_send.h +++ b/src/public/dt_send.h @@ -603,11 +603,7 @@ inline void SendTable::SetHasPropsEncodedAgainstTickcount( bool bState ) #define SENDINFO_STRUCTARRAYELEM(varName, i)#varName "[" #i "]", _hacky_dtsend_offsetof(currentSendDTClass, varName.m_Value[i]), sizeof(((currentSendDTClass*)0)->varName.m_Value[0]) // Use this when you're not using a CNetworkVar to represent the data you're sending. -#ifdef NEO -#define SENDINFO_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName), narrow_cast(sizeof(((currentSendDTClass*)0)->varName)) -#else #define SENDINFO_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName), sizeof(((currentSendDTClass*)0)->varName) -#endif #define SENDINFO_STRING_NOCHECK(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName) #define SENDINFO_DT(varName) #varName, _hacky_dtsend_offsetof(currentSendDTClass, varName) #define SENDINFO_DT_NAME(varName, remoteVarName) #remoteVarName, _hacky_dtsend_offsetof(currentSendDTClass, varName) From 1bb0d58ccb3ef3640ec2e2ce4a82b31d493a568f Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 05:02:26 +0200 Subject: [PATCH 15/96] Remove unused helper macro --- src/vgui2/vgui_controls/ListPanel.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vgui2/vgui_controls/ListPanel.cpp b/src/vgui2/vgui_controls/ListPanel.cpp index 69e7cfae93..3e991a01e4 100644 --- a/src/vgui2/vgui_controls/ListPanel.cpp +++ b/src/vgui2/vgui_controls/ListPanel.cpp @@ -43,7 +43,7 @@ enum }; -#ifndef NEO // Please use Max/Min from basetypes.h instead +#ifndef NEO // Please use Max/Min/Clamp from basetypes.h instead #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif @@ -56,9 +56,6 @@ enum #define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) ) #endif #endif -#ifdef NEO -#define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) ) -#endif //----------------------------------------------------------------------------- // From ed3550108501e70fe137e037f847795ffe6b6ec6 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 07:51:28 +0200 Subject: [PATCH 16/96] fix ub "output" must be initialized, because in the call to LowLevelByteSwap its value is evaluated, and as per [basic.indet] 2: > Except in the following cases, if an indeterminate value is produced by an evaluation, the behavior is undefined (...) Also change the "output" type from int to T. --- src/public/tier1/byteswap.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/public/tier1/byteswap.h b/src/public/tier1/byteswap.h index 8dae8363f8..aa7e318aae 100644 --- a/src/public/tier1/byteswap.h +++ b/src/public/tier1/byteswap.h @@ -122,7 +122,11 @@ class CByteswap if( input == nativeConstant ) return 1; +#ifdef NEO + T output{}; +#else int output; +#endif LowLevelByteSwap( &output, &input ); if( output == nativeConstant ) return 0; From 194db6063601500c1a2634d95b68fe2be495b8cc Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 07:54:21 +0200 Subject: [PATCH 17/96] -Wmaybe-uninitialized --- src/game/client/c_baseentity.cpp | 8 +++++++ src/game/client/hltvcamera.cpp | 7 +++++++ .../client/neo/ui/neo_root_serverbrowser.cpp | 19 +++-------------- src/game/server/ai_navigator.cpp | 4 ++++ .../bot/behavior/neo_bot_seek_and_destroy.cpp | 11 ++++++++-- .../server/neo/bot/neo_bot_path_compute.cpp | 2 ++ src/game/server/vscript_server.cpp | 8 +++++++ src/public/mathlib/vector.h | 20 ++++++++++++++++++ src/public/tier1/byteswap.h | 21 +++++++++++++++++++ 9 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/game/client/c_baseentity.cpp b/src/game/client/c_baseentity.cpp index 15b2af7afa..f2bf709b64 100644 --- a/src/game/client/c_baseentity.cpp +++ b/src/game/client/c_baseentity.cpp @@ -2775,6 +2775,14 @@ void C_BaseEntity::OnStoreLastNetworkedValue() bool bRestore = false; Vector savePos; QAngle saveAng; +#ifdef NEO +#if ((__GNUC__ >= 11) && (__GNUC__ <= 13)) + // suppress maybe-uninitialized false positive + // (can't use -Wno-maybe-uninitialized because it's broken for some GCC versions in this range...) + savePos = vec3_invalid; + saveAng = QAngle(0,0,0); +#endif +#endif // Kind of a hack, but we want to latch the actual networked value for origin/angles, not what's sitting in m_vecOrigin in the // ragdoll case where we don't copy it over in MoveToLastNetworkOrigin diff --git a/src/game/client/hltvcamera.cpp b/src/game/client/hltvcamera.cpp index 22d7a373fb..7fab97c4e9 100644 --- a/src/game/client/hltvcamera.cpp +++ b/src/game/client/hltvcamera.cpp @@ -109,6 +109,13 @@ void C_HLTVCamera::CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float bool bManual = !spec_autodirector.GetBool(); // chase camera controlled manually Vector targetOrigin1, targetOrigin2, cameraOrigin, forward; +#ifdef NEO +#if (__GNUC__ == 11) && (__GNUC_MINOR__ == 4) + // suppress maybe-uninitialized false positive + // (can't use -Wno-maybe-uninitialized because it's broken for this compiler...) + targetOrigin2 = vec3_invalid; +#endif +#endif if ( m_iTraget1 == 0 ) return; diff --git a/src/game/client/neo/ui/neo_root_serverbrowser.cpp b/src/game/client/neo/ui/neo_root_serverbrowser.cpp index b563637f4f..05bd6063d7 100644 --- a/src/game/client/neo/ui/neo_root_serverbrowser.cpp +++ b/src/game/client/neo/ui/neo_root_serverbrowser.cpp @@ -134,9 +134,6 @@ bool ServerBlacklisted(const gameserveritem_t &server) return false; } -#ifdef _MSC_VER // msvc quirk: we gotta disable the warning before entering the function scope for this to work -#pragma warning( disable : 4701, justification : "iLeft, iRight guaranteed assigned by the previous switch case" ) -#endif void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) { if (g_blacklistedServers.IsEmpty()) @@ -156,7 +153,7 @@ void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) // Always set wszLeft/wszRight to name as fallback const wchar_t *wszLeft = blLeft.wszName; const wchar_t *wszRight = blRight.wszName; - int64 iLeft, iRight; + [[maybe_unused]] int64 iLeft{}, iRight{}; switch (sortCtx.col) { case SBLIST_COL_TYPE: @@ -176,9 +173,6 @@ void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) case SBLIST_COL_TYPE: case SBLIST_COL_DATETIME: if (iLeft != iRight) return (sortCtx.bDescending) ? iLeft < iRight : iLeft > iRight; -#ifdef _MSC_VER -#pragma warning( default : 4701 ) // undo warning suppression from start of func -#endif break; default: break; @@ -201,9 +195,6 @@ void ServerBlacklistUpdateSortedList(const GameServerSortContext &sortCtx) } } -#ifdef _MSC_VER // msvc quirk: we gotta disable the warning before entering the function scope for this to work -#pragma warning( disable : 4701, justification : "iLeft, iRight guaranteed assigned by the previous switch case" ) -#endif void CNeoServerList::UpdateFilteredList() { if (m_iType == GS_BLACKLIST) @@ -231,8 +222,8 @@ void CNeoServerList::UpdateFilteredList() // Always set szLeft/szRight to name as fallback const char *szLeft = gsiLeft.GetName(); const char *szRight = gsiRight.GetName(); - int iLeft, iRight; - bool bLeft, bRight; + [[maybe_unused]] int iLeft{}, iRight{}; + [[maybe_unused]] bool bLeft{}, bRight{}; switch (m_pSortCtx->col) { case GSIW_LOCKED: @@ -286,10 +277,6 @@ void CNeoServerList::UpdateFilteredList() default: break; } -#ifdef _MSC_VER -#pragma warning( default : 4701 ) // undo warning suppression from start of func -#endif - return (m_pSortCtx->bDescending) ? (V_strcmp(szRight, szLeft) > 0) : (V_strcmp(szLeft, szRight) > 0); }); diff --git a/src/game/server/ai_navigator.cpp b/src/game/server/ai_navigator.cpp index ddbb5c3eab..2d892b7907 100644 --- a/src/game/server/ai_navigator.cpp +++ b/src/game/server/ai_navigator.cpp @@ -1936,7 +1936,11 @@ bool CAI_Navigator::OnFailedSteer( AILocalMoveGoal_t *pMoveGoal, float distClear if ( !TestingSteering() && pMoveGoal->directTrace.fStatus == AIMR_BLOCKED_NPC && pMoveGoal->directTrace.vHitNormal != vec3_origin ) { AIMoveTrace_t moveTrace; +#ifdef NEO + Vector vDeflection(0, 0, 0); // silence Clang 19 nag +#else Vector vDeflection; +#endif CalculateDeflection( GetLocalOrigin(), pMoveGoal->dir, pMoveGoal->directTrace.vHitNormal, &vDeflection ); if ( pMoveGoal->dir.AsVector2D().Dot( vDeflection.AsVector2D() ) > 0.7 ) diff --git a/src/game/server/neo/bot/behavior/neo_bot_seek_and_destroy.cpp b/src/game/server/neo/bot/behavior/neo_bot_seek_and_destroy.cpp index 8094c5ec3b..b284a7c668 100644 --- a/src/game/server/neo/bot/behavior/neo_bot_seek_and_destroy.cpp +++ b/src/game/server/neo/bot/behavior/neo_bot_seek_and_destroy.cpp @@ -378,7 +378,7 @@ void CNEOBotSeekAndDestroy::RecomputeSeekPath( CNEOBot *me ) // If there's a player playing ghost, turn toward cap zones that's // closest to the ghoster player - Vector vrTargetCapPos; + Vector vrTargetCapPos = vec3_invalid; int iMinCapGhostLength = INT_MAX; // Enemy team is carrying the ghost - try to defend the cap zone @@ -421,6 +421,7 @@ void CNEOBotSeekAndDestroy::RecomputeSeekPath( CNEOBot *me ) if (bGetCloserToGhoster) { + Assert(vGhostPos.IsValid()); m_vGoalPos = vGhostPos; bQuickToGoalPos = true; } @@ -429,14 +430,19 @@ void CNEOBotSeekAndDestroy::RecomputeSeekPath( CNEOBot *me ) // iMinCapGhostLength == INT_MAX should never happen, just disable going to target Assert(iMinCapGhostLength < INT_MAX); bGoToGoalPos = (iMinCapGhostLength < INT_MAX); + if (bGoToGoalPos) // else, vrTargetCapPos may be uninitialized + { + Assert(vrTargetCapPos.IsValid()); + m_vGoalPos = vrTargetCapPos; + } - m_vGoalPos = vrTargetCapPos; bQuickToGoalPos = (iGhosterTeam != iMyTeam); } } else { // If the ghost exists, go to the ghost + Assert(vGhostPos.IsValid()); m_vGoalPos = vGhostPos; // NEO TODO (nullsystem): More sophisticated on handling non-ghost playing scenario, // although it kind of already prefer hunting down players when they're in view, but @@ -445,6 +451,7 @@ void CNEOBotSeekAndDestroy::RecomputeSeekPath( CNEOBot *me ) if (bGoToGoalPos) { + Assert(m_vGoalPos.IsValid()); if (bGetCloserToGhoster) { const int iDistSqrConsidered = (iGhosterTeam == iMyTeam) ? 50000 : 5000; diff --git a/src/game/server/neo/bot/neo_bot_path_compute.cpp b/src/game/server/neo/bot/neo_bot_path_compute.cpp index 3d0fb36069..e17d5959d5 100644 --- a/src/game/server/neo/bot/neo_bot_path_compute.cpp +++ b/src/game/server/neo/bot/neo_bot_path_compute.cpp @@ -41,6 +41,8 @@ static void CNEOBotReservePath(CNEOBot* me, PathFollower& path) bool CNEOBotPathCompute(CNEOBot* bot, PathFollower& path, const Vector& goal, RouteType route, float maxPathLength, bool includeGoalIfPathFails, bool requireGoalArea) { + Assert(goal.IsValid()); + CNEOBotPathCost cost_with_reservations(bot, route); if (path.Compute(bot, goal, cost_with_reservations, maxPathLength, includeGoalIfPathFails, requireGoalArea) && path.IsValid()) { diff --git a/src/game/server/vscript_server.cpp b/src/game/server/vscript_server.cpp index 3a287fd32d..db411f25b3 100644 --- a/src/game/server/vscript_server.cpp +++ b/src/game/server/vscript_server.cpp @@ -1852,6 +1852,14 @@ static bool Script_TraceHull( HSCRIPT hTable ) ScriptVariant_t rval; Vector vStart, vEnd; Vector vHullMin, vHullMax; +#if defined(NEO) && defined(ACTUALLY_COMPILER_GCC) +#if (__GNUC__ >= 14) + // suppress maybe-uninitialized false positive + // (can't use -Wno-maybe-uninitialized because it's broken at least for GCC 14...) + vHullMin = vec3_invalid; + vHullMax = vec3_invalid; +#endif +#endif CBaseEntity* pIgnoreEnt = NULL; bool bNoParams = false; diff --git a/src/public/mathlib/vector.h b/src/public/mathlib/vector.h index 75a73b38b9..b811d6b959 100644 --- a/src/public/mathlib/vector.h +++ b/src/public/mathlib/vector.h @@ -578,8 +578,18 @@ inline void VectorClear( Vector& a ) inline Vector& Vector::operator=(const Vector &vOther) { +#if defined(NEO) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + CHECK_VALID(vOther); x=vOther.x; y=vOther.y; z=vOther.z; + +#if defined(NEO) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + return *this; } @@ -1971,8 +1981,18 @@ inline QAngle RadianEuler::ToQAngle( void) const //----------------------------------------------------------------------------- inline QAngle& QAngle::operator=(const QAngle &vOther) { +#if defined(NEO) && defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + CHECK_VALID(vOther); x=vOther.x; y=vOther.y; z=vOther.z; + +#if defined(NEO) && defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + return *this; } diff --git a/src/public/tier1/byteswap.h b/src/public/tier1/byteswap.h index aa7e318aae..03a50e8995 100644 --- a/src/public/tier1/byteswap.h +++ b/src/public/tier1/byteswap.h @@ -213,7 +213,24 @@ class CByteswap //----------------------------------------------------------------------------- template static void LowLevelByteSwap( T *output, const T *input ) { +#ifdef NEO + static_assert(sizeof(T) > 0); +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif // __GNUC__ + Assert(output); + Assert(input); +#endif // NEO + T temp = *output; + +#ifdef NEO +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif // __GNUC__ +#endif // NEO + #if defined( _X360 ) // Intrinsics need the source type to be fixed-point DWORD* word = (DWORD*)input; @@ -237,8 +254,12 @@ class CByteswap default: Assert( "Invalid size in CByteswap::LowLevelByteSwap" && 0 ); } +#else +#ifdef NEO + for( size_t i = 0; i < sizeof(T); i++ ) #else for( auto i = 0; i < sizeof(T); i++ ) +#endif { unsigned char *pByteOut = (unsigned char *) &temp; const unsigned char *pByteIn = (const unsigned char *) input; From 6a1b42e1ce3a676c3dcdaedefc87c34360a417b8 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 09:19:18 +0200 Subject: [PATCH 18/96] fix array index overflow --- src/game/server/hl2/grenade_beam.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/game/server/hl2/grenade_beam.cpp b/src/game/server/hl2/grenade_beam.cpp index 56c9e9e9ee..7f4b13c8e5 100644 --- a/src/game/server/hl2/grenade_beam.cpp +++ b/src/game/server/hl2/grenade_beam.cpp @@ -244,9 +244,22 @@ void CGrenadeBeam::GrenadeBeamTouch( CBaseEntity *pOther ) m_hBeamChaser->SetLocalOrigin( m_pHitLocation[0] ); for (int i=0;i= ARRAYSIZE(m_pHitLocation)) + { + Assert(false); // m_pHitLocation[i+1] would overflow + break; + } +#endif m_pHitLocation[i] = m_pHitLocation[i+1]; } +#ifdef NEO + Assert(m_nNumHits - 1 >= 0); + Assert(m_nNumHits - 1 < ARRAYSIZE(m_pHitLocation)); + m_pHitLocation[m_nNumHits - 1] = GetLocalOrigin(); +#else m_pHitLocation[m_nNumHits-1]=GetLocalOrigin(); +#endif } UpdateBeams(); @@ -296,6 +309,13 @@ void CGrenadeBeam::GetNextTargetPos(Vector *vPosition) { for (int i=0;i= ARRAYSIZE(m_pHitLocation)) + { + Assert(false); // m_pHitLocation[i+1] would overflow + break; + } +#endif m_pHitLocation[i] = m_pHitLocation[i+1]; } m_nNumHits--; From 0248eaa3880381c879216502a8e24bd2d0af270f Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 13:37:28 +0200 Subject: [PATCH 19/96] Exclude compiler opts unused by MSVC fp:fast, O2, and Oy- for msvc --- src/CMakeLists.txt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 736bacc9de..760c77a961 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,12 +107,14 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWith NDEBUG ) - add_compile_options( - #-fno-strict-aliasing - -ffast-math - -fno-omit-frame-pointer - -ftree-vectorize - ) + if (NOT COMPILER_MSVC) + add_compile_options( + #-fno-strict-aliasing + -ffast-math + -fno-omit-frame-pointer + -ftree-vectorize + ) + endif() endif() add_compile_definitions( From cf633e31a4e35e9c372e6fe0dfc226b9a921fcfa Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 13:41:29 +0200 Subject: [PATCH 20/96] Fix MSVC compiler options warning Oy- is not available for x64 --- src/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 760c77a961..c18934010c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -227,7 +227,6 @@ if(OS_WINDOWS) /Zc:forScope /Zc:inline /Zc:forScope - /Oy- /MTd ) @@ -254,10 +253,14 @@ if(OS_WINDOWS) /GF # EnableStringPooling /Gy # EnableFunctionLevelLinking #/Zo - /Oy- /MT ) + if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + # In x64 compilers, /Oy and /Oy- are not available. + add_compile_options(/Oy-) + endif() + add_link_options( /NODEFAULTLIB:libcmtd /NODEFAULTLIB:libcpmtd From 646d13e19d406a9a9336e1b61847cda58fe148ba Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 13:44:21 +0200 Subject: [PATCH 21/96] Simplify MSVC optimization flags O2 is equivalent to /Og /Oi /Ot /Oy /Ob2 /GF /Gy --- src/CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c18934010c..73528119ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -246,12 +246,7 @@ if(OS_WINDOWS) add_compile_options( #/Z7 # DebugInformationFormat - C7 Compatible #/Wp64 # Detect64bitPortabilityIssues - #/O2 # Optimization - Maximize Speed - /Ob2 # InlineFunctionExpansion - Any Suitable - /Oi # EnableIntrinsicFunctions - /Ot # FavorSizeOrSpeed - Favor Fast Code - /GF # EnableStringPooling - /Gy # EnableFunctionLevelLinking + /O2 # Optimization - Maximize Speed #/Zo /MT ) From 4862b43013c0f232f94aaec8be26ebaf5cc05efa Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 14:24:31 +0200 Subject: [PATCH 22/96] Set initial default branch name Silence a git warning emitted from actions/checkout For context: https://git-scm.com/docs/git-init#Documentation/git-init.txt---initial-branchbranch-name --- .github/workflows/cibuild.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 3c8304dcf4..03216ff54b 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -32,6 +32,11 @@ jobs: image: 'registry.gitlab.steamos.cloud/steamrt/sniper/sdk:latest' steps: + # Silence a git warning emitted from actions/checkout. + # For context: https://git-scm.com/docs/git-init#Documentation/git-init.txt---initial-branchbranch-name + - name: Set initial default branch name + run: git config --global init.defaultBranch master + - uses: actions/checkout@v4 with: fetch-depth: 0 From 568e2a32dc59871be7b7b834ea653399c7cac2c1 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 14:26:55 +0200 Subject: [PATCH 23/96] Remove redundant ninja install Resolves build log warning: 2025-12-13T11:50:19.1670599Z Warnings: 2025-12-13T11:50:19.1679122Z - ninja - ninja v1.13.2 already installed. 2025-12-13T11:50:19.1679513Z Use --force to reinstall, specify a version to install, or try upgrade. --- .github/workflows/cibuild.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 03216ff54b..10ebcb31f8 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -179,10 +179,6 @@ jobs: echo "install_dir=$install_dir" >> "$GITHUB_ENV" echo "preset_name=$preset_name" >> "$GITHUB_ENV" - - - name: Install packages - run: choco install -y ninja - - uses: ilammy/msvc-dev-cmd@v1 with: arch: x64 @@ -295,9 +291,6 @@ jobs: - name: Git fetch tags run: git fetch origin --tags --force - - name: Install packages - run: choco install -y ninja - - uses: ilammy/msvc-dev-cmd@v1 with: arch: x64 From b523e1b2eb95f67c85c6df0167f45b48ea7ddaf6 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 14:52:17 +0200 Subject: [PATCH 24/96] Error on missing files for upload-artifact action --- .github/workflows/cibuild.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 10ebcb31f8..4168e5e77e 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -116,24 +116,28 @@ jobs: with: name: ${{ env.libraries }} path: ${{ env.install_dir }}/${{ env.libraries }} + if-no-files-found: error - name: Upload libraries debug information uses: actions/upload-artifact@v4 with: name: ${{ env.libraries_debuginfo }} path: ${{ env.install_dir }}/${{ env.libraries_debuginfo }} + if-no-files-found: error - name: Upload dedicated library uses: actions/upload-artifact@v4 with: name: ${{ env.dedicated }} path: ${{ env.install_dir }}/${{ env.dedicated }} + if-no-files-found: error - name: Upload dedicated library debug information uses: actions/upload-artifact@v4 with: name: ${{ env.dedicated_debuginfo }} path: ${{ env.install_dir }}/${{ env.dedicated_debuginfo }} + if-no-files-found: error - name: Upload SourceMod gamedata if: ${{ matrix.preset_build_type.name == 'release' }} @@ -141,6 +145,7 @@ jobs: with: name: ${{ env.gamedata }} path: ${{ env.install_dir }}/${{ env.gamedata }} + if-no-files-found: error windows-build: name: ${{ matrix.platform.display_name }} ${{ matrix.preset_build_type.display_name }} @@ -245,24 +250,28 @@ jobs: with: name: ${{ env.libraries }} path: ${{ env.install_dir }}/${{ env.libraries }} + if-no-files-found: error - name: Upload libraries debug information uses: actions/upload-artifact@v4 with: name: ${{ env.libraries_debuginfo }} path: ${{ env.install_dir }}/${{ env.libraries_debuginfo }} + if-no-files-found: error - name: Upload dedicated library uses: actions/upload-artifact@v4 with: name: ${{ env.dedicated }} path: ${{ env.install_dir }}/${{ env.dedicated }} + if-no-files-found: error - name: Upload dedicated library debug information uses: actions/upload-artifact@v4 with: name: ${{ env.dedicated_debuginfo }} path: ${{ env.install_dir }}/${{ env.dedicated_debuginfo }} + if-no-files-found: error pack-resources: name: Windows Native Resources @@ -320,6 +329,7 @@ jobs: with: name: ${{ env.resources }} path: ${{ env.install_dir }}/${{ env.resources }} + if-no-files-found: error upload-latest-build: name: Upload Latest Build From 78dd054adf34560ed3615214a8761d4bb52b8fea Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 15:42:39 +0200 Subject: [PATCH 25/96] Fix comment url --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 73528119ab..e7f180e887 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -361,7 +361,7 @@ if(OS_LINUX OR OS_MACOS) endif() # We should always specify -Wl,--build-id, as documented at: - # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId + # http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId add_link_options( -Wl,--build-id -static-libgcc From ff6c4b52994f1f42b4b76fe80e57eff978478a61 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 16:28:41 +0200 Subject: [PATCH 26/96] Cleanup unused variable --- src/game/client/neo/ui/neo_loading.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/game/client/neo/ui/neo_loading.cpp b/src/game/client/neo/ui/neo_loading.cpp index 52b5548b51..955a53373b 100644 --- a/src/game/client/neo/ui/neo_loading.cpp +++ b/src/game/client/neo/ui/neo_loading.cpp @@ -148,7 +148,9 @@ void CNeoLoading::FetchGameUIPanels() { const vgui::VPANEL curLoadChPanel = vgui::ipanel()->GetChild(loadingPanel, i); const char *curLoadChPanelName = vgui::ipanel()->GetName(curLoadChPanel); - [[maybe_unused]] const char *curLoadChPanelClass = vgui::ipanel()->GetClassName(curLoadChPanel); +#ifdef DBGFLAG_ASSERT + const char *curLoadChPanelClass = vgui::ipanel()->GetClassName(curLoadChPanel); +#endif Panel *pPanel = vgui::ipanel()->GetPanel(curLoadChPanel, "GAMEUI"); if (!pPanel) { From b6b84ef527d5a8a9299248c0bdf46b90341a51f9 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 13 Dec 2025 16:28:29 +0200 Subject: [PATCH 27/96] Treat warnings as errors --- src/CMakeLists.txt | 2 ++ src/cmake/build_info.cmake | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7f180e887..e5abb9c93b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,6 +22,7 @@ if(NOT OS_WINDOWS AND NOT OS_LINUX AND NOT OS_MACOS) message(FATAL_ERROR "Unknown OS") endif() +option(CMAKE_COMPILE_WARNING_AS_ERROR "Treat compile warnings as errors" ${DEFAULT_WARN_AS_ERR}) option(NEO_CI_BUILD "CI build mode" OFF) option(NEO_USE_CCACHE "Use ccache" ${OS_LINUX}) option(NEO_STAGING_ONLY "Staging mode (STAGING_ONLY)" OFF) @@ -49,6 +50,7 @@ option(NEO_ENABLE_CPACK "Enable CPack" OFF) option(NEO_USE_MEM_DEBUG "Enable USE_MEM_DEBUG defines" OFF) option(NEO_GENERATE_GAMEDATA "Generate SourceMod gamedata" ${NEO_DEDICATED}) +message(STATUS "Treat compile warnings as errors: ${CMAKE_COMPILE_WARNING_AS_ERROR}") message(STATUS "CI build mode: ${NEO_CI_BUILD}") message(STATUS "Use ccache: ${NEO_USE_CCACHE}") message(STATUS "Staging (STAGING_ONLY): ${NEO_STAGING_ONLY}") diff --git a/src/cmake/build_info.cmake b/src/cmake/build_info.cmake index d604f15afc..33cf6e4cb1 100644 --- a/src/cmake/build_info.cmake +++ b/src/cmake/build_info.cmake @@ -28,13 +28,13 @@ execute_process( OUTPUT_VARIABLE GIT_LATESTTAG OUTPUT_STRIP_TRAILING_WHITESPACE ) - -# Get version number from GIT_LATESTTAG -# EX: v20.0-alpha -> 20 0 message(STATUS "GIT_LATESTTAG: ${GIT_LATESTTAG}") if ("${GIT_LATESTTAG}" STREQUAL "") message(FATAL_ERROR "Failed to get git tag") endif () + +# Get version number from GIT_LATESTTAG +# EX: v20.0-alpha -> 20 0 string(REPLACE "-" ";" GIT_LATESTTAG_SPLIT "${GIT_LATESTTAG}") list(GET GIT_LATESTTAG_SPLIT 0 GIT_LATESTTAG_0) string(REPLACE "v" "" GIT_LATESTTAG_VERSION "${GIT_LATESTTAG_0}") @@ -50,6 +50,21 @@ endif () message(STATUS "NEO_VERSION_MAJOR: ${NEO_VERSION_MAJOR}") message(STATUS "NEO_VERSION_MINOR: ${NEO_VERSION_MINOR}") +# For tagged releases, don't treat warnings as errors to always produce the build +if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + execute_process( + COMMAND git tag --points-at + OUTPUT_VARIABLE GIT_HEADTAG + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if("${GIT_HEADTAG}" STREQUAL "${GIT_LATESTTAG}") + set(DEFAULT_WARN_AS_ERR OFF) + endif() +endif() +if(NOT DEFINED DEFAULT_WARN_AS_ERR) + set(DEFAULT_WARN_AS_ERR ON) +endif() + string(TIMESTAMP BUILD_DATE_SHORT "%Y%m%d") string(TIMESTAMP BUILD_DATE_LONG "%Y-%m-%d") From ba29d6c04ead9a76497c1bbe815324b20675266e Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 14 Dec 2025 04:03:04 +0200 Subject: [PATCH 28/96] Add "nwae" option If the branch name or the latest commit message contains the phrase "nwae" (short for: no-warnings-as-errors), allow CI to skip warnings-as-errors for the build. This is inteded as means for devs to temporarily dodge the warning rules in exceptional situations (breakage from compiler version changes etc), but the preferred solution almost always is to actually fix the warning instead. --- src/cmake/build_info.cmake | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/cmake/build_info.cmake b/src/cmake/build_info.cmake index 33cf6e4cb1..53d479f99a 100644 --- a/src/cmake/build_info.cmake +++ b/src/cmake/build_info.cmake @@ -50,7 +50,7 @@ endif () message(STATUS "NEO_VERSION_MAJOR: ${NEO_VERSION_MAJOR}") message(STATUS "NEO_VERSION_MINOR: ${NEO_VERSION_MINOR}") -# For tagged releases, don't treat warnings as errors to always produce the build +# For tagged releases ("v...."), never treat warnings as errors to guarantee build generation. if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") execute_process( COMMAND git tag --points-at @@ -62,7 +62,21 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebI endif() endif() if(NOT DEFINED DEFAULT_WARN_AS_ERR) - set(DEFAULT_WARN_AS_ERR ON) + # If the branch name or the latest commit message contains the phrase "nwae" + # (short for: no-warnings-as-errors), allow CI to skip warnings-as-errors for the build. + # This is inteded as means for devs to temporarily dodge the warning rules in exceptional + # situations (breakage from compiler version changes etc), but the preferred solution almost + # always is to actually fix the warning. + execute_process( + COMMAND git log --oneline -n 1 + OUTPUT_VARIABLE GIT_LATESTCOMMIT_MSG + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if("${GIT_LATESTCOMMIT_MSG}" MATCHES ".*[Nn][Ww][Aa][Ee].*") + set(DEFAULT_WARN_AS_ERR OFF) + else() + set(DEFAULT_WARN_AS_ERR ON) + endif() endif() string(TIMESTAMP BUILD_DATE_SHORT "%Y%m%d") From 6afd41b459ae9bb741e6470b54c79e5cf16320b1 Mon Sep 17 00:00:00 2001 From: Rainyan Date: Sun, 14 Dec 2025 05:06:32 +0200 Subject: [PATCH 29/96] Update documentation --- CONTRIBUTING.md | 56 ++++++++++++++++++++++++++++++++++---- src/cmake/build_info.cmake | 4 +-- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 34d8ac142d..99a0051239 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -116,13 +116,57 @@ This project uses the [CMake](https://cmake.org/) build system to generate ninja ### Preprocessor definitions In shared code, clientside code can be differentiated with CLIENT_DLL, vs. serverside's GAME_DLL. In more general engine files, Neotokyo specific code can be marked with a NEO ifdef. -### Code style +## Supported compilers + +Only the x64 (64-bit) architecture is supported. + +### Windows +* MSVC v143 - VS 2022 C++ x64/x86 build tools (Latest) +* MSVC version used by the latest `windows-2025` [runner image](https://github.com/actions/runner-images/blob/main/images/windows/Windows2025-Readme.md) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64) -No big restrictions on general code format, just try to more or less match the other SDK code style. +### Linux +* GCC 10 [steamrt3 'sniper'](https://gitlab.steamos.cloud/steamrt/sniper/sdk) +* GCC 14 [steamrt3 'sniper'](https://gitlab.steamos.cloud/steamrt/sniper/sdk) +* GCC 14 [steamrt4](https://gitlab.steamos.cloud/steamrt/steamrt4/sdk) +* Clang 19 [steamrt4](https://gitlab.steamos.cloud/steamrt/steamrt4/sdk) + +### Code style -* C++20 within GCC 10+ and MSVC v143+ support. -* STL generally shouldn't be included in as it may conflicts with existing similar functions. -* Valve likes to ( space ) their arguments, especially with macros, but it's not necessary to strictly follow everywhere. +* C++20, within the [supported compilers'](#supported-compilers) capabilities. +* Formatting: + * No big restrictions on general format, but try to more or less match the surrounding SDK code style for consistency. +* Warnings are treated as errors. + * You may choose to suppress a warning with compiler-specific preprocessing directives if it is a false positive, but **please do not suppress valid warnings**; instead resolve it by fixing the underlying issue. + * For local development, you may disable warnings-as-errors by modifying your `CMAKE_COMPILE_WARNING_AS_ERROR` option, eg. by modifying the entry in your `CMakeCache.txt` file. + * For the CI runners, the following cases are exempt from the *warnings-as-errors* rule: + * Tagged release builds (`v.`...) + * Branch name or its latest commit message containing the phrase `nwae` (acronym for: *"no warnings as errors"*) + * The `nwae` phrase also works locally, but you may need to refresh the CMake cache for it to take effect. + * Please note that the above methods of disabling warnings-as-errors are intended as temporary workarounds to allow devs to resolve exceptional situations (eg. the un-pinned MSVC compiler version changes unexpectedly changing warnings behaviour), and it should *not* be regularly relied upon to dodge warnings. The preferred long-term solution is almost always to properly fix the warning! +* STL and platform-specific headers may be used when needed, but generally the SDK libraries should be preferred. If you do use such includes, be careful with not bringing in conflicting macro definitions or performance-costly code. +* The `min` and `max` from the SDK macros have been disabled, because they were polluting namespaces and making things like like `::max` awkward to use. You may use the templated `Min` and `Max` functions from `basetypes.h` instead. +* Some nonstandard casting helpers are available: + * `assert_cast`: + * The preferred cast for pointer conversion where an incompatible cast may occur by accident + * If you know for a fact it is always a safe cast, you can use `static_cast` instead + * For debug builds, will runtime-validate the cast with `ptr == dynamic_cast(ptr)` + * For release builds, it is identical to `static_cast` + * `narrow_cast`: + * The preferred cast for narrowing conversions where loss of information may occur + * If you know for a fact it is always a safe cast, you can use `static_cast` instead + * For debug builds, will runtime-validate narrowing conversions for: + * Roundtrip equality: `value v of type A equals itself after A->B->A type conversion` + * Signed/unsigned conversion overflow + * For release builds, it is identical to `static_cast` + * `neo::bit_cast`: + * Well-formed type punning helper. Mostly used to avoid UB in the SDK code. + * For the general case, it is a constexpr wrapper for `std::bit_cast` if it's available, but will also support `memcpy` based conversions for when this is not the case (either `std::bit_cast` unavailable or its constraints not satisfied). + * For debug builds, a runtime assertion test is available as an additional parameter: + * `auto output = neo::bit_cast(BC_TEST(input, expectedOutput));` + * When replacing ill-formed type puns, this test syntax can be used to ensure the output of `neo::bit_cast(input)` remains identical to `expectedOutput` + * For release builds, the above test optimizes away, into: + * `auto output = neo::bit_cast(input);` +* Valve likes to `( space )` indent their parentheses, especially with macros, but it's not necessary to strictly follow everywhere. * Tabs are preferred for indentation, to be consistent with the SDK code. -* When using a TODO/FIXME/HACK... style comment, use the format "// NEO TODO (Your-username): Example comment." to make it easier to search NEO specific todos/fixmes (opposed to Valve ones), and at a glance figure out who has written them. +* When using a TODO/FIXME/HACK... style comment, use the format `// NEO TODO (Your-username): Example comment.` to make it easier to search for `NEO` specific todos/fixmes (opposed to Valve ones of the original SDK), and at a glance figure out who has written them. * For classes running on both client and server, you should generally follow Valve's C_Thing (client) -- CThing (server) convention. On shared files, this might mean #defining serverclass for client, or vice versa. There's plenty of examples of this pattern in Valve's classes for reference, [for example here](https://github.com/NeotokyoRebuild/neo/blob/f749c07a4701d285bbb463686d5a5a50c20b9528/mp/src/game/shared/hl2mp/weapon_357.cpp#L20). diff --git a/src/cmake/build_info.cmake b/src/cmake/build_info.cmake index 53d479f99a..d1410b7772 100644 --- a/src/cmake/build_info.cmake +++ b/src/cmake/build_info.cmake @@ -63,10 +63,10 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebI endif() if(NOT DEFINED DEFAULT_WARN_AS_ERR) # If the branch name or the latest commit message contains the phrase "nwae" - # (short for: no-warnings-as-errors), allow CI to skip warnings-as-errors for the build. + # (acronym for: "no warnings as errors"), allow CI to skip warnings-as-errors for the build. # This is inteded as means for devs to temporarily dodge the warning rules in exceptional # situations (breakage from compiler version changes etc), but the preferred solution almost - # always is to actually fix the warning. + # always is to actually fix the warning or suppress a false positive. execute_process( COMMAND git log --oneline -n 1 OUTPUT_VARIABLE GIT_LATESTCOMMIT_MSG From 7ea63ba4371b30ffef731c0da15fb0e50c088bfa Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 14 Dec 2025 08:49:44 +0200 Subject: [PATCH 30/96] Unsuppress -Waddress and -Wstrict-aliasing --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e5abb9c93b..a772f67304 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -331,8 +331,8 @@ if(OS_LINUX OR OS_MACOS) -Wno-float-equal -Wno-unused-local-typedefs -Wno-switch - -Wno-strict-aliasing - -Wno-address + #-Wno-strict-aliasing + #-Wno-address -Werror=return-type -fdiagnostics-show-option From a48163f36f18e0c694b972cda5ff9c789d4e7f55 Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 14 Dec 2025 13:33:48 +0200 Subject: [PATCH 31/96] Fix incorrect logic in IsKeypad The SDK path of IsKeypad always returns false because of comparing against an incorrect value. Probably a typo? --- src/public/inputsystem/ButtonCode.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/public/inputsystem/ButtonCode.h b/src/public/inputsystem/ButtonCode.h index ee6cb29762..61254e8d8f 100644 --- a/src/public/inputsystem/ButtonCode.h +++ b/src/public/inputsystem/ButtonCode.h @@ -310,7 +310,11 @@ inline bool IsSpace( ButtonCode_t code ) inline bool IsKeypad( ButtonCode_t code ) { +#ifdef NEO // NEO NOTE (Rain): the SDK logic is incorrect here + return (code >= KEY_PAD_0) && (code <= KEY_PAD_DECIMAL); +#else return ( code >= MOUSE_FIRST ) && ( code <= KEY_PAD_DECIMAL ); +#endif } inline bool IsPunctuation( ButtonCode_t code ) From a283529bc12e9fc476c85ee8fd7a34fbc36b8730 Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 14 Dec 2025 14:08:47 +0200 Subject: [PATCH 32/96] Fix overflow check Have to check int against INT_... limits instead of LONG_..., because the standard only specifies the *minimum* width of fundamental types. This would break at least for Clang 14 otherwise. --- src/tier1/KeyValues.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tier1/KeyValues.cpp b/src/tier1/KeyValues.cpp index 648b452223..8fd6521c79 100644 --- a/src/tier1/KeyValues.cpp +++ b/src/tier1/KeyValues.cpp @@ -2523,7 +2523,11 @@ void KeyValues::RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &b int ival = strtol( value, &pIEnd, 10 ); float fval = (float)strtod( value, &pFEnd ); - bool bOverflow = ( ival == LONG_MAX || ival == LONG_MIN ) && errno == ERANGE; +#ifdef NEO + bool bOverflow = (ival == INT_MAX || ival == INT_MIN) && errno == ERANGE; +#else + bool bOverflow = (ival == LONG_MAX || ival == LONG_MIN) && errno == ERANGE; +#endif #ifdef POSIX // strtod supports hex representation in strings under posix but we DON'T // want that support in keyvalues, so undo it here if needed From 9212097451503eec9b46d461219cf686bdf760ea Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 14 Dec 2025 14:22:52 +0200 Subject: [PATCH 33/96] Fix Clang 14 warning --- src/tier1/KeyValues.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tier1/KeyValues.cpp b/src/tier1/KeyValues.cpp index 8fd6521c79..9ca39af599 100644 --- a/src/tier1/KeyValues.cpp +++ b/src/tier1/KeyValues.cpp @@ -3056,6 +3056,11 @@ bool KeyValues::Dump( IKeyValuesDumpContext *pDump, int nIndentLevel /* = 0 */, if ( !pDump->KvBeginKey( this, nIndentLevel ) ) return false; +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-bool-conversion" +#endif + if ( bSorted ) { CUtlSortVector< KeyValues*, CUtlSortVectorKeyValuesByName > vecSortedKeys; @@ -3105,6 +3110,10 @@ bool KeyValues::Dump( IKeyValuesDumpContext *pDump, int nIndentLevel /* = 0 */, } } +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic pop +#endif + return pDump->KvEndKey( this, nIndentLevel ); } From e266962351deee9dfd4ed3b908e80c550d22c42d Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 14 Dec 2025 14:29:16 +0200 Subject: [PATCH 34/96] Fix warnings compatibility with Clang --- src/CMakeLists.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a772f67304..f33d26767d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -333,6 +333,7 @@ if(OS_LINUX OR OS_MACOS) -Wno-switch #-Wno-strict-aliasing #-Wno-address + $<$:-Wno-inconsistent-missing-override> -Werror=return-type -fdiagnostics-show-option @@ -343,10 +344,10 @@ if(OS_LINUX OR OS_MACOS) -Ustrncpy # Fix for non-clickable vgui buttons when using -O2 - -fno-devirtualize-speculatively + $<$:-fno-devirtualize-speculatively> # Fix for non-clickable vgui buttons when using -O3 - -fno-ipa-cp-clone + $<$:-fno-ipa-cp-clone> # Fix for "error: cast from pointer to smaller type 'unsigned int' loses information" #-fms-extensions @@ -356,9 +357,9 @@ if(OS_LINUX OR OS_MACOS) if(NOT CMAKE_CXX_COMPILER_VERSION STREQUAL "4.8.4") add_compile_options( $<$:-fabi-compat-version=2> - $<$:-Wno-class-memaccess> - $<$:-Wno-template-id-cdtor> - -Wno-nonnull-compare + $<$:-Wno-class-memaccess> + $<$:-Wno-template-id-cdtor> + $<$:-Wno-nonnull-compare> ) endif() From 8729342bbc753b7cf7a1034b9830a77c31b7ce9a Mon Sep 17 00:00:00 2001 From: Rain Date: Mon, 15 Dec 2025 16:37:34 +0200 Subject: [PATCH 35/96] Fix strict aliasing rule violations --- src/common/neo/bit_cast.h | 102 +++++++++++++++++++++ src/game/client/cdll_client_int.cpp | 4 + src/game/client/detailobjectsystem.cpp | 12 ++- src/game/client/hud_closecaption.cpp | 11 ++- src/game/server/client.cpp | 5 + src/game/server/player.cpp | 6 ++ src/game/shared/predictableid.cpp | 23 +++++ src/game/shared/querycache.cpp | 7 ++ src/mathlib/almostequal.cpp | 29 ++++++ src/mathlib/color_conversion.cpp | 4 + src/mathlib/powsse.cpp | 107 ++++++++++++++++++++++ src/public/dt_send.cpp | 24 +++++ src/public/mathlib/compressed_vector.h | 21 +++++ src/public/mathlib/mathlib.h | 16 ++++ src/public/mathlib/ssemath.h | 8 ++ src/public/tier0/basetypes.h | 8 ++ src/public/tier0/threadtools.h | 45 +++++++++ src/public/tier1/bitbuf.h | 7 ++ src/public/tier1/utlhandletable.h | 46 ++++++++++ src/public/tier1/utlsymbol.h | 4 + src/public/vgui_controls/consoledialog.h | 3 + src/tier1/CMakeLists.txt | 1 + src/tier1/utlsymbol.cpp | 12 +++ src/vgui2/vgui_controls/consoledialog.cpp | 14 +++ 24 files changed, 517 insertions(+), 2 deletions(-) create mode 100644 src/common/neo/bit_cast.h diff --git a/src/common/neo/bit_cast.h b/src/common/neo/bit_cast.h new file mode 100644 index 0000000000..abe0a9e23e --- /dev/null +++ b/src/common/neo/bit_cast.h @@ -0,0 +1,102 @@ +#pragma once + +#include + +#pragma push_macro("STD_BIT_CAST_SUPPORTED") +#undef STD_BIT_CAST_SUPPORTED + +#ifdef __cpp_lib_bit_cast +#if __cpp_lib_bit_cast != 201806L // this value gets bumped with major api changes, so we error here to catch your attention +#error Expected to find __cpp_lib_bit_cast version of 201806L, please verify if this is ok +#endif +#define STD_BIT_CAST_SUPPORTED 1 // whether std::bit_cast is available +#else +#define STD_BIT_CAST_SUPPORTED 0 // whether std::bit_cast is available +#endif + +#if STD_BIT_CAST_SUPPORTED +#include +#endif + +#include +#include +#include +#include + +namespace neo +{ + template + constexpr bool IsBitCastable() noexcept + { + return ( + sizeof(To) == sizeof(From) + && std::is_trivially_constructible_v + && std::is_nothrow_constructible_v + && std::is_trivially_copyable_v + && std::is_trivially_copyable_v + ); + } + + // Will transparently call std::bit_cast when it's available and its constraints are satisfied. + // Else, will perform a well-defined type pun using memcpy. + // If you want a sanity check for the result, see BC_TEST + template + constexpr auto bit_cast(const From& input) noexcept + { + constexpr bool fromVoidPtr = std::is_same_v>>; +#if STD_BIT_CAST_SUPPORTED + if constexpr (fromVoidPtr) +#endif + { + static_assert(fromVoidPtr || IsBitCastable()); + std::remove_cv_t output; + memcpy(std::addressof(output), std::addressof(input), sizeof(output)); + return output; + } +#if STD_BIT_CAST_SUPPORTED + else + { + return std::bit_cast(input); + } +#endif + } + +/** @brief Dynamic assertions for neo::bit +* +* For debug builds, dynamically asserts that neo::bitcast(input) == the original SDK type pun result. +* For release builds (i.e. DBGFLAG_ASSERT disabled), the test is optimized away and input passed directly +* to neo::bit_cast. +* +* \code{.cpp} + // Example: + neo::bit_cast(BC_TEST(inputToBitCast, 42)); + \endcode +* +* @param[in] input The input value for the bit cast. Also used as the assertion lambda's capture. +* If you need to specify the capture, use BC_TEST_EX instead. +* @param[in] expectedOutput The expected result of the cast +*/ +#define BC_TEST(input, expectedOutput) input, [input](const auto& v){ (void)input; Assert(v == expectedOutput); } + +// Same as BC_TEST, but allows specifying the lambda capture. +#define BC_TEST_EX(input, capture, expectedOutput) input, [capture](const auto& v){ (void)capture; Assert(v == expectedOutput); } + + template + constexpr auto bit_cast(const From& input, TestFunc&& +#ifdef DEBUG + test +#endif + ) noexcept + { +#ifdef DEBUG + const auto output = bit_cast(input); + test(output); + return output; +#else + return bit_cast(input); +#endif + } +}; + +#undef STD_BIT_CAST_SUPPORTED +#pragma pop_macro("STD_BIT_CAST_SUPPORTED") diff --git a/src/game/client/cdll_client_int.cpp b/src/game/client/cdll_client_int.cpp index 091d9e1ba2..c1ae3a749f 100644 --- a/src/game/client/cdll_client_int.cpp +++ b/src/game/client/cdll_client_int.cpp @@ -939,6 +939,10 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi { InitCRTMemDebug(); MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); +#if defined(NEO) && defined(DBGFLAG_ASSERT) + Assert(s_bMathlibInitialized); + ValidateFastFuncs(); +#endif #ifdef SIXENSE diff --git a/src/game/client/detailobjectsystem.cpp b/src/game/client/detailobjectsystem.cpp index f8fd300322..6219942c51 100644 --- a/src/game/client/detailobjectsystem.cpp +++ b/src/game/client/detailobjectsystem.cpp @@ -38,6 +38,10 @@ #include "materialsystem/imaterialsystemhardwareconfig.h" +#ifdef NEO +#include "../../common/neo/bit_cast.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -2026,8 +2030,14 @@ int CDetailObjectSystem::CountSpriteQuadsInLeafList( int nLeafCount, LeafIndex_t #endif } - +#ifdef NEO +constexpr int32 TREATASINT(float x) +{ + return neo::bit_cast(BC_TEST(x, *(((int32 const*)(&(x)))))); +} +#else #define TREATASINT(x) ( *( ( (int32 const *)( &(x) ) ) ) ) +#endif //----------------------------------------------------------------------------- // Sorts sprites in back-to-front order diff --git a/src/game/client/hud_closecaption.cpp b/src/game/client/hud_closecaption.cpp index 116e41ee41..90628c4bb5 100644 --- a/src/game/client/hud_closecaption.cpp +++ b/src/game/client/hud_closecaption.cpp @@ -23,6 +23,7 @@ #include "datacache/idatacache.h" #include "SoundEmitterSystem/isoundemittersystembase.h" + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1685,7 +1686,15 @@ void CHudCloseCaption::AddWorkUnit( CCloseCaptionItem *item, if ( wcslen( params.stream ) > 0 ) #else // params.stream is still in ucs2 format here so just do a basic zero compare for length or just space - if ( ((uint16 *)params.stream)[0] != 0 && ((uint16 *)params.stream)[0] != 32 ) +#ifdef NEO + const auto c = params.stream[0]; + uint16 punnedC; + static_assert(sizeof(c) >= sizeof(punnedC)); + memcpy(&punnedC, &c, sizeof(punnedC)); + if (punnedC != 0 && punnedC != 32) +#else + if ( ((uint16 *)params.stream)[0] != 0 && ((uint16 *)params.stream)[0] != 32 ) +#endif // NEO #endif { CCloseCaptionWorkUnit *wu = new CCloseCaptionWorkUnit(); diff --git a/src/game/server/client.cpp b/src/game/server/client.cpp index 88df41aa96..08610300c9 100644 --- a/src/game/server/client.cpp +++ b/src/game/server/client.cpp @@ -48,6 +48,7 @@ #ifdef NEO #include "neo_player.h" #include "neo_gamerules.h" +#include "../../common/neo/bit_cast.h" #endif // memdbgon must be the last include file in a .cpp file!!! @@ -1391,7 +1392,11 @@ static float GetHexFloat( const char *pStr ) if ( ( pStr[0] == '0' ) && ( pStr[1] == 'x' ) ) { uint32 f = (uint32)V_atoi64( pStr ); +#ifdef NEO + return neo::bit_cast(BC_TEST(f, *reinterpret_cast(&f))); +#else return *reinterpret_cast< const float * >( &f ); +#endif } return atof( pStr ); diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index aa4c57e005..804f7e02d9 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -83,6 +83,7 @@ #endif #ifdef NEO +#include "../../common/neo/bit_cast.h" #include "neo_player.h" #include "weapon_tachi.h" #include "neo_gamerules.h" @@ -3685,7 +3686,12 @@ void CBasePlayer::ProcessUsercmds( CUserCmd *cmds, int numcmds, int totalcmds, if ( sv_usercmd_custom_random_seed.GetBool() ) { float fltTimeNow = float( Plat_FloatTime() * 1000.0 ); +#ifdef NEO + pCmd->server_random_seed = neo::bit_castserver_random_seed)>( + BC_TEST(fltTimeNow, *reinterpret_cast((char*)&fltTimeNow))); +#else pCmd->server_random_seed = *reinterpret_cast( (char*)&fltTimeNow ); +#endif } else { diff --git a/src/game/shared/predictableid.cpp b/src/game/shared/predictableid.cpp index b1ca780acd..7f2d4ff45c 100644 --- a/src/game/shared/predictableid.cpp +++ b/src/game/shared/predictableid.cpp @@ -109,7 +109,11 @@ void CPredictableId::ResetInstanceCounters( void ) //----------------------------------------------------------------------------- bool CPredictableId::IsActive( void ) const { +#ifdef NEO + if (neo::bit_cast(BC_TEST_EX(m_PredictableID, this, *(const int*)&m_PredictableID)) == 0) +#else if ( *(const int *)&m_PredictableID == 0 ) +#endif return false; return true; @@ -267,7 +271,11 @@ bool CPredictableId::GetAcknowledged( void ) const //----------------------------------------------------------------------------- int CPredictableId::GetRaw( void ) const { +#ifdef NEO + return neo::bit_cast(BC_TEST_EX(m_PredictableID, this, *(int*)&m_PredictableID)); +#else return *(int *)&m_PredictableID; +#endif } //----------------------------------------------------------------------------- @@ -276,7 +284,22 @@ int CPredictableId::GetRaw( void ) const //----------------------------------------------------------------------------- void CPredictableId::SetRaw( int raw ) { +#ifdef NEO + using T = decltype(m_PredictableID); + static_assert(std::is_trivially_copyable_v); + m_PredictableID = neo::bit_cast(raw); +#ifdef DBGFLAG_ASSERT + T sdkRet; + *(int*)&sdkRet = raw; + Assert(sdkRet.ack == m_PredictableID.ack); + Assert(sdkRet.command == m_PredictableID.command); + Assert(sdkRet.hash == m_PredictableID.hash); + Assert(sdkRet.instance == m_PredictableID.instance); + Assert(sdkRet.player == m_PredictableID.player); +#endif +#else *(int *)&m_PredictableID = raw; +#endif } //----------------------------------------------------------------------------- diff --git a/src/game/shared/querycache.cpp b/src/game/shared/querycache.cpp index 7ec06a7be7..a7cf525ad0 100644 --- a/src/game/shared/querycache.cpp +++ b/src/game/shared/querycache.cpp @@ -12,6 +12,9 @@ #include "datacache/imdlcache.h" #include "vstdlib/jobthread.h" +#ifdef NEO +#include "../../common/neo/bit_cast.h" +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -47,7 +50,11 @@ void QueryCacheKey_t::ComputeHashIndex( void ) ret += ( unsigned int ) m_pEntities[i].ToInt(); ret += size_cast< unsigned int >( (uintp)m_nOffsetMode ); } +#ifdef NEO + ret += neo::bit_cast(BC_TEST_EX(m_flMinimumUpdateInterval, this, *((uint32*)&m_flMinimumUpdateInterval))); +#else ret += *( ( uint32 *) &m_flMinimumUpdateInterval ); +#endif ret += m_nTraceMask; m_nHashIdx = ret % QUERYCACHE_HASH_SIZE; } diff --git a/src/mathlib/almostequal.cpp b/src/mathlib/almostequal.cpp index 53b8a9e353..480c9e6065 100644 --- a/src/mathlib/almostequal.cpp +++ b/src/mathlib/almostequal.cpp @@ -11,23 +11,40 @@ #include "mathlib/mathlib.h" +#ifdef NEO +#include "../common/neo/bit_cast.h" +#include + +static_assert(sizeof(float) == sizeof(int)); +static_assert(std::numeric_limits::is_iec559); +#endif + static inline bool AE_IsInfinite(float a) { const int kInfAsInt = 0x7F800000; // An infinity has an exponent of 255 (shift left 23 positions) and // a zero mantissa. There are two infinities - positive and negative. +#ifdef NEO + return ((neo::bit_cast(BC_TEST(a, *(int*)&a)) & 0x7FFFFFFF) == kInfAsInt); +#else if ((*(int*)&a & 0x7FFFFFFF) == kInfAsInt) return true; return false; +#endif } static inline bool AE_IsNan(float a) { // a NAN has an exponent of 255 (shifted left 23 positions) and // a non-zero mantissa. +#ifdef NEO + int exp = neo::bit_cast(BC_TEST(a, *(int*)&a)) & 0x7F800000; + int mantissa = neo::bit_cast(BC_TEST(a, *(int*)&a)) & 0x007FFFFF; +#else int exp = *(int*)&a & 0x7F800000; int mantissa = *(int*)&a & 0x007FFFFF; +#endif if (exp == 0x7F800000 && mantissa != 0) return true; return false; @@ -36,7 +53,11 @@ static inline bool AE_IsNan(float a) static inline int AE_Sign(float a) { // The sign bit of a number is the high bit. +#ifdef NEO + return neo::bit_cast(BC_TEST(a, *(int*)&a)) & 0x80000000; +#else return (*(int*)&a) & 0x80000000; +#endif } // This is the 'final' version of the AlmostEqualUlps function. @@ -77,12 +98,20 @@ bool AlmostEqual(float a, float b, int maxUlps) if (AE_Sign(a) != AE_Sign(b)) return a == b; +#ifdef NEO + int aInt = neo::bit_cast(BC_TEST(a, *(int*)&a)); +#else int aInt = *(int*)&a; +#endif // Make aInt lexicographically ordered as a twos-complement int if (aInt < 0) aInt = 0x80000000 - aInt; // Make bInt lexicographically ordered as a twos-complement int +#ifdef NEO + int bInt = neo::bit_cast(BC_TEST(b, *(int*)&b)); +#else int bInt = *(int*)&b; +#endif if (bInt < 0) bInt = 0x80000000 - bInt; diff --git a/src/mathlib/color_conversion.cpp b/src/mathlib/color_conversion.cpp index 1b33b83031..f0f7b6b7ad 100644 --- a/src/mathlib/color_conversion.cpp +++ b/src/mathlib/color_conversion.cpp @@ -606,7 +606,11 @@ void VectorToColorRGBExp32( const Vector& vin, ColorRGBExp32 &c ) float scalar; { unsigned int fbits = (127 - exponent) << 23; +#ifdef NEO + scalar = neo::bit_cast(BC_TEST(fbits, *reinterpret_cast(&fbits))); +#else scalar = *reinterpret_cast(&fbits); +#endif } // We can totally wind up above 255 and that's okay--but above 256 would be right out. diff --git a/src/mathlib/powsse.cpp b/src/mathlib/powsse.cpp index b026c64233..ad79d0bc57 100644 --- a/src/mathlib/powsse.cpp +++ b/src/mathlib/powsse.cpp @@ -6,6 +6,14 @@ #include "mathlib/ssemath.h" +#ifdef NEO +#include "../common/neo/bit_cast.h" +#if defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT) +#include "tier0/commonmacros.h" +#include "vstdlib/random.h" +#endif // ACTUALLY_COMPILER_MSVC && DBGFLAG_ASSERT +#endif // NEO + // NOTE: This has to be the last file included! #include "tier0/memdbgon.h" @@ -53,6 +61,10 @@ fltx4 Pow_FixedPoint_Exponent_SIMD( const fltx4 & x, int exponent) */ +#if defined(NEO) && defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT) +namespace Reference { +#endif +#if !defined(NEO) || (defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT)) static float shift23=(1<<23); static float OOshift23=1.0/(1<<23); @@ -93,4 +105,99 @@ float FastPow10( float i ) { return FastPow2( i * 3.321928f ); } +#endif // !defined(NEO) || (defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT)) +#if defined(NEO) && defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT) +} // end of Reference namespace +#endif + +#ifdef NEO +float FastLog2(const float i) +{ + constexpr float LogBodge = 0.346607f; + float x; + float y; + x = neo::bit_cast(BC_TEST(i, *(int*)&i)); + constexpr float OOshift23 = 1.0 / (1 << 23); + x *= OOshift23; //1/pow(2,23); + x = x - 127; + + y = x - floorf(x); + y = (y - y * y) * LogBodge; + + return x + y; +} +float FastPow2(const float i) +{ + constexpr float PowBodge = 0.33971f; + float x; + float y = i - floorf(i); + y = (y - y * y) * PowBodge; + + x = i + 127 - y; + constexpr float shift23 = (1 << 23); + x *= shift23; //pow(2,23); + x = neo::bit_cast(neo::bit_cast((int)x)); + return x; +} + +#if defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT) +template +auto TestFun() +{ + return Namespace::FastLog2(); +} +void ValidateFastFuncs() +{ + const auto fn1 = FastLog2, ref1 = Reference::FastLog2; + const auto fn2 = FastPow2, ref2 = Reference::FastPow2; + + const auto compareFns = [](auto input, decltype(ref1) fn, decltype(fn) ref) + { + static_assert(&fn != &ref); + const float fnOutput = fn(input); + const float refOutput = ref(input); + const bool resultsEqual = (fnOutput == refOutput); + AssertMsg3(resultsEqual, "FF output differs for input %f: fn %f ref %f", input, fnOutput, refOutput); + }; + + constexpr float vals[] = { + 0, 1, 2, 3, 4, 0.1234, 1.234, 1.01234, + }; + for (int i = 0; i < ARRAYSIZE(vals); ++i) + { + const auto val = vals[i]; + Assert(val >= 0); // because we already try both val and -val below + + compareFns(val, fn1, ref1); + compareFns(-val, fn1, ref1); + + compareFns(val, fn2, ref2); + compareFns(-val, fn2, ref2); + } + + constexpr auto numIters = 10; + for (auto i = 0; i < numIters; ++i) + { + { + const float input = RandomFloat(0, 1); + + compareFns(input, fn1, ref1); + compareFns(-input, fn1, ref1); + + compareFns(input, fn2, ref2); + compareFns(-input, fn2, ref2); + } + { + const float input = RandomFloat(0, 0xffff); + + compareFns(input, fn1, ref1); + compareFns(-input, fn1, ref1); + + compareFns(input, fn2, ref2); + compareFns(-input, fn2, ref2); + } + } +} +#endif // ACTUALLY_COMPILER_MSVC && DBGFLAG_ASSERT +#endif // NEO diff --git a/src/public/dt_send.cpp b/src/public/dt_send.cpp index a22e55f473..df56a7265e 100644 --- a/src/public/dt_send.cpp +++ b/src/public/dt_send.cpp @@ -13,6 +13,10 @@ #include "tier0/dbg.h" #include "dt_utlvector_common.h" +#if defined(NEO) && defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -69,6 +73,22 @@ CStandardSendProxies g_StandardSendProxies; // ---------------------------------------------------------------------- // // Proxies. // ---------------------------------------------------------------------- // +template +void pun(auto& dst, const void* src) +{ +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + *((T*)&dst) = *(T*)src; + const auto sdkRes = dst; + constexpr std::remove_reference_t dbgVal = 42; + memcpy(&dst, &dbgVal, sizeof(dst)); +#endif + memcpy(&dst, src, sizeof(dst)); +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + const auto neoRes = dst; + Assert(neoRes == sdkRes); +#endif +} + void SendProxy_AngleToFloat( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) { float angle; @@ -156,7 +176,11 @@ void SendProxy_UInt16ToInt32( const SendProp *pProp, const void *pStruct, const void SendProxy_UInt32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) { +#ifdef NEO + pun(pOut->m_Int, pData); +#else *((unsigned long*)&pOut->m_Int) = *((unsigned long*)pData); +#endif } #ifdef SUPPORTS_INT64 void SendProxy_UInt64ToInt64( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) diff --git a/src/public/mathlib/compressed_vector.h b/src/public/mathlib/compressed_vector.h index ad2f95d1de..cb59f933f7 100644 --- a/src/public/mathlib/compressed_vector.h +++ b/src/public/mathlib/compressed_vector.h @@ -27,6 +27,10 @@ #include "mathlib/mathlib.h" +#ifdef NEO +#include "../../common/neo/bit_cast.h" +#endif + #if defined( _X360 ) #pragma bitfield_order( push, lsb_to_msb ) #endif @@ -461,7 +465,12 @@ class float16 static float Convert16bitFloatTo32bits( unsigned short input ) { float32bits output; +#ifdef NEO + const auto inFloat = neo::bit_cast(input); + Assert(inFloat.rawWord == ((float16bits*)&input)->rawWord); +#else const float16bits &inFloat = *((float16bits *)&input); +#endif if( IsInfinity( inFloat ) ) { @@ -488,7 +497,19 @@ class float16 biased_exponent = ( (biased_exponent - float16bias + float32bias) * (biased_exponent != 0) ) << 23; mantissa <<= (23-10); +#ifdef NEO + output.rawFloat = neo::bit_cast(mantissa | biased_exponent | sign); +#ifdef DBGFLAG_ASSERT + decltype(output) sdkRes; + *((unsigned*)&sdkRes) = (mantissa | biased_exponent | sign); + Assert(output.rawFloat == sdkRes.rawFloat); + Assert(output.bits.biased_exponent == sdkRes.bits.biased_exponent); + Assert(output.bits.mantissa == sdkRes.bits.mantissa); + Assert(output.bits.sign == sdkRes.bits.sign); +#endif +#else *((unsigned *)&output) = ( mantissa | biased_exponent | sign ); +#endif } return output.rawFloat; diff --git a/src/public/mathlib/mathlib.h b/src/public/mathlib/mathlib.h index 30548a5451..e0baa0e66b 100644 --- a/src/public/mathlib/mathlib.h +++ b/src/public/mathlib/mathlib.h @@ -17,6 +17,10 @@ #include "mathlib/math_pfns.h" +#ifdef NEO +#include +#endif + // For MMX intrinsics #include @@ -339,7 +343,16 @@ extern const Quaternion quat_identity; extern const Vector vec3_invalid; extern const int nanmask; +#ifdef NEO +template + requires std::is_same_v +inline bool IS_NAN(T x) +{ + return (neo::bit_cast(BC_TEST(x, *(int*)&x)) & nanmask) == nanmask; +} +#else #define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) +#endif FORCEINLINE vec_t DotProduct(const vec_t *v1, const vec_t *v2) { @@ -2139,6 +2152,9 @@ float FastLog2(float i); // log2( i ) float FastPow2(float i); // 2^i float FastPow(float a, float b); // a^b float FastPow10( float i ); // 10^i +#if defined(NEO) && defined(DBGFLAG_ASSERT) +void ValidateFastFuncs(); +#endif //----------------------------------------------------------------------------- // For testing float equality diff --git a/src/public/mathlib/ssemath.h b/src/public/mathlib/ssemath.h index e6af1bb607..e90e2eadf2 100644 --- a/src/public/mathlib/ssemath.h +++ b/src/public/mathlib/ssemath.h @@ -25,6 +25,10 @@ #define _SSE1 1 #endif +#if (defined(NEO) && (USE_STDC_FOR_SIMD == 0)) +#include "../../common/neo/bit_cast.h" +#endif + // I thought about defining a class/union for the SIMD packed floats instead of using fltx4, // but decided against it because (a) the nature of SIMD code which includes comparisons is to blur // the relationship between packed floats and packed integer types and (b) not sure that the @@ -1832,7 +1836,11 @@ NO_ASAN_FORCEINLINE fltx4 LoadUnaligned3SIMD( const void *pSIMD ) /// replicate a single 32 bit integer value to all 4 components of an m128 FORCEINLINE fltx4 ReplicateIX4( int i ) { +#ifdef NEO + fltx4 value = _mm_set_ss( neo::bit_cast(BC_TEST(i, *((float*)&i) )) ); +#else fltx4 value = _mm_set_ss( * ( ( float *) &i ) );; +#endif return _mm_shuffle_ps( value, value, 0); } diff --git a/src/public/tier0/basetypes.h b/src/public/tier0/basetypes.h index fdf515e932..e141f0573a 100644 --- a/src/public/tier0/basetypes.h +++ b/src/public/tier0/basetypes.h @@ -44,6 +44,10 @@ #include +#ifdef NEO +#include "../../common/neo/bit_cast.h" +#endif + #define ExecuteNTimes( nTimes, x ) \ { \ static int __executeCount=0;\ @@ -201,7 +205,11 @@ inline unsigned int const& FloatBits( vec_t const& f ) inline vec_t BitsToFloat( unsigned int i ) { +#ifdef NEO + return neo::bit_cast(i); +#else return *reinterpret_cast(&i); +#endif } inline bool IsFinite( vec_t f ) diff --git a/src/public/tier0/threadtools.h b/src/public/tier0/threadtools.h index bfead0b4dc..e7563dfde2 100644 --- a/src/public/tier0/threadtools.h +++ b/src/public/tier0/threadtools.h @@ -18,6 +18,10 @@ #include "tier0/vcrmode.h" #include "tier0/vprof_telemetry.h" +#ifdef NEO +#include "../../common/neo/bit_cast.h" +#endif + #ifdef PLATFORM_WINDOWS_PC #include #endif @@ -619,6 +623,24 @@ class PLATFORM_CLASS CThreadLocalBase template class CThreadLocal : public CThreadLocalBase { +#if defined(NEO) && defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + T Ref_Get() const + { +#ifdef PLATFORM_64BITS + void* pData = CThreadLocalBase::Get(); + return *reinterpret_cast(&pData); +#else +#ifdef COMPILER_MSVC +#pragma warning ( disable : 4311 ) +#endif + return reinterpret_cast(CThreadLocalBase::Get()); +#ifdef COMPILER_MSVC +#pragma warning ( default : 4311 ) +#endif +#endif + } +#endif + public: CThreadLocal() { @@ -633,7 +655,26 @@ class PLATFORM_CLASS CThreadLocalBase { #ifdef PLATFORM_64BITS void *pData = CThreadLocalBase::Get(); +#ifdef NEO +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + const auto neoRes = neo::bit_cast(pData); + const auto memcpyImpl = [pData]()->T { + T ret; + memcpy(&ret, &pData, sizeof(ret)); + return ret; + }; + const auto memcpyRes = memcpyImpl(); + const auto refRes = Ref_Get(); + Assert(neoRes == memcpyRes); + Assert(neoRes == refRes); + return neoRes; +#else + return neo::bit_cast(pData); +#endif + +#else return *reinterpret_cast( &pData ); +#endif #else #ifdef COMPILER_MSVC #pragma warning ( disable : 4311 ) @@ -647,6 +688,9 @@ class PLATFORM_CLASS CThreadLocalBase void Set(T val) { +#ifdef NEO + CThreadLocalBase::Set(reinterpret_cast(&val)); +#else #ifdef PLATFORM_64BITS void *pData = 0; *reinterpret_cast( &pData ) = val; @@ -659,6 +703,7 @@ class PLATFORM_CLASS CThreadLocalBase #ifdef COMPILER_MSVC #pragma warning ( default : 4312 ) #endif +#endif #endif } }; diff --git a/src/public/tier1/bitbuf.h b/src/public/tier1/bitbuf.h index 9d76836503..95ad889d50 100644 --- a/src/public/tier1/bitbuf.h +++ b/src/public/tier1/bitbuf.h @@ -22,6 +22,9 @@ #include "basetypes.h" #include "tier0/dbg.h" +#ifdef NEO +#include "../../common/neo/bit_cast.h" +#endif #if _DEBUG #define BITBUF_INLINE inline @@ -471,7 +474,11 @@ BITBUF_INLINE void bf_write::WriteBitFloat(float val) Assert(sizeof(int32) == sizeof(float)); Assert(sizeof(float) == 4); +#ifdef NEO + intVal = neo::bit_cast(BC_TEST(val, *((int32*)&val))); +#else intVal = *((int32*)&val); +#endif WriteUBitLong( intVal, 32 ); } diff --git a/src/public/tier1/utlhandletable.h b/src/public/tier1/utlhandletable.h index b8fc6bf567..b44e58f0c7 100644 --- a/src/public/tier1/utlhandletable.h +++ b/src/public/tier1/utlhandletable.h @@ -15,6 +15,9 @@ #include "tier1/utlvector.h" #include "tier1/utlqueue.h" +#ifdef NEO +#include +#endif //--------------------------------------------------------------------------------- // Handles are 32 bits on 32-bit and 64 bits on 64-bit. Invalid handles are all 1s @@ -241,20 +244,63 @@ int CUtlHandleTable::GetIndexFromHandle( UtlHandle_t h ) const template< class T, int HandleBits > unsigned int CUtlHandleTable::GetSerialNumber( UtlHandle_t handle ) { +#ifdef NEO + static_assert(sizeof(handle) == CHAR_BIT); + static_assert(sizeof(HandleType_t) <= sizeof(handle)); + HandleType_t ret(0, 0); + memcpy(&ret, &handle, sizeof(ret)); +#if defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + decltype(ret) ref(0, 0); + ref = *((HandleType_t*)&handle); + Assert(ret.nSerial == ref.nSerial); + Assert(ret.nIndex == ref.nIndex); +#endif + return ret.nSerial; +#else return ( ( HandleType_t* )&handle )->nSerial; +#endif } template< class T, int HandleBits > unsigned int CUtlHandleTable::GetListIndex( UtlHandle_t handle ) { +#ifdef NEO + static_assert(sizeof(handle) == CHAR_BIT); + static_assert(sizeof(HandleType_t) <= sizeof(handle)); + HandleType_t ret(0, 0); + memcpy(&ret, &handle, sizeof(ret)); +#if defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + decltype(ret) ref(0, 0); + ref = *((HandleType_t*)&handle); + Assert(ret.nSerial == ref.nSerial); + Assert(ret.nIndex == ref.nIndex); +#endif + return ret.nIndex; +#else return ( ( HandleType_t* )&handle )->nIndex; +#endif } template< class T, int HandleBits > UtlHandle_t CUtlHandleTable::CreateHandle( unsigned int nSerial, unsigned int nIndex ) { HandleType_t h( nIndex, nSerial ); +#ifdef NEO + // We could also pad HandleType_t on x64 so that neo::bit_cast works (or relax its constraints), + // but that'd widen the object from 4 bytes of data to 4+4 padding, which would need profiling. + static_assert(sizeof(h) == 4); + static_assert(sizeof(UtlHandle_t) >= sizeof(h)); + UtlHandle_t ret; + memcpy(&ret, &h, sizeof(h)); +#if defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + UtlHandle_t ref; + ref = *(UtlHandle_t*)&h; + Assert(ret == ref); +#endif + return ret; +#else return *( UtlHandle_t* )&h; +#endif } diff --git a/src/public/tier1/utlsymbol.h b/src/public/tier1/utlsymbol.h index fa5604a949..5e2def8747 100644 --- a/src/public/tier1/utlsymbol.h +++ b/src/public/tier1/utlsymbol.h @@ -238,6 +238,10 @@ class CUtlSymbolTableMT : private CUtlSymbolTable // copies them into a static char buffer for return. typedef void* FileNameHandle_t; #define FILENAMEHANDLE_INVALID 0 +#ifdef NEO +// These are used interchangeably elsewhere in the code base, so changing the constant could cause breakage. +static_assert(FILENAMEHANDLE_INVALID == NULL); +#endif // Symbol table for more efficiently storing filenames by breaking paths and filenames apart. // Refactored from BaseFileSystem.h diff --git a/src/public/vgui_controls/consoledialog.h b/src/public/vgui_controls/consoledialog.h index 7bbc8dd4bd..144ee63301 100644 --- a/src/public/vgui_controls/consoledialog.h +++ b/src/public/vgui_controls/consoledialog.h @@ -30,6 +30,9 @@ class CHistoryItem CHistoryItem( void ); CHistoryItem( const char *text, const char *extra = NULL ); CHistoryItem( const CHistoryItem& src ); +#ifdef NEO + CHistoryItem( const CHistoryItem* src ); +#endif ~CHistoryItem( void ); const char *GetText() const; diff --git a/src/tier1/CMakeLists.txt b/src/tier1/CMakeLists.txt index d07e4f0be5..71e19bb9bb 100644 --- a/src/tier1/CMakeLists.txt +++ b/src/tier1/CMakeLists.txt @@ -140,6 +140,7 @@ target_sources_grouped( TARGET tier1 NAME "Header Files" FILES + ${CMAKE_SOURCE_DIR}/common/neo/bit_cast.h ${CMAKE_SOURCE_DIR}/common/neo/narrow_cast.h ${CMAKE_SOURCE_DIR}/public/tier1/bitbuf.h diff --git a/src/tier1/utlsymbol.cpp b/src/tier1/utlsymbol.cpp index d75eaa52f3..16d96cf75f 100644 --- a/src/tier1/utlsymbol.cpp +++ b/src/tier1/utlsymbol.cpp @@ -16,6 +16,10 @@ #include "utlhashtable.h" #include "utlstring.h" +#ifdef NEO +#include "../common/neo/bit_cast.h" +#endif + // Ensure that everybody has the right compiler version installed. The version // number can be obtained by looking at the compiler output when you type 'cl' // and removing the last two digits and the periods: 16.00.40219.01 becomes 160040219 @@ -356,7 +360,11 @@ FileNameHandle_t CUtlFilenameSymbolTable::FindOrAddFileName( const char *pFileNa //handle.file = m_StringPool.ReferenceStringHandle( filename ); m_lock.UnlockWrite(); +#ifdef NEO + return neo::bit_cast(BC_TEST(handle, *(FileNameHandle_t*)(&handle))); +#else return *( FileNameHandle_t * )( &handle ); +#endif } FileNameHandle_t CUtlFilenameSymbolTable::FindFileName( const char *pFileName ) @@ -394,7 +402,11 @@ FileNameHandle_t CUtlFilenameSymbolTable::FindFileName( const char *pFileName ) if ( handle.path == 0 || handle.file == 0 ) return NULL; +#ifdef NEO + return neo::bit_cast(BC_TEST(handle, *(FileNameHandle_t*)(&handle))); +#else return *( FileNameHandle_t * )( &handle ); +#endif } //----------------------------------------------------------------------------- diff --git a/src/vgui2/vgui_controls/consoledialog.cpp b/src/vgui2/vgui_controls/consoledialog.cpp index d1bc4e0820..3f3396f5ec 100644 --- a/src/vgui2/vgui_controls/consoledialog.cpp +++ b/src/vgui2/vgui_controls/consoledialog.cpp @@ -135,6 +135,16 @@ CHistoryItem::CHistoryItem( const CHistoryItem& src ) SetText( src.GetText(), src.GetExtra() ); } +#ifdef NEO +CHistoryItem::CHistoryItem( const CHistoryItem* src ) +{ + m_text = NULL; + m_extraText = NULL; + m_bHasExtra = false; + SetText( src->GetText(), src->GetExtra() ); +} +#endif + CHistoryItem::~CHistoryItem( void ) { delete[] m_text; @@ -209,7 +219,11 @@ CConsolePanel::CompletionItem::CompletionItem( const CompletionItem& src ) m_pCommand = src.m_pCommand; if ( src.m_pText ) { +#ifdef NEO + m_pText = new CHistoryItem(src.m_pText); +#else m_pText = new CHistoryItem( (const CHistoryItem& )src.m_pText ); +#endif } else { From 0646d94a7f8f4f5fc8e9eaf98d408a60407daa7b Mon Sep 17 00:00:00 2001 From: Rain Date: Mon, 15 Dec 2025 17:14:03 +0200 Subject: [PATCH 36/96] [[maybe_unused]] on members only used for Clang So we heard you like [[maybe_unused]] so we emitted maybe unused warnings for your maybe unused attributes --- src/public/tier1/utlstring.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/public/tier1/utlstring.h b/src/public/tier1/utlstring.h index 6ca831fcf4..d6801ff898 100644 --- a/src/public/tier1/utlstring.h +++ b/src/public/tier1/utlstring.h @@ -759,6 +759,9 @@ class CUtlStringBuilder char *m_pchString; uint32 m_nLength; uint32 m_nCapacity; // without trailing null; ie: m_pchString[m_nCapacity] = '\0' is not out of bounds +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif uint8 scrap[3]; uint8 sentinel; public: From e7f1eb3d461ba289efb565267266741c9faee962 Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 16 Dec 2025 15:04:21 +0200 Subject: [PATCH 37/96] Fix ambiguous whitespace --- src/vgui2/vgui_controls/Slider.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vgui2/vgui_controls/Slider.cpp b/src/vgui2/vgui_controls/Slider.cpp index 33bc7fe07c..0b2ce2570f 100644 --- a/src/vgui2/vgui_controls/Slider.cpp +++ b/src/vgui2/vgui_controls/Slider.cpp @@ -751,14 +751,14 @@ void Slider::OnMousePressed(MouseCode code) { int x,y; - if (!IsEnabled()) - return; + if (!IsEnabled()) + return; // input()->GetCursorPos(x,y); input()->GetCursorPosition( x, y ); ScreenToLocal(x,y); - RequestFocus(); + RequestFocus(); bool startdragging = false, bPostDragStartSignal = false; From 1b09b7675defc38075800017f2fe24f8d6ef2b19 Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 16 Dec 2025 15:08:03 +0200 Subject: [PATCH 38/96] Fix Clang ambiguous GCC/MSVC preprocessor defines Clang may opt to define preprocessor identifiers of other compilers like GCC and MSVC. This breaks compiler-specific code. Add helper macros to work around this without needing to ifndef for clang all over the place. --- CONTRIBUTING.md | 3 ++- src/CMakeLists.txt | 5 +++++ src/public/mathlib/vector.h | 8 ++++---- src/public/tier1/byteswap.h | 8 ++++---- src/public/tier1/utlstring.h | 4 ++-- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 99a0051239..9d47dd8ec3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -153,6 +153,7 @@ Only the x64 (64-bit) architecture is supported. * For release builds, it is identical to `static_cast` * `narrow_cast`: * The preferred cast for narrowing conversions where loss of information may occur + * Use to mark narrowing conversions where the input could overflow * If you know for a fact it is always a safe cast, you can use `static_cast` instead * For debug builds, will runtime-validate narrowing conversions for: * Roundtrip equality: `value v of type A equals itself after A->B->A type conversion` @@ -160,7 +161,7 @@ Only the x64 (64-bit) architecture is supported. * For release builds, it is identical to `static_cast` * `neo::bit_cast`: * Well-formed type punning helper. Mostly used to avoid UB in the SDK code. - * For the general case, it is a constexpr wrapper for `std::bit_cast` if it's available, but will also support `memcpy` based conversions for when this is not the case (either `std::bit_cast` unavailable or its constraints not satisfied). + * Wrapper for `std::bit_cast` when it's available, else will fall back to `memcpy` based conversions (for example on the steamrt3 default GCC compiler). * For debug builds, a runtime assertion test is available as an additional parameter: * `auto output = neo::bit_cast(BC_TEST(input, expectedOutput));` * When replacing ill-formed type puns, this test syntax can be used to ensure the output of `neo::bit_cast(input)` remains identical to `expectedOutput` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f33d26767d..92ebedcb2d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -386,10 +386,15 @@ if(OS_LINUX) ) endif() +# Clang may define GCC or MSVC values as some kind of a compatibility thing, +# but this can break code that relies on accurately identifying the used compiler. +# The "ACTUALLY_..." defs here can be used for succintly determining the compiler for real. if(COMPILER_MSVC) add_compile_definitions(COMPILER_MSVC) + add_compile_definitions(ACTUALLY_COMPILER_MSVC) elseif(COMPILER_GCC) add_compile_definitions(COMPILER_GCC) + add_compile_definitions(ACTUALLY_COMPILER_GCC) elseif(COMPILER_CLANG) add_compile_definitions(COMPILER_CLANG) endif() diff --git a/src/public/mathlib/vector.h b/src/public/mathlib/vector.h index b811d6b959..3f11db37a1 100644 --- a/src/public/mathlib/vector.h +++ b/src/public/mathlib/vector.h @@ -578,7 +578,7 @@ inline void VectorClear( Vector& a ) inline Vector& Vector::operator=(const Vector &vOther) { -#if defined(NEO) && defined(__GNUC__) +#if defined(NEO) && defined(ACTUALLY_COMPILER_GCC) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif @@ -586,7 +586,7 @@ inline Vector& Vector::operator=(const Vector &vOther) CHECK_VALID(vOther); x=vOther.x; y=vOther.y; z=vOther.z; -#if defined(NEO) && defined(__GNUC__) +#if defined(NEO) && defined(ACTUALLY_COMPILER_GCC) #pragma GCC diagnostic pop #endif @@ -1981,7 +1981,7 @@ inline QAngle RadianEuler::ToQAngle( void) const //----------------------------------------------------------------------------- inline QAngle& QAngle::operator=(const QAngle &vOther) { -#if defined(NEO) && defined(__GNUC__) +#if defined(NEO) && defined(ACTUALLY_COMPILER_GCC) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif @@ -1989,7 +1989,7 @@ inline QAngle& QAngle::operator=(const QAngle &vOther) CHECK_VALID(vOther); x=vOther.x; y=vOther.y; z=vOther.z; -#if defined(NEO) && defined(__GNUC__) +#if defined(NEO) && defined(ACTUALLY_COMPILER_GCC) #pragma GCC diagnostic pop #endif diff --git a/src/public/tier1/byteswap.h b/src/public/tier1/byteswap.h index 03a50e8995..af51a47e2f 100644 --- a/src/public/tier1/byteswap.h +++ b/src/public/tier1/byteswap.h @@ -215,10 +215,10 @@ class CByteswap { #ifdef NEO static_assert(sizeof(T) > 0); -#ifdef __GNUC__ +#ifdef ACTUALLY_COMPILER_GCC #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif // __GNUC__ +#endif // ACTUALLY_COMPILER_GCC Assert(output); Assert(input); #endif // NEO @@ -226,9 +226,9 @@ class CByteswap T temp = *output; #ifdef NEO -#ifdef __GNUC__ +#ifdef ACTUALLY_COMPILER_GCC #pragma GCC diagnostic pop -#endif // __GNUC__ +#endif // ACTUALLY_COMPILER_GCC #endif // NEO #if defined( _X360 ) diff --git a/src/public/tier1/utlstring.h b/src/public/tier1/utlstring.h index d6801ff898..163987531a 100644 --- a/src/public/tier1/utlstring.h +++ b/src/public/tier1/utlstring.h @@ -399,7 +399,7 @@ class StringFuncs #ifdef NEO static void Copy(OUT_CAP(iLengthInChars) char* out_pOut, const char* pIn, int iLengthInChars) { -#ifdef __GNUC__ +#ifdef ACTUALLY_COMPILER_GCC #pragma GCC diagnostic push #if ((__GNUC__ >= 10) && (__GNUC__ <= 13)) #pragma GCC diagnostic ignored "-Wstringop-overflow" @@ -407,7 +407,7 @@ class StringFuncs #endif #endif strncpy(out_pOut, pIn, iLengthInChars); -#ifdef __GNUC__ +#ifdef ACTUALLY_COMPILER_GCC #pragma GCC diagnostic pop #endif } From bef550195732aebd1bd86088aef821136336593e Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 16 Dec 2025 15:34:09 +0200 Subject: [PATCH 39/96] Fix warning: unused-private-field --- src/game/client/c_pixel_visibility.cpp | 6 ++++++ src/game/client/camomaterialproxy.cpp | 3 +++ src/game/client/history_resource.h | 3 +++ src/game/client/hud_basetimer.h | 3 +++ src/game/client/neo/ui/neo_hud_friendly_marker.h | 9 ++------- src/game/client/neo/ui/neo_hud_ghost_cap_point.h | 1 - src/game/server/NextBot/Path/NextBotPathFollow.h | 3 +++ src/game/server/hl2/npc_attackchopper.cpp | 6 ++++++ src/game/shared/hl2mp/hl2mp_playeranimstate.h | 2 ++ src/public/bone_setup.h | 3 +++ src/public/vgui_controls/FileOpenDialog.h | 3 +++ src/public/vgui_controls/Frame.h | 3 +++ src/public/vgui_controls/ListPanel.h | 6 ++++++ src/public/vgui_controls/MessageMap.h | 3 +++ src/public/vgui_controls/ProgressBar.h | 3 +++ src/public/vgui_controls/TextEntry.h | 6 ++++++ 16 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/game/client/c_pixel_visibility.cpp b/src/game/client/c_pixel_visibility.cpp index b581e003b3..2766f2fb1f 100644 --- a/src/game/client/c_pixel_visibility.cpp +++ b/src/game/client/c_pixel_visibility.cpp @@ -261,6 +261,9 @@ class CPixelVisibilityQuery unsigned short m_wasQueriedThisFrame : 1; unsigned short m_failed : 1; unsigned short m_hasValidQueryResults : 1; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif unsigned short m_pad : 13; unsigned short m_viewID; @@ -503,6 +506,9 @@ class CPixelVisibilitySystem : public CAutoGameSystem unsigned short m_freeQueriesList; unsigned short m_activeSetsList; unsigned short m_freeSetsList; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif unsigned short m_pad0; IMaterial *m_pProxyMaterial; diff --git a/src/game/client/camomaterialproxy.cpp b/src/game/client/camomaterialproxy.cpp index d30f5fe062..f06f695a5c 100644 --- a/src/game/client/camomaterialproxy.cpp +++ b/src/game/client/camomaterialproxy.cpp @@ -96,6 +96,9 @@ class CCamoMaterialProxy : public CEntityMaterialProxy int m_CamoPatternHeight; #if 0 cache_user_t m_camoImageDataCache; +#endif +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] #endif unsigned char m_CamoPalette[256][3]; // these represent that part of the entitiy's bounding box that we diff --git a/src/game/client/history_resource.h b/src/game/client/history_resource.h index 962b16882c..2dab6bde42 100644 --- a/src/game/client/history_resource.h +++ b/src/game/client/history_resource.h @@ -80,6 +80,9 @@ class CHudHistoryResource : public CHudElement, public vgui::Panel private: // these vars are for hl1-port compatibility +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif int m_iHistoryGap; int m_iCurrentHistorySlot; bool m_bDoNotDraw; diff --git a/src/game/client/hud_basetimer.h b/src/game/client/hud_basetimer.h index f407b1310e..83f6ef5f2b 100644 --- a/src/game/client/hud_basetimer.h +++ b/src/game/client/hud_basetimer.h @@ -38,6 +38,9 @@ class CHudBaseTimer : public CHudNumericDisplay int m_iMinutes; int m_iSeconds; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif wchar_t m_LabelText[32]; CPanelAnimationVar( float, m_flBlur, "Blur", "0" ); diff --git a/src/game/client/neo/ui/neo_hud_friendly_marker.h b/src/game/client/neo/ui/neo_hud_friendly_marker.h index a4fb771c85..2fa361e180 100644 --- a/src/game/client/neo/ui/neo_hud_friendly_marker.h +++ b/src/game/client/neo/ui/neo_hud_friendly_marker.h @@ -85,16 +85,11 @@ class CNEOHud_FriendlyMarker : public CNEOHud_WorldPosMarker private: int m_iIconWidth, m_iIconHeight; - - int m_x0[MAX_PLAYERS]; - int m_x1[MAX_PLAYERS]; - int m_y0[MAX_PLAYERS]; - int m_y1[MAX_PLAYERS]; - vgui::HTexture m_hStarTex = 0UL; + vgui::HTexture m_hStarTex = 0; vgui::HTexture m_hNonStarTex = 0UL; vgui::HTexture m_hUniqueTex = 0UL; - vgui::HFont m_hFont = 0UL; + vgui::HFont m_hFont = vgui::INVALID_FONT; void DrawPlayer(Color teamColor, C_NEO_Player *player, const C_NEO_Player *localPlayer) const; static Color GetTeamColour(int team); diff --git a/src/game/client/neo/ui/neo_hud_ghost_cap_point.h b/src/game/client/neo/ui/neo_hud_ghost_cap_point.h index cb244499ed..95baf6132b 100644 --- a/src/game/client/neo/ui/neo_hud_ghost_cap_point.h +++ b/src/game/client/neo/ui/neo_hud_ghost_cap_point.h @@ -30,7 +30,6 @@ class CNEOHud_GhostCapPoint : public CNEOHud_WorldPosMarker int m_flMyRadius = 0; int m_iCapTeam = TEAM_INVALID; float m_flDistance = 0.0f; - float m_flCapTexScale = 1.0f; float m_fMarkerScalesStart[4] = { 0.78f, 0.6f, 0.38f, 0.0f }; float m_fMarkerScalesCurrent[4] = { 0.78f, 0.6f, 0.38f, 0.0f }; wchar_t m_wszMarkerTextUnicode[64 + 1] = {}; diff --git a/src/game/server/NextBot/Path/NextBotPathFollow.h b/src/game/server/NextBot/Path/NextBotPathFollow.h index 3262148e81..4b0316f1a6 100644 --- a/src/game/server/NextBot/Path/NextBotPathFollow.h +++ b/src/game/server/NextBot/Path/NextBotPathFollow.h @@ -50,6 +50,9 @@ class PathFollower : public Path bool IsAtGoal( INextBot *bot ) const; // return true if reached current path goal //bool IsOnStairs( INextBot *bot ) const; // return true if bot is standing on a stairway +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif bool m_isOnStairs; Path::ResultType m_result = NO_PATH; diff --git a/src/game/server/hl2/npc_attackchopper.cpp b/src/game/server/hl2/npc_attackchopper.cpp index 336dae1098..e42cefbeb4 100644 --- a/src/game/server/hl2/npc_attackchopper.cpp +++ b/src/game/server/hl2/npc_attackchopper.cpp @@ -1649,7 +1649,13 @@ class CTraceFilterChopper : public CTraceFilterSimple virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask ); private: +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif const IHandleEntity *m_pPassEnt; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif int m_collisionGroup; }; diff --git a/src/game/shared/hl2mp/hl2mp_playeranimstate.h b/src/game/shared/hl2mp/hl2mp_playeranimstate.h index bea91c50b7..f288dc067b 100644 --- a/src/game/shared/hl2mp/hl2mp_playeranimstate.h +++ b/src/game/shared/hl2mp/hl2mp_playeranimstate.h @@ -63,8 +63,10 @@ class CHL2MPPlayerAnimState : public CMultiPlayerAnimState virtual void ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr ); CHL2MP_Player *m_pHL2MPPlayer; +#ifndef NEO bool m_bInAirWalk; float m_flHoldDeployedPoseUntilTime; +#endif }; CHL2MPPlayerAnimState *CreateHL2MPPlayerAnimState( CHL2MP_Player *pPlayer ); diff --git a/src/public/bone_setup.h b/src/public/bone_setup.h index 6ec21b2e65..41b8c5ea9b 100644 --- a/src/public/bone_setup.h +++ b/src/public/bone_setup.h @@ -431,6 +431,9 @@ class CBoneCache unsigned short m_cachedBoneCount; unsigned short m_matrixOffset; unsigned short m_cachedToStudioOffset; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif unsigned short m_boneOutOffset; }; diff --git a/src/public/vgui_controls/FileOpenDialog.h b/src/public/vgui_controls/FileOpenDialog.h index bcaccf0f70..6ca0b45fa8 100644 --- a/src/public/vgui_controls/FileOpenDialog.h +++ b/src/public/vgui_controls/FileOpenDialog.h @@ -142,6 +142,9 @@ class FileOpenDialog : public vgui::Frame vgui::Button *m_pNewFolderButton; vgui::Button *m_pOpenInExplorerButton; vgui::ImagePanel *m_pFolderIcon; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif vgui::Label *m_pFileTypeLabel; KeyValues *m_pContextKeyValues; diff --git a/src/public/vgui_controls/Frame.h b/src/public/vgui_controls/Frame.h index 24da59810f..4637330174 100644 --- a/src/public/vgui_controls/Frame.h +++ b/src/public/vgui_controls/Frame.h @@ -237,6 +237,9 @@ class Frame : public EditablePanel int m_iClientInsetX; int m_iClientInsetY; int m_iTitleTextInsetX; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif int m_nGripperWidth; VPANEL m_hPreviousModal; HFont m_hCustomTitleFont; diff --git a/src/public/vgui_controls/ListPanel.h b/src/public/vgui_controls/ListPanel.h index f2fb15eb21..da21fbdb5e 100644 --- a/src/public/vgui_controls/ListPanel.h +++ b/src/public/vgui_controls/ListPanel.h @@ -334,7 +334,13 @@ class ListPanel : public Panel bool m_bNeedsSort : 1; bool m_bSortAscending : 1; bool m_bSortAscendingSecondary : 1; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif bool m_bCanSelectIndividualCells : 1; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif bool m_bShiftHeldDown : 1; bool m_bMultiselectEnabled : 1; bool m_bAllowUserAddDeleteColumns : 1; diff --git a/src/public/vgui_controls/MessageMap.h b/src/public/vgui_controls/MessageMap.h index e8a1d9d374..85999114b2 100644 --- a/src/public/vgui_controls/MessageMap.h +++ b/src/public/vgui_controls/MessageMap.h @@ -345,6 +345,9 @@ class CBuildFactoryHelper // Next factory in list CBuildFactoryHelper *m_pNext; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif int m_Type; PANELCREATEFUNC m_CreateFunc; char const *m_pClassName; diff --git a/src/public/vgui_controls/ProgressBar.h b/src/public/vgui_controls/ProgressBar.h index d65e0ce3a4..6736161b64 100644 --- a/src/public/vgui_controls/ProgressBar.h +++ b/src/public/vgui_controls/ProgressBar.h @@ -77,6 +77,9 @@ class ProgressBar : public Panel float _progress; private: +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif int _segmentCount; int _segmentGap; int _segmentWide; diff --git a/src/public/vgui_controls/TextEntry.h b/src/public/vgui_controls/TextEntry.h index 7231acc425..8e036330ad 100644 --- a/src/public/vgui_controls/TextEntry.h +++ b/src/public/vgui_controls/TextEntry.h @@ -330,6 +330,9 @@ class TextEntry : public Panel bool _editable; // whether text is editable or not bool _mouseSelection; // whether we are highlighting text or not (selecting text) bool _mouseDragSelection; // tells weather mouse is outside window and button is down so we select text +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif int _mouseSelectCursorStart; // where mouse button was pressed down in text window long _cursorNextBlinkTime; // time of next cursor blink int _cursorBlinkRate; // speed of cursor blinking @@ -365,6 +368,9 @@ class TextEntry : public Panel int _recalculateBreaksIndex; // tells next linebreakindex index to Start recalculating line breaks bool _selectAllOnFirstFocus : 1; // highlights all text in window when focus is gained. bool _selectAllOnFocusAlways : 1; +#if defined(NEO) && defined(COMPILER_CLANG) + [[maybe_unused]] +#endif bool _firstFocusStatus; // keep track if we've had that first focus or not bool m_bAllowNumericInputOnly; bool m_bAllowNonAsciiCharacters; From e1fb258717f6423a2b391cab0092ed6f449192d1 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 06:32:32 +0200 Subject: [PATCH 40/96] Fix redundant assignment warning --- src/game/client/c_entitydissolve.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/game/client/c_entitydissolve.cpp b/src/game/client/c_entitydissolve.cpp index b4f7fffc9d..cffe38746a 100644 --- a/src/game/client/c_entitydissolve.cpp +++ b/src/game/client/c_entitydissolve.cpp @@ -72,7 +72,16 @@ void C_EntityDissolve::GetRenderBounds( Vector& theMins, Vector& theMaxs ) else { theMins = GetAbsOrigin(); + + // NEO NOTE (Rain): Is this redundant assignment meant to silence an unused variable warning? + // Even if so, it seems sketch that we'd leave theMaxs possibly uninitialized, so I'm changing + // it to theMins value so at least we're guaranteed to have something valid in it before attempting to use it. + // This line would warn for the redundant assignment in Clang 14. +#ifdef NEO + theMaxs = theMins; +#else theMaxs = theMaxs; +#endif } } From abbd822112de27f721a1c923c51a10f62cfd18fa Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 06:38:56 +0200 Subject: [PATCH 41/96] Fix EHANDLE operator== ambiguity Declare a non-member overloaded operator== candidate for CHandle to fix the ISO C++20 ambiguous-reversed-operator warning for cases where lhs and rhs ordering could be either. --- src/game/shared/ehandle.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/game/shared/ehandle.h b/src/game/shared/ehandle.h index 5d4fea96aa..07c9d1e1fd 100644 --- a/src/game/shared/ehandle.h +++ b/src/game/shared/ehandle.h @@ -109,6 +109,12 @@ class CHandle : public CBaseHandle // Inlines. // ----------------------------------------------------------------------- // +template +inline bool operator==(const CHandle& lhs, const CHandle& rhs) +{ + return lhs.Get() == rhs.Get(); +} + template inline CHandle::CHandle() { From 09ce869635983be94769cca53f745314ff121856 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 06:50:33 +0200 Subject: [PATCH 42/96] Fix nullptr indirection --- src/game/client/c_basetempentity.h | 9 +++++++++ src/game/client/detailobjectsystem.cpp | 14 ++++++++++++++ src/public/iclientrenderable.h | 13 +++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/game/client/c_basetempentity.h b/src/game/client/c_basetempentity.h index 2f3740ead0..ae3a92cae5 100644 --- a/src/game/client/c_basetempentity.h +++ b/src/game/client/c_basetempentity.h @@ -37,7 +37,16 @@ class C_BaseTempEntity : public IClientUnknown, public IClientNetworkable public: virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); } +#ifdef NEO + virtual const CBaseHandle& GetRefEHandle() const override + { + Assert(false); + const static auto invalidHandle = CBaseHandle(INVALID_EHANDLE); + return invalidHandle; + } +#else virtual const CBaseHandle& GetRefEHandle() const { return *((CBaseHandle*)0); } +#endif virtual IClientUnknown* GetIClientUnknown() { return this; } virtual ICollideable* GetCollideable() { return 0; } diff --git a/src/game/client/detailobjectsystem.cpp b/src/game/client/detailobjectsystem.cpp index 6219942c51..2a6e02698c 100644 --- a/src/game/client/detailobjectsystem.cpp +++ b/src/game/client/detailobjectsystem.cpp @@ -228,7 +228,16 @@ class CDetailModel : public IClientUnknown, public IClientRenderable // IHandleEntity stubs. public: virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); } +#ifdef NEO + virtual const CBaseHandle& GetRefEHandle() const override + { + Assert(false); + const static auto invalidHandle = CBaseHandle(INVALID_EHANDLE); + return invalidHandle; + } +#else virtual const CBaseHandle& GetRefEHandle() const { Assert( false ); return *((CBaseHandle*)0); } +#endif //--------------------------------- struct LightStyleInfo_t @@ -647,7 +656,12 @@ ClientShadowHandle_t CDetailModel::GetShadowHandle() const ClientRenderHandle_t& CDetailModel::RenderHandle() { AssertMsg( 0, "CDetailModel has no render handle" ); +#ifdef NEO + static ClientRenderHandle_t invalidHandle = INVALID_CLIENT_RENDER_HANDLE; + return invalidHandle; +#else return *((ClientRenderHandle_t*)NULL); +#endif } diff --git a/src/public/iclientrenderable.h b/src/public/iclientrenderable.h index 77ce8f220f..8dd3b86ad7 100644 --- a/src/public/iclientrenderable.h +++ b/src/public/iclientrenderable.h @@ -17,6 +17,10 @@ #include "client_render_handle.h" #include "engine/ivmodelrender.h" +#ifdef NEO +#include "basehandle.h" +#endif + struct model_t; struct matrix3x4_t; @@ -263,7 +267,16 @@ abstract_class CDefaultClientRenderable : public IClientUnknown, public IClientR // IClientUnknown implementation. public: virtual void SetRefEHandle( const CBaseHandle &handle ) { Assert( false ); } +#ifdef NEO + virtual const CBaseHandle& GetRefEHandle() const override + { + Assert(false); + const static auto invalidHandle = CBaseHandle(INVALID_EHANDLE); + return invalidHandle; + } +#else virtual const CBaseHandle& GetRefEHandle() const { Assert( false ); return *((CBaseHandle*)0); } +#endif virtual IClientUnknown* GetIClientUnknown() { return this; } virtual ICollideable* GetCollideable() { return 0; } From 95cdc30b6c34290d8a425924faec0b857ddfb11e Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 08:46:58 +0200 Subject: [PATCH 43/96] Suppress thisptr null check warning Suppress warning for Clang 14: error: 'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true [-Werror,-Wundefined-bool-conversion] Not removing the check, just in case there is some bizarre way in which non-well-defined SDK code relies on this condition. --- src/public/studio.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/public/studio.cpp b/src/public/studio.cpp index bbbd45bb14..55a1437264 100644 --- a/src/public/studio.cpp +++ b/src/public/studio.cpp @@ -833,10 +833,17 @@ const virtualmodel_t * CStudioHdr::ResetVModel( const virtualmodel_t *pVModel ) const studiohdr_t *CStudioHdr::GroupStudioHdr( int i ) { +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-bool-conversion" +#endif if ( !this ) { ExecuteNTimes( 5, Warning( "Call to NULL CStudioHdr::GroupStudioHdr()\n" ) ); } +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic pop +#endif if ( m_nFrameUnlockCounter != *m_pFrameUnlockCounter ) { From 5bb3d365fa47896afd1d2990a073835e08c2d813 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 08:51:23 +0200 Subject: [PATCH 44/96] Fix undefined-bool-conversion --- src/public/vstdlib/jobthread.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/public/vstdlib/jobthread.h b/src/public/vstdlib/jobthread.h index 91623684ff..bfa7291599 100644 --- a/src/public/vstdlib/jobthread.h +++ b/src/public/vstdlib/jobthread.h @@ -492,8 +492,15 @@ class CJob : public CRefCounted1 //----------------------------------------------------- // Thread event support (safe for NULL this to simplify code ) //----------------------------------------------------- +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-bool-conversion" +#endif bool WaitForFinish( uint32 dwTimeout = TT_INFINITE ) { if (!this) return true; return ( !IsFinished() ) ? g_pThreadPool->YieldWait( this, dwTimeout ) : true; } bool WaitForFinishAndRelease( uint32 dwTimeout = TT_INFINITE ) { if (!this) return true; bool bResult = WaitForFinish( dwTimeout); Release(); return bResult; } +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic pop +#endif CThreadEvent *AccessEvent() { return &m_CompleteEvent; } //----------------------------------------------------- From 97e9dd8d72b338e9ea0c7bb47118cdd226306943 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 09:06:35 +0200 Subject: [PATCH 45/96] Qualify crash trap as volatile Mark the debug crash trap as volatile to avoid it being optimized away. Fix for Clang 14: error: indirection of non-volatile null pointer will be deleted, not trap [-Werror,-Wnull-dereference] --- src/game/client/clientmode_shared.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/game/client/clientmode_shared.cpp b/src/game/client/clientmode_shared.cpp index 5d971071b5..df06445c97 100644 --- a/src/game/client/clientmode_shared.cpp +++ b/src/game/client/clientmode_shared.cpp @@ -185,6 +185,9 @@ CON_COMMAND( hud_reloadscheme, "Reloads hud layout and animation scripts." ) CON_COMMAND_F( crash, "Crash the client. Optional parameter -- type of crash:\n 0: read from NULL\n 1: write to NULL\n 2: DmCrashDump() (xbox360 only)", FCVAR_CHEAT ) { int crashtype = 0; +#ifdef NEO + volatile +#endif int dummy; if ( args.ArgC() > 1 ) { @@ -193,11 +196,19 @@ CON_COMMAND_F( crash, "Crash the client. Optional parameter -- type of crash:\n switch (crashtype) { case 0: +#ifdef NEO + dummy = *((volatile int*)NULL); +#else dummy = *((int *) NULL); +#endif Msg("Crashed! %d\n", dummy); // keeps dummy from optimizing out break; case 1: +#ifdef NEO + *((volatile int*)NULL) = 42; +#else *((int *)NULL) = 42; +#endif break; #if defined( _X360 ) case 2: From a0856f3fc01a949afb80b91379b89a8a001fbf50 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 09:33:41 +0200 Subject: [PATCH 46/96] Fix operator precedence bug logical NOT in !lhs==rhs applies to lhs only, but meant to check lhs!=rhs --- src/game/client/colorcorrectionmgr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/client/colorcorrectionmgr.cpp b/src/game/client/colorcorrectionmgr.cpp index 770354b0fc..5cd361d9b9 100644 --- a/src/game/client/colorcorrectionmgr.cpp +++ b/src/game/client/colorcorrectionmgr.cpp @@ -100,7 +100,11 @@ void CColorCorrectionMgr::SetResetable( ClientCCHandle_t h, bool bResetable ) // NOTE: Setting stuff to be not resettable doesn't work when in queued mode // because the logic that sets m_nActiveWeightCount to 0 in ResetColorCorrectionWeights // is no longer valid when stuff is not resettable. +#ifdef NEO + Assert( bResetable || g_pMaterialSystem->GetThreadMode() != MATERIAL_SINGLE_THREADED ); +#else Assert( bResetable || !g_pMaterialSystem->GetThreadMode() == MATERIAL_SINGLE_THREADED ); +#endif if ( h != INVALID_CLIENT_CCHANDLE ) { CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); From 9c5e11e12d509cbb70ae35431921f60fea68d703 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 09:42:17 +0200 Subject: [PATCH 47/96] Fix tautological ptr compare --- src/game/client/vgui_debugoverlaypanel.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/client/vgui_debugoverlaypanel.cpp b/src/game/client/vgui_debugoverlaypanel.cpp index 20543f9154..d86d543ce3 100644 --- a/src/game/client/vgui_debugoverlaypanel.cpp +++ b/src/game/client/vgui_debugoverlaypanel.cpp @@ -115,7 +115,11 @@ void CDebugOverlay::Paint() OverlayText_t* pCurrText = debugoverlay->GetFirst(); while (pCurrText) { +#ifdef NEO + if (*pCurrText->text) +#else if ( pCurrText->text != NULL ) +#endif { // -------------- // Draw the text From 904019544523847dcd5fd42b1e0e40f50f4ace35 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 10:05:12 +0200 Subject: [PATCH 48/96] Fix incorrect arguments for BuildWorldRenderLists --- src/game/client/viewdebug.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/client/viewdebug.cpp b/src/game/client/viewdebug.cpp index 7b67c8f754..3167ef85d8 100644 --- a/src/game/client/viewdebug.cpp +++ b/src/game/client/viewdebug.cpp @@ -66,7 +66,11 @@ class CLightmapDebugView : public CRendering3dView s_bCanAccessCurrentView = true; Frustum frustum; render->Push3DView( *this, 0, NULL, frustum ); +#ifdef NEO + BuildWorldRenderLists(true, -1, true, true); +#else BuildWorldRenderLists( this, true, true ); +#endif render->PopView( frustum ); s_bCanAccessCurrentView = false; From 9622b497db29261efd68e15112938b64c68f22fa Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 27 Dec 2025 19:11:52 +0200 Subject: [PATCH 49/96] Refactor neo_root_serverbrowser --- src/game/client/neo/ui/neo_root.cpp | 9 +++++---- src/game/client/neo/ui/neo_root_serverbrowser.h | 10 ++++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/game/client/neo/ui/neo_root.cpp b/src/game/client/neo/ui/neo_root.cpp index 803dbd0d66..0986f476d4 100644 --- a/src/game/client/neo/ui/neo_root.cpp +++ b/src/game/client/neo/ui/neo_root.cpp @@ -1402,21 +1402,22 @@ void CNeoRoot::MainLoopServerBrowser(const MainLoopParam param) NeoUI::SetPerRowLayout(iColTotal, pirLayout); for (int i = 0; i < iColTotal; ++i) { - vgui::surface()->DrawSetColor((m_sortCtx.col == i) ? COLOR_NEOPANELACCENTBG : COLOR_NEOPANELNORMALBG); + const bool isSortCol = (m_sortCtx.col == i); + vgui::surface()->DrawSetColor(isSortCol ? COLOR_NEOPANELACCENTBG : COLOR_NEOPANELNORMALBG); if (NeoUI::Button(pwszNames[i]).bPressed) { - if (m_sortCtx.col == i) + if (isSortCol) { m_sortCtx.bDescending = !m_sortCtx.bDescending; } else { - m_sortCtx.col = static_cast(i); + m_sortCtx.col = i; } m_bSBFiltModified = true; } - if (m_sortCtx.col == i) + if (isSortCol) { DrawSortHint(m_sortCtx.bDescending); } diff --git a/src/game/client/neo/ui/neo_root_serverbrowser.h b/src/game/client/neo/ui/neo_root_serverbrowser.h index 02251d054a..aa297d5031 100644 --- a/src/game/client/neo/ui/neo_root_serverbrowser.h +++ b/src/game/client/neo/ui/neo_root_serverbrowser.h @@ -38,11 +38,13 @@ enum ServerBlacklistCols // and SDK's blacklist read/write would collide if it's the same filename static constexpr const char SERVER_BLACKLIST_DEFFILE[] = "cfg/ntre_server_blacklist.txt"; +struct GameServerSortContext; + void ServerBlacklistRead(const char *szPath); void ServerBlacklistWrite(const char *szPath); void ServerBlacklistCacheWsz(ServerBlacklistInfo *sbInfo); bool ServerBlacklisted(const gameserveritem_t &server); -void ServerBlacklistUpdateSortedList(); +void ServerBlacklistUpdateSortedList(const GameServerSortContext& sortCtx); enum GameServerType { @@ -89,7 +91,11 @@ enum GameServerPlayerSort struct GameServerSortContext { - GameServerInfoW col = GSIW_NAME; + // NEO NOTE (Rain): this type is not GameServerInfoW anymore, because it may be treated as ServerBlacklistCols + // in the column sorting logic, and that would emit an error for the steamrt4 Clang 19 compiler for linux-debug build: + // error: comparison of different enumeration types in switch statement ('GameServerInfoW' and 'ServerBlacklistCols') + // Just always make sure col has a meaningful value for the context in which you evaluate it. + int col = GSIW_NAME; bool bDescending = false; }; From 0b860181e77a70f23d0d2fd19f5c30e29cb5d7dc Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 17:12:06 +0200 Subject: [PATCH 50/96] Qualify ->~T for nonvirtual CUtlVector cleanup For CUtlVector container cleanup, qualify all destructor calls for nonvirtual type T. Also statically assert that all contained elements of type T either are final, have a virtual destructor, or are nonpolymorphic, to catch most cases where the dtor of an inherited object might accidentally be invoked via a base class ptr (which would be UB). --- src/game/server/hl2/cbasehelicopter.h | 3 +++ src/game/server/vehicle_sounds.h | 6 ++++++ src/public/tier0/platform.h | 4 ++++ src/public/tier1/fmtstr.h | 3 +++ src/public/tier1/utlvector.h | 9 +++++++++ 5 files changed, 25 insertions(+) diff --git a/src/game/server/hl2/cbasehelicopter.h b/src/game/server/hl2/cbasehelicopter.h index 4ca3b091bf..d0bf462f10 100644 --- a/src/game/server/hl2/cbasehelicopter.h +++ b/src/game/server/hl2/cbasehelicopter.h @@ -55,6 +55,9 @@ enum HelicopterFlags_t // Wash physics pushing struct washentity_t +#ifdef NEO + final +#endif { DECLARE_DATADESC(); diff --git a/src/game/server/vehicle_sounds.h b/src/game/server/vehicle_sounds.h index 82557b9109..542d36aead 100644 --- a/src/game/server/vehicle_sounds.h +++ b/src/game/server/vehicle_sounds.h @@ -40,6 +40,9 @@ extern vehiclesound g_iSoundsToStopOnExit[NUM_SOUNDS_TO_STOP_ON_EXIT]; // Purpose: //----------------------------------------------------------------------------- struct vehicle_gear_t +#ifdef NEO + final +#endif { DECLARE_DATADESC(); @@ -49,6 +52,9 @@ struct vehicle_gear_t }; struct vehicle_crashsound_t +#ifdef NEO + final +#endif { DECLARE_DATADESC(); diff --git a/src/public/tier0/platform.h b/src/public/tier0/platform.h index 60ebde2f61..cf4570f40a 100644 --- a/src/public/tier0/platform.h +++ b/src/public/tier0/platform.h @@ -1599,6 +1599,10 @@ inline T* CopyConstruct( T* pMemory, T const& src ) template inline void Destruct( T* pMemory ) { +#ifdef NEO + if (!std::has_virtual_destructor_v) pMemory->T::~T(); + else +#endif pMemory->~T(); #ifdef _DEBUG diff --git a/src/public/tier1/fmtstr.h b/src/public/tier1/fmtstr.h index bcac9a264c..7ef8637b1d 100644 --- a/src/public/tier1/fmtstr.h +++ b/src/public/tier1/fmtstr.h @@ -78,6 +78,9 @@ template class CFmtStrN +#ifdef NEO + final +#endif { public: CFmtStrN() diff --git a/src/public/tier1/utlvector.h b/src/public/tier1/utlvector.h index b2622648fa..1ac63c681b 100644 --- a/src/public/tier1/utlvector.h +++ b/src/public/tier1/utlvector.h @@ -26,6 +26,10 @@ #include "tier1/strtools.h" #include "vstdlib/random.h" +#ifdef NEO +#include +#endif + #define FOR_EACH_VEC( vecName, iteratorName ) \ for ( int iteratorName = 0; (vecName).IsUtlVector && iteratorName < (vecName).Count(); iteratorName++ ) #define FOR_EACH_VEC_BACK( vecName, iteratorName ) \ @@ -49,6 +53,11 @@ struct base_vector_t template< class T, class A = CUtlMemory > class CUtlVector : public base_vector_t { +#ifdef NEO + static_assert(std::is_final_v || std::has_virtual_destructor_v || !std::is_polymorphic_v, + "Expecting all nonfinal contained elements of type T to either have a virtual destructor " + "or be nonpolymorphic, because deleting an object via nonvirtual dtor of a base ptr is UB."); +#endif typedef A CAllocator; public: typedef T ElemType_t; From 83e6bcfd2c3daca92ed1807e2b45abf5af797de4 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 17:25:06 +0200 Subject: [PATCH 51/96] fixup: qualify nonvirtual dtor calls --- src/public/tier0/platform.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/public/tier0/platform.h b/src/public/tier0/platform.h index cf4570f40a..2a8b5b1ece 100644 --- a/src/public/tier0/platform.h +++ b/src/public/tier0/platform.h @@ -38,6 +38,10 @@ #undef _XBOX #endif +#ifdef NEO +#include +#endif + #define __STDC_LIMIT_MACROS #include From cdf395ba0e1918cfaa03af89eba2fd43ccb5a74e Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 17:32:36 +0200 Subject: [PATCH 52/96] Fix operator typo bitwise OR -> logical OR --- src/game/server/ai_behavior_assault.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/server/ai_behavior_assault.cpp b/src/game/server/ai_behavior_assault.cpp index e02627cc60..98170cedce 100644 --- a/src/game/server/ai_behavior_assault.cpp +++ b/src/game/server/ai_behavior_assault.cpp @@ -1257,7 +1257,11 @@ int CAI_AssaultBehavior::TranslateSchedule( int scheduleType ) break; case SCHED_HOLD_RALLY_POINT: +#ifdef NEO + if( HasCondition(COND_NO_PRIMARY_AMMO) || HasCondition(COND_LOW_PRIMARY_AMMO) ) +#else if( HasCondition(COND_NO_PRIMARY_AMMO) | HasCondition(COND_LOW_PRIMARY_AMMO) ) +#endif { return SCHED_RELOAD; } From e48c688bcc968c5bf9dc99b57c3482f55e7f5242 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 17:35:15 +0200 Subject: [PATCH 53/96] Fix incorrect input args Assuming a random range was intended --- src/game/server/ai_behavior_standoff.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/server/ai_behavior_standoff.cpp b/src/game/server/ai_behavior_standoff.cpp index 7783d16251..447eeac756 100644 --- a/src/game/server/ai_behavior_standoff.cpp +++ b/src/game/server/ai_behavior_standoff.cpp @@ -239,7 +239,11 @@ CAI_StandoffBehavior::CAI_StandoffBehavior( CAI_BaseNPC *pOuter ) SetPosture( AIP_STANDING ); m_SavedDistTooFar = FLT_MAX; m_fForceNewEnemy = false; +#ifdef NEO + m_TimePreventForceNewEnemy.Set( RandomFloat( 3.0, 6.0 ) ); +#else m_TimePreventForceNewEnemy.Set( 3.0, 6.0 ); +#endif m_fIgnoreFronts = false; m_bHasLowCoverActivity = false; } From a40e545e29733d5928c0374e645a475adb28d177 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 17:45:50 +0200 Subject: [PATCH 54/96] Fix implicit-const-int-float-conversion --- src/game/server/ai_trackpather.cpp | 9 +++++++++ src/game/server/basecombatcharacter.cpp | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/src/game/server/ai_trackpather.cpp b/src/game/server/ai_trackpather.cpp index 18596c9a0e..77bc49c760 100644 --- a/src/game/server/ai_trackpather.cpp +++ b/src/game/server/ai_trackpather.cpp @@ -275,7 +275,11 @@ CPathTrack *CAI_TrackPather::BestPointOnPath( CPathTrack *pPath, const Vector &t // Find the nearest node to the target (going forward) CPathTrack *pNearestPath = NULL; +#ifdef NEO + float flNearestDist = bFarthestPoint ? 0 : 999999999.f; +#else float flNearestDist = bFarthestPoint ? 0 : 999999999; +#endif float flPathDist; float flFarthestDistSqr = ( m_flFarthestPathDist - 2.0f * m_flTargetDistanceThreshold ); @@ -800,8 +804,13 @@ CPathTrack *CAI_TrackPather::FindClosestPointOnPath( CPathTrack *pPath, // Find the nearest node to the target (going forward) CPathTrack *pNearestPath = NULL; +#ifdef NEO + float flNearestDist2D = 999999999.f; + float flNearestDist = 999999999.f; +#else float flNearestDist2D = 999999999; float flNearestDist = 999999999; +#endif float flPathDist, flPathDist2D; // NOTE: Gotta do it this crazy way because paths can be one-way. diff --git a/src/game/server/basecombatcharacter.cpp b/src/game/server/basecombatcharacter.cpp index afe2b114d5..2b532b0a9b 100644 --- a/src/game/server/basecombatcharacter.cpp +++ b/src/game/server/basecombatcharacter.cpp @@ -2179,8 +2179,13 @@ void CBaseCombatCharacter::Weapon_Equip( CBaseCombatWeapon *pWeapon ) // If SF_NPC_LONG_RANGE spawn flags is set let weapon work from any distance if ( HasSpawnFlags(SF_NPC_LONG_RANGE) ) { +#ifdef NEO + m_hActiveWeapon->m_fMaxRange1 = 999999999.f; + m_hActiveWeapon->m_fMaxRange2 = 999999999.f; +#else m_hActiveWeapon->m_fMaxRange1 = 999999999; m_hActiveWeapon->m_fMaxRange2 = 999999999; +#endif } } From 0160c2670dde29c955002cfe59299672ec4fb70c Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 17:52:52 +0200 Subject: [PATCH 55/96] Fix: tautological-undefined-compare --- src/game/server/baseentity.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/game/server/baseentity.cpp b/src/game/server/baseentity.cpp index 2c8aa2cdbb..59e2028f06 100644 --- a/src/game/server/baseentity.cpp +++ b/src/game/server/baseentity.cpp @@ -4237,8 +4237,15 @@ void CBaseEntity::ComputeWorldSpaceSurroundingBox( Vector *pMins, Vector *pMaxs //------------------------------------------------------------------------------ const char *CBaseEntity::GetDebugName(void) { +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wtautological-undefined-compare" +#endif if ( this == NULL ) return "<>"; +#if defined(NEO) && defined(COMPILER_CLANG) +#pragma clang diagnostic pop +#endif if ( m_iName != NULL_STRING ) { From f3530eb05f7e36d00aaaa6ab472a517e3622fbe6 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 19:35:16 +0200 Subject: [PATCH 56/96] Fix ambiguous operator== --- src/public/networkvar.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/public/networkvar.h b/src/public/networkvar.h index 9877e09381..199f3981f1 100644 --- a/src/public/networkvar.h +++ b/src/public/networkvar.h @@ -633,7 +633,14 @@ class CNetworkQuaternionBase : public CNetworkVarBase< Type, Changer > } }; - +#ifdef NEO + class CBaseCombatWeapon; + template< class Type, class Changer > + bool operator==(CBaseCombatWeapon* lhs, const CNetworkHandleBase& rhs) + { + return lhs == rhs.Get(); + } +#endif #define CNetworkHandle( type, name ) CNetworkHandleInternal( type, name, NetworkStateChanged ) From 4bcd6a03cc7b960b66572639ade9773622a0ca84 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 19:46:55 +0200 Subject: [PATCH 57/96] Fix warning about implicit float->bool conversion clang 14 -Wliteral-conversion --- src/public/soundflags.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/public/soundflags.h b/src/public/soundflags.h index a033942d5b..88d499a4da 100644 --- a/src/public/soundflags.h +++ b/src/public/soundflags.h @@ -105,7 +105,11 @@ enum soundlevel_t #define MAX_SNDLVL_VALUE ((1< 50) ? (20.0f / (float)(a - 50)) : 4.0 ) // This is a limit due to network encoding. From 5f26f47f7d31a563c4fc521152656065b25f0985 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 19:54:00 +0200 Subject: [PATCH 58/96] Fix bug with incorrect color rgba input args type --- src/game/server/hl2/grenade_bugbait.cpp | 4 ++++ src/game/server/hl2/weapon_bugbait.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/game/server/hl2/grenade_bugbait.cpp b/src/game/server/hl2/grenade_bugbait.cpp index 12e3dda128..625c400247 100644 --- a/src/game/server/hl2/grenade_bugbait.cpp +++ b/src/game/server/hl2/grenade_bugbait.cpp @@ -165,7 +165,11 @@ void CGrenadeBugBait::BugBaitTouch( CBaseEntity *pOther ) pSporeExplosion->SetLocalOrigin( GetAbsOrigin() ); pSporeExplosion->m_flSpawnRate = 8.0f; pSporeExplosion->m_flParticleLifetime = 2.0f; +#ifdef NEO + pSporeExplosion->SetRenderColor( 255 * 0.0f, 255 * 0.5f, 255 * 0.25f, 255 * 0.15f ); +#else pSporeExplosion->SetRenderColor( 0.0f, 0.5f, 0.25f, 0.15f ); +#endif pSporeExplosion->m_flStartSize = 32.0f; pSporeExplosion->m_flEndSize = 64.0f; diff --git a/src/game/server/hl2/weapon_bugbait.cpp b/src/game/server/hl2/weapon_bugbait.cpp index 38c02239e2..a0e4308872 100644 --- a/src/game/server/hl2/weapon_bugbait.cpp +++ b/src/game/server/hl2/weapon_bugbait.cpp @@ -168,7 +168,11 @@ void CWeaponBugBait::Drop( const Vector &vecVelocity ) pSporeExplosion->m_flSpawnRate = 16.0f; pSporeExplosion->m_flParticleLifetime = 0.5f; +#ifdef NEO + pSporeExplosion->SetRenderColor( 255 * 0.0f, 255 * 0.5f, 255 * 0.25f, 255 * 0.15f ); +#else pSporeExplosion->SetRenderColor( 0.0f, 0.5f, 0.25f, 0.15f ); +#endif pSporeExplosion->m_flStartSize = 32; pSporeExplosion->m_flEndSize = 48; From 3b012efd5ed3189e20dc4a2a9f9955d6475f6794 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 19:54:25 +0200 Subject: [PATCH 59/96] Fix operator bug with bitflag check Logical to bitwise AND --- src/game/server/nav_mesh.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/server/nav_mesh.cpp b/src/game/server/nav_mesh.cpp index 62e41064e1..299bf76ff3 100644 --- a/src/game/server/nav_mesh.cpp +++ b/src/game/server/nav_mesh.cpp @@ -808,7 +808,11 @@ CNavArea *CNavMesh::GetNavArea( CBaseEntity *pEntity, int nFlags, float flBeneat } // Check LOS if necessary +#ifdef NEO + if ( use && ( nFlags & GETNAVAREA_CHECK_LOS ) && ( useZ < testPos.z - flStepHeight ) ) +#else if ( use && ( nFlags && GETNAVAREA_CHECK_LOS ) && ( useZ < testPos.z - flStepHeight ) ) +#endif { // trace directly down to see if it's below us and unobstructed trace_t result; From 9d58e1e61c660ab40b7e3646e2fd012da7dc498e Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 19:56:35 +0200 Subject: [PATCH 60/96] Fix bad ptr compare --- src/game/server/hl2/npc_BaseZombie.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/server/hl2/npc_BaseZombie.cpp b/src/game/server/hl2/npc_BaseZombie.cpp index a4384f03ea..de86ee79f6 100644 --- a/src/game/server/hl2/npc_BaseZombie.cpp +++ b/src/game/server/hl2/npc_BaseZombie.cpp @@ -1628,7 +1628,11 @@ void CNPC_BaseZombie::HandleAnimEvent( animevent_t *pEvent ) pString = nexttoken( token, pString, ' ' ); +#ifdef NEO + if (!*token) +#else if ( *token == NULL ) +#endif { Warning( "AE_ZOMBIE_POPHEADCRAB event format missing velocity parameter! Usage: event AE_ZOMBIE_POPHEADCRAB \" \" \n" ); return; From df398c9faa882223d54500925d7d291a8e14003b Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 20:08:05 +0200 Subject: [PATCH 61/96] fix self-assign warning -Wself-assign-field --- src/game/server/hl2/npc_scanner.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/game/server/hl2/npc_scanner.cpp b/src/game/server/hl2/npc_scanner.cpp index be3943b8a8..2cc4f204d2 100644 --- a/src/game/server/hl2/npc_scanner.cpp +++ b/src/game/server/hl2/npc_scanner.cpp @@ -1727,7 +1727,9 @@ Vector CNPC_CScanner::SpotlightCurrentPos(void) // Calculate new beam direction // ------------------------------ m_vSpotlightDir = m_vSpotlightDir + m_vSpotlightAngVelocity; +#ifndef NEO m_vSpotlightDir = m_vSpotlightDir; +#endif VectorNormalize(m_vSpotlightDir); From ddd0714f8f8ff6756834aa2320adbd90a44f7175 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 20:09:09 +0200 Subject: [PATCH 62/96] Fix bad float->int conversion --- src/game/server/hl2mp/grenade_tripmine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/server/hl2mp/grenade_tripmine.cpp b/src/game/server/hl2mp/grenade_tripmine.cpp index b0e8d3b1bb..8b942911ef 100644 --- a/src/game/server/hl2mp/grenade_tripmine.cpp +++ b/src/game/server/hl2mp/grenade_tripmine.cpp @@ -195,7 +195,11 @@ void CTripmineGrenade::MakeBeam( void ) m_pBeam = CBeam::BeamCreate( g_pModelNameLaser, 0.35 ); m_pBeam->PointEntInit( vecTmpEnd, this ); m_pBeam->SetColor( 255, 55, 52 ); +#ifdef NEO + m_pBeam->SetScrollRate(26); +#else m_pBeam->SetScrollRate( 25.6 ); +#endif m_pBeam->SetBrightness( 64 ); int beamAttach = LookupAttachment("beam_attach"); From 0d083736e4d76db204b2e8a178744ceb7f10fbf4 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 20:09:33 +0200 Subject: [PATCH 63/96] Clean redundant lambda capture --- src/game/server/neo/neo_player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/server/neo/neo_player.cpp b/src/game/server/neo/neo_player.cpp index 29e027c611..65459cb543 100644 --- a/src/game/server/neo/neo_player.cpp +++ b/src/game/server/neo/neo_player.cpp @@ -4044,7 +4044,7 @@ static void BotChangeClassFn(const CCommand& args) constexpr int minValue = NEO_CLASS_RECON; constexpr int maxValue = NEO_CLASS_LOADOUTABLE_COUNT - 1; - const auto nag = [&args, minValue, maxValue]() { + const auto nag = [&args]() { Msg("Format: %s \n", args.Arg(0), minValue, maxValue); }; From 8bfb8f648239c7c5f9fd64f5804045cc9dbfbe5f Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 21:44:54 +0200 Subject: [PATCH 64/96] Fix operator precedence --- src/game/server/NextBot/Path/NextBotPath.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/game/server/NextBot/Path/NextBotPath.cpp b/src/game/server/NextBot/Path/NextBotPath.cpp index 4514887cce..02ced4b052 100644 --- a/src/game/server/NextBot/Path/NextBotPath.cpp +++ b/src/game/server/NextBot/Path/NextBotPath.cpp @@ -262,7 +262,11 @@ bool Path::ComputePathDetails( INextBot *bot, const Vector &start ) if ( from->how != NUM_TRAVERSE_TYPES && from->how > GO_WEST ) continue; +#ifdef NEO + if ( to->how > GO_WEST || to->type != ON_GROUND ) +#else if ( to->how > GO_WEST || !to->type == ON_GROUND ) +#endif continue; // if areas are separated, we may need to 'gap jump' between them @@ -589,7 +593,11 @@ int Path::FindNextOccludedNode( INextBot *bot, int anchorIndex ) Segment *to = &m_path[i]; // if this segment is not on the ground, or is precise, don't skip past it +#ifdef NEO + if ( to->type != ON_GROUND || (to->area->GetAttributes() & NAV_MESH_PRECISE) ) +#else if ( !to->type == ON_GROUND || (to->area->GetAttributes() & NAV_MESH_PRECISE) ) +#endif { return i; } From e1865401c8fb78338088a796e0d71e332e50f396 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 17 Dec 2025 22:09:39 +0200 Subject: [PATCH 65/96] Suppress VMT overwrite warning --- src/public/tier1/utlvector.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/public/tier1/utlvector.h b/src/public/tier1/utlvector.h index 1ac63c681b..9a7d71257c 100644 --- a/src/public/tier1/utlvector.h +++ b/src/public/tier1/utlvector.h @@ -1314,7 +1314,11 @@ void CUtlVector::FastRemove( int elem ) if (m_Size > 0) { if ( elem != m_Size -1 ) +#ifdef NEO + memcpy( (void*)&Element(elem), (void*)&Element(m_Size - 1), sizeof(T)); +#else memcpy( &Element(elem), &Element(m_Size-1), sizeof(T) ); +#endif --m_Size; } } From 7de13f3d549ab03d51dedae4c1f557460d048722 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 20 Dec 2025 09:19:11 +0200 Subject: [PATCH 66/96] Fix literal to nullptr comparison warning --- src/public/tier1/utlsymbol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public/tier1/utlsymbol.h b/src/public/tier1/utlsymbol.h index 5e2def8747..ba5189eca5 100644 --- a/src/public/tier1/utlsymbol.h +++ b/src/public/tier1/utlsymbol.h @@ -240,7 +240,7 @@ typedef void* FileNameHandle_t; #define FILENAMEHANDLE_INVALID 0 #ifdef NEO // These are used interchangeably elsewhere in the code base, so changing the constant could cause breakage. -static_assert(FILENAMEHANDLE_INVALID == NULL); +static_assert(bool(FILENAMEHANDLE_INVALID) == bool(NULL)); #endif // Symbol table for more efficiently storing filenames by breaking paths and filenames apart. From a7b134f1d1e0bcf1d717588f91d0acd00ae7914c Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 19 Dec 2025 01:19:47 +0200 Subject: [PATCH 67/96] Fix linker error --- src/game/client/cdll_client_int.cpp | 4 +++- src/public/mathlib/mathlib.h | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/game/client/cdll_client_int.cpp b/src/game/client/cdll_client_int.cpp index c1ae3a749f..61635eecdc 100644 --- a/src/game/client/cdll_client_int.cpp +++ b/src/game/client/cdll_client_int.cpp @@ -939,10 +939,12 @@ int CHLClient::Init( CreateInterfaceFn appSystemFactory, CreateInterfaceFn physi { InitCRTMemDebug(); MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); -#if defined(NEO) && defined(DBGFLAG_ASSERT) +#if defined(NEO) +#if defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT) Assert(s_bMathlibInitialized); ValidateFastFuncs(); #endif +#endif #ifdef SIXENSE diff --git a/src/public/mathlib/mathlib.h b/src/public/mathlib/mathlib.h index e0baa0e66b..87d569e330 100644 --- a/src/public/mathlib/mathlib.h +++ b/src/public/mathlib/mathlib.h @@ -2152,8 +2152,8 @@ float FastLog2(float i); // log2( i ) float FastPow2(float i); // 2^i float FastPow(float a, float b); // a^b float FastPow10( float i ); // 10^i -#if defined(NEO) && defined(DBGFLAG_ASSERT) -void ValidateFastFuncs(); +#if defined(NEO) && defined(ACTUALLY_COMPILER_MSVC) && defined(DBGFLAG_ASSERT) +extern void ValidateFastFuncs(); #endif //----------------------------------------------------------------------------- From b92da87e71a8c8f142bc4ff04e9cee1028870c63 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 20 Dec 2025 20:59:50 +0200 Subject: [PATCH 68/96] Use crash intrinsics --- src/public/dt_utlvector_recv.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/public/dt_utlvector_recv.cpp b/src/public/dt_utlvector_recv.cpp index 3198d9f6d6..1cd2b538b0 100644 --- a/src/public/dt_utlvector_recv.cpp +++ b/src/public/dt_utlvector_recv.cpp @@ -37,7 +37,19 @@ void RecvProxy_UtlVectorLength( const CRecvProxyData *pData, void *pStruct, void // There isn't much we can do at this point - we're deep in the networking stack, it's hard to recover // gracefully and we shouldn't be talking to this server anymore. // So we crash. +#ifdef NEO +#ifdef ACTUALLY_COMPILER_MSVC + __fastfail(8); +#elif defined(COMPILER_GCC) || defined(COMPILER_CLANG) + __builtin_trap(); +#else +#error No compiler instrinsic defined *(int *) 1 = 2; +#endif + return; +#else + *(int *) 1 = 2; +#endif } pExtra->m_ResizeFn( pStruct, pExtra->m_Offset, pData->m_Value.m_Int ); } From c36dcea652f4806e9d4623dfd5d0584ae3f06852 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 20 Dec 2025 21:00:08 +0200 Subject: [PATCH 69/96] Clang 19 warning suppression compat --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 92ebedcb2d..eeb5985cf5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -321,7 +321,7 @@ if(OS_LINUX OR OS_MACOS) -Wno-multichar -Wno-write-strings -Wno-unused-variable - -Wno-unused-but-set-variable + $<$:-Wno-unused-but-set-variable> -Wno-unused-function -Wno-unknown-pragmas -Wno-unused-parameter From 5ee85b8a6290f7d692d39f323b61f8721e445a4a Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 20 Dec 2025 21:55:35 +0200 Subject: [PATCH 70/96] Check for nullptr from GetPlayerNetInfo --- src/game/server/neo/neo_dm_spawn.cpp | 8 ++++-- src/game/shared/neo/neo_gamerules.cpp | 41 ++++++++++++++------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/game/server/neo/neo_dm_spawn.cpp b/src/game/server/neo/neo_dm_spawn.cpp index f6ccfb2b99..e1fe2a4d2a 100644 --- a/src/game/server/neo/neo_dm_spawn.cpp +++ b/src/game/server/neo/neo_dm_spawn.cpp @@ -60,9 +60,13 @@ static CNEO_Player *LoopbackPlayer() continue; } INetChannelInfo *nci = engine->GetPlayerNetInfo(i); - if (nci->IsLoopback()) + Assert(nci); + if (nci) { - return pPlayer; + if (nci->IsLoopback()) + { + return pPlayer; + } } } return nullptr; diff --git a/src/game/shared/neo/neo_gamerules.cpp b/src/game/shared/neo/neo_gamerules.cpp index f48d41d0fc..8d9f512ff0 100644 --- a/src/game/shared/neo/neo_gamerules.cpp +++ b/src/game/shared/neo/neo_gamerules.cpp @@ -2559,29 +2559,32 @@ void CNEORules::StartNextRound() const bool bBotsonlyDontDoWarmup = !sv_neo_botsonly_warmup_round.GetBool(); if (bLoopbackDontDoWarmup || bBotsonlyDontDoWarmup) { - int iCountBots = 0; - int iCountHumans = 0; - int iCountLoopback = 0; + int iCountBots = 0, iCountHumans = 0, iCountLoopback = 0; for (int i = 1; i <= gpGlobals->maxClients; i++) { - if (auto* pPlayer = static_cast(UTIL_PlayerByIndex(i))) - { - const int teamNum = pPlayer->GetTeamNumber(); - if (teamNum == TEAM_JINRAI || teamNum == TEAM_NSF) - { - const bool bIsBot = pPlayer->IsBot(); - const bool bIsHuman = (!bIsBot && !pPlayer->IsHLTV()); - iCountBots += bIsBot; - iCountHumans += bIsHuman; - if (bIsHuman) - { - INetChannelInfo* nci = engine->GetPlayerNetInfo(i); - iCountLoopback += nci->IsLoopback(); - } - } - } + auto* pPlayer = static_cast(UTIL_PlayerByIndex(i)); + if (!pPlayer) + continue; + + const int teamNum = pPlayer->GetTeamNumber(); + if (teamNum <= LAST_SHARED_TEAM) + continue; + + const bool bIsBot = pPlayer->IsBot(); + const bool bIsHuman = (!bIsBot && !pPlayer->IsHLTV()); + Assert(bIsBot || bIsHuman); + iCountBots += bIsBot; + iCountHumans += bIsHuman; + if (!bIsHuman) + continue; + + if (auto* nci = engine->GetPlayerNetInfo(i)) + iCountLoopback += nci->IsLoopback(); + else + Assert(false); } + if (bLoopbackDontDoWarmup) { loopbackSkipWarmup = (iCountLoopback > 0 && iCountLoopback == iCountHumans); From d25b8aa423c266715d5dec07fda0703203d8f0d5 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 20 Dec 2025 22:44:30 +0200 Subject: [PATCH 71/96] Fix threadtools regression --- src/public/tier0/threadtools.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/public/tier0/threadtools.h b/src/public/tier0/threadtools.h index e7563dfde2..81daaf93ee 100644 --- a/src/public/tier0/threadtools.h +++ b/src/public/tier0/threadtools.h @@ -688,12 +688,23 @@ class PLATFORM_CLASS CThreadLocalBase void Set(T val) { +#ifdef PLATFORM_64BITS + void* pData = 0; #ifdef NEO - CThreadLocalBase::Set(reinterpret_cast(&val)); + static_assert(sizeof(T) == sizeof(void*)); +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + *reinterpret_cast(&pData) = val; + void* sdkRet = pData; + memset(&pData, 0x42, sizeof(pData)); +#endif + memcpy(&pData, &val, sizeof(pData)); +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) + void* neoRet = pData; + Assert(neoRet == sdkRet); +#endif #else -#ifdef PLATFORM_64BITS - void *pData = 0; *reinterpret_cast( &pData ) = val; +#endif CThreadLocalBase::Set( pData ); #else #ifdef COMPILER_MSVC @@ -703,7 +714,6 @@ class PLATFORM_CLASS CThreadLocalBase #ifdef COMPILER_MSVC #pragma warning ( default : 4312 ) #endif -#endif #endif } }; From 3489d61987774b35a8dcc38ebebb34cf76862e8d Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 24 Dec 2025 09:29:35 +0200 Subject: [PATCH 72/96] Nontrivial memcpy --- src/game/client/c_baseanimating.cpp | 21 +++++ src/game/client/c_prop_vehicle.cpp | 4 + src/game/client/c_soundscape.cpp | 21 +++++ src/game/client/c_vehicle_choreo_generic.cpp | 4 + src/game/client/fx_impact.cpp | 12 +++ src/game/client/game_controls/MapOverview.cpp | 20 ++++ src/game/client/history_resource.cpp | 4 + src/game/client/history_resource.h | 23 +++++ src/game/client/hl2/c_vehicle_cannon.cpp | 4 + src/game/client/hl2/c_vehicle_crane.cpp | 4 + .../client/hl2/c_vehicle_prisoner_pod.cpp | 4 + src/game/client/particlemgr.cpp | 13 +++ src/game/client/particlesphererenderer.cpp | 25 +++++ src/game/client/physics.cpp | 11 +++ src/game/client/prediction.cpp | 32 +++++++ src/game/client/viewrender.cpp | 58 ++++++++++++ src/game/server/ai_basenpc.cpp | 31 +++++++ src/game/server/ai_behavior_follow.cpp | 46 ++++++++++ src/game/server/ai_blended_movement.h | 19 ++++ src/game/server/ai_hint.cpp | 26 ++++++ src/game/server/ai_localnavigator.cpp | 34 +++++++ src/game/server/ai_motor.cpp | 11 +++ src/game/server/ai_movetypes.h | 46 ++++++++++ src/game/server/ai_waypoint.cpp | 31 +++++++ src/game/server/ai_waypoint.h | 36 ++++++++ src/game/server/physics.cpp | 8 ++ src/game/server/smokestack.cpp | 32 +++++++ src/game/server/util.cpp | 8 ++ src/game/server/vehicle_base.cpp | 25 +++++ src/game/shared/particlesystemquery.cpp | 15 +++ src/game/shared/physics_saverestore.cpp | 30 ++++++ src/game/shared/physics_shared.cpp | 20 ++++ src/game/shared/saverestore.cpp | 7 ++ src/game/shared/sheetsimulator.cpp | 28 ++++++ src/game/shared/util_shared.cpp | 10 ++ src/game/shared/vehicle_viewblend_shared.h | 39 ++++++++ .../stdshaders/BaseVSShader.cpp | 20 ++++ src/public/SoundParametersInternal.cpp | 8 ++ src/public/bitvec.h | 15 +++ src/public/bone_setup.cpp | 54 +++++++++++ src/public/bone_setup.h | 20 ++++ src/public/dt_send.cpp | 4 +- src/public/mathlib/simdvectormatrix.h | 35 +++++++ src/public/saverestoretypes.h | 24 +++++ src/public/sentence.cpp | 9 ++ src/public/sentence.h | 22 +++++ src/public/studio.h | 92 +++++++++++++++++++ src/public/vcollide_parse.h | 27 ++++++ src/public/vphysics_interface.h | 18 ++++ 49 files changed, 1109 insertions(+), 1 deletion(-) diff --git a/src/game/client/c_baseanimating.cpp b/src/game/client/c_baseanimating.cpp index 5e9b73c0ed..fae4565098 100644 --- a/src/game/client/c_baseanimating.cpp +++ b/src/game/client/c_baseanimating.cpp @@ -63,6 +63,8 @@ #ifdef NEO #include "c_neo_player.h" + +#include #endif // memdbgon must be the last include file in a .cpp file!!! @@ -1789,6 +1791,25 @@ void C_BaseAnimating::SaveRagdollInfo( int numbones, const matrix3x4_t &cameraTr Msg( "Memory allocation of RagdollInfo_t failed!\n" ); return; } +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_same_v>); + static_assert(sizeof(RagdollInfo_t) == 3596, "update this zero-init code if you changed the layout!"); + m_pRagdollInfo->m_bActive = {}; + m_pRagdollInfo->m_flSaveTime = {}; + m_pRagdollInfo->m_nNumBones = {}; + for (int i = 0; i < ARRAYSIZE(m_pRagdollInfo->m_rgBonePos); ++i) + { + m_pRagdollInfo->m_rgBonePos[i].Zero(); + } + for (int i = 0; i < ARRAYSIZE(m_pRagdollInfo->m_rgBoneQuaternion); ++i) + { + m_pRagdollInfo->m_rgBoneQuaternion[i].Init(); + } + } + else +#endif memset( m_pRagdollInfo, 0, sizeof( *m_pRagdollInfo ) ); } diff --git a/src/game/client/c_prop_vehicle.cpp b/src/game/client/c_prop_vehicle.cpp index d093656fff..50139b7889 100644 --- a/src/game/client/c_prop_vehicle.cpp +++ b/src/game/client/c_prop_vehicle.cpp @@ -72,7 +72,11 @@ C_PropVehicleDriveable::C_PropVehicleDriveable() : { m_hPrevPlayer = NULL; +#ifdef NEO + ZeroViewSmoothingData(m_ViewSmoothingData); +#else memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) ); +#endif m_ViewSmoothingData.pVehicle = this; m_ViewSmoothingData.bClampEyeAngles = true; diff --git a/src/game/client/c_soundscape.cpp b/src/game/client/c_soundscape.cpp index 82586dc02c..1a6cb0ac55 100644 --- a/src/game/client/c_soundscape.cpp +++ b/src/game/client/c_soundscape.cpp @@ -16,6 +16,12 @@ #include "engine/ivdebugoverlay.h" #include "tier0/icommandline.h" +#ifdef NEO +#include "interval.h" // Do not remove this include!! See comment "bad include order" below in this file for reasoning + +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -59,6 +65,21 @@ struct randomsound_t void Init() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(*this) == 72, "update the Init code if you changed this layout!"); + static_assert(std::is_trivially_copyable_v && std::is_default_constructible_v); + + position.Zero(); + nextPlayTime = masterVolume = {}; + time = volume = pitch = soundlevel = {}; + waveCount = {}; + isAmbient = isRandom = {}; + pWaves = {}; + } + else +#endif memset( this, 0, sizeof(*this) ); } }; diff --git a/src/game/client/c_vehicle_choreo_generic.cpp b/src/game/client/c_vehicle_choreo_generic.cpp index 52eba09e12..b1b68c520b 100644 --- a/src/game/client/c_vehicle_choreo_generic.cpp +++ b/src/game/client/c_vehicle_choreo_generic.cpp @@ -119,7 +119,11 @@ END_DATADESC() //----------------------------------------------------------------------------- C_PropVehicleChoreoGeneric::C_PropVehicleChoreoGeneric( void ) { +#ifdef NEO + ZeroViewSmoothingData(m_ViewSmoothingData); +#else memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) ); +#endif m_ViewSmoothingData.pVehicle = this; m_ViewSmoothingData.flPitchCurveZero = PITCH_CURVE_ZERO; diff --git a/src/game/client/fx_impact.cpp b/src/game/client/fx_impact.cpp index 0f3868f7a0..65fb4d62e5 100644 --- a/src/game/client/fx_impact.cpp +++ b/src/game/client/fx_impact.cpp @@ -18,6 +18,10 @@ #include "c_impact_effects.h" #include "tier0/vprof.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -106,6 +110,14 @@ bool Impact( Vector &vecOrigin, Vector &vecStart, int iMaterial, int iDamageType Assert ( pEntity ); // Clear out the trace +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_default_constructible_v); + tr = {}; + } + else +#endif memset( &tr, 0, sizeof(trace_t)); tr.fraction = 1.0f; diff --git a/src/game/client/game_controls/MapOverview.cpp b/src/game/client/game_controls/MapOverview.cpp index ff6215e893..ba9608a3a6 100644 --- a/src/game/client/game_controls/MapOverview.cpp +++ b/src/game/client/game_controls/MapOverview.cpp @@ -23,6 +23,10 @@ #include "clientmode.h" #include +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -760,6 +764,22 @@ void CMapOverview::DrawMapPlayers() // convert from PlayerObject_t MapObject_t tempObj; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(tempObj) == 104); + tempObj.objectID = tempObj.index = tempObj.icon = {}; + tempObj.color.SetColor(0, 0, 0, 0); + tempObj.name[0] = '\0'; + tempObj.position.Zero(); + tempObj.angle.Init(); + tempObj.endtime = tempObj.size = tempObj.status = {}; + tempObj.statusColor.SetColor(0, 0, 0, 0); + tempObj.flags = {}; + tempObj.text = {}; + } + else +#endif memset( &tempObj, 0, sizeof(MapObject_t) ); tempObj.icon = player->icon; tempObj.position = player->position; diff --git a/src/game/client/history_resource.cpp b/src/game/client/history_resource.cpp index c0743b4100..9d397464b5 100644 --- a/src/game/client/history_resource.cpp +++ b/src/game/client/history_resource.cpp @@ -314,7 +314,11 @@ void CHudHistoryResource::Paint( void ) if ( m_PickupHistory[i].DisplayTime <= gpGlobals->curtime ) { // pic drawing time has expired +#ifdef NEO + ZeroHistItem(m_PickupHistory[i]); +#else memset( &m_PickupHistory[i], 0, sizeof(HIST_ITEM) ); +#endif CheckClearHistory(); continue; } diff --git a/src/game/client/history_resource.h b/src/game/client/history_resource.h index 2dab6bde42..1a3e4bad44 100644 --- a/src/game/client/history_resource.h +++ b/src/game/client/history_resource.h @@ -14,6 +14,10 @@ #include +#ifdef NEO +#include +#endif + enum { HISTSLOT_EMPTY, @@ -54,6 +58,25 @@ class CHudHistoryResource : public CHudElement, public vgui::Panel CHudTexture *icon; }; +#ifdef NEO + static void ZeroHistItem(HIST_ITEM& item) + { + if constexpr (std::is_trivially_constructible_v) + { + memset( &item, 0, sizeof(HIST_ITEM) ); + } + else + { + item.type = {}; + item.DisplayTime = {}; + item.iCount = item.iId = {}; + static_assert(std::is_default_constructible_v); + item.m_hWeapon = {}; + item.icon = {}; + } + } +#endif + CUtlVector m_PickupHistory; public: diff --git a/src/game/client/hl2/c_vehicle_cannon.cpp b/src/game/client/hl2/c_vehicle_cannon.cpp index 74e49ce684..100762071c 100644 --- a/src/game/client/hl2/c_vehicle_cannon.cpp +++ b/src/game/client/hl2/c_vehicle_cannon.cpp @@ -104,7 +104,11 @@ END_DATADESC() //----------------------------------------------------------------------------- C_PropCannon::C_PropCannon( void ) { +#ifdef NEO + ZeroViewSmoothingData(m_ViewSmoothingData); +#else memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) ); +#endif m_ViewSmoothingData.pVehicle = this; } diff --git a/src/game/client/hl2/c_vehicle_crane.cpp b/src/game/client/hl2/c_vehicle_crane.cpp index 933bef8167..af4a8c9ac3 100644 --- a/src/game/client/hl2/c_vehicle_crane.cpp +++ b/src/game/client/hl2/c_vehicle_crane.cpp @@ -44,7 +44,11 @@ END_DATADESC() //----------------------------------------------------------------------------- C_PropCrane::C_PropCrane( void ) { +#ifdef NEO + ZeroViewSmoothingData(m_ViewSmoothingData); +#else memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) ); +#endif m_ViewSmoothingData.pVehicle = this; m_ViewSmoothingData.flFOV = CRANE_FOV; } diff --git a/src/game/client/hl2/c_vehicle_prisoner_pod.cpp b/src/game/client/hl2/c_vehicle_prisoner_pod.cpp index 1b78bddab8..41ee7fd8d0 100644 --- a/src/game/client/hl2/c_vehicle_prisoner_pod.cpp +++ b/src/game/client/hl2/c_vehicle_prisoner_pod.cpp @@ -113,7 +113,11 @@ END_DATADESC() //----------------------------------------------------------------------------- C_PropVehiclePrisonerPod::C_PropVehiclePrisonerPod( void ) { +#ifdef NEO + ZeroViewSmoothingData(m_ViewSmoothingData); +#else memset( &m_ViewSmoothingData, 0, sizeof( m_ViewSmoothingData ) ); +#endif m_ViewSmoothingData.pVehicle = this; m_ViewSmoothingData.bClampEyeAngles = true; diff --git a/src/game/client/particlemgr.cpp b/src/game/client/particlemgr.cpp index a0d4a335ed..6e9f5c1716 100644 --- a/src/game/client/particlemgr.cpp +++ b/src/game/client/particlemgr.cpp @@ -29,6 +29,9 @@ #ifdef TF_CLIENT_DLL #include "rtime.h" #endif +#ifdef NEO +#include +#endif #include "tier0/icommandline.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1065,6 +1068,16 @@ CParticleMgr::CParticleMgr() m_pMaterialSystem = NULL; m_pThreadPool[0] = 0; m_pThreadPool[1] = 0; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(m_DirectionalLight) == 28, "please update this zero-init logic for new data"); + m_DirectionalLight.m_flIntensity = {}; + m_DirectionalLight.m_vColor.Zero(); + m_DirectionalLight.m_vPos.Zero(); + } + else +#endif memset( &m_DirectionalLight, 0, sizeof( m_DirectionalLight ) ); m_FrameCode = 1; diff --git a/src/game/client/particlesphererenderer.cpp b/src/game/client/particlesphererenderer.cpp index f995ee1343..f140b50675 100644 --- a/src/game/client/particlesphererenderer.cpp +++ b/src/game/client/particlesphererenderer.cpp @@ -8,14 +8,39 @@ #include "particlesphererenderer.h" #include "materialsystem/imaterialvar.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" CParticleSphereRenderer::CParticleSphereRenderer() { m_vBaseColor.Init(); +#ifdef NEO + static_assert(std::is_same_v< + decltype(m_AmbientLight), decltype(m_DirectionalLight)>); + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(m_AmbientLight) == 28); + + m_AmbientLight.m_flIntensity = {}; + m_AmbientLight.m_vColor.Zero(); + m_AmbientLight.m_vPos.Zero(); + + m_DirectionalLight.m_flIntensity = {}; + m_DirectionalLight.m_vColor.Zero(); + m_DirectionalLight.m_vPos.Zero(); + } + else + { +#endif memset( &m_AmbientLight, 0, sizeof( m_AmbientLight ) ); memset( &m_DirectionalLight, 0, sizeof( m_DirectionalLight ) ); +#ifdef NEO + } +#endif m_bUsingPixelShaders = false; m_iLastTickStartRenderCalled = -1; diff --git a/src/game/client/physics.cpp b/src/game/client/physics.cpp index 15d292b4e4..30cbbbe309 100644 --- a/src/game/client/physics.cpp +++ b/src/game/client/physics.cpp @@ -23,6 +23,9 @@ #include "fx_water.h" #include "positionwatcher.h" #include "vphysics/constraints.h" +#ifdef NEO +#include +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -612,6 +615,14 @@ void CCollisionEvent::StartTouch( IPhysicsObject *pObject1, IPhysicsObject *pObj void CCollisionEvent::DispatchStartTouch( C_BaseEntity *pEntity0, C_BaseEntity *pEntity1, const Vector &point, const Vector &normal ) { trace_t trace; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_default_constructible_v); + trace = {}; + } + else +#endif memset( &trace, 0, sizeof(trace) ); trace.endpos = point; trace.plane.dist = DotProduct( point, normal ); diff --git a/src/game/client/prediction.cpp b/src/game/client/prediction.cpp index 58ed195d1f..ad30a24bbb 100644 --- a/src/game/client/prediction.cpp +++ b/src/game/client/prediction.cpp @@ -25,6 +25,10 @@ #include "c_basehlplayer.h" #endif +#ifdef NEO +#include +#endif + #include "tier0/vprof.h" // memdbgon must be the last include file in a .cpp file!!! @@ -164,6 +168,34 @@ void CPrediction::CheckError( int commands_acknowledged ) Vector predicted_origin; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + memcpy( predicted_origin.Base(), (Vector*)((byte*)slot + td->fieldOffset[PC_DATA_PACKED]), sizeof(Vector)); +#ifdef DBGFLAG_ASSERT + constexpr bool paranoid = false; + if constexpr (paranoid) + { + Assert((void*)& predicted_origin == (void*)predicted_origin.Base()); + + void* tmpNeoRes = malloc(sizeof(Vector)); + Assert(tmpNeoRes); + memcpy(tmpNeoRes, predicted_origin.Base(), sizeof(Vector)); + + memcpy( (Vector *)&predicted_origin, (Vector *)( (byte *)slot + td->fieldOffset[ PC_DATA_PACKED ] ), sizeof( Vector ) ); + void* sdkRes = (void*)&predicted_origin; + Assert(tmpNeoRes != sdkRes); + Assert(((Vector*)tmpNeoRes)->IsValid() == ((Vector*)sdkRes)->IsValid()); + if (((Vector*)tmpNeoRes)->IsValid()) + Assert(*((Vector*)tmpNeoRes) == *(Vector*)sdkRes); + Assert(0 == memcmp(tmpNeoRes, sdkRes, sizeof(Vector))); + + free(tmpNeoRes); + } +#endif + } + else +#endif memcpy( (Vector *)&predicted_origin, (Vector *)( (byte *)slot + td->fieldOffset[ PC_DATA_PACKED ] ), sizeof( Vector ) ); // Compare what the server returned with what we had predicted it to be diff --git a/src/game/client/viewrender.cpp b/src/game/client/viewrender.cpp index 07daeecf0d..bb1d607325 100644 --- a/src/game/client/viewrender.cpp +++ b/src/game/client/viewrender.cpp @@ -67,6 +67,7 @@ #endif #ifdef NEO #include "neo_player_shared.h" +#include #endif // NEO #include "rendertexture.h" #include "viewpostprocess.h" @@ -3554,7 +3555,64 @@ CRendering3dView::CRendering3dView(CViewRender *pMainView) : void CRendering3dView::Setup( const CViewSetup &setup ) { // @MULTICORE (toml 8/15/2006): don't reset if parameters don't require it. For now, just reset +#ifdef NEO + // NEO NOTE (Rain): not a trivial copy, so we have this wonderful macro +#pragma push_macro("COPYVALS") +#pragma push_macro("X") +#undef COPYVALS +#undef X +#define COPYVALS \ + X(x) \ + X(m_nUnscaledX) \ + X(y) \ + X(m_nUnscaledY) \ + X(width) \ + X(m_nUnscaledWidth) \ + X(height) \ + X(m_eStereoEye) \ + X(m_nUnscaledHeight) \ + X(m_bOrtho) \ + X(m_OrthoLeft) \ + X(m_OrthoTop) \ + X(m_OrthoRight) \ + X(m_OrthoBottom) \ + X(fov) \ + X(fovViewmodel) \ + X(origin) \ + X(angles) \ + X(zNear) \ + X(zFar) \ + X(zNearViewmodel) \ + X(zFarViewmodel) \ + X(m_bRenderToSubrectOfLargerScreen) \ + X(m_flAspectRatio) \ + X(m_bOffCenter) \ + X(m_flOffCenterTop) \ + X(m_flOffCenterBottom) \ + X(m_flOffCenterLeft) \ + X(m_flOffCenterRight) \ + X(m_bDoBloomAndToneMapping) \ + X(m_bCacheFullSceneState) \ + X(m_bViewToProjectionOverride) \ + X(m_ViewToProjection) + +#define X(x) if constexpr (std::is_trivially_copyable_v) \ +{ memcpy(&(this->x), &setup.x, sizeof(setup.x)); } \ +else { static_assert(std::is_move_assignable_v); \ +this->x = setup.x; } + + COPYVALS + + static_assert(sizeof(CViewSetup) == 200, "Please update the COPYVALS logic above this error"); + +#undef X +#undef COPYVALS +#pragma pop_macro("X") +#pragma pop_macro("COPYVALS") + +#else memcpy( static_cast(this), &setup, sizeof( setup ) ); +#endif ReleaseLists(); m_pRenderablesList = new CClientRenderablesList; diff --git a/src/game/server/ai_basenpc.cpp b/src/game/server/ai_basenpc.cpp index e2b3b4fbf5..cf72fffc3a 100644 --- a/src/game/server/ai_basenpc.cpp +++ b/src/game/server/ai_basenpc.cpp @@ -107,6 +107,10 @@ extern ConVar sk_healthkit; #include "utlbuffer.h" #include "gamestats.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -13156,6 +13160,33 @@ void CAI_BaseNPC::AddScriptedNPCInteraction( ScriptedNPCInteraction_t *pInteract // Copy the interaction over ScriptedNPCInteraction_t *pNewInt = &(m_ScriptedInteractions[nNewIndex]); +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v>) + { + static_assert(sizeof(*pNewInt) == 200); + pNewInt->angRelativeAngles = pInteraction->angRelativeAngles; + pNewInt->bValidOnCurrentEnemy = pInteraction->bValidOnCurrentEnemy; + pNewInt->flDelay = pInteraction->flDelay; + pNewInt->flDistSqr = pInteraction->flDistSqr; + pNewInt->flNextAttemptTime = pInteraction->flNextAttemptTime; + pNewInt->iFlags = pInteraction->iFlags; + pNewInt->iLoopBreakTriggerMethod = pInteraction->iLoopBreakTriggerMethod; + pNewInt->iszInteractionName = pInteraction->iszInteractionName; + pNewInt->iszMyWeapon = pInteraction->iszMyWeapon; + pNewInt->iszTheirWeapon = pInteraction->iszTheirWeapon; + pNewInt->iTriggerMethod = pInteraction->iTriggerMethod; + pNewInt->matDesiredLocalToWorld = pInteraction->matDesiredLocalToWorld; + pNewInt->m_DataMap = pInteraction->m_DataMap; + for (int i = 0; i < ARRAYSIZE(pNewInt->sPhases); ++i) + { + pNewInt->sPhases[i] = pInteraction->sPhases[i]; + } + pNewInt->vecRelativeOrigin = pInteraction->vecRelativeOrigin; + pNewInt->vecRelativeVelocity = pInteraction->vecRelativeVelocity; + } + else +#endif memcpy( pNewInt, pInteraction, sizeof(ScriptedNPCInteraction_t) ); // Calculate the local to world matrix diff --git a/src/game/server/ai_behavior_follow.cpp b/src/game/server/ai_behavior_follow.cpp index 0ebca7a017..4320b81d72 100644 --- a/src/game/server/ai_behavior_follow.cpp +++ b/src/game/server/ai_behavior_follow.cpp @@ -22,6 +22,10 @@ #include "info_darknessmode_lightsource.h" #endif +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -48,6 +52,27 @@ struct AI_Follower_t AI_Follower_t() { slot = -1; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(navInfo) == 56); + static_assert(std::is_same_v); + navInfo.chaseEnemyTolerance = {}; + navInfo.coverTolerance = {}; + navInfo.enemyLOSTolerance = {}; + navInfo.flags = {}; + navInfo.followPointTolerance = {}; + navInfo.m_DataMap = {}; + navInfo.position = {}; + navInfo.range = {}; + navInfo.repathOnRouteTolerance = {}; + navInfo.targetMoveTolerance = {}; + navInfo.tolerance = {}; + navInfo.walkTolerance = {}; + navInfo.Zrange = {}; + } + else +#endif memset( &navInfo, 0, sizeof(navInfo) ); pGroup = NULL; } @@ -232,6 +257,27 @@ END_DATADESC(); CAI_FollowBehavior::CAI_FollowBehavior( const AI_FollowParams_t ¶ms ) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(m_FollowNavGoal) == 56); + static_assert(std::is_same_v); + m_FollowNavGoal.chaseEnemyTolerance = {}; + m_FollowNavGoal.coverTolerance = {}; + m_FollowNavGoal.enemyLOSTolerance = {}; + m_FollowNavGoal.flags = {}; + m_FollowNavGoal.followPointTolerance = {}; + m_FollowNavGoal.m_DataMap = {}; + m_FollowNavGoal.position = {}; + m_FollowNavGoal.range = {}; + m_FollowNavGoal.repathOnRouteTolerance = {}; + m_FollowNavGoal.targetMoveTolerance = {}; + m_FollowNavGoal.tolerance = {}; + m_FollowNavGoal.walkTolerance = {}; + m_FollowNavGoal.Zrange = {}; + } + else +#endif memset( &m_FollowNavGoal, 0, sizeof( m_FollowNavGoal ) ); m_FollowDelay.Set( 1.0, 3.0 ); diff --git a/src/game/server/ai_blended_movement.h b/src/game/server/ai_blended_movement.h index dab62be686..d7e2215bfb 100644 --- a/src/game/server/ai_blended_movement.h +++ b/src/game/server/ai_blended_movement.h @@ -12,6 +12,10 @@ #include "ai_motor.h" #include "ai_navigator.h" +#ifdef NEO +#include +#endif + struct AI_Waypoint_t; //----------------------------------------------------------------------------- @@ -121,6 +125,21 @@ class CAI_BlendedMotor : public CAI_Motor void Init( void ) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v< + std::remove_cvref_t>) + { + static_assert(sizeof(*this) == 72); + flTime = flElapsedTime = flDist = flMaxVelocity = + flYaw = flAngularVelocity = {}; + bLooping = {}; + nFlags = {}; + pWaypoint = {}; + pNext = pPrev = {}; + vecLocation.Zero(); + } + else +#endif memset( this, 0, sizeof(*this) ); }; diff --git a/src/game/server/ai_hint.cpp b/src/game/server/ai_hint.cpp index 0cf434e60d..b1043f75fd 100644 --- a/src/game/server/ai_hint.cpp +++ b/src/game/server/ai_hint.cpp @@ -18,6 +18,10 @@ #include "tier1/strtools.h" #include "mapentities_shared.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -604,6 +608,28 @@ CAI_Hint* CAI_HintManager::CreateHint( HintNodeData *pNodeData, const char *pMap pHint->SetName( pNodeData->strEntityName ); pHint->SetAbsOrigin( pNodeData->vecPosition ); +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v>) + { + static_assert(std::is_same_v < HintNodeData, decltype(pHint->m_NodeData)>); + static_assert(sizeof(pHint->m_NodeData) == 80); + pHint->m_NodeData.fIgnoreFacing = pNodeData->fIgnoreFacing; + pHint->m_NodeData.iDisabled = pNodeData->iDisabled; + pHint->m_NodeData.iszActivityName = pNodeData->iszActivityName; + pHint->m_NodeData.maxState = pNodeData->maxState; + pHint->m_NodeData.minState = pNodeData->minState; + pHint->m_NodeData.m_DataMap = pNodeData->m_DataMap; + pHint->m_NodeData.nHintType = pNodeData->nHintType; + pHint->m_NodeData.nNodeID = pNodeData->nNodeID; + pHint->m_NodeData.nTargetWCNodeID = pNodeData->nTargetWCNodeID; + pHint->m_NodeData.nWCNodeID = pNodeData->nWCNodeID; + pHint->m_NodeData.strEntityName = pNodeData->strEntityName; + pHint->m_NodeData.strGroup = pNodeData->strGroup; + pHint->m_NodeData.vecPosition = pNodeData->vecPosition; + } + else +#endif memcpy( &(pHint->m_NodeData), pNodeData, sizeof(HintNodeData) ); DispatchSpawn( pHint ); diff --git a/src/game/server/ai_localnavigator.cpp b/src/game/server/ai_localnavigator.cpp index 48f8f9b9cd..cbd23099f2 100644 --- a/src/game/server/ai_localnavigator.cpp +++ b/src/game/server/ai_localnavigator.cpp @@ -13,6 +13,10 @@ #include "ai_moveprobe.h" #include "ai_motor.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -38,6 +42,36 @@ CAI_LocalNavigator::CAI_LocalNavigator(CAI_BaseNPC *pOuter) : CAI_Component( pOu m_pPlaneSolver = new CAI_PlaneSolver( pOuter ); m_fLastWasClear = false; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(m_LastMoveGoal) == +#ifdef DEBUG + 224 +#else + 216 +#endif + ); + static_assert(std::is_same_v); + m_LastMoveGoal.bHasTraced = {}; + m_LastMoveGoal.curExpectedDist = {}; + m_LastMoveGoal.dir = {}; + m_LastMoveGoal.directTrace = {}; + m_LastMoveGoal.facing = {}; + m_LastMoveGoal.flags = {}; + m_LastMoveGoal.maxDist = {}; + m_LastMoveGoal.navType = {}; + m_LastMoveGoal.pMoveTarget = {}; + m_LastMoveGoal.pPath = {}; +#ifdef DEBUG + m_LastMoveGoal.solveCookie = {}; +#endif + m_LastMoveGoal.speed = {}; + m_LastMoveGoal.target = {}; + m_LastMoveGoal.thinkTrace = {}; + } + else +#endif memset( &m_LastMoveGoal, 0, sizeof(m_LastMoveGoal) ); } diff --git a/src/game/server/ai_motor.cpp b/src/game/server/ai_motor.cpp index 49f3d5f462..b5bd63ad5b 100644 --- a/src/game/server/ai_motor.cpp +++ b/src/game/server/ai_motor.cpp @@ -16,6 +16,10 @@ #include "ai_moveprobe.h" #include "saverestore_utlvector.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -469,6 +473,13 @@ void CAI_Motor::MoveStart() void CAI_Motor::MoveStop() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + m_vecVelocity.Zero(); + } + else +#endif memset( &m_vecVelocity, 0, sizeof(m_vecVelocity) ); GetOuter()->GetLocalNavigator()->ResetMoveCalculations(); } diff --git a/src/game/server/ai_movetypes.h b/src/game/server/ai_movetypes.h index b255921e74..f706882feb 100644 --- a/src/game/server/ai_movetypes.h +++ b/src/game/server/ai_movetypes.h @@ -13,6 +13,10 @@ #include "ai_navtype.h" +#ifdef NEO +#include +#endif + class CAI_Path; //----------------------------------------------------------------------------- @@ -77,6 +81,20 @@ struct AIMoveTrace_t { AIMoveTrace_t() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v>) + { + static_assert(sizeof(*this) == 64); + fStatus = {}; + vEndPosition.Zero(); + vHitNormal.Zero(); + pObstruction = {}; + flTotalDist = flDistObstructed = {}; + vJumpVelocity.Zero(); + flStepUpDistance = {}; + } + else +#endif memset( this, 0, sizeof(*this) ); } @@ -124,6 +142,34 @@ struct AILocalMoveGoal_t { AILocalMoveGoal_t() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v>) + { + static_assert(sizeof(*this) == +#ifdef DEBUG + 224 +#else + 216 +#endif + ); + + target.Zero(); + dir.Zero(); + facing.Zero(); + speed = maxDist = curExpectedDist = {}; + navType = {}; + pMoveTarget = {}; + flags = {}; + pPath = {}; + bHasTraced = {}; + directTrace = {}; + thinkTrace = {}; +#ifdef DEBUG + solveCookie = {}; +#endif + } + else +#endif memset( this, 0, sizeof(*this) ); } diff --git a/src/game/server/ai_waypoint.cpp b/src/game/server/ai_waypoint.cpp index 79885c374c..885c1d92d6 100644 --- a/src/game/server/ai_waypoint.cpp +++ b/src/game/server/ai_waypoint.cpp @@ -11,6 +11,10 @@ #include "ai_node.h" #include "ai_waypoint.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -43,6 +47,21 @@ END_DATADESC() AI_Waypoint_t::AI_Waypoint_t() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v< + std::remove_cvref_t>) + { + this->flYaw = {}; + this->hPathCorner = {}; + this->m_DataMap = {}; + this->m_fWaypointFlags = {}; + this->m_hData = {}; + this->m_iWPType = {}; + this->pNext = {}; + this->pPrev = {}; + } + else +#endif memset( this, 0, sizeof(*this) ); vecLocation = vec3_invalid; iNodeID = NO_NODE; @@ -53,6 +72,18 @@ AI_Waypoint_t::AI_Waypoint_t() AI_Waypoint_t::AI_Waypoint_t( const Vector &initPosition, float initYaw, Navigation_t initNavType, int initWaypointFlags, int initNodeID ) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v< + std::remove_cvref_t>) + { + this->hPathCorner = {}; + this->m_DataMap = {}; + this->m_hData = {}; + this->pNext = {}; + this->pPrev = {}; + } + else +#endif memset( this, 0, sizeof(*this) ); // A Route of length one to the endpoint diff --git a/src/game/server/ai_waypoint.h b/src/game/server/ai_waypoint.h index cc899b5ed2..ebcd867826 100644 --- a/src/game/server/ai_waypoint.h +++ b/src/game/server/ai_waypoint.h @@ -14,6 +14,10 @@ #include +#ifdef NEO +#include +#endif + // ---------------------------------------------------------------------------- // Forward declarations // ---------------------------------------------------------------------------- @@ -44,6 +48,22 @@ struct AI_Waypoint_t AI_Waypoint_t( const Vector &vecPosition, float flYaw, Navigation_t navType, int fWaypointFlags, int nNodeID ); AI_Waypoint_t( const AI_Waypoint_t &from ) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v>) + { + static_assert(sizeof(*this) == 56); + flYaw = from.flYaw; + hPathCorner = from.hPathCorner; + iNodeID = from.iNodeID; + m_DataMap = from.m_DataMap; + m_fWaypointFlags = from.m_fWaypointFlags; + m_hData = from.m_hData; + m_iWPType = from.m_iWPType; + s_Allocator = from.s_Allocator; + vecLocation = from.vecLocation; + } + else +#endif memcpy( this, &from, sizeof(*this) ); flPathDistGoal = -1; pNext = pPrev = NULL; @@ -51,6 +71,22 @@ struct AI_Waypoint_t AI_Waypoint_t &operator=( const AI_Waypoint_t &from ) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v>) + { + static_assert(sizeof(*this) == 56); + flYaw = from.flYaw; + hPathCorner = from.hPathCorner; + iNodeID = from.iNodeID; + m_DataMap = from.m_DataMap; + m_fWaypointFlags = from.m_fWaypointFlags; + m_hData = from.m_hData; + m_iWPType = from.m_iWPType; + s_Allocator = from.s_Allocator; + vecLocation = from.vecLocation; + } + else +#endif memcpy( this, &from, sizeof(*this) ); flPathDistGoal = -1; pNext = pPrev = NULL; diff --git a/src/game/server/physics.cpp b/src/game/server/physics.cpp index 279fd507d9..c6930361b1 100644 --- a/src/game/server/physics.cpp +++ b/src/game/server/physics.cpp @@ -2099,6 +2099,14 @@ void CCollisionEvent::UpdateFrictionSounds( void ) void CCollisionEvent::DispatchStartTouch( CBaseEntity *pEntity0, CBaseEntity *pEntity1, const Vector &point, const Vector &normal ) { trace_t trace; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_default_constructible_v); + trace = {}; + } + else +#endif memset( &trace, 0, sizeof(trace) ); trace.endpos = point; trace.plane.dist = DotProduct( point, normal ); diff --git a/src/game/server/smokestack.cpp b/src/game/server/smokestack.cpp index d7b7ee89d8..9cbd0f7cc4 100644 --- a/src/game/server/smokestack.cpp +++ b/src/game/server/smokestack.cpp @@ -10,6 +10,10 @@ #include "particle_light.h" #include "filesystem.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -95,7 +99,35 @@ END_DATADESC() //----------------------------------------------------------------------------- CSmokeStack::CSmokeStack() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(m_AmbientLight) == 40); + static_assert(std::is_same_v< + decltype(m_AmbientLight), CSmokeStackLightInfo>); + m_AmbientLight.m_DataMap = {}; + m_AmbientLight.m_flIntensity = {}; + m_AmbientLight.m_vColor.Init(); + m_AmbientLight.m_vPos.Init(); + m_AmbientLight.__m_pChainEntity = {}; + } + else +#endif memset( &m_AmbientLight, 0, sizeof(m_AmbientLight) ); +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(m_DirLight) == 40); + static_assert(std::is_same_v< + decltype(m_DirLight), CSmokeStackLightInfo>); + m_DirLight.m_DataMap = {}; + m_DirLight.m_flIntensity = {}; + m_DirLight.m_vColor.Init(); + m_DirLight.m_vPos.Init(); + m_DirLight.__m_pChainEntity = {}; + } + else +#endif memset( &m_DirLight, 0, sizeof(m_DirLight) ); IMPLEMENT_NETWORKVAR_CHAIN( &m_AmbientLight ); diff --git a/src/game/server/util.cpp b/src/game/server/util.cpp index ba23fa9d08..8473c23e1e 100644 --- a/src/game/server/util.cpp +++ b/src/game/server/util.cpp @@ -1217,6 +1217,14 @@ void UTIL_SetTrace(trace_t& trace, const Ray_t &ray, edict_t *ent, float fractio void UTIL_ClearTrace( trace_t &trace ) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_default_constructible_v); + trace = {}; + } + else +#endif memset( &trace, 0, sizeof(trace)); trace.fraction = 1.f; trace.fractionleftsolid = 0; diff --git a/src/game/server/vehicle_base.cpp b/src/game/server/vehicle_base.cpp index f916ba6915..dcd6ba74d3 100644 --- a/src/game/server/vehicle_base.cpp +++ b/src/game/server/vehicle_base.cpp @@ -19,6 +19,10 @@ #include "physics_impact_damage.h" #include "entityblocker.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1095,6 +1099,27 @@ void CPropVehicleDriveable::Event_KilledOther( CBaseEntity *pVictim, const CTake CFourWheelServerVehicle::CFourWheelServerVehicle( void ) { // Setup our smoothing data +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(m_ViewSmoothing) == 128); + static_assert(std::is_same_v); + m_ViewSmoothing.bRunningEnterExit = + m_ViewSmoothing.bWasRunningAnim = {}; + m_ViewSmoothing.flEnterExitDuration = {}; + m_ViewSmoothing.flEnterExitStartTime = + m_ViewSmoothing.flFOV = {}; + m_ViewSmoothing.m_DataMap = {}; + m_ViewSmoothing.pitchLockData = {}; + m_ViewSmoothing.pVehicle = {}; + m_ViewSmoothing.rollLockData = {}; + m_ViewSmoothing.vecAngleDiffMin.Init(); + m_ViewSmoothing.vecAngleDiffSaved.Init(); + m_ViewSmoothing.vecAnglesSaved.Init(); + m_ViewSmoothing.vecOriginSaved.Zero(); + } + else +#endif memset( &m_ViewSmoothing, 0, sizeof( m_ViewSmoothing ) ); m_ViewSmoothing.bClampEyeAngles = true; diff --git a/src/game/shared/particlesystemquery.cpp b/src/game/shared/particlesystemquery.cpp index 34c7a62e5c..318c9cac3f 100644 --- a/src/game/shared/particlesystemquery.cpp +++ b/src/game/shared/particlesystemquery.cpp @@ -22,6 +22,10 @@ #include "ai_utils.h" #endif +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -149,6 +153,17 @@ void CParticleSystemQuery::TraceLine( const Vector& vecAbsStart, { trace_t tempTrace; UTIL_TraceLine( vecAbsStart, vecAbsEnd, mask, ignore, collisionGroup, &tempTrace ); +#ifdef NEO + using FromT = decltype(tempTrace); + using ToT = std::remove_pointer_t; + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_copy_assignable_v); + static_assert(std::is_same_v || std::derived_from); + *ptr = tempTrace; + } + else +#endif memcpy( ptr, &tempTrace, sizeof ( CBaseTrace ) ); } else diff --git a/src/game/shared/physics_saverestore.cpp b/src/game/shared/physics_saverestore.cpp index 434be1f420..f074a5ce48 100644 --- a/src/game/shared/physics_saverestore.cpp +++ b/src/game/shared/physics_saverestore.cpp @@ -20,6 +20,10 @@ #include "entitylist.h" #endif +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -79,6 +83,23 @@ struct PhysObjectHeader_t { PhysObjectHeader_t() { +#ifdef NEO + using ThisType = std::remove_cvref_t; + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(ThisType) == 64, "implement ctor zero-init!!"); + type = {}; + hEntity = INVALID_ENTITY_HANDLE; + fieldName = NULL_STRING; + nObjects = {}; + modelName = NULL_STRING; + bbox.maxs.Zero(); + bbox.mins.Zero(); + sphere.radius = {}; + iCollide = {}; + } + else +#endif memset( this, 0, sizeof(*this) ); } @@ -436,6 +457,15 @@ class CPhysSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler, // the field name would normally be in the string // pool anyway. (toml 12-10-02) item.header.modelName = NULL_STRING; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(item.header.bbox) == sizeof(Vector)*2); + item.header.bbox.maxs.Zero(); + item.header.bbox.mins.Zero(); + } + else +#endif memset( &item.header.bbox, 0, sizeof( item.header.bbox ) ); item.header.sphere.radius = 0; diff --git a/src/game/shared/physics_shared.cpp b/src/game/shared/physics_shared.cpp index 4e064c8927..0190403ff5 100644 --- a/src/game/shared/physics_shared.cpp +++ b/src/game/shared/physics_shared.cpp @@ -22,6 +22,10 @@ #include "physics_saverestore.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -189,7 +193,11 @@ bool PhysModelParseSolidByIndex( solid_t &solid, CBaseEntity *pEntity, int model bool parsed = false; +#ifdef NEO + ZeroSolid(solid); +#else memset( &solid, 0, sizeof(solid) ); +#endif solid.params = g_PhysDefaultObjectParams; IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pCollide->pKeyValues ); @@ -199,7 +207,11 @@ bool PhysModelParseSolidByIndex( solid_t &solid, CBaseEntity *pEntity, int model if ( !strcmpi( pBlock, "solid" ) ) { solid_t tmpSolid; +#ifdef NEO + ZeroSolid(tmpSolid); +#else memset( &tmpSolid, 0, sizeof(tmpSolid) ); +#endif tmpSolid.params = g_PhysDefaultObjectParams; pParse->ParseSolid( &tmpSolid, &g_SolidSetup ); @@ -252,7 +264,11 @@ bool PhysModelParseSolidByIndex( solid_t &solid, CBaseEntity *pEntity, vcollide_ { bool parsed = false; +#ifdef NEO + ZeroSolid(solid); +#else memset( &solid, 0, sizeof(solid) ); +#endif solid.params = g_PhysDefaultObjectParams; IVPhysicsKeyParser *pParse = physcollision->VPhysicsKeyParserCreate( pCollide->pKeyValues ); @@ -262,7 +278,11 @@ bool PhysModelParseSolidByIndex( solid_t &solid, CBaseEntity *pEntity, vcollide_ if ( !strcmpi( pBlock, "solid" ) ) { solid_t tmpSolid; +#ifdef NEO + ZeroSolid(tmpSolid); +#else memset( &tmpSolid, 0, sizeof(tmpSolid) ); +#endif tmpSolid.params = g_PhysDefaultObjectParams; pParse->ParseSolid( &tmpSolid, &g_SolidSetup ); diff --git a/src/game/shared/saverestore.cpp b/src/game/shared/saverestore.cpp index 02e4621185..3ece450f71 100644 --- a/src/game/shared/saverestore.cpp +++ b/src/game/shared/saverestore.cpp @@ -2019,7 +2019,14 @@ int CRestore::ReadEHandle( EHANDLE *pEHandle, int count, int nBytesAvailable ) if ( nRead < count) { +#ifdef NEO + static_assert(sizeof(EHANDLE) == 4); + static_assert(sizeof(pEHandle[0]) == sizeof(EHANDLE)); + // HACK: not trivial! :-( + memset( (void*) & pEHandle[nRead], 0xFF, (count - nRead) * sizeof(pEHandle[0])); +#else memset( &pEHandle[nRead], 0xFF, ( count - nRead ) * sizeof(pEHandle[0]) ); +#endif } return nRead; diff --git a/src/game/shared/sheetsimulator.cpp b/src/game/shared/sheetsimulator.cpp index 4c4de5748d..332f33983f 100644 --- a/src/game/shared/sheetsimulator.cpp +++ b/src/game/shared/sheetsimulator.cpp @@ -15,6 +15,10 @@ #include "edict.h" #include "collisionutils.h" +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -390,6 +394,20 @@ void CSheetSimulator::InitPosition( int i ) MASK_SOLID_BRUSHONLY, m_CollisionGroup, &tr ); if ( tr.fraction - 1.0 < 0 ) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + m_pCollisionPlanes[i].normal = tr.plane.normal; + m_pCollisionPlanes[i].dist = tr.plane.dist; + for (int j = 0; j < ARRAYSIZE(tr.plane.pad); ++j) + { + m_pCollisionPlanes[i].pad[j] = tr.plane.pad[j]; + } + m_pCollisionPlanes[i].signbits = tr.plane.signbits; + m_pCollisionPlanes[i].type = tr.plane.type; + } + else +#endif memcpy( &m_pCollisionPlanes[i], &tr.plane, sizeof(cplane_t) ); m_pCollisionPlanes[i].dist += COLLISION_PLANE_OFFSET; @@ -440,6 +458,16 @@ void CSheetSimulator::DetectCollision( int i, float flPlaneOffset ) if ( tr.fraction - 1.0 < 0 ) { m_pValidCollisionPlane[i] = true; + +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_trivially_move_constructible_v); + static_assert(std::is_same_v); + m_pCollisionPlanes[i] = tr.plane; + } + else +#endif memcpy( &m_pCollisionPlanes[i], &tr.plane, sizeof(cplane_t) ); m_pCollisionPlanes[i].dist += flPlaneOffset; } diff --git a/src/game/shared/util_shared.cpp b/src/game/shared/util_shared.cpp index e3dd560277..04b84b3bfd 100644 --- a/src/game/shared/util_shared.cpp +++ b/src/game/shared/util_shared.cpp @@ -39,6 +39,8 @@ bool NPC_CheckBrushExclude( CBaseEntity *pEntity, CBaseEntity *pBrush ); #include "steam/steam_api.h" #ifdef NEO // NEO NOTE (nullsystem): Missing include? #include "steam/steamclientpublic.h" + +#include #endif // memdbgon must be the last include file in a .cpp file!!! @@ -581,6 +583,14 @@ void UTIL_TraceModel( const Vector &vecStart, const Vector &vecEnd, const Vector } else { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_default_constructible_v); + *ptr = {}; + } + else +#endif memset( ptr, 0, sizeof(trace_t) ); ptr->fraction = 1.0f; } diff --git a/src/game/shared/vehicle_viewblend_shared.h b/src/game/shared/vehicle_viewblend_shared.h index a741490669..dc77a0bd94 100644 --- a/src/game/shared/vehicle_viewblend_shared.h +++ b/src/game/shared/vehicle_viewblend_shared.h @@ -10,6 +10,10 @@ #pragma once #endif +#ifdef NEO +#include +#endif + // Definition for how to calculate a point on the remap curve enum RemapAngleRange_CurvePart_t { @@ -68,6 +72,41 @@ struct ViewSmoothingData_t QAngle vecAngleDiffMin; // Tracks the minimum angular error achieved so we can converge on the anim's angles. }; +#ifdef NEO +inline void ZeroViewSmoothingData(ViewSmoothingData_t& data) +{ + if constexpr (std::is_trivially_copyable_v) + { + memset(&data, 0, sizeof(data)); + } + else + { + static_assert(sizeof(ViewSmoothingData_t) == 128, "please update this zero-init function for the changed data layout"); + + data.pVehicle = {}; + data.bClampEyeAngles = {}; + data.flPitchCurveZero = data.flPitchCurveLinear = + data.flRollCurveZero = data.flRollCurveLinear = {}; + data.flFOV = {}; + + static_assert(std::is_trivially_copyable_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + memset(&data.pitchLockData, 0, sizeof(data.pitchLockData)); + memset(&data.rollLockData, 0, sizeof(data.rollLockData)); + + data.bDampenEyePosition = {}; + + data.bRunningEnterExit = data.bWasRunningAnim = {}; + data.flEnterExitStartTime = data.flEnterExitDuration = {}; + data.vecAnglesSaved.Init(); + data.vecOriginSaved.Zero(); + data.vecAngleDiffSaved.Init(); + data.vecAngleDiffMin.Init(); + } +} +#endif + // TEMP: Shared vehicle view smoothing void SharedVehicleViewSmoothing(CBasePlayer *pPlayer, Vector *pAbsOrigin, QAngle *pAbsAngles, diff --git a/src/materialsystem/stdshaders/BaseVSShader.cpp b/src/materialsystem/stdshaders/BaseVSShader.cpp index 184d2ea07d..b43d0366ae 100644 --- a/src/materialsystem/stdshaders/BaseVSShader.cpp +++ b/src/materialsystem/stdshaders/BaseVSShader.cpp @@ -44,6 +44,10 @@ #include "lightmappedgeneric_bumpmappedlightmap.inc" #endif // GAME_SHADER_DLL +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -580,6 +584,14 @@ void CBaseVSShader::LoadBumpLightmapCoordinateAxes_PixelShader( int pixelReg ) Vector4D basis[3]; for (int i = 0; i < 3; ++i) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v< + std::remove_all_extents_t>) + { + basis[i].AsVector3D() = g_localBumpBasis[i]; + } + else +#endif memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); basis[i][3] = 0.0f; } @@ -606,6 +618,14 @@ void CBaseVSShader::LoadBumpLightmapCoordinateAxes_VertexShader( int vertexReg ) s_pShaderAPI->SetVertexShaderConstant( vertexReg, (float*)basis, 3 ); for (i = 0; i < 3; ++i) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v< + std::remove_all_extents_t>) + { + basis[i].AsVector3D() = g_localBumpBasis[i]; + } + else +#endif memcpy( &basis[i], &g_localBumpBasis[i], 3 * sizeof(float) ); basis[i][3] = 0.0f; } diff --git a/src/public/SoundParametersInternal.cpp b/src/public/SoundParametersInternal.cpp index 662627c64f..e2c605fece 100644 --- a/src/public/SoundParametersInternal.cpp +++ b/src/public/SoundParametersInternal.cpp @@ -388,7 +388,11 @@ void CSoundParametersInternal::CopyFrom( const CSoundParametersInternal& src ) if ( m_nSoundNames > 1 ) { m_pSoundNames = (SoundFile*)malloc( sizeof(SoundFile)*m_nSoundNames); +#ifdef NEO + memcpy( (void*)m_pSoundNames, src.m_pSoundNames, m_nSoundNames * sizeof(SoundFile) ); +#else memcpy( m_pSoundNames, src.m_pSoundNames, m_nSoundNames * sizeof(SoundFile) ); +#endif } else { @@ -406,7 +410,11 @@ void CSoundParametersInternal::CopyFrom( const CSoundParametersInternal& src ) if ( m_nConvertedNames > 1 ) { m_pConvertedNames = (SoundFile*)malloc( sizeof(SoundFile)*m_nConvertedNames); +#ifdef NEO + memcpy( (void*)m_pConvertedNames, src.m_pConvertedNames, m_nConvertedNames * sizeof(SoundFile) ); +#else memcpy( m_pConvertedNames, src.m_pConvertedNames, m_nConvertedNames * sizeof(SoundFile) ); +#endif } else { diff --git a/src/public/bitvec.h b/src/public/bitvec.h index a1a984d0a6..50d591d085 100644 --- a/src/public/bitvec.h +++ b/src/public/bitvec.h @@ -14,6 +14,10 @@ #include "tier0/dbg.h" #include "tier0/basetypes.h" +#ifdef NEO +#include +#endif + class CBitVecAccessor { @@ -448,6 +452,17 @@ typedef CBitVec<32> CDWordBitVec; template inline CVarBitVecBase::CVarBitVecBase() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v>) + { + static_assert(std::is_trivially_constructible_v); + m_numBits = {}; + m_numInts = {}; + m_iBitStringStorage = {}; + m_pInt = {}; + } + else +#endif Plat_FastMemset( this, 0, sizeof( *this ) ); } diff --git a/src/public/bone_setup.cpp b/src/public/bone_setup.cpp index ef06bed3ad..9c0bd5b7f4 100644 --- a/src/public/bone_setup.cpp +++ b/src/public/bone_setup.cpp @@ -25,6 +25,10 @@ #include "posedebugger.h" #endif +#ifdef NEO +#include +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -3044,6 +3048,15 @@ bool Studio_IKSequenceError( const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seq { int i; +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_same_v>); + static_assert(std::is_constructible_v); + ikRule = {}; + } + else +#endif memset( &ikRule, 0, sizeof(ikRule) ); ikRule.start = ikRule.peak = ikRule.tail = ikRule.end = 0; @@ -3235,7 +3248,11 @@ void CIKContext::Init( const CStudioHdr *pStudioHdr, const QAngle &angles, const if (m_target.Count() == 0) { m_target.SetSize(12); +#ifdef NEO + memset( (void*)m_target.Base(), 0, sizeof(m_target[0])*m_target.Count() ); +#else memset( m_target.Base(), 0, sizeof(m_target[0])*m_target.Count() ); +#endif ClearTargets(); } @@ -3310,7 +3327,11 @@ void CIKContext::AddDependencies( mstudioseqdesc_t &seqdesc, int iSequence, floa if (m_target.Count() == 0) { m_target.SetSize(12); +#ifdef NEO + memset( (void*)m_target.Base(), 0, sizeof(m_target[0])*m_target.Count() ); +#else memset( m_target.Base(), 0, sizeof(m_target[0])*m_target.Count() ); +#endif ClearTargets(); } @@ -3352,6 +3373,17 @@ void CIKContext::AddAutoplayLocks( Vector pos[], Quaternion q[] ) CBoneBitList boneComputed; int ikOffset = m_ikLock.AddMultipleToTail( m_pStudioHdr->GetNumIKAutoplayLocks() ); +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + for (int i = 0; i < m_pStudioHdr->GetNumIKAutoplayLocks(); ++i) + { + static_assert(std::is_constructible_v); + m_ikLock[ikOffset + i] = {}; + } + } + else +#endif memset( &m_ikLock[ikOffset], 0, sizeof(ikcontextikrule_t)*m_pStudioHdr->GetNumIKAutoplayLocks() ); for (int i = 0; i < m_pStudioHdr->GetNumIKAutoplayLocks(); i++) @@ -3411,6 +3443,17 @@ void CIKContext::AddSequenceLocks( mstudioseqdesc_t &seqdesc, Vector pos[], Quat CBoneBitList boneComputed; int ikOffset = m_ikLock.AddMultipleToTail( seqdesc.numiklocks ); +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + for (int i = 0; i < seqdesc.numiklocks; ++i) + { + static_assert(std::is_constructible_v); + m_ikLock[ikOffset + i] = {}; + } + } + else +#endif memset( &m_ikLock[ikOffset], 0, sizeof(ikcontextikrule_t) * seqdesc.numiklocks ); for (int i = 0; i < seqdesc.numiklocks; i++) @@ -4327,6 +4370,17 @@ void CIKContext::AddAllLocks( Vector pos[], Quaternion q[] ) CBoneBitList boneComputed; int ikOffset = m_ikLock.AddMultipleToTail( m_pStudioHdr->GetNumIKChains() ); +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + for (int i = 0; i < m_pStudioHdr->GetNumIKChains(); ++i) + { + static_assert(std::is_constructible_v); + m_ikLock[ikOffset + i] = {}; + } + } + else +#endif memset( &m_ikLock[ikOffset], 0, sizeof(ikcontextikrule_t)*m_pStudioHdr->GetNumIKChains() ); for (int i = 0; i < m_pStudioHdr->GetNumIKChains(); i++) diff --git a/src/public/bone_setup.h b/src/public/bone_setup.h index 41b8c5ea9b..00c6d24d56 100644 --- a/src/public/bone_setup.h +++ b/src/public/bone_setup.h @@ -16,6 +16,9 @@ #include "cmodel.h" #include "bitvec.h" +#ifdef NEO +#include +#endif class CBoneToWorld; class CIKContext; @@ -251,6 +254,23 @@ struct ikcontextikrule_t ikcontextikrule_t() { +#ifdef NEO + using MyType = std::remove_cvref_t; + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(MyType) == 136, "implement ctor zero-init for changed members!!"); + index = type = chain = bone = slot = {}; + height = radius = floor = start = peak = tail = end + = top = drop = commit = release = flWeight + = flRuleWeight = latched = {}; + pos.Zero(); + kneeDir.Zero(); + kneePos.Zero(); + q.x = q.y = q.z = q.w = {}; + szLabel = {}; + } + else +#endif memset( this, 0, sizeof( *this ) ); } diff --git a/src/public/dt_send.cpp b/src/public/dt_send.cpp index df56a7265e..b6f7d0e30e 100644 --- a/src/public/dt_send.cpp +++ b/src/public/dt_send.cpp @@ -13,7 +13,7 @@ #include "tier0/dbg.h" #include "dt_utlvector_common.h" -#if defined(NEO) && defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) +#ifdef NEO #include #endif @@ -73,6 +73,7 @@ CStandardSendProxies g_StandardSendProxies; // ---------------------------------------------------------------------- // // Proxies. // ---------------------------------------------------------------------- // +#ifdef NEO template void pun(auto& dst, const void* src) { @@ -88,6 +89,7 @@ void pun(auto& dst, const void* src) Assert(neoRes == sdkRes); #endif } +#endif void SendProxy_AngleToFloat( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) { diff --git a/src/public/mathlib/simdvectormatrix.h b/src/public/mathlib/simdvectormatrix.h index f88cd328ca..defd98378a 100644 --- a/src/public/mathlib/simdvectormatrix.h +++ b/src/public/mathlib/simdvectormatrix.h @@ -21,6 +21,10 @@ #include "tier1/utlsoacontainer.h" #include "mathlib/ssemath.h" +#ifdef NEO +#include +#endif + class CSIMDVectorMatrix { public: @@ -85,6 +89,19 @@ class CSIMDVectorMatrix CSIMDVectorMatrix &operator=( CSIMDVectorMatrix const &src ) { SetSize( src.m_nWidth, src.m_nHeight ); +#ifdef NEO + using ToT = std::remove_pointer_t; + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_copy_assignable_v); + static_assert(std::is_same_v >); + if (m_pData && src.m_pData) + { + *m_pData = *src.m_pData; + } + } + else +#endif if ( m_pData ) memcpy( m_pData, src.m_pData, m_nHeight*m_nPaddedWidth*sizeof(m_pData[0]) ); return *this; @@ -131,6 +148,24 @@ class CSIMDVectorMatrix void Clear( void ) { Assert( m_pData ); +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v< + std::remove_pointer_t>) + { +#ifdef DEBUG + // Play nice with data alignment to avoid compiler errors + struct AssertWrap { + decltype(m_pData->x) v; + }; + static_assert(std::is_trivially_move_assignable_v); +#endif + + m_pData->x = Four_Zeros; + m_pData->y = Four_Zeros; + m_pData->z = Four_Zeros; + } + else +#endif memset( m_pData, 0, m_nHeight*m_nPaddedWidth*sizeof(m_pData[0]) ); } diff --git a/src/public/saverestoretypes.h b/src/public/saverestoretypes.h index cd9e457f3c..e903bbc4e7 100644 --- a/src/public/saverestoretypes.h +++ b/src/public/saverestoretypes.h @@ -20,6 +20,9 @@ #include // NULL_STRING define struct edict_t; +#ifdef NEO +#include +#endif #ifdef EHANDLE_H // not available to engine #define SR_ENTS_VISIBLE 1 @@ -180,6 +183,27 @@ class CGameSaveRestoreInfo CGameSaveRestoreInfo() : tableCount( 0 ), pTable( 0 ), m_pCurrentEntity( 0 ), m_EntityToIndex( 1024 ) { +#ifdef NEO + if (!std::is_trivially_copyable_v) + { + levelInfo.connectionCount = 0; + for (int i = 0; i < ARRAYSIZE(levelInfo.levelList); ++i) + { + auto& level = levelInfo.levelList[i]; + level.landmarkName[0] = 0; + level.mapName[0] = 0; + level.pentLandmark = nullptr; + level.vecLandmarkOrigin.Zero(); + } + levelInfo.fUseLandmark = 0; + levelInfo.szLandmarkName[0] = 0; + levelInfo.vecLandmarkOffset.Zero(); + levelInfo.time = 0; + levelInfo.szCurrentMapName[0] = 0; + levelInfo.mapVersion = 0; + } + else +#endif memset( &levelInfo, 0, sizeof( levelInfo ) ); modelSpaceOffset.Init( 0, 0, 0 ); } diff --git a/src/public/sentence.cpp b/src/public/sentence.cpp index 74bc99bf8b..b755708e3f 100644 --- a/src/public/sentence.cpp +++ b/src/public/sentence.cpp @@ -240,6 +240,15 @@ CBasePhonemeTag::CBasePhonemeTag() CBasePhonemeTag::CBasePhonemeTag( const CBasePhonemeTag& from ) { +#ifdef NEO + using ThisT = std::remove_cvref_t; + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(std::is_move_assignable_v); + *this = from; + } + else +#endif memcpy( this, &from, sizeof(*this) ); } diff --git a/src/public/sentence.h b/src/public/sentence.h index de0f8d9a92..317b40d952 100644 --- a/src/public/sentence.h +++ b/src/public/sentence.h @@ -17,6 +17,10 @@ #include "utlvector.h" +#ifdef NEO +#include +#endif + class CUtlBuffer; #define CACHED_SENTENCE_VERSION 1 @@ -48,7 +52,25 @@ class CBasePhonemeTag CBasePhonemeTag(); CBasePhonemeTag( const CBasePhonemeTag& from ); +#ifdef NEO + CBasePhonemeTag &operator=( const CBasePhonemeTag &from ) + { + if constexpr (std::is_trivially_copyable_v) + { + memcpy( this, &from, sizeof(*this) ); + } + else + { + static_assert(sizeof(CBasePhonemeTag) == 12); + m_flStartTime = from.m_flStartTime; + m_flEndTime = from.m_flEndTime; + m_nPhonemeCode = from.m_nPhonemeCode; + } + return *this; + } +#else CBasePhonemeTag &operator=( const CBasePhonemeTag &from ) { memcpy( this, &from, sizeof(*this) ); return *this; } +#endif float GetStartTime() const { return m_flStartTime; } void SetStartTime( float startTime ) { m_flStartTime = startTime; } diff --git a/src/public/studio.h b/src/public/studio.h index 9480d15d95..732fafb76e 100644 --- a/src/public/studio.h +++ b/src/public/studio.h @@ -28,6 +28,10 @@ #include "localflexcontroller.h" #include "utlsymbol.h" +#ifdef NEO +#include +#endif + #define STUDIO_ENABLE_PERF_COUNTERS #define STUDIO_SEQUENCE_ACTIVITY_LOOKUPS_ARE_SLOW 0 @@ -3315,18 +3319,106 @@ inline int Studio_LoadVertexes( const vertexFileHeader_t *pTempVvdHdr, vertexFil } // copy vertexes +#ifdef NEO + // NEO NOTE (Rain): we don't currently hit this code path anywhere because we aren't building VRAD, hence this is untested... + // but see the "paranoidMemcpy" check below for the validation sanity checks. + if constexpr (!std::is_trivially_copyable_v) + { + constexpr int increment = 48; + static_assert(sizeof(mstudiovertex_t) == increment); + for (int vert = 0; vert < numVertexes; ++vert) + { + const auto offset = vert * increment; + auto* dst = (mstudiovertex_t*)((byte*)pNewVvdHdr + pNewVvdHdr->vertexDataStart) + offset; + auto* src = (mstudiovertex_t*)((byte*)pTempVvdHdr + pTempVvdHdr->vertexDataStart) + pFixupTable[i].sourceVertexID + offset; + Assert(dst); + Assert(src); + static_assert(std::is_move_assignable_v>); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + *dst = *src; + } + } + else +#endif memcpy( (mstudiovertex_t *)((byte *)pNewVvdHdr+pNewVvdHdr->vertexDataStart) + target, (mstudiovertex_t *)((byte *)pTempVvdHdr+pTempVvdHdr->vertexDataStart) + pFixupTable[i].sourceVertexID, pFixupTable[i].numVertexes*sizeof(mstudiovertex_t) ); +#ifdef NEO +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) + constexpr bool paranoidMemcpy = true && IsWindows(); // because MSVC is more lenient about nontrivial memcpy with Wall + if constexpr (paranoidMemcpy) + { + if (pFixupTable[i].numVertexes > 0) + { + auto* memBeforeBuf = malloc(pFixupTable[i].numVertexes * sizeof(mstudiovertex_t)); + Assert(memBeforeBuf); + memcpy(memBeforeBuf, (mstudiovertex_t*)((byte*)pNewVvdHdr + pNewVvdHdr->vertexDataStart) + target, pFixupTable[i].numVertexes * sizeof(mstudiovertex_t)); + memcpy( + (mstudiovertex_t *)((byte *)pNewVvdHdr+pNewVvdHdr->vertexDataStart) + target, + (mstudiovertex_t *)((byte *)pTempVvdHdr+pTempVvdHdr->vertexDataStart) + pFixupTable[i].sourceVertexID, + pFixupTable[i].numVertexes*sizeof(mstudiovertex_t) ); + const auto res = memcmp((mstudiovertex_t*)((byte*)pNewVvdHdr + pNewVvdHdr->vertexDataStart) + target, memBeforeBuf, + pFixupTable[i].numVertexes * sizeof(mstudiovertex_t)); + free(memBeforeBuf); + Assert(0 == res); + } + } +#endif // DEBUG && DBGFLAG_ASSERT +#endif // NEO + if (bNeedsTangentS) { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + for (int vert = 0; vert < pFixupTable[i].numVertexes; ++vert) + { + constexpr int increment = 16; + static_assert(sizeof(Vector4D) == increment); + const auto offset = vert * increment; + auto* src = (Vector4D*)((byte*)pNewVvdHdr + pNewVvdHdr->tangentDataStart) + target + offset; + auto* dst = (Vector4D*)((byte*)pTempVvdHdr + pTempVvdHdr->tangentDataStart) + pFixupTable[i].sourceVertexID + offset; + static_assert(std::is_move_assignable_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + Assert(dst); + Assert(src); + *src = *dst; + } + } + else +#endif // copy tangents memcpy( (Vector4D *)((byte *)pNewVvdHdr+pNewVvdHdr->tangentDataStart) + target, (Vector4D *)((byte *)pTempVvdHdr+pTempVvdHdr->tangentDataStart) + pFixupTable[i].sourceVertexID, pFixupTable[i].numVertexes*sizeof(Vector4D) ); + +#ifdef NEO +#ifdef DEBUG + if constexpr (paranoidMemcpy) + { + if (pFixupTable[i].numVertexes > 0) + { + const auto memBeforeBufSize = pFixupTable[i].numVertexes * sizeof(Vector4D); + auto* memBeforeBuf = malloc(memBeforeBufSize); + Assert(memBeforeBuf); + memcpy(memBeforeBuf, (Vector4D*)((byte*)pNewVvdHdr + pNewVvdHdr->tangentDataStart) + target, memBeforeBufSize); + memcpy( + (Vector4D *)((byte *)pNewVvdHdr+pNewVvdHdr->tangentDataStart) + target, + (Vector4D *)((byte *)pTempVvdHdr+pTempVvdHdr->tangentDataStart) + pFixupTable[i].sourceVertexID, + memBeforeBufSize ); + const auto res = memcmp((Vector4D *)((byte *)pNewVvdHdr+pNewVvdHdr->tangentDataStart) + target, memBeforeBuf, + memBeforeBufSize ); + free(memBeforeBuf); + Assert(0 == res); + } + } +#endif +#endif } // data is placed consecutively diff --git a/src/public/vcollide_parse.h b/src/public/vcollide_parse.h index 675c4569d4..e8eb19c1a1 100644 --- a/src/public/vcollide_parse.h +++ b/src/public/vcollide_parse.h @@ -13,6 +13,12 @@ #include "vphysics_interface.h" +#ifdef NEO +#include "mathlib/vector.h" + +#include +#endif + struct solid_t { int index; @@ -23,6 +29,27 @@ struct solid_t objectparams_t params; }; +#ifdef NEO +inline void ZeroSolid(solid_t& solid) +{ + if constexpr (!std::is_trivially_copyable_v< + std::remove_cvref_t>) + { + static_assert(sizeof(solid) == 1616); + solid.index = 0; + solid.name[0] = '\0'; + solid.parent[0] = '\0'; + solid.surfaceprop[0] = '\0'; + solid.massCenterOverride.Zero(); + + static_assert(std::is_trivially_constructible_v< + decltype(solid.params)>); + solid.params = {}; + } + else memset( &solid, 0, sizeof(solid) ); +} +#endif + struct fluid_t { int index; diff --git a/src/public/vphysics_interface.h b/src/public/vphysics_interface.h index 55e3518080..ba8d032823 100644 --- a/src/public/vphysics_interface.h +++ b/src/public/vphysics_interface.h @@ -18,6 +18,9 @@ #include "mathlib/vector4d.h" #include "vcollide.h" +#ifdef NEO +#include +#endif // ------------------------------------------------------------------------------------ // UNITS: @@ -1043,6 +1046,21 @@ struct springparams_t { springparams_t() { +#ifdef NEO + if constexpr (!std::is_trivially_copyable_v) + { + static_assert(sizeof(*this) == 44); + constant = 0; + naturalLength = 0; + damping = 0; + relativeDamping = 0; + startPosition.Zero(); + endPosition.Zero(); + useLocalPositions = false; + onlyStretch = false; + } + else +#endif memset( this, 0, sizeof(*this) ); } float constant; // spring constant From 3dae6eac76f2354943574fea0b92650a29cd16f2 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 24 Dec 2025 09:44:12 +0200 Subject: [PATCH 73/96] Use std::swap for V_swap --- src/public/mathlib/mathlib.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/public/mathlib/mathlib.h b/src/public/mathlib/mathlib.h index 87d569e330..d9e19bebb8 100644 --- a/src/public/mathlib/mathlib.h +++ b/src/public/mathlib/mathlib.h @@ -19,6 +19,7 @@ #ifdef NEO #include +#include #endif // For MMX intrinsics @@ -745,6 +746,18 @@ template<> FORCEINLINE QAngleByValue Lerp( float flPercent, const #endif // VECTOR_NO_SLOW_OPERATIONS +#ifdef NEO +// NEO NOTE (Rain): +// SDK version was causing problems with modern compilers at more pedantic warning levels. +// Since we don't appear to run into any problems with std::swap, as noted by the original +// comment below, switching back. + +template +constexpr void V_swap(T& x, T& y) noexcept +{ + std::swap(x, y); +} +#else /// Same as swap(), but won't cause problems with std::swap template FORCEINLINE void V_swap( T& x, T& y ) @@ -753,6 +766,7 @@ FORCEINLINE void V_swap( T& x, T& y ) x = y; y = temp; } +#endif template FORCEINLINE T AVG(T a, T b) { From 4ab527b9fe6351729600f61b3e250ac772826f47 Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 23 Dec 2025 20:37:11 +0200 Subject: [PATCH 74/96] Avoid dangling pointer from reference The memory is technically properly allocated in the reentrant pReturn->ConvertToCopiedData() call in the vscript binding macros, but as the reference goes out of scope it could technically blow up. This change makes g++-14 (SteamRT 14.2.0-19~steamrt3.1+bsrt3.1) 14.2.0 happy for the release build with -Wall --- src/public/vscript/variant.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/public/vscript/variant.h b/src/public/vscript/variant.h index dbc2e4286e..e09b9bc360 100644 --- a/src/public/vscript/variant.h +++ b/src/public/vscript/variant.h @@ -140,11 +140,19 @@ class CVariantBase void operator=( uint64 i ) { Free(); m_type = FIELD_UINT64; m_uint64 = i; } void operator=( float f ) { Free(); m_type = FIELD_FLOAT; m_float = f; } void operator=( float64 f ) { Free(); m_type = FIELD_FLOAT64; m_float64 = f; } +#ifdef NEO + void operator=( const Vector2D &vec ) { CopyData( vec, true ); } + void operator=( const Vector &vec ) { CopyData( vec, true ); } +// void operator=( const Vector4D &vec ) { CopyData( vec, true ); } + void operator=( const QAngle &vec ) { CopyData( vec, true ); } + void operator=( const Quaternion &q ) { CopyData( q, true ); } +#else void operator=( const Vector2D &vec ) { CopyData( vec ); } void operator=( const Vector &vec ) { CopyData( vec ); } // void operator=( const Vector4D &vec ) { CopyData( vec ); } void operator=( const QAngle &vec ) { CopyData( vec ); } void operator=( const Quaternion &q ) { CopyData( q ); } +#endif void operator=( const Vector2D *vec ) { CopyData( *vec ); } void operator=( QAngle *a ) { CopyData( *a ); } void operator=( const QAngle *a ) { CopyData( *a ); } From 8da5469e02435509578fe652c5cd25925222d219 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 24 Dec 2025 10:34:58 +0200 Subject: [PATCH 75/96] Fix backslash-newline at end of file g++-14 (SteamRT 14.2.0-19~steamrt3.1+bsrt3.1) 14.2.0 --- src/game/shared/neo/achievements_neo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/shared/neo/achievements_neo.h b/src/game/shared/neo/achievements_neo.h index c944f9ea9e..07d71708fa 100644 --- a/src/game/shared/neo/achievements_neo.h +++ b/src/game/shared/neo/achievements_neo.h @@ -37,4 +37,4 @@ DECLARE_ACHIEVEMENT_( CAchievementNEO_##achievementID, achievementID, achievemen DECLARE_NEO_ACHIEVEMENT_( className, achievementID, achievementName, false ) #define DECLARE_NEO_ACHIEVEMENT_HIDDEN( className, achievementID, achievementName ) \ - DECLARE_NEO_ACHIEVEMENT_( className, achievementID, achievementName, true ) \ No newline at end of file + DECLARE_NEO_ACHIEVEMENT_( className, achievementID, achievementName, true ) From bcb832d504ec76007162e4eee48050fcdcf3b88a Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 24 Dec 2025 13:20:09 +0200 Subject: [PATCH 76/96] suppress array index warning --- src/game/server/player_lagcompensation.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/server/player_lagcompensation.cpp b/src/game/server/player_lagcompensation.cpp index 020af6fccb..14884fae65 100644 --- a/src/game/server/player_lagcompensation.cpp +++ b/src/game/server/player_lagcompensation.cpp @@ -446,6 +446,10 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, float flTar VPROF_BUDGET( "BacktrackPlayer", "CLagCompensationManager" ); int pl_index = pPlayer->entindex() - 1; +#ifdef NEO + Assert(pl_index >= 0); + pl_index = Max(0, pl_index); +#endif // get track history of this player CUtlFixedLinkedList< LagRecord > *track = &m_PlayerTrack[ pl_index ]; From 94e33e4534194ba1eccaf1d977c80a89feb0f3bb Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 24 Dec 2025 13:43:32 +0200 Subject: [PATCH 77/96] Fix uninitialized struct bug --- src/game/server/hl2/vehicle_airboat.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/game/server/hl2/vehicle_airboat.cpp b/src/game/server/hl2/vehicle_airboat.cpp index f29931c052..b76b886ea2 100644 --- a/src/game/server/hl2/vehicle_airboat.cpp +++ b/src/game/server/hl2/vehicle_airboat.cpp @@ -2061,15 +2061,23 @@ void CPropAirboat::VPhysicsUpdate( IPhysicsObject *pPhysics ) //----------------------------------------------------------------------------- float CPropAirboat::CalculatePhysicsStressDamage( vphysics_objectstress_t *pStressOut, IPhysicsObject *pPhysics ) { +#ifdef NEO + CalculateObjectStress( pPhysics, this, pStressOut); +#else vphysics_objectstress_t stressOut; CalculateObjectStress( pPhysics, this, &stressOut ); +#endif //if ( ( stressOut.exertedStress > 100 ) || ( stressOut.receivedStress > 100 ) ) // Msg( "stress: %f %d %f\n", stressOut.exertedStress, stressOut.hasNonStaticStress, stressOut.receivedStress ); // Make sure the stress isn't from being stuck inside some static object. // If we're being crushed by more than the fatal stress amount, kill the driver. +#ifdef NEO + if ( pStressOut->hasNonStaticStress && ( pStressOut->receivedStress > airboat_fatal_stress.GetFloat() ) ) +#else if ( stressOut.hasNonStaticStress && ( stressOut.receivedStress > airboat_fatal_stress.GetFloat() ) ) +#endif { // if stuck, don't do this! if ( !(pPhysics->GetGameFlags() & FVPHYSICS_PENETRATING) ) From 035ab1961f001e3b0bc4c3df0927c83279ab4e03 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 24 Dec 2025 14:26:54 +0200 Subject: [PATCH 78/96] Fix array mismatched bound --- src/game/shared/saverestore.cpp | 5 ++++- src/public/bone_setup.cpp | 5 ++++- src/public/mathlib/mathlib.h | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/game/shared/saverestore.cpp b/src/game/shared/saverestore.cpp index 3ece450f71..a6d0f0cc36 100644 --- a/src/game/shared/saverestore.cpp +++ b/src/game/shared/saverestore.cpp @@ -1623,8 +1623,11 @@ void CRestore::StartBlock( SaveRestoreRecordHeader_t *pHeader ) } //------------------------------------- - +#ifdef NEO +void CRestore::StartBlock( char szBlockName[SIZE_BLOCK_NAME_BUF] ) +#else void CRestore::StartBlock( char szBlockName[] ) +#endif { SaveRestoreRecordHeader_t header; StartBlock( &header ); diff --git a/src/public/bone_setup.cpp b/src/public/bone_setup.cpp index 9c0bd5b7f4..d788c9c41f 100644 --- a/src/public/bone_setup.cpp +++ b/src/public/bone_setup.cpp @@ -5120,8 +5120,11 @@ float Studio_GetController( const CStudioHdr *pStudioHdr, int iController, float // Purpose: Calculates default values for the pose parameters // Output: fills in an array //----------------------------------------------------------------------------- - +#ifdef NEO +void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[MAXSTUDIOPOSEPARAM], int nCount ) +#else void Studio_CalcDefaultPoseParameters( const CStudioHdr *pStudioHdr, float flPoseParameter[], int nCount ) +#endif { int nPoseCount = pStudioHdr->GetNumPoseParameters(); int nNumParams = MIN( nCount, MAXSTUDIOPOSEPARAM ); diff --git a/src/public/mathlib/mathlib.h b/src/public/mathlib/mathlib.h index d9e19bebb8..13770afb74 100644 --- a/src/public/mathlib/mathlib.h +++ b/src/public/mathlib/mathlib.h @@ -1637,8 +1637,11 @@ float Hermite_Spline( float p2, float t ); - +#ifdef NEO +void Hermite_SplineBasis( float t, float basis[4] ); +#else void Hermite_SplineBasis( float t, float basis[] ); +#endif void Hermite_Spline( const Quaternion &q0, From 0d22b7b311720f30151d10c4e039749ed82d81f8 Mon Sep 17 00:00:00 2001 From: Rain Date: Wed, 24 Dec 2025 14:27:31 +0200 Subject: [PATCH 79/96] non-const ref can't bind to bit-field --- src/public/tier1/utlblockmemory.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/public/tier1/utlblockmemory.h b/src/public/tier1/utlblockmemory.h index ae987c161b..47e826e106 100644 --- a/src/public/tier1/utlblockmemory.h +++ b/src/public/tier1/utlblockmemory.h @@ -136,10 +136,27 @@ CUtlBlockMemory::~CUtlBlockMemory() template< class T, class I > void CUtlBlockMemory::Swap( CUtlBlockMemory< T, I > &mem ) { +#ifdef NEO // non-const reference cannot bind to bit-field + decltype(m_pMemory) tmpMemory = m_pMemory; + decltype(m_nBlocks) blocks = m_nBlocks; + decltype(m_nIndexMask) idxMask = m_nIndexMask; + decltype(m_nIndexShift) idxShift = m_nIndexShift; + + m_pMemory = mem.m_pMemory; + m_nBlocks = mem.m_nBlocks; + m_nIndexMask = mem.m_nIndexMask; + m_nIndexShift = mem.m_nIndexShift; + + mem.m_pMemory = tmpMemory; + mem.m_nBlocks = blocks; + mem.m_nIndexMask = idxMask; + mem.m_nIndexShift = idxShift; +#else V_swap( m_pMemory, mem.m_pMemory ); V_swap( m_nBlocks, mem.m_nBlocks ); V_swap( m_nIndexMask, mem.m_nIndexMask ); V_swap( m_nIndexShift, mem.m_nIndexShift ); +#endif } From 449c2d645d17d0b574f9dbaf6b2b6c7c9dcb32ed Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 25 Dec 2025 18:43:42 +0200 Subject: [PATCH 80/96] Fix unused member vars --- src/game/client/c_pixel_visibility.cpp | 7 ++++--- src/game/client/camomaterialproxy.cpp | 5 ++--- src/game/client/history_resource.h | 5 ++--- src/game/client/hud_basetimer.h | 5 ++--- src/game/server/NextBot/Path/NextBotPathFollow.h | 5 ++--- src/game/server/hl2/npc_attackchopper.cpp | 8 ++------ src/public/bone_setup.h | 5 ++--- src/public/tier1/CommandBuffer.h | 2 ++ src/public/vgui_controls/AnalogBar.h | 2 ++ src/public/vgui_controls/FileOpenDialog.h | 5 ++--- src/public/vgui_controls/Frame.h | 5 ++--- src/public/vgui_controls/ListPanel.h | 7 +++---- src/public/vgui_controls/MessageMap.h | 5 ++--- src/public/vgui_controls/ProgressBar.h | 5 ++--- src/public/vgui_controls/TextEntry.h | 10 ++++------ 15 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/game/client/c_pixel_visibility.cpp b/src/game/client/c_pixel_visibility.cpp index 2766f2fb1f..e33d0bf44c 100644 --- a/src/game/client/c_pixel_visibility.cpp +++ b/src/game/client/c_pixel_visibility.cpp @@ -261,10 +261,11 @@ class CPixelVisibilityQuery unsigned short m_wasQueriedThisFrame : 1; unsigned short m_failed : 1; unsigned short m_hasValidQueryResults : 1; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifdef NEO // don't name padding bits to make Clang happy + unsigned short : 13; +#else unsigned short m_pad : 13; +#endif unsigned short m_viewID; friend void PixelVisibility_ShiftVisibilityViews( int iSourceViewID, int iDestViewID ); //need direct access to private data to make shifting smooth diff --git a/src/game/client/camomaterialproxy.cpp b/src/game/client/camomaterialproxy.cpp index f06f695a5c..f7c61eadd8 100644 --- a/src/game/client/camomaterialproxy.cpp +++ b/src/game/client/camomaterialproxy.cpp @@ -97,10 +97,9 @@ class CCamoMaterialProxy : public CEntityMaterialProxy #if 0 cache_user_t m_camoImageDataCache; #endif -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO unsigned char m_CamoPalette[256][3]; +#endif // these represent that part of the entitiy's bounding box that we // want to cast rays through to get colors for the camo Vector m_SubBoundingBoxMin; // normalized diff --git a/src/game/client/history_resource.h b/src/game/client/history_resource.h index 1a3e4bad44..c0b9f649c2 100644 --- a/src/game/client/history_resource.h +++ b/src/game/client/history_resource.h @@ -103,10 +103,9 @@ class CHudHistoryResource : public CHudElement, public vgui::Panel private: // these vars are for hl1-port compatibility -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO int m_iHistoryGap; +#endif int m_iCurrentHistorySlot; bool m_bDoNotDraw; wchar_t m_wcsAmmoFullMsg[16]; diff --git a/src/game/client/hud_basetimer.h b/src/game/client/hud_basetimer.h index 83f6ef5f2b..b85725f227 100644 --- a/src/game/client/hud_basetimer.h +++ b/src/game/client/hud_basetimer.h @@ -38,10 +38,9 @@ class CHudBaseTimer : public CHudNumericDisplay int m_iMinutes; int m_iSeconds; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO wchar_t m_LabelText[32]; +#endif CPanelAnimationVar( float, m_flBlur, "Blur", "0" ); CPanelAnimationVar( float, m_flAlphaOverride, "Alpha", "255" ); diff --git a/src/game/server/NextBot/Path/NextBotPathFollow.h b/src/game/server/NextBot/Path/NextBotPathFollow.h index 4b0316f1a6..1dad94ed61 100644 --- a/src/game/server/NextBot/Path/NextBotPathFollow.h +++ b/src/game/server/NextBot/Path/NextBotPathFollow.h @@ -49,11 +49,10 @@ class PathFollower : public Path bool CheckProgress( INextBot *bot ); bool IsAtGoal( INextBot *bot ) const; // return true if reached current path goal +#ifndef NEO //bool IsOnStairs( INextBot *bot ) const; // return true if bot is standing on a stairway -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif bool m_isOnStairs; +#endif Path::ResultType m_result = NO_PATH; diff --git a/src/game/server/hl2/npc_attackchopper.cpp b/src/game/server/hl2/npc_attackchopper.cpp index e42cefbeb4..77caa3490c 100644 --- a/src/game/server/hl2/npc_attackchopper.cpp +++ b/src/game/server/hl2/npc_attackchopper.cpp @@ -1648,15 +1648,11 @@ class CTraceFilterChopper : public CTraceFilterSimple CTraceFilterChopper( const IHandleEntity *passentity, int collisionGroup ); virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask ); +#ifndef NEO private: -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif const IHandleEntity *m_pPassEnt; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif int m_collisionGroup; +#endif }; CTraceFilterChopper::CTraceFilterChopper( const IHandleEntity *passentity, int collisionGroup ) : diff --git a/src/public/bone_setup.h b/src/public/bone_setup.h index 00c6d24d56..9a3d6ec002 100644 --- a/src/public/bone_setup.h +++ b/src/public/bone_setup.h @@ -451,10 +451,9 @@ class CBoneCache unsigned short m_cachedBoneCount; unsigned short m_matrixOffset; unsigned short m_cachedToStudioOffset; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO unsigned short m_boneOutOffset; +#endif }; CBoneCache *Studio_GetBoneCache( memhandle_t cacheHandle ); diff --git a/src/public/tier1/CommandBuffer.h b/src/public/tier1/CommandBuffer.h index cde77e3c15..f364416ca6 100644 --- a/src/public/tier1/CommandBuffer.h +++ b/src/public/tier1/CommandBuffer.h @@ -119,7 +119,9 @@ class CCommandBuffer bool ParseArgV0( CUtlBuffer &buf, char *pArgv0, int nMaxLen, const char **pArgs ); char m_pArgSBuffer[ ARGS_BUFFER_LENGTH ]; +#ifndef NEO int m_nLastUsedArgSSize; +#endif int m_nArgSBufferSize; CUtlFixedLinkedList< Command_t > m_Commands; int m_nCurrentTick; diff --git a/src/public/vgui_controls/AnalogBar.h b/src/public/vgui_controls/AnalogBar.h index 2ae5131e1a..6bf1bc5fc5 100644 --- a/src/public/vgui_controls/AnalogBar.h +++ b/src/public/vgui_controls/AnalogBar.h @@ -81,7 +81,9 @@ class AnalogBar : public Panel float _analogValue; private: +#ifndef NEO int _segmentCount; +#endif int _segmentGap; int _segmentWide; int m_iBarInset; diff --git a/src/public/vgui_controls/FileOpenDialog.h b/src/public/vgui_controls/FileOpenDialog.h index 6ca0b45fa8..c7e340447f 100644 --- a/src/public/vgui_controls/FileOpenDialog.h +++ b/src/public/vgui_controls/FileOpenDialog.h @@ -142,10 +142,9 @@ class FileOpenDialog : public vgui::Frame vgui::Button *m_pNewFolderButton; vgui::Button *m_pOpenInExplorerButton; vgui::ImagePanel *m_pFolderIcon; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO vgui::Label *m_pFileTypeLabel; +#endif KeyValues *m_pContextKeyValues; diff --git a/src/public/vgui_controls/Frame.h b/src/public/vgui_controls/Frame.h index 4637330174..37ee0472b6 100644 --- a/src/public/vgui_controls/Frame.h +++ b/src/public/vgui_controls/Frame.h @@ -237,10 +237,9 @@ class Frame : public EditablePanel int m_iClientInsetX; int m_iClientInsetY; int m_iTitleTextInsetX; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO int m_nGripperWidth; +#endif VPANEL m_hPreviousModal; HFont m_hCustomTitleFont; diff --git a/src/public/vgui_controls/ListPanel.h b/src/public/vgui_controls/ListPanel.h index da21fbdb5e..fac1c15435 100644 --- a/src/public/vgui_controls/ListPanel.h +++ b/src/public/vgui_controls/ListPanel.h @@ -335,13 +335,12 @@ class ListPanel : public Panel bool m_bSortAscending : 1; bool m_bSortAscendingSecondary : 1; #if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] + [[maybe_unused]] // Clang false positive #endif bool m_bCanSelectIndividualCells : 1; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO bool m_bShiftHeldDown : 1; +#endif bool m_bMultiselectEnabled : 1; bool m_bAllowUserAddDeleteColumns : 1; bool m_bDeleteImageListWhenDone : 1; diff --git a/src/public/vgui_controls/MessageMap.h b/src/public/vgui_controls/MessageMap.h index 85999114b2..e6570823bc 100644 --- a/src/public/vgui_controls/MessageMap.h +++ b/src/public/vgui_controls/MessageMap.h @@ -345,10 +345,9 @@ class CBuildFactoryHelper // Next factory in list CBuildFactoryHelper *m_pNext; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO int m_Type; +#endif PANELCREATEFUNC m_CreateFunc; char const *m_pClassName; }; diff --git a/src/public/vgui_controls/ProgressBar.h b/src/public/vgui_controls/ProgressBar.h index 6736161b64..4f192923fd 100644 --- a/src/public/vgui_controls/ProgressBar.h +++ b/src/public/vgui_controls/ProgressBar.h @@ -77,10 +77,9 @@ class ProgressBar : public Panel float _progress; private: -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO int _segmentCount; +#endif int _segmentGap; int _segmentWide; int m_iBarInset; diff --git a/src/public/vgui_controls/TextEntry.h b/src/public/vgui_controls/TextEntry.h index 8e036330ad..0ee7622e3e 100644 --- a/src/public/vgui_controls/TextEntry.h +++ b/src/public/vgui_controls/TextEntry.h @@ -330,10 +330,9 @@ class TextEntry : public Panel bool _editable; // whether text is editable or not bool _mouseSelection; // whether we are highlighting text or not (selecting text) bool _mouseDragSelection; // tells weather mouse is outside window and button is down so we select text -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO int _mouseSelectCursorStart; // where mouse button was pressed down in text window +#endif long _cursorNextBlinkTime; // time of next cursor blink int _cursorBlinkRate; // speed of cursor blinking int _select[2]; // select[1] is the offset in the text to where the cursor is currently @@ -368,10 +367,9 @@ class TextEntry : public Panel int _recalculateBreaksIndex; // tells next linebreakindex index to Start recalculating line breaks bool _selectAllOnFirstFocus : 1; // highlights all text in window when focus is gained. bool _selectAllOnFocusAlways : 1; -#if defined(NEO) && defined(COMPILER_CLANG) - [[maybe_unused]] -#endif +#ifndef NEO bool _firstFocusStatus; // keep track if we've had that first focus or not +#endif bool m_bAllowNumericInputOnly; bool m_bAllowNonAsciiCharacters; bool m_bAutoProgressOnHittingCharLimit; From 7aa73e56ef07e64865ec2aacf08496f0bc2dd0bd Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 25 Dec 2025 22:05:52 +0200 Subject: [PATCH 81/96] Check getcwd return value for errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ``` error: ignoring return value of ‘char* getcwd(char*, size_t)’ declared with attribute ‘warn_unused_result’ [-Werror=unused-result] 281 | _getcwd( szCwd, sizeof( szCwd ) ); ``` --- src/tier1/interface.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tier1/interface.cpp b/src/tier1/interface.cpp index 7c77028afa..ee4d995205 100644 --- a/src/tier1/interface.cpp +++ b/src/tier1/interface.cpp @@ -36,6 +36,10 @@ #include "xbox/xbox_win32stubs.h" #endif +#ifdef NEO +#include +#include +#endif // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -278,7 +282,18 @@ CSysModule *Sys_LoadModule( const char *pModuleName, Sys_Flags flags /* = SYS_NO if ( !Q_IsAbsolutePath( pModuleName ) ) { // full path wasn't passed in, using the current working dir +#ifdef NEO + const auto* getCwdRes = +#endif _getcwd( szCwd, sizeof( szCwd ) ); +#ifdef NEO + if (!getCwdRes) + { + Assert(false); + Warning("%s(%s, 0x%X): _getcwd failed: %s\n", __FUNCTION__, pModuleName, flags, strerror(errno)); + return nullptr; + } +#endif if ( IsX360() ) { int i = CommandLine()->FindParm( "-basedir" ); From 6d6bed69a5ced79b1f7f76a3e44704bb62cb7217 Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 25 Dec 2025 22:27:57 +0200 Subject: [PATCH 82/96] Check system call retvals for errors --- src/game/client/neo/ui/neo_ui.cpp | 12 +++++++++++- src/vgui2/vgui_controls/FileOpenDialog.cpp | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/game/client/neo/ui/neo_ui.cpp b/src/game/client/neo/ui/neo_ui.cpp index ccea1ea8a2..6eac8c0bb8 100644 --- a/src/game/client/neo/ui/neo_ui.cpp +++ b/src/game/client/neo/ui/neo_ui.cpp @@ -2369,7 +2369,17 @@ void OpenURL(const char *szBaseUrl, const char *szPath) ; char syscmd[512] = {}; V_sprintf_safe(syscmd, "%s %s%s", CMD, szBaseUrl, szPath); - system(syscmd); + [[maybe_unused]] const auto sysRet = system(syscmd); +#ifdef LINUX + // Retvals are implementation-defined. + // Linux may declare system with "warn_unused_result", so we gotta check to avoid a warning. + constexpr auto linuxErrRet = -1; + if (sysRet == linuxErrRet) + { + Warning("%s system call failed: \"%s\"\n", __FUNCTION__, syscmd); + Assert(false); + } +#endif } const wchar_t *HintAlt(const wchar *wszKey, const wchar *wszController) diff --git a/src/vgui2/vgui_controls/FileOpenDialog.cpp b/src/vgui2/vgui_controls/FileOpenDialog.cpp index 718f8af425..a411a99447 100644 --- a/src/vgui2/vgui_controls/FileOpenDialog.cpp +++ b/src/vgui2/vgui_controls/FileOpenDialog.cpp @@ -855,7 +855,17 @@ void FileOpenDialog::OnNewFolder() void FileOpenDialog::OnOpenInExplorer() { char pCurrentDirectory[MAX_PATH]; +#ifdef NEO + pCurrentDirectory[0] = '\0'; +#endif GetCurrentDirectory( pCurrentDirectory, sizeof(pCurrentDirectory) ); +#ifdef NEO + if (!*pCurrentDirectory) + { + Assert(false); + return; + } +#endif // NEO #if !defined( _X360 ) && defined( WIN32 ) ShellExecute( NULL, NULL, pCurrentDirectory, NULL, NULL, SW_SHOWNORMAL ); #elif defined( OSX ) @@ -865,7 +875,18 @@ void FileOpenDialog::OnOpenInExplorer() #elif defined( LINUX ) char szCmd[ MAX_PATH * 2 ]; Q_snprintf( szCmd, sizeof(szCmd), "xdg-open \"%s\" &", pCurrentDirectory ); +#ifdef NEO + const int systemRes = +#endif // NEO ::system( szCmd ); +#ifdef NEO + if (systemRes == -1) + { + Assert(false); + Warning("%s: ::system(%s) returned %d. Last error: %s\n", + __FUNCTION__, szCmd, systemRes, strerror(errno)); + } +#endif // NEO #endif } From aaeca45dd4f492bb2eb2f5f11c908c7c63243241 Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 25 Dec 2025 23:07:13 +0200 Subject: [PATCH 83/96] Fix SHA1 algorithm compile --- src/public/tier1/checksum_sha1.h | 36 +++++++++++ src/tier1/checksum_sha1.cpp | 106 +++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) diff --git a/src/public/tier1/checksum_sha1.h b/src/public/tier1/checksum_sha1.h index d14e4a8b72..113c1ffd01 100644 --- a/src/public/tier1/checksum_sha1.h +++ b/src/public/tier1/checksum_sha1.h @@ -40,8 +40,13 @@ #include // Needed for strcat and strcpy #endif +#ifdef NEO +#include "../public/filesystem.h" +#include +#else // If you're compiling big endian, just comment out the following line #define SHA1_LITTLE_ENDIAN +#endif typedef union { @@ -56,6 +61,10 @@ const unsigned int k_cchHash = 41; // k_cubHash * 2, plus 1 for terminator typedef unsigned char SHADigest_t[ k_cubHash ]; #pragma pack( pop ) +#ifdef NEO +class IFileSystem; +#endif + #if !defined(_MINIMUM_BUILD_) class CSHA1 #else @@ -63,6 +72,28 @@ class Minimum_CSHA1 #endif { public: +#ifdef NEO + // Rotate x bits to the left + constexpr static auto ROL32(auto _val32, auto _nBits) + { + return (((_val32) << (_nBits)) | ((_val32) >> (32 - (_nBits)))); + } + + constexpr auto SHABLK0(size_t i) + { + constexpr bool isLittleEndian = (std::endian::native == std::endian::little); + if constexpr (isLittleEndian) + { + return (m_block->l[i] = + (ROL32(m_block->l[i], 24) & 0xFF00FF00) | (ROL32(m_block->l[i], 8) & 0x00FF00FF)); + } + else + { + return (m_block->l[i]); + } + } +#endif // NEO + // Two different formats for ReportHash(...) enum { @@ -89,7 +120,12 @@ class Minimum_CSHA1 // Update the hash value void Update(unsigned char *data, unsigned int len); #if !defined(_MINIMUM_BUILD_) +#ifdef NEO + [[nodiscard]] + bool HashFile(const char* szFileName, IFileSystem* fs); +#else bool HashFile(char *szFileName); +#endif #endif // Finalize hash and report diff --git a/src/tier1/checksum_sha1.cpp b/src/tier1/checksum_sha1.cpp index 7b06f7535b..10bc517a65 100644 --- a/src/tier1/checksum_sha1.cpp +++ b/src/tier1/checksum_sha1.cpp @@ -31,8 +31,13 @@ #include "tier1/checksum_sha1.h" #endif +#if defined(NEO) && defined(DEBUG) +#include +#endif + #define MAX_FILE_READ_BUFFER 8000 +#ifndef NEO // Rotate x bits to the left #ifndef ROL32 #define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits)))) @@ -44,6 +49,7 @@ #else #define SHABLK0(i) (m_block->l[i]) #endif +#endif #define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \ ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) @@ -172,39 +178,139 @@ void CSHA1::Update(unsigned char *data, unsigned int len) #if !defined(_MINIMUM_BUILD_) // Hash in file contents +#ifdef NEO +bool CSHA1::HashFile(const char* szFileName, IFileSystem* fs) +#else bool CSHA1::HashFile(char *szFileName) +#endif { +#ifdef NEO +#pragma push_macro("has_fopen") +#pragma push_macro("dont_use_fopen") +#undef dont_use_fopen +#define dont_use_fopen 0xbadc0de +#if (fopen == dont_use_fopen) +#define has_fopen 0 +#else +#define has_fopen 1 +#endif +#undef dont_use_fopen +#pragma pop_macro("dont_use_fopen") +#endif + uint32 ulFileSize = 0, ulRest = 0, ulBlocks = 0; uint32 i = 0; unsigned char uData[MAX_FILE_READ_BUFFER]; +#if defined(NEO) && !has_fopen + FileHandle_t fIn = nullptr; +#else FILE *fIn = NULL; +#endif if(szFileName == NULL) return(false); +#if defined(NEO) && !has_fopen + if (!fs) + { +#ifdef DBGFLAG_ASSERT + Assert(false); +#endif + return false; + } + if (!fs->FileExists(szFileName)) return false; + + fIn = fs->Open(szFileName, "rb"); + if (!fIn) return false; + fs->Seek(fIn, 0, FileSystemSeek_t::FILESYSTEM_SEEK_TAIL); + ulFileSize = fs->Tell(fIn); + fs->Seek(fIn, 0, FileSystemSeek_t::FILESYSTEM_SEEK_HEAD); +#else if((fIn = fopen(szFileName, "rb")) == NULL) return(false); fseek(fIn, 0, SEEK_END); ulFileSize = ftell(fIn); fseek(fIn, 0, SEEK_SET); +#endif ulRest = ulFileSize % MAX_FILE_READ_BUFFER; ulBlocks = ulFileSize / MAX_FILE_READ_BUFFER; +#ifdef NEO + unsigned short freadRes; +#endif // NEO for(i = 0; i < ulBlocks; i++) { +#ifdef NEO +#ifdef DEBUG + static_assert(sizeof(uData) == MAX_FILE_READ_BUFFER); + static_assert(sizeof(uData) <= std::numeric_limits::max()); + static_assert(sizeof(uData) <= std::numeric_limits::max()); +#endif // DEBUG +#endif // NEO + +#ifdef NEO + freadRes = (decltype(freadRes)) +#endif +#if defined(NEO) && !has_fopen + fs->Read(uData, 1 * MAX_FILE_READ_BUFFER, fIn); +#else fread(uData, 1, MAX_FILE_READ_BUFFER, fIn); +#endif + +#ifdef NEO + if (freadRes != MAX_FILE_READ_BUFFER) + { +#ifdef DBGFLAG_ASSERT + Assert(false); +#endif // DBGFLAG_ASSERT + return false; + } +#endif // NEO Update(uData, MAX_FILE_READ_BUFFER); } if(ulRest != 0) { +#ifdef NEO + if (sizeof(uData) < (size_t)1 * ulRest) + { +#ifdef DBGFLAG_ASSERT + Assert(false); +#endif // DBGFLAG_ASSERT + return false; + } + freadRes = (decltype(freadRes)) +#endif // NEO + +#if defined(NEO) && !has_fopen + fs->Read(uData, ulRest, fIn); +#else fread(uData, 1, ulRest, fIn); +#endif + +#ifdef NEO + if (freadRes != ulRest) + { +#ifdef DBGFLAG_ASSERT + Assert(false); +#endif // DBGFLAG_ASSERT + return false; + } +#endif // NEO Update(uData, ulRest); } +#if defined(NEO) && !has_fopen + fs->Close(fIn); +#else fclose(fIn); +#endif fIn = NULL; +#ifdef NEO +#undef has_fopen +#pragma pop_macro("has_fopen") +#endif return(true); } #endif From 4f006160ff02e38a210e68b544253f50b83be5cf Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 26 Dec 2025 13:16:16 +0200 Subject: [PATCH 84/96] Windows runner image from latest -> 2025 Soft-pin the image name to Windows Server 2025 to avoid breakage if/when the latest tag starts pointing to a newer image. --- .github/workflows/cibuild.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cibuild.yml b/.github/workflows/cibuild.yml index 4168e5e77e..7ef4f68865 100644 --- a/.github/workflows/cibuild.yml +++ b/.github/workflows/cibuild.yml @@ -161,7 +161,7 @@ jobs: matrix: platform: - - { display_name: 'Windows Native Libraries', os: windows-latest, preset_os: windows } + - { display_name: 'Windows Native Libraries', os: windows-2025, preset_os: windows } preset_build_type: - { display_name: 'Debug', name: debug } @@ -276,7 +276,7 @@ jobs: pack-resources: name: Windows Native Resources - runs-on: windows-latest + runs-on: windows-2025 defaults: run: From 5c63db65115dd92aae2a8a71894d7625125553de Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 26 Dec 2025 18:07:41 +0200 Subject: [PATCH 85/96] Add tests for bit_cast --- src/common/neo/narrow_cast.h | 5 +- src/common/neo/test_bit_cast.h | 126 ++++++++++++++++++++++++++++ src/game/client/cdll_client_int.cpp | 9 ++ src/tier1/CMakeLists.txt | 7 ++ 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 src/common/neo/test_bit_cast.h diff --git a/src/common/neo/narrow_cast.h b/src/common/neo/narrow_cast.h index 771988b2fb..d62ad861b4 100644 --- a/src/common/neo/narrow_cast.h +++ b/src/common/neo/narrow_cast.h @@ -19,8 +19,8 @@ #ifdef PARANOID_NARROWING template -concept Numeric = std::is_arithmetic_v> || - std::is_enum_v>; +concept Numeric = ((std::is_arithmetic_v> && std::numeric_limits>::is_bounded) + || std::is_enum_v>); template concept DifferentTypes = (!std::is_same_v); @@ -33,6 +33,7 @@ constexpr void AssertFitsInto(const Value& input) { using inputType = std::remove_reference_t; using outputType = std::add_const_t; + static_assert(!std::is_reference_v); static_assert(!std::is_reference_v); diff --git a/src/common/neo/test_bit_cast.h b/src/common/neo/test_bit_cast.h new file mode 100644 index 0000000000..152a8eb505 --- /dev/null +++ b/src/common/neo/test_bit_cast.h @@ -0,0 +1,126 @@ +#pragma once + +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) + +#include "bit_cast.h" +#include "narrow_cast.h" + +#include "tier0/dbg.h" + +#include +#include +#include + +namespace neo::test +{ + namespace + { + template + requires (neo::IsBitCastable()) + void _verifyRoundtrip(From input) + { + To a = neo::bit_cast(input); + From b = neo::bit_cast(a); + static_assert(std::is_same_v); + Assert(b == input); + } + + template + requires std::is_floating_point_v + static T Rnd() + { + static std::default_random_engine e; + static std::uniform_real_distribution d{ T{0},T{1} }; + return d(e); + } + + template + requires (neo::IsBitCastable() + && std::is_signed_v && std::is_signed_v) + constexpr void testToFrom() + { + constexpr bool bothTypesIntegral = ( + std::is_integral_v> && + std::is_integral_v>); + + _verifyRoundtrip(From{}); + if constexpr (bothTypesIntegral) + _verifyRoundtrip>(std::make_unsigned_t{}); + + for (auto i = 0; i < 10; ++i) + { + const auto r = Rnd(); + + // Just something that most types can fit, for testing. + constexpr auto range = std::numeric_limits::max(); + + static_assert(range <= std::numeric_limits::max()); + static_assert(range <= std::numeric_limits::max()); + _verifyRoundtrip(static_cast(range * r)); + + if constexpr (bothTypesIntegral) + _verifyRoundtrip>(static_cast(range * r)); + + static_assert(-range >= std::numeric_limits::lowest()); + static_assert(-range >= std::numeric_limits::lowest()); + _verifyRoundtrip(static_cast(-range * r)); + } + } + + // For a sequence of signed types, tests all bitcastable permutations against each other. + template + void testTypes() + { + size_t nTests = 0, nTestsSkipped = 0; + ([&]() + { + ([&]() + { + ++nTests; + if constexpr (neo::IsBitCastable()) + { + testToFrom(); + } + else + { + ++nTestsSkipped; + } + }.template operator()(), ...); + }.template operator()(), ...); + Assert(nTests >= nTestsSkipped); + AssertMsg1(nTests != nTestsSkipped, "All %zu test(s) skipped!", nTests); + } + } + + // Test type conversions using the custom helper utilities. + void conversions() + { + // bool doesn't play nice with the signed/unsigned tests in testTypes, + // so test it manually here + constexpr char vals[] = { + std::numeric_limits::lowest(), + 0x00, + 0x01, + 0x10, + 0x11, + std::numeric_limits::max(), + }; + for (const auto v : vals) + { + _verifyRoundtrip(v); + _verifyRoundtrip(v); + _verifyRoundtrip(v); + _verifyRoundtrip(v); + } + + testTypes< + char + ,int + ,float + ,double + ,long + ,long long + >(); + } +} +#endif // DEBUG diff --git a/src/game/client/cdll_client_int.cpp b/src/game/client/cdll_client_int.cpp index 61635eecdc..01cda4bbd3 100644 --- a/src/game/client/cdll_client_int.cpp +++ b/src/game/client/cdll_client_int.cpp @@ -174,6 +174,8 @@ extern vgui::IInputInternal *g_InputInternal; #endif #ifdef NEO +#include "../../common/neo/test_bit_cast.h" + #include "neo_version.h" #include "neo_version_number.h" #include "ui/neo_loading.h" @@ -1398,6 +1400,13 @@ void CHLClient::PostInit() #endif #ifdef NEO +#if defined(DEBUG) && defined(DBGFLAG_ASSERT) + // Tests + { + neo::test::conversions(); + } +#endif + if (g_pCVar) { g_pCVar->FindVar("neo_name")->InstallChangeCallback(NeoConVarStrLimitChangeCallback); diff --git a/src/tier1/CMakeLists.txt b/src/tier1/CMakeLists.txt index 71e19bb9bb..8371c3d146 100644 --- a/src/tier1/CMakeLists.txt +++ b/src/tier1/CMakeLists.txt @@ -136,6 +136,13 @@ target_sources_grouped( ${CMAKE_SOURCE_DIR}/utils/lzma/C/7zTypes.h ) +target_sources_grouped( + TARGET tier1 + NAME "Tests" + FILES + ${CMAKE_SOURCE_DIR}/common/neo/test_bit_cast.h +) + target_sources_grouped( TARGET tier1 NAME "Header Files" From 15a7c3d70a98a28732d33001630de353fee6242f Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 27 Dec 2025 20:39:51 +0200 Subject: [PATCH 86/96] Fix CMakeLists compiler options for steamrt3 Clang 11 --- src/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eeb5985cf5..f66e14f934 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -321,7 +321,6 @@ if(OS_LINUX OR OS_MACOS) -Wno-multichar -Wno-write-strings -Wno-unused-variable - $<$:-Wno-unused-but-set-variable> -Wno-unused-function -Wno-unknown-pragmas -Wno-unused-parameter @@ -335,6 +334,9 @@ if(OS_LINUX OR OS_MACOS) #-Wno-address $<$:-Wno-inconsistent-missing-override> + # Unsupported by the steamrt3 Clang compiler + $<$,$>>:-Wno-unused-but-set-variable> + -Werror=return-type -fdiagnostics-show-option -Wformat -Wformat-security From 58e5492d5544ef0e21bf82bd82674b419e648fc2 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 27 Dec 2025 23:44:54 +0200 Subject: [PATCH 87/96] Cleanup bit_cast --- src/common/neo/bit_cast.h | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/common/neo/bit_cast.h b/src/common/neo/bit_cast.h index abe0a9e23e..66a7e242ad 100644 --- a/src/common/neo/bit_cast.h +++ b/src/common/neo/bit_cast.h @@ -16,10 +16,11 @@ #if STD_BIT_CAST_SUPPORTED #include +#else +#include #endif #include -#include #include #include @@ -37,27 +38,19 @@ namespace neo ); } - // Will transparently call std::bit_cast when it's available and its constraints are satisfied. + // Will transparently call std::bit_cast when it's available. // Else, will perform a well-defined type pun using memcpy. // If you want a sanity check for the result, see BC_TEST template + requires (IsBitCastable()) constexpr auto bit_cast(const From& input) noexcept { - constexpr bool fromVoidPtr = std::is_same_v>>; #if STD_BIT_CAST_SUPPORTED - if constexpr (fromVoidPtr) -#endif - { - static_assert(fromVoidPtr || IsBitCastable()); - std::remove_cv_t output; - memcpy(std::addressof(output), std::addressof(input), sizeof(output)); - return output; - } -#if STD_BIT_CAST_SUPPORTED - else - { - return std::bit_cast(input); - } + return std::bit_cast(input); +#else + std::remove_cv_t output; + memcpy(std::addressof(output), std::addressof(input), sizeof(output)); + return output; #endif } From 0d91a3f6ff61412ff857905a2e5f5140f9546912 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 27 Dec 2025 23:43:27 +0200 Subject: [PATCH 88/96] Cleanup --- src/public/tier0/threadtools.h | 57 +++------------------------------- 1 file changed, 5 insertions(+), 52 deletions(-) diff --git a/src/public/tier0/threadtools.h b/src/public/tier0/threadtools.h index 81daaf93ee..6ba01feff9 100644 --- a/src/public/tier0/threadtools.h +++ b/src/public/tier0/threadtools.h @@ -18,10 +18,6 @@ #include "tier0/vcrmode.h" #include "tier0/vprof_telemetry.h" -#ifdef NEO -#include "../../common/neo/bit_cast.h" -#endif - #ifdef PLATFORM_WINDOWS_PC #include #endif @@ -623,24 +619,6 @@ class PLATFORM_CLASS CThreadLocalBase template class CThreadLocal : public CThreadLocalBase { -#if defined(NEO) && defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) - T Ref_Get() const - { -#ifdef PLATFORM_64BITS - void* pData = CThreadLocalBase::Get(); - return *reinterpret_cast(&pData); -#else -#ifdef COMPILER_MSVC -#pragma warning ( disable : 4311 ) -#endif - return reinterpret_cast(CThreadLocalBase::Get()); -#ifdef COMPILER_MSVC -#pragma warning ( default : 4311 ) -#endif -#endif - } -#endif - public: CThreadLocal() { @@ -654,25 +632,10 @@ class PLATFORM_CLASS CThreadLocalBase T Get() const { #ifdef PLATFORM_64BITS - void *pData = CThreadLocalBase::Get(); #ifdef NEO -#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) - const auto neoRes = neo::bit_cast(pData); - const auto memcpyImpl = [pData]()->T { - T ret; - memcpy(&ret, &pData, sizeof(ret)); - return ret; - }; - const auto memcpyRes = memcpyImpl(); - const auto refRes = Ref_Get(); - Assert(neoRes == memcpyRes); - Assert(neoRes == refRes); - return neoRes; -#else - return neo::bit_cast(pData); -#endif - + return reinterpret_cast( CThreadLocalBase::Get() ); #else + void *pData = CThreadLocalBase::Get(); return *reinterpret_cast( &pData ); #endif #else @@ -689,23 +652,13 @@ class PLATFORM_CLASS CThreadLocalBase void Set(T val) { #ifdef PLATFORM_64BITS - void* pData = 0; #ifdef NEO - static_assert(sizeof(T) == sizeof(void*)); -#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) - *reinterpret_cast(&pData) = val; - void* sdkRet = pData; - memset(&pData, 0x42, sizeof(pData)); -#endif - memcpy(&pData, &val, sizeof(pData)); -#if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) - void* neoRet = pData; - Assert(neoRet == sdkRet); -#endif + CThreadLocalBase::Set( reinterpret_cast( val ) ); #else + void *pData = 0; *reinterpret_cast( &pData ) = val; -#endif CThreadLocalBase::Set( pData ); +#endif #else #ifdef COMPILER_MSVC #pragma warning ( disable : 4312 ) From bc6e6223e846c9903444e88bf0f4da2ee7754280 Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 28 Dec 2025 02:41:21 +0200 Subject: [PATCH 89/96] Improve memory pun debug --- src/public/dt_send.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/public/dt_send.cpp b/src/public/dt_send.cpp index b6f7d0e30e..83b68cb4cd 100644 --- a/src/public/dt_send.cpp +++ b/src/public/dt_send.cpp @@ -77,11 +77,11 @@ CStandardSendProxies g_StandardSendProxies; template void pun(auto& dst, const void* src) { + static_assert(sizeof(T) == sizeof(std::remove_cvref_t)); #if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) *((T*)&dst) = *(T*)src; const auto sdkRes = dst; - constexpr std::remove_reference_t dbgVal = 42; - memcpy(&dst, &dbgVal, sizeof(dst)); + memset(&dst, 0xdd, sizeof(dst)); #endif memcpy(&dst, src, sizeof(dst)); #if defined(DEBUG) && defined(DBGFLAG_ASSERT) && defined(ACTUALLY_COMPILER_MSVC) From ac6da0cfdb04a72b48274ab4d8e0f6ea0a7b8337 Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 28 Dec 2025 03:28:41 +0200 Subject: [PATCH 90/96] Fix type pun size ambiguity sizeof(unsigned long) is not guaranteed to equal sizeof(int); while this technically doesn't matter since the punned value is truncated to sizeof the destination, this would break the sizeof equality assert in our pun(...) helper func for such a case. --- src/public/dt_send.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/public/dt_send.cpp b/src/public/dt_send.cpp index 83b68cb4cd..09e981ecff 100644 --- a/src/public/dt_send.cpp +++ b/src/public/dt_send.cpp @@ -179,7 +179,7 @@ void SendProxy_UInt16ToInt32( const SendProp *pProp, const void *pStruct, const void SendProxy_UInt32ToInt32( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID) { #ifdef NEO - pun(pOut->m_Int, pData); + pun(pOut->m_Int, pData); #else *((unsigned long*)&pOut->m_Int) = *((unsigned long*)pData); #endif From 2b50bd3615ff1f89b87b5e87318d8ec4863fe534 Mon Sep 17 00:00:00 2001 From: Rain Date: Sun, 28 Dec 2025 15:34:42 +0200 Subject: [PATCH 91/96] BasicVector --- src/mathlib/polyhedron.cpp | 67 ++++++++++++++++++++++++++++++++- src/public/mathlib/polyhedron.h | 56 ++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/src/mathlib/polyhedron.cpp b/src/mathlib/polyhedron.cpp index 2f866a218a..de58ca5595 100644 --- a/src/mathlib/polyhedron.cpp +++ b/src/mathlib/polyhedron.cpp @@ -12,6 +12,9 @@ #include #include "tier1/utlvector.h" +#ifdef NEO +#include +#endif struct GeneratePolyhedronFromPlanes_Point; @@ -90,7 +93,11 @@ CPolyhedron_AllocByNew *CPolyhedron_AllocByNew::Allocate( unsigned short iVertic pAllocated->iLineCount = iLines; pAllocated->iIndexCount = iIndices; pAllocated->iPolygonCount = iPolygons; +#ifdef NEO + pAllocated->pVertices = (BasicVector *)(pAllocated + 1); //start vertex memory at the end of the class +#else pAllocated->pVertices = (Vector *)(pAllocated + 1); //start vertex memory at the end of the class +#endif pAllocated->pLines = (Polyhedron_IndexedLine_t *)(pAllocated->pVertices + iVertices); pAllocated->pIndices = (Polyhedron_IndexedLineReference_t *)(pAllocated->pLines + iLines); pAllocated->pPolygons = (Polyhedron_IndexedPolygon_t *)(pAllocated->pIndices + iIndices); @@ -130,7 +137,11 @@ CPolyhedron *GetTempPolyhedron( unsigned short iVertices, unsigned short iLines, #ifdef DBGFLAG_ASSERT ++s_TempMemoryPolyhedron.iReferenceCount; #endif +#ifdef NEO + s_TempMemoryPolyhedron_Buffer.SetCount( (sizeof( BasicVector ) * iVertices) + +#else s_TempMemoryPolyhedron_Buffer.SetCount( (sizeof( Vector ) * iVertices) + +#endif (sizeof( Polyhedron_IndexedLine_t ) * iLines) + (sizeof( Polyhedron_IndexedLineReference_t ) * iIndices) + (sizeof( Polyhedron_IndexedPolygon_t ) * iPolygons) ); @@ -140,7 +151,11 @@ CPolyhedron *GetTempPolyhedron( unsigned short iVertices, unsigned short iLines, s_TempMemoryPolyhedron.iIndexCount = iIndices; s_TempMemoryPolyhedron.iPolygonCount = iPolygons; +#ifdef NEO + s_TempMemoryPolyhedron.pVertices = (BasicVector *)s_TempMemoryPolyhedron_Buffer.Base(); +#else s_TempMemoryPolyhedron.pVertices = (Vector *)s_TempMemoryPolyhedron_Buffer.Base(); +#endif s_TempMemoryPolyhedron.pLines = (Polyhedron_IndexedLine_t *)(&s_TempMemoryPolyhedron.pVertices[s_TempMemoryPolyhedron.iVertexCount]); s_TempMemoryPolyhedron.pIndices = (Polyhedron_IndexedLineReference_t *)(&s_TempMemoryPolyhedron.pLines[s_TempMemoryPolyhedron.iLineCount]); s_TempMemoryPolyhedron.pPolygons = (Polyhedron_IndexedPolygon_t *)(&s_TempMemoryPolyhedron.pIndices[s_TempMemoryPolyhedron.iIndexCount]); @@ -154,11 +169,19 @@ Vector CPolyhedron::Center( void ) if( iVertexCount == 0 ) return vec3_origin; +#ifdef NEO + BasicVector vAABBMin, vAABBMax; +#else Vector vAABBMin, vAABBMax; +#endif vAABBMin = vAABBMax = pVertices[0]; for( int i = 1; i != iVertexCount; ++i ) { +#ifdef NEO + BasicVector &vPoint = pVertices[i]; +#else Vector &vPoint = pVertices[i]; +#endif if( vPoint.x < vAABBMin.x ) vAABBMin.x = vPoint.x; if( vPoint.y < vAABBMin.y ) @@ -173,7 +196,12 @@ Vector CPolyhedron::Center( void ) if( vPoint.z > vAABBMax.z ) vAABBMax.z = vPoint.z; } +#ifdef NEO + auto ret = ((vAABBMin + vAABBMax) * 0.5f); + return Vector{ ret.x, ret.y, ret.z }; +#else return ((vAABBMin + vAABBMax) * 0.5f); +#endif } enum PolyhedronPointPlanarity @@ -185,7 +213,11 @@ enum PolyhedronPointPlanarity struct GeneratePolyhedronFromPlanes_Point { +#ifdef NEO + BasicVector ptPosition; +#else Vector ptPosition; +#endif GeneratePolyhedronFromPlanes_LineLL *pConnectedLines; //keep these in a clockwise order, circular linking float fPlaneDist; //used in plane cutting PolyhedronPointPlanarity planarity; @@ -217,7 +249,11 @@ struct GeneratePolyhedronFromPlanes_LineLL struct GeneratePolyhedronFromPlanes_Polygon { +#ifdef NEO + BasicVector vSurfaceNormal; +#else Vector vSurfaceNormal; +#endif GeneratePolyhedronFromPlanes_LineLL *pLines; //keep these in a clockwise order, circular linking bool bMissingASide; @@ -256,7 +292,11 @@ CPolyhedron *ClipPolyhedron( const CPolyhedron *pExistingPolyhedron, const float float *pUsefulPlanes = (float *)stackalloc( sizeof( float ) * 4 * iPlaneCount ); int iUsefulPlaneCount = 0; +#ifdef NEO + BasicVector *pExistingVertices = pExistingPolyhedron->pVertices; +#else Vector *pExistingVertices = pExistingPolyhedron->pVertices; +#endif //A large part of clipping will either eliminate the polyhedron entirely, or clip nothing at all, so lets just check for those first and throw away useless planes { @@ -271,7 +311,11 @@ CPolyhedron *ClipPolyhedron( const CPolyhedron *pExistingPolyhedron, const float for( int j = 0; j != pExistingPolyhedron->iVertexCount; ++j ) { +#ifdef NEO + float fPointDist = vNormal.Dot(Vector{ pExistingVertices[j].x, pExistingVertices[j].y, pExistingVertices[j].z }) - fPlaneDist; +#else float fPointDist = vNormal.Dot( pExistingVertices[j] ) - fPlaneDist; +#endif if( fPointDist <= fNegativeOnPlaneEpsilon ) ++iLiveCount; @@ -317,6 +361,15 @@ CPolyhedron *ClipPolyhedron( const CPolyhedron *pExistingPolyhedron, const float pExistingPolyhedron->iPolygonCount ); } +#ifdef NEO + // Assumptions + static_assert(std::is_trivially_copyable_vpVertices)>>); + static_assert(std::is_trivially_copyable_vpLines)>>); + static_assert(std::is_trivially_copyable_vpIndices)>>); + static_assert(std::is_trivially_copyable_vpPolygons)>>); + static_assert(std::is_trivially_copyable_v); +#endif + memcpy( pReturn->pVertices, pExistingPolyhedron->pVertices, sizeof( Vector ) * pReturn->iVertexCount ); memcpy( pReturn->pLines, pExistingPolyhedron->pLines, sizeof( Polyhedron_IndexedLine_t ) * pReturn->iLineCount ); memcpy( pReturn->pIndices, pExistingPolyhedron->pIndices, sizeof( Polyhedron_IndexedLineReference_t ) * pReturn->iIndexCount ); @@ -713,7 +766,11 @@ CPolyhedron *ConvertLinkedGeometryToPolyhedron( GeneratePolyhedronFromPlanes_Uno pReturn = CPolyhedron_AllocByNew::Allocate( iPointCount, iLineCount, iIndexCount, iPolyCount ); } +#ifdef NEO + BasicVector *pVertexArray = pReturn->pVertices; +#else Vector *pVertexArray = pReturn->pVertices; +#endif Polyhedron_IndexedLine_t *pLineArray = pReturn->pLines; Polyhedron_IndexedLineReference_t *pIndexArray = pReturn->pIndices; Polyhedron_IndexedPolygon_t *pPolyArray = pReturn->pPolygons; @@ -915,7 +972,11 @@ CPolyhedron *ClipLinkedGeometry( GeneratePolyhedronFromPlanes_UnorderedPolygonLL pDeadLineLinkCollection = NULL; pDeadPolygonCollection = NULL; - Vector vNormal = *((Vector *)&pOutwardFacingPlanes[(iCurrentPlane * 4) + 0]); +#ifdef NEO + BasicVector vNormal = *((BasicVector *)&pOutwardFacingPlanes[(iCurrentPlane * 4) + 0]); +#else + float fPointDist = vNormal.Dot( pPoint->ptPosition ) - fPlaneDist; +#endif /*double vNormalAsDouble[3]; vNormalAsDouble[0] = vNormal.x; vNormalAsDouble[1] = vNormal.y; @@ -934,7 +995,11 @@ CPolyhedron *ClipLinkedGeometry( GeneratePolyhedronFromPlanes_UnorderedPolygonLL do { GeneratePolyhedronFromPlanes_Point *pPoint = pActivePointWalk->pPoint; +#ifdef NEO + float fPointDist = Vector(vNormal).Dot( pPoint->ptPosition ) - fPlaneDist; +#else float fPointDist = vNormal.Dot( pPoint->ptPosition ) - fPlaneDist; +#endif if( fPointDist > fOnPlaneEpsilon ) { pPoint->planarity = POINT_DEAD; //point is dead, bang bang diff --git a/src/public/mathlib/polyhedron.h b/src/public/mathlib/polyhedron.h index 38b465c719..22859167fb 100644 --- a/src/public/mathlib/polyhedron.h +++ b/src/public/mathlib/polyhedron.h @@ -15,7 +15,53 @@ #include "mathlib/mathlib.h" - +#ifdef NEO +struct BasicVector +{ + vec_t x; + vec_t y; + vec_t z; + + inline BasicVector operator+(const BasicVector& v) const + { + BasicVector res; + res.x = x + v.x; + res.x = y + v.y; + res.x = z + v.z; + return res; + } + + inline BasicVector operator-(const BasicVector& v) const + { + BasicVector res; + res.x = x - v.x; + res.x = y - v.y; + res.x = z - v.z; + return res; + } + + inline BasicVector operator*(const float v) const + { + BasicVector res; + res.x = x * v; + res.x = y * v; + res.x = z * v; + return res; + } + + inline void Init(vec_t x, vec_t y, vec_t z) + { + this->x = x; + this->y = y; + this->z = z; + } + + inline operator Vector () + { + return Vector{ x,y,z }; + } +}; +#endif struct Polyhedron_IndexedLine_t { @@ -32,13 +78,21 @@ struct Polyhedron_IndexedPolygon_t { unsigned short iFirstIndex; unsigned short iIndexCount; +#ifdef NEO + BasicVector polyNormal; +#else Vector polyNormal; +#endif }; class CPolyhedron //made into a class because it's going virtual to support distinctions between temp and permanent versions { public: +#ifdef NEO + BasicVector *pVertices; +#else Vector *pVertices; +#endif Polyhedron_IndexedLine_t *pLines; Polyhedron_IndexedLineReference_t *pIndices; Polyhedron_IndexedPolygon_t *pPolygons; From 41b3598e1dc0d181cb055eda1cffb7c976e94a95 Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 20 Jan 2026 06:09:19 +0200 Subject: [PATCH 92/96] Fix bad indentation --- src/materialsystem/stdshaders/BaseVSShader.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/materialsystem/stdshaders/BaseVSShader.cpp b/src/materialsystem/stdshaders/BaseVSShader.cpp index b43d0366ae..7b06b7cf48 100644 --- a/src/materialsystem/stdshaders/BaseVSShader.cpp +++ b/src/materialsystem/stdshaders/BaseVSShader.cpp @@ -1153,7 +1153,11 @@ void CBaseVSShader::DrawWorldBumpedDiffuseLighting( int bumpmapVar, int bumpFram s_pShaderShadow->SetPixelShader( "LightmappedGeneric_SSBumpmappedLightmap" ); else s_pShaderShadow->SetPixelShader( "LightmappedGeneric_BumpmappedLightmap" ); +#ifndef NEO FogToFogColor(); +#else + FogToFogColor(); // fix bad indentation to silence warning +#endif } else { From 2c96aed23ddc36ca782fde9c7a01e4e09eeaa019 Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 22 Jan 2026 11:20:19 +0200 Subject: [PATCH 93/96] fix bad include order --- src/game/client/c_soundscape.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/game/client/c_soundscape.cpp b/src/game/client/c_soundscape.cpp index 1a6cb0ac55..5d8e410160 100644 --- a/src/game/client/c_soundscape.cpp +++ b/src/game/client/c_soundscape.cpp @@ -47,7 +47,9 @@ struct loopingsound_t ConVar soundscape_fadetime( "soundscape_fadetime", "3.0", FCVAR_CHEAT, "Time to crossfade sound effects between soundscapes" ); +#ifndef NEO // bad include order; we fix this in the main top-level include list #include "interval.h" +#endif struct randomsound_t { From 270b72dd799f431c916850ef0b24fafea624ba46 Mon Sep 17 00:00:00 2001 From: Rain Date: Thu, 29 Jan 2026 14:44:44 +0200 Subject: [PATCH 94/96] Fix Clang 21.1 compatibility --- src/public/vscript/variant.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/public/vscript/variant.h b/src/public/vscript/variant.h index e09b9bc360..05ac04cb87 100644 --- a/src/public/vscript/variant.h +++ b/src/public/vscript/variant.h @@ -425,6 +425,14 @@ template< class CValueAllocator > template< typename T > inline void CVariantBase::CopyData( const T &src, bool bForceCopy ) { +#ifdef NEO +#ifdef __clang__ +#if __clang_major__ > 21 || (__clang_major__ == 21 && __clang_minor__ >= 1) + Assert( ( ExtendedFieldType_t )VariantDeduceType( T ) != FIELD_TYPEUNKNOWN ); + if constexpr (false) +#endif // clang ver +#endif // __clang__ +#endif // NEO COMPILE_TIME_ASSERT( ( ExtendedFieldType_t )VariantDeduceType( T ) != FIELD_TYPEUNKNOWN ); Free(); From fe88a33533836be6ee89f3411d1b3116e9eb55d8 Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 30 Jan 2026 06:58:44 +0200 Subject: [PATCH 95/96] Update documentation --- CONTRIBUTING.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d47dd8ec3..cfa63ab458 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -118,23 +118,23 @@ In shared code, clientside code can be differentiated with CLIENT_DLL, vs. serve ## Supported compilers -Only the x64 (64-bit) architecture is supported. +Only the x86-64 architecture is supported. ### Windows * MSVC v143 - VS 2022 C++ x64/x86 build tools (Latest) * MSVC version used by the latest `windows-2025` [runner image](https://github.com/actions/runner-images/blob/main/images/windows/Windows2025-Readme.md) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64) ### Linux -* GCC 10 [steamrt3 'sniper'](https://gitlab.steamos.cloud/steamrt/sniper/sdk) -* GCC 14 [steamrt3 'sniper'](https://gitlab.steamos.cloud/steamrt/sniper/sdk) -* GCC 14 [steamrt4](https://gitlab.steamos.cloud/steamrt/steamrt4/sdk) -* Clang 19 [steamrt4](https://gitlab.steamos.cloud/steamrt/steamrt4/sdk) +* GCC 10 [steamrt3 'sniper'](https://gitlab.steamos.cloud/steamrt/sniper/sdk#toolchains) +* GCC 14 [steamrt3 'sniper'](https://gitlab.steamos.cloud/steamrt/sniper/sdk#toolchains) +* GCC 14 [steamrt4](https://gitlab.steamos.cloud/steamrt/steamrt4/sdk#toolchains) +* Clang 19 [steamrt4](https://gitlab.steamos.cloud/steamrt/steamrt4/sdk#toolchains) ### Code style * C++20, within the [supported compilers'](#supported-compilers) capabilities. * Formatting: - * No big restrictions on general format, but try to more or less match the surrounding SDK code style for consistency. + * No big restrictions on general format, but try to more or less match the surrounding SDK code style for consistency. For example this typically means using tabs for whitespace, but generally go with what the file you're editing is doing stylistically. * Warnings are treated as errors. * You may choose to suppress a warning with compiler-specific preprocessing directives if it is a false positive, but **please do not suppress valid warnings**; instead resolve it by fixing the underlying issue. * For local development, you may disable warnings-as-errors by modifying your `CMAKE_COMPILE_WARNING_AS_ERROR` option, eg. by modifying the entry in your `CMakeCache.txt` file. @@ -160,8 +160,9 @@ Only the x64 (64-bit) architecture is supported. * Signed/unsigned conversion overflow * For release builds, it is identical to `static_cast` * `neo::bit_cast`: - * Well-formed type punning helper. Mostly used to avoid UB in the SDK code. - * Wrapper for `std::bit_cast` when it's available, else will fall back to `memcpy` based conversions (for example on the steamrt3 default GCC compiler). + * The preferred bit cast function, for performing a well-formed type pun + * Mostly used to avoid strict aliasing rule violations in the SDK code + * Acts as a wrapper for `std::bit_cast` when it's available, else will fall back to `memcpy` based conversions (for example on the steamrt3 default GCC compiler) * For debug builds, a runtime assertion test is available as an additional parameter: * `auto output = neo::bit_cast(BC_TEST(input, expectedOutput));` * When replacing ill-formed type puns, this test syntax can be used to ensure the output of `neo::bit_cast(input)` remains identical to `expectedOutput` From 8cad74c7bd163b5f5914a4dcad2320f6eb099c0c Mon Sep 17 00:00:00 2001 From: Rain Date: Fri, 30 Jan 2026 12:52:31 +0200 Subject: [PATCH 96/96] Fix type pun --- src/game/shared/saverestore.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/shared/saverestore.cpp b/src/game/shared/saverestore.cpp index a6d0f0cc36..7c7a20aecd 100644 --- a/src/game/shared/saverestore.cpp +++ b/src/game/shared/saverestore.cpp @@ -112,7 +112,11 @@ static void Matrix3x4Offset( matrix3x4_t& dest, const matrix3x4_t& matrixIn, con // This does the necessary casting / extract to grab a pointer to a member function as a void * // UNDONE: Cast to BASEPTR or something else here? +#ifdef NEO +#define EXTRACT_INPUTFUNC_FUNCTIONPTR(x) (static_cast(&(x))) +#else #define EXTRACT_INPUTFUNC_FUNCTIONPTR(x) (*(inputfunc_t **)(&(x))) +#endif //----------------------------------------------------------------------------- // Purpose: Search this datamap for the name of this member function