From f7963e9d7b59ae08d981e0a1b514939567a40941 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:53:50 +0200 Subject: [PATCH 1/3] fix(wdump): Add missing names for primary gradient and detail color shader functions The name tables for the primary gradient and the detail color function were shorter than their W3DSHADER_*_MAX enumerations, so dumping a shader that uses bump environment luminance, modulate 2x, add signed, add signed 2x, scale 2x or mod alpha add color read past the end of the table. Co-Authored-By: Claude Opus 5.5 --- GeneralsMD/Code/Tools/wdump/chunk_d.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GeneralsMD/Code/Tools/wdump/chunk_d.cpp b/GeneralsMD/Code/Tools/wdump/chunk_d.cpp index 7526d34c5f4..7c7933c9f61 100644 --- a/GeneralsMD/Code/Tools/wdump/chunk_d.cpp +++ b/GeneralsMD/Code/Tools/wdump/chunk_d.cpp @@ -211,11 +211,11 @@ void ChunkTableClass::AddItem(CListCtrl *list, int &Counter, const char *name, W static const char * _color_mask[] = { "Write Disable", "Write Enable" }; static const char * _destblend[] = { "Zero","One","Src Color","One Minus Src Color","Src Alpha","One Minus Src Alpha","Src Color Prefog" }; static const char * _fogfunc[] = { "Disable","Enable","Scale Fragment","Replace Fragment" }; - static const char * _prigradient[] = { "Disable","Modulate","Add","Bump-Environment" }; + static const char * _prigradient[] = { "Disable","Modulate","Add","Bump-Environment","Bump-Environment Luminance","Modulate 2X" }; static const char * _secgradient[] = { "Disable","Enable" }; static const char * _srcblend[] = { "Zero","One","Src Alpha","One Minus Src Alpha" }; static const char * _texturing[] = { "Disable","Enable" }; - static const char * _detailcolor[] = { "Disable","Detail","Scale","InvScale","Add","Sub","SubR","Blend","DetailBlend" }; + static const char * _detailcolor[] = { "Disable","Detail","Scale","InvScale","Add","Sub","SubR","Blend","DetailBlend","AddSigned","AddSigned2X","Scale2X","ModAlphaAddColor" }; static const char * _detailalpha[] = { "Disable","Detail","Scale","InvScale" }; static const char * _dithermask[] = { "Disable", "Enable" }; static const char * _shademodel[] = { "Smooth", "Flat" }; From 8e9008f82a00b870f1fbbbf883925a41eac38a35 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:54:40 +0200 Subject: [PATCH 2/3] chore: Add static asserts to verify the size of arrays for enum values Adds static_assert's for enum indexed name, lookup and function tables, so that editing an enum fails to compile until the associated array is updated. Arrays that were declared with an explicit enum count now use an unsized bound, because an explicit bound silently zero fills missing entries. Enums without a count get one. The waveTypeInfo table gets an explicit zero entry for WaveTypeStationary, which it previously got through zero fill, and the padding of the memory category names is replaced by the assert. Co-Authored-By: Claude Opus 5.5 --- Core/GameEngine/Include/Common/Debug.h | 2 +- Core/GameEngine/Include/Common/Dict.h | 4 ++- .../Include/GameClient/GlobalLanguage.h | 1 + .../GameEngine/Include/GameClient/MetaEvent.h | 1 + .../Include/GameNetwork/GameSpy/PeerDefs.h | 2 +- .../GameEngine/Source/Common/System/Debug.cpp | 3 +- .../GameEngine/Source/Common/System/Radar.cpp | 1 + .../Source/GameClient/GlobalLanguage.cpp | 1 + .../Source/GameClient/Input/Mouse.cpp | 3 +- .../Source/GameNetwork/ConnectionManager.cpp | 3 +- .../Source/GameNetwork/GameSpy/Chat.cpp | 4 ++- .../Source/GameNetwork/GameSpyOverlay.cpp | 3 +- .../Drawable/Draw/W3DDebrisDraw.cpp | 3 +- .../GameClient/Drawable/Draw/W3DModelDraw.cpp | 3 +- .../GameClient/Water/W3DWaterTracks.cpp | 4 ++- .../Source/Compression/CompressionManager.cpp | 6 ++-- .../Source/WWVegas/WW3D2/assetstatus.cpp | 3 +- .../Source/WWVegas/WW3D2/dx8caps.cpp | 8 +++++ Core/Libraries/Source/WWVegas/WW3D2/dx8caps.h | 32 ++++++++++++++----- .../Source/WWVegas/WW3D2/formconv.cpp | 6 ++-- .../Source/WWVegas/WW3D2/texturefilter.cpp | 3 +- .../Source/WWVegas/WW3D2/texturefilter.h | 2 +- .../Source/WWVegas/WWDebug/wwmemlog.cpp | 8 ++--- Core/Tools/W3DView/Vector3RndCombo.cpp | 5 ++- .../GameEngine/Include/GameLogic/Locomotor.h | 4 +-- .../GameLogic/Module/SupplyTruckAIUpdate.h | 4 ++- .../GameEngine/Include/GameLogic/ObjectIter.h | 4 ++- .../Include/GameLogic/PartitionManager.h | 4 ++- .../GameEngine/Include/GameLogic/WeaponSet.h | 3 +- .../GameEngine/Source/Common/RTS/Handicap.cpp | 6 ++-- .../GameEngine/Source/GameClient/Drawable.cpp | 3 +- .../GameEngine/Source/GameClient/InGameUI.cpp | 1 + .../Source/GameLogic/Object/Locomotor.cpp | 2 +- .../Source/GameLogic/Object/Object.cpp | 6 ++-- .../GameLogic/Object/PartitionManager.cpp | 2 ++ .../GameLogic/Object/SimpleObjectIterator.cpp | 2 ++ .../Update/AIUpdate/SupplyTruckAIUpdate.cpp | 1 + .../Object/Update/ProductionUpdate.cpp | 12 ++++--- .../Update/SpectreGunshipDeploymentUpdate.cpp | 2 +- .../Object/Update/StructureCollapseUpdate.cpp | 2 +- .../Source/GameLogic/Object/WeaponSet.cpp | 21 ++++++++---- .../Source/GameLogic/ScriptEngine/Scripts.cpp | 2 ++ .../GameClient/Shadow/W3DBufferManager.cpp | 3 +- .../Source/WWVegas/WW3D2/part_ldr.cpp | 3 +- .../Libraries/Source/WWVegas/WW3D2/shader.cpp | 6 ++-- .../Libraries/Source/WWVegas/WW3D2/w3d_file.h | 5 +-- .../Code/Tools/GUIEdit/Source/Properties.cpp | 1 + .../Tools/WorldBuilder/src/DrawObject.cpp | 3 +- .../WorldBuilder/src/WorldBuilderDoc.cpp | 2 ++ GeneralsMD/Code/Tools/wdump/chunk_d.cpp | 14 ++++++++ 50 files changed, 162 insertions(+), 67 deletions(-) diff --git a/Core/GameEngine/Include/Common/Debug.h b/Core/GameEngine/Include/Common/Debug.h index 7288a753cda..b900d25b319 100644 --- a/Core/GameEngine/Include/Common/Debug.h +++ b/Core/GameEngine/Include/Common/Debug.h @@ -154,7 +154,7 @@ class AsciiString; DEBUG_LEVEL_NET = 0, // in-game network DEBUG_LEVEL_MAX }; - extern const char *TheDebugLevels[DEBUG_LEVEL_MAX]; + extern const char *TheDebugLevels[]; #define DEBUG_LOG(m) do { { DebugLog m ; } } while (0) // Log message with trailing new line character (LF) #define DEBUG_LOG_RAW(m) do { { DebugLogRaw m ; } } while (0) // Log message without trailing new line character (LF) diff --git a/Core/GameEngine/Include/Common/Dict.h b/Core/GameEngine/Include/Common/Dict.h index bdd741ffe3b..240a4015163 100644 --- a/Core/GameEngine/Include/Common/Dict.h +++ b/Core/GameEngine/Include/Common/Dict.h @@ -75,7 +75,9 @@ class Dict DICT_INT, DICT_REAL, DICT_ASCIISTRING, - DICT_UNICODESTRING + DICT_UNICODESTRING, + + DICT_TYPE_COUNT }; /** diff --git a/Core/GameEngine/Include/GameClient/GlobalLanguage.h b/Core/GameEngine/Include/GameClient/GlobalLanguage.h index b256c6d6259..432c4fc8b42 100644 --- a/Core/GameEngine/Include/GameClient/GlobalLanguage.h +++ b/Core/GameEngine/Include/GameClient/GlobalLanguage.h @@ -74,6 +74,7 @@ class GlobalLanguage : public SubsystemInterface ResolutionFontSizeMethod_Strict, // Uses a strict scaling method. Width and height are strictly bounded on upscales. Works well for accurate UI layouts and with large resolutions. ResolutionFontSizeMethod_Balanced, // Uses a balanced scaling method. Width and height are evenly weighted for upscales. Works well for the original Game UI and with large resolutions. + ResolutionFontSizeMethod_Count, ResolutionFontSizeMethod_Default = ResolutionFontSizeMethod_ClassicNoCeiling, }; diff --git a/Core/GameEngine/Include/GameClient/MetaEvent.h b/Core/GameEngine/Include/GameClient/MetaEvent.h index a610c4f5e7d..db6f2175370 100644 --- a/Core/GameEngine/Include/GameClient/MetaEvent.h +++ b/Core/GameEngine/Include/GameClient/MetaEvent.h @@ -57,6 +57,7 @@ static const LookupListRec CategoryListName[] = {"DEBUG", CATEGORY_DEBUG}, { nullptr, 0} }; +static_assert(ARRAY_SIZE(CategoryListName) == CATEGORY_NUM_CATEGORIES + 1, "Incorrect array size"); // ------------------------------------------------------------------------------- diff --git a/Core/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h b/Core/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h index 18512a0b9d6..443718a75a5 100644 --- a/Core/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h +++ b/Core/GameEngine/Include/GameNetwork/GameSpy/PeerDefs.h @@ -155,7 +155,7 @@ enum GameSpyColors CPP_11(: Int) { GSCOLOR_MAX }; -extern Color GameSpyColor[GSCOLOR_MAX]; +extern Color GameSpyColor[]; enum GameSpyBuddyStatus CPP_11(: Int) { BUDDY_OFFLINE, diff --git a/Core/GameEngine/Source/Common/System/Debug.cpp b/Core/GameEngine/Source/Common/System/Debug.cpp index 815ec558ea8..11764c058dd 100644 --- a/Core/GameEngine/Source/Common/System/Debug.cpp +++ b/Core/GameEngine/Source/Common/System/Debug.cpp @@ -121,9 +121,10 @@ static DWORD theMainThreadID = 0; char* TheCurrentIgnoreCrashPtr = nullptr; #ifdef DEBUG_LOGGING UnsignedInt DebugLevelMask = 0; -const char *TheDebugLevels[DEBUG_LEVEL_MAX] = { +const char *TheDebugLevels[] = { "NET" }; +static_assert(ARRAY_SIZE(TheDebugLevels) == DEBUG_LEVEL_MAX, "Incorrect array size"); #endif // ---------------------------------------------------------------------------- diff --git a/Core/GameEngine/Source/Common/System/Radar.cpp b/Core/GameEngine/Source/Common/System/Radar.cpp index 313b8f36e47..32d8deb3ff8 100644 --- a/Core/GameEngine/Source/Common/System/Radar.cpp +++ b/Core/GameEngine/Source/Common/System/Radar.cpp @@ -882,6 +882,7 @@ static RadarColorLookup radarColorLookupTable[] = { RADAR_EVENT_FAKE, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, { RADAR_EVENT_INVALID, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } } }; +static_assert(ARRAY_SIZE(radarColorLookupTable) == RADAR_EVENT_NUM_EVENTS, "Incorrect array size"); //------------------------------------------------------------------------------------------------- /** Create a new radar event */ diff --git a/Core/GameEngine/Source/GameClient/GlobalLanguage.cpp b/Core/GameEngine/Source/GameClient/GlobalLanguage.cpp index a9bc586d494..d6cd9e73463 100644 --- a/Core/GameEngine/Source/GameClient/GlobalLanguage.cpp +++ b/Core/GameEngine/Source/GameClient/GlobalLanguage.cpp @@ -74,6 +74,7 @@ static const LookupListRec ResolutionFontSizeMethodNames[] = { "BALANCED", GlobalLanguage::ResolutionFontSizeMethod_Balanced }, { nullptr, 0 } }; +static_assert(ARRAY_SIZE(ResolutionFontSizeMethodNames) == GlobalLanguage::ResolutionFontSizeMethod_Count + 1, "Incorrect array size"); static const FieldParse TheGlobalLanguageDataFieldParseTable[] = { diff --git a/Core/GameEngine/Source/GameClient/Input/Mouse.cpp b/Core/GameEngine/Source/GameClient/Input/Mouse.cpp index db7c287cfe8..5568f840749 100644 --- a/Core/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Core/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -1266,7 +1266,7 @@ Int Mouse::getCursorIndex(const AsciiString& name) /** @todo This is silly to have to define these names from INI in the code ... * that should be changed (CBD) */ - static const char *CursorININames[NUM_MOUSE_CURSORS] = + static const char *CursorININames[] = { //"InvalidMouseCursor", // this entry is not actually a mouse cursor, but just a // reminder that it does exist @@ -1323,6 +1323,7 @@ Int Mouse::getCursorIndex(const AsciiString& name) "ParticleUplinkCannon", }; + static_assert(ARRAY_SIZE(CursorININames) == NUM_MOUSE_CURSORS, "Incorrect array size"); for (Int i=0; iSet_Transform(*transformMtx); - static const RenderObjClass::AnimMode TheAnimModes[STATECOUNT] = + static const RenderObjClass::AnimMode TheAnimModes[] = { RenderObjClass::ANIM_MODE_ONCE, RenderObjClass::ANIM_MODE_LOOP, RenderObjClass::ANIM_MODE_ONCE }; + static_assert(ARRAY_SIZE(TheAnimModes) == STATECOUNT, "Incorrect array size"); Int oldState = m_state; Object* obj = getDrawable()->getObject(); diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp index 6a98dd58398..25c12b268d5 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp @@ -266,7 +266,7 @@ inline Bool isCommonMaintainFrameFlagSet(Int a, Int b) // Note: these values are saved in save files, so you MUST NOT REMOVE OR CHANGE // existing values! // -static const char *TerrainDecalTextureName[TERRAIN_DECAL_MAX]= +static const char *TerrainDecalTextureName[]= { #ifdef ALLOW_DEMORALIZE "DM_RING",//demoralized @@ -289,6 +289,7 @@ static const char *TerrainDecalTextureName[TERRAIN_DECAL_MAX]= #endif "" //dummy entry for TERRAIN_DECAL_SHADOW_TEXTURE }; +static_assert(ARRAY_SIZE(TerrainDecalTextureName) == TERRAIN_DECAL_MAX, "Incorrect array size"); const UnsignedInt NO_NEXT_DURATION = 0xffffffff; diff --git a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp index 9e34695c46a..dbd26e1ee6f 100644 --- a/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp @@ -105,14 +105,16 @@ struct waveInfo const char *m_waveTypeName; //name of this wave type. }; -waveInfo waveTypeInfo[WaveTypeMax]= +waveInfo waveTypeInfo[]= { {28.0f, 18.0f, 25.0f, 0.018f, 900, 0.01f, 0.18f, 1500, 0,"wave256.tga","Pond"}, //pond {55.0f, 36.0f, 80.0f, 0.015f, 2000, 0.5f, 0.18f, 1000, 6267,"wave256.tga","Ocean"}, //ocean {55.0f, 36.0f, 80.0f, 0.015f, 2000, 0.05f, 0.18f, 1000, 6267,"wave256.tga","Close Ocean"}, {55.0f, 36.0f, 80.0f, 0.015f, 4000, 0.01f, 0.18f, 2000, 6267,"wave256.tga","Close Ocean Double"}, {55.0f, 27.0f, 80.0f, 0.015f, 2000, 0.01f, 8.0f, 2000, 5367,"wave256.tga","Radial"}, + {0.0f, 0.0f, 0.0f, 0.0f, 0, 0.0f, 0.0f, 0, 0, nullptr, nullptr}, //stationary }; +static_assert(ARRAY_SIZE(waveTypeInfo) == WaveTypeMax, "Incorrect array size"); //============================================================================= // WaterTracksObj::~WaterTracksObj diff --git a/Core/Libraries/Source/Compression/CompressionManager.cpp b/Core/Libraries/Source/Compression/CompressionManager.cpp index b90d0531c3b..ce7e3faafe8 100644 --- a/Core/Libraries/Source/Compression/CompressionManager.cpp +++ b/Core/Libraries/Source/Compression/CompressionManager.cpp @@ -41,7 +41,7 @@ const char *CompressionManager::getCompressionNameByType( CompressionType compType ) { - static const char *s_compressionNames[COMPRESSION_MAX+1] = { + static const char *s_compressionNames[] = { "No compression", "RefPack", "LZHL", @@ -57,13 +57,14 @@ const char *CompressionManager::getCompressionNameByType( CompressionType compTy "BTree", "Huff", }; + static_assert(ARRAY_SIZE(s_compressionNames) == COMPRESSION_MAX + 1, "Incorrect array size"); return s_compressionNames[compType]; } // For perf timers, so we can have separate ones for compression/decompression const char *CompressionManager::getDecompressionNameByType( CompressionType compType ) { - static const char *s_decompressionNames[COMPRESSION_MAX+1] = { + static const char *s_decompressionNames[] = { "d_None", "d_RefPack", "d_NoxLZW", @@ -79,6 +80,7 @@ const char *CompressionManager::getDecompressionNameByType( CompressionType comp "d_BTree", "d_Huff", }; + static_assert(ARRAY_SIZE(s_decompressionNames) == COMPRESSION_MAX + 1, "Incorrect array size"); return s_decompressionNames[compType]; } diff --git a/Core/Libraries/Source/WWVegas/WW3D2/assetstatus.cpp b/Core/Libraries/Source/WWVegas/WW3D2/assetstatus.cpp index 2423f17c67c..b1b730df987 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/assetstatus.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/assetstatus.cpp @@ -23,7 +23,7 @@ AssetStatusClass AssetStatusClass::Instance; -const char* ReportCategoryNames[AssetStatusClass::REPORT_COUNT]={ +const char* ReportCategoryNames[]={ "LOAD_ON_DEMAND_ROBJ", "LOAD_ON_DEMAND_HANIM", "LOAD_ON_DEMAND_HTREE", @@ -31,6 +31,7 @@ const char* ReportCategoryNames[AssetStatusClass::REPORT_COUNT]={ "MISSING_HANIM", "MISSING_HTREE" }; +static_assert(ARRAY_SIZE(ReportCategoryNames) == AssetStatusClass::REPORT_COUNT, "Incorrect array size"); AssetStatusClass::AssetStatusClass() : diff --git a/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp b/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp index 3407fa61a56..bf6d032b601 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp @@ -130,6 +130,7 @@ static const char* DeviceNamesNVidia[]={ "GeFORCE2_MX 400", "Quadro DCC" }; +static_assert(ARRAY_SIZE(DeviceNamesNVidia) == DX8Caps::DEVICE_NVIDIA_COUNT, "Incorrect array size"); static const char* DeviceNamesATI[]={ "Unknown ATI Device", @@ -157,6 +158,7 @@ static const char* DeviceNamesATI[]={ "R7500", "R8500" }; +static_assert(ARRAY_SIZE(DeviceNamesATI) == DX8Caps::DEVICE_ATI_COUNT, "Incorrect array size"); static const char* DeviceNames3DLabs[]={ "Unknown 3DLabs Device", @@ -176,6 +178,7 @@ static const char* DeviceNames3DLabs[]={ "TI P1", "Permedia2" }; +static_assert(ARRAY_SIZE(DeviceNames3DLabs) == DX8Caps::DEVICE_3DLABS_COUNT, "Incorrect array size"); static const char* DeviceNames3Dfx[]={ "Unknown 3Dfx Device", @@ -186,6 +189,7 @@ static const char* DeviceNames3Dfx[]={ "Voodoo Graphics", "Voodoo Rush" }; +static_assert(ARRAY_SIZE(DeviceNames3Dfx) == DX8Caps::DEVICE_3DFX_COUNT, "Incorrect array size"); static const char* DeviceNamesMatrox[]={ "Unknown Matrox Device", @@ -202,11 +206,13 @@ static const char* DeviceNamesMatrox[]={ "Parhelia", "Parhelia AGP 8X" }; +static_assert(ARRAY_SIZE(DeviceNamesMatrox) == DX8Caps::DEVICE_MATROX_COUNT, "Incorrect array size"); static const char* DeviceNamesPowerVR[]={ "Unknown PowerVR Device", "Kyro" }; +static_assert(ARRAY_SIZE(DeviceNamesPowerVR) == DX8Caps::DEVICE_POWERVR_COUNT, "Incorrect array size"); static const char* DeviceNamesS3[]={ "Unknown S3 Device", @@ -214,6 +220,7 @@ static const char* DeviceNamesS3[]={ "Savage 4", "Savage 200" }; +static_assert(ARRAY_SIZE(DeviceNamesS3) == DX8Caps::DEVICE_S3_COUNT, "Incorrect array size"); static const char* DeviceNamesIntel[]={ "Unknown Intel Device", @@ -221,6 +228,7 @@ static const char* DeviceNamesIntel[]={ "i810e", "i815" }; +static_assert(ARRAY_SIZE(DeviceNamesIntel) == DX8Caps::DEVICE_INTEL_COUNT, "Incorrect array size"); DX8Caps::DeviceTypeATI DX8Caps::Get_ATI_Device(unsigned device_id) { diff --git a/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.h b/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.h index 9ecde597dd0..fd7d5a9de51 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.h +++ b/Core/Libraries/Source/WWVegas/WW3D2/dx8caps.h @@ -94,7 +94,9 @@ class DX8Caps DEVICE_ATI_RADEON, DEVICE_ATI_MOBILITY_R7500, DEVICE_ATI_R7500, - DEVICE_ATI_R8500 + DEVICE_ATI_R8500, + + DEVICE_ATI_COUNT }; enum DeviceType3DLabs { @@ -113,7 +115,9 @@ class DX8Caps DEVICE_3DLABS_G2, DEVICE_3DLABS_OXYGEN_VX1, DEVICE_3DLABS_TI_P1, - DEVICE_3DLABS_PERMEDIA2 + DEVICE_3DLABS_PERMEDIA2, + + DEVICE_3DLABS_COUNT }; enum DeviceTypeNVidia { @@ -156,7 +160,9 @@ class DX8Caps DEVICE_NVIDIA_QUADRO2_MXR_EX_GO, DEVICE_NVIDIA_GEFORCE2_MX_100_200, DEVICE_NVIDIA_GEFORCE2_MX_400, - DEVICE_NVIDIA_QUADRO_DCC + DEVICE_NVIDIA_QUADRO_DCC, + + DEVICE_NVIDIA_COUNT }; enum DeviceType3Dfx { @@ -166,7 +172,9 @@ class DX8Caps DEVICE_3DFX_BANSHEE, DEVICE_3DFX_VOODOO_2, DEVICE_3DFX_VOODOO_GRAPHICS, - DEVICE_3DFX_VOODOO_RUSH + DEVICE_3DFX_VOODOO_RUSH, + + DEVICE_3DFX_COUNT }; enum DeviceTypeMatrox { @@ -182,26 +190,34 @@ class DX8Caps DEVICE_MATROX_MYSTIQUE, DEVICE_MATROX_MILLENNIUM, DEVICE_MATROX_PARHELIA, - DEVICE_MATROX_PARHELIA_AGP8X + DEVICE_MATROX_PARHELIA_AGP8X, + + DEVICE_MATROX_COUNT }; enum DeviceTypePowerVR { DEVICE_POWERVR_UNKNOWN, - DEVICE_POWERVR_KYRO + DEVICE_POWERVR_KYRO, + + DEVICE_POWERVR_COUNT }; enum DeviceTypeS3 { DEVICE_S3_UNKNOWN, DEVICE_S3_SAVAGE_MX, DEVICE_S3_SAVAGE_4, - DEVICE_S3_SAVAGE_200 + DEVICE_S3_SAVAGE_200, + + DEVICE_S3_COUNT }; enum DeviceTypeIntel { DEVICE_INTEL_UNKNOWN, DEVICE_INTEL_810, DEVICE_INTEL_810E, - DEVICE_INTEL_815 + DEVICE_INTEL_815, + + DEVICE_INTEL_COUNT }; diff --git a/Core/Libraries/Source/WWVegas/WW3D2/formconv.cpp b/Core/Libraries/Source/WWVegas/WW3D2/formconv.cpp index 9ad461efa42..471102ed660 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/formconv.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/formconv.cpp @@ -38,7 +38,7 @@ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "formconv.h" -D3DFORMAT WW3DFormatToD3DFormatConversionArray[WW3D_FORMAT_COUNT] = { +D3DFORMAT WW3DFormatToD3DFormatConversionArray[] = { D3DFMT_UNKNOWN, D3DFMT_R8G8B8, D3DFMT_A8R8G8B8, @@ -65,9 +65,10 @@ D3DFORMAT WW3DFormatToD3DFormatConversionArray[WW3D_FORMAT_COUNT] = { D3DFMT_DXT4, D3DFMT_DXT5 }; +static_assert(ARRAY_SIZE(WW3DFormatToD3DFormatConversionArray) == WW3D_FORMAT_COUNT, "Incorrect array size"); // adding depth stencil format conversion -D3DFORMAT WW3DZFormatToD3DFormatConversionArray[WW3D_ZFORMAT_COUNT] = +D3DFORMAT WW3DZFormatToD3DFormatConversionArray[] = { D3DFMT_UNKNOWN, D3DFMT_D16_LOCKABLE, // 16-bit z-buffer bit depth. This is an application-lockable surface format. @@ -78,6 +79,7 @@ D3DFORMAT WW3DZFormatToD3DFormatConversionArray[WW3D_ZFORMAT_COUNT] = D3DFMT_D24X8, // 32-bit z-buffer bit depth using 24 bits for the depth channel. D3DFMT_D24X4S4, // 32-bit z-buffer bit depth using 24 bits for the depth channel and 4 bits for the stencil channel. }; +static_assert(ARRAY_SIZE(WW3DZFormatToD3DFormatConversionArray) == WW3D_ZFORMAT_COUNT, "Incorrect array size"); /* diff --git a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp index 777f32a0bae..a0a8a7aeff4 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.cpp @@ -40,13 +40,14 @@ #include "texturefilter.h" #include "dx8wrapper.h" -const char* const TextureFilterClass::TextureFilterModeString[TEXTURE_FILTER_COUNT] = { +const char* const TextureFilterClass::TextureFilterModeString[] = { "None", "Point", "Bilinear", "Trilinear", "Anisotropic" }; +static_assert(ARRAY_SIZE(TextureFilterClass::TextureFilterModeString) == TextureFilterClass::TEXTURE_FILTER_COUNT, "Incorrect array size"); TextureFilterClass::TextureFilterMode TextureFilterClass::getTextureFilterMode(const char* str) { for (int i = 0; i < TextureFilterClass::TEXTURE_FILTER_COUNT; ++i) { diff --git a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h index 762d1252d19..ee41f148826 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h +++ b/Core/Libraries/Source/WWVegas/WW3D2/texturefilter.h @@ -92,7 +92,7 @@ class TextureFilterClass TEXTURE_FILTER_COUNT }; - static const char* const TextureFilterModeString[TEXTURE_FILTER_COUNT]; + static const char* const TextureFilterModeString[]; static TextureFilterMode getTextureFilterMode(const char* str); diff --git a/Core/Libraries/Source/WWVegas/WWDebug/wwmemlog.cpp b/Core/Libraries/Source/WWVegas/WWDebug/wwmemlog.cpp index 81f13b97e38..c3cd64c9e17 100644 --- a/Core/Libraries/Source/WWVegas/WWDebug/wwmemlog.cpp +++ b/Core/Libraries/Source/WWVegas/WWDebug/wwmemlog.cpp @@ -92,8 +92,7 @@ static unsigned AllocateCount; static unsigned FreeCount; /* -** Name for each memory category. I'm padding the array with some "undefined" strings in case -** someone forgets to set the name when adding a new category. +** Name for each memory category. */ static const char *const _MemoryCategoryNames[] = { @@ -114,11 +113,8 @@ static const char *const _MemoryCategoryNames[] = "Renderer", "Network", "BINK", - "", - "", - "", - "", }; +static_assert(ARRAY_SIZE(_MemoryCategoryNames) == MEM_COUNT, "Incorrect array size"); /** diff --git a/Core/Tools/W3DView/Vector3RndCombo.cpp b/Core/Tools/W3DView/Vector3RndCombo.cpp index 3ec0a9e6a43..3484d0d569a 100644 --- a/Core/Tools/W3DView/Vector3RndCombo.cpp +++ b/Core/Tools/W3DView/Vector3RndCombo.cpp @@ -35,13 +35,14 @@ #include "Vector3RndCombo.h" #include "WWMath/v3_rnd.h" -const char * const RANDOMIZER_NAMES[Vector3Randomizer::CLASSID_MAXKNOWN] = +const char * const RANDOMIZER_NAMES[] = { "Solid Box", "Solid Sphere", "Hollow Sphere", "Solid Cylinder", }; +static_assert(ARRAY_SIZE(RANDOMIZER_NAMES) == Vector3Randomizer::CLASSID_MAXKNOWN, "Incorrect array size"); //////////////////////////////////////////////////////////////////// @@ -52,8 +53,6 @@ const char * const RANDOMIZER_NAMES[Vector3Randomizer::CLASSID_MAXKNOWN] = void Fill_Vector3_Rnd_Combo (HWND hcombobox) { - ASSERT (Vector3Randomizer::CLASSID_MAXKNOWN == (sizeof (RANDOMIZER_NAMES) / sizeof (char *))); - // // Add all the strings to the combobox // diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Locomotor.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Locomotor.h index 3649866a957..9fbd4ea25b6 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Locomotor.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Locomotor.h @@ -87,7 +87,7 @@ static const char *const TheLocomotorAppearanceNames[] = nullptr }; -static_assert(ARRAY_SIZE(TheLocomotorAppearanceNames) == LOCOMOTOR_APPEARANCE_COUNT + 1, "Array size"); +static_assert(ARRAY_SIZE(TheLocomotorAppearanceNames) == LOCOMOTOR_APPEARANCE_COUNT + 1, "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- @@ -119,7 +119,7 @@ static const char *const TheLocomotorBehaviorZNames[] = nullptr }; -static_assert(ARRAY_SIZE(TheLocomotorBehaviorZNames) == LOCOMOTOR_BEHAVIOR_Z_COUNT + 1, "Array size"); +static_assert(ARRAY_SIZE(TheLocomotorBehaviorZNames) == LOCOMOTOR_BEHAVIOR_Z_COUNT + 1, "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h index 10b178c045d..ed12e1aed5f 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h @@ -114,7 +114,9 @@ enum ST_BUSY, ///< Direct player involvement (move) has taken me off autopilot ST_WANTING, ///< Search for warehouse or center and dock with it ST_REGROUPING, ///< Wanting failed, so hang out at base until something changes. Autopilot will turn off. - ST_DOCKING ///< Docking substates are running, wait for them to finish + ST_DOCKING, ///< Docking substates are running, wait for them to finish + + ST_COUNT }; //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/ObjectIter.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/ObjectIter.h index cf41ba55d06..5945e1e2c90 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/ObjectIter.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/ObjectIter.h @@ -42,7 +42,9 @@ enum IterOrderType CPP_11(: Int) ITER_SORTED_NEAR_TO_FAR, ///< iterate in nearest-to-farthest order (may be slower) ITER_SORTED_FAR_TO_NEAR, ///< iterate in farthest-to-nearest order (may be slower) ITER_SORTED_CHEAP_TO_EXPENSIVE, ///< iterate in cheapest-to-most-expensive order (slower) - ITER_SORTED_EXPENSIVE_TO_CHEAP ///< iterate in most-expensive-to-cheapest order (slower) + ITER_SORTED_EXPENSIVE_TO_CHEAP, ///< iterate in most-expensive-to-cheapest order (slower) + + ITER_ORDER_TYPE_COUNT }; diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/PartitionManager.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/PartitionManager.h index a183f54feb0..a37b9e33dad 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/PartitionManager.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/PartitionManager.h @@ -151,7 +151,9 @@ enum DistanceCalculationType CPP_11(: Int) FROM_CENTER_2D = 0, ///< measure from Object center in 2d. FROM_CENTER_3D = 1, ///< measure from Object center in 3d. FROM_BOUNDINGSPHERE_2D = 2, ///< measure from Object bounding sphere in 2d. - FROM_BOUNDINGSPHERE_3D = 3 ///< measure from Object bounding sphere in 3d. + FROM_BOUNDINGSPHERE_3D = 3, ///< measure from Object bounding sphere in 3d. + + DISTANCE_CALCULATION_TYPE_COUNT }; //===================================== diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h index 0a1b9879f31..23666d95af3 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/WeaponSet.h @@ -83,7 +83,7 @@ static_assert(ARRAY_SIZE(TheWeaponSlotTypeNamesLookupList) == WEAPONSLOT_COUNT + //Purpose: Whenever you change a weaponset, the model condition state associated with it //will be properly set exclusively. -static const ModelConditionFlagType TheWeaponSetTypeToModelConditionTypeMap[WEAPONSET_COUNT] = +static const ModelConditionFlagType TheWeaponSetTypeToModelConditionTypeMap[] = { /*WEAPONSET_VETERAN*/ MODELCONDITION_WEAPONSET_VETERAN, /*WEAPONSET_ELITE*/ MODELCONDITION_WEAPONSET_ELITE, @@ -103,6 +103,7 @@ static const ModelConditionFlagType TheWeaponSetTypeToModelConditionTypeMap[WEAP /*WEAPONSET_RIDER7*/ MODELCONDITION_RIDER7, /*WEAPONSET_RIDER8*/ MODELCONDITION_RIDER8, }; +static_assert(ARRAY_SIZE(TheWeaponSetTypeToModelConditionTypeMap) == WEAPONSET_COUNT, "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Handicap.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Handicap.cpp index 4261129cf8a..a31c39334f3 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Handicap.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Handicap.cpp @@ -69,7 +69,7 @@ void Handicap::readFromDict(const Dict* d) // this isn't very efficient, but is only called at load times, // so it probably doesn't really matter. - const char* htNames[HANDICAP_TYPE_COUNT] = + const char* htNames[] = { "BUILDCOST", "BUILDTIME", @@ -79,12 +79,14 @@ void Handicap::readFromDict(const Dict* d) // "AIRSPEED", // "INCOME" }; + static_assert(ARRAY_SIZE(htNames) == HANDICAP_TYPE_COUNT, "Incorrect array size"); - const char* ttNames[THING_TYPE_COUNT] = + const char* ttNames[] = { "GENERIC", "BUILDINGS", }; + static_assert(ARRAY_SIZE(ttNames) == THING_TYPE_COUNT, "Incorrect array size"); // no, you should NOT call init() here. //init(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp index 1fbf9009eb0..ee687310d87 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -1072,13 +1072,14 @@ Real Drawable::getScale () const //------------------------------------------------------------------------------------------------- void Drawable::reactToBodyDamageStateChange(BodyDamageType newState) { - static const ModelConditionFlagType TheDamageMap[BODYDAMAGETYPE_COUNT] = + static const ModelConditionFlagType TheDamageMap[] = { MODELCONDITION_INVALID, MODELCONDITION_DAMAGED, MODELCONDITION_REALLY_DAMAGED, MODELCONDITION_RUBBLE, }; + static_assert(ARRAY_SIZE(TheDamageMap) == BODYDAMAGETYPE_COUNT, "Incorrect array size"); ModelConditionFlags newDamage; if (TheDamageMap[newState] != MODELCONDITION_INVALID) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 2e3877cc956..93d1b581447 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -6343,6 +6343,7 @@ void InGameUI::drawPlayerInfoList() const UnicodeString nameValue = player->getPlayerDisplayName(); const UnsignedInt currentValues[] = {teamValue, moneyValue, moneyPerMinuteValue, rankValue, xpValue}; + static_assert(ARRAY_SIZE(currentValues) == PlayerInfoList::LabelType_Count, "Incorrect array size"); for (column = 0; column < ARRAY_SIZE(currentValues); ++column) { UnsignedInt &lastValue = m_playerInfoList.lastValues.values[column][row]; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp index 205c1a99457..d13219ef122 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp @@ -67,7 +67,7 @@ static const char *const TheLocomotorPriorityNames[] = nullptr }; -static_assert(ARRAY_SIZE(TheLocomotorPriorityNames) == LOCOMOTOR_PRIORITY_COUNT + 1, "Array size"); +static_assert(ARRAY_SIZE(TheLocomotorPriorityNames) == LOCOMOTOR_PRIORITY_COUNT + 1, "Incorrect array size"); /////////////////////////////////////////////////////////////////////////////////////////////////// // PRIVATE DATA /////////////////////////////////////////////////////////////////////////////////// diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp index 514c577a8cf..891e0683da3 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp @@ -118,7 +118,7 @@ ObjectID TheObjectIDToDebug = INVALID_ID; #endif // ------------------------------------------------------------------------------------------------ -static const ModelConditionFlags s_allWeaponFireFlags[WEAPONSLOT_COUNT] = +static const ModelConditionFlags s_allWeaponFireFlags[] = { MAKE_MODELCONDITION_MASK5( MODELCONDITION_FIRING_A, @@ -142,6 +142,7 @@ static const ModelConditionFlags s_allWeaponFireFlags[WEAPONSLOT_COUNT] = MODELCONDITION_USING_WEAPON_C ) }; +static_assert(ARRAY_SIZE(s_allWeaponFireFlags) == WEAPONSLOT_COUNT, "Incorrect array size"); //------------------------------------------------------------------------------------------------- extern void addIcon(const Coord3D *pos, Real width, Int numFramesDuration, RGBColor color); @@ -4816,7 +4817,7 @@ void Object::adjustModelConditionForWeaponStatus() { WeaponStatus newStatus = w->getStatus(); - const static WeaponSetConditionType s_wsfLookup[WEAPON_STATUS_COUNT] = + const static WeaponSetConditionType s_wsfLookup[] = { WSF_NONE, // READY_TO_FIRE, WSF_NONE, // OUT_OF_AMMO, @@ -4824,6 +4825,7 @@ void Object::adjustModelConditionForWeaponStatus() WSF_RELOADING, // RELOADING_CLIP, WSF_PREATTACK // PRE_ATTACK, }; + static_assert(ARRAY_SIZE(s_wsfLookup) == WEAPON_STATUS_COUNT, "Incorrect array size"); conditionToSet = s_wsfLookup[newStatus]; // special case this: say we are firing in bursts: pow-pow-pow-pause, etc. diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp index a7f9cad0123..c9261fd7837 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp @@ -960,6 +960,7 @@ static DistCalcProc theDistCalcProcs[] = distCalcProc_BoundaryAndBoundary_2D, distCalcProc_BoundaryAndBoundary_3D, }; +static_assert(ARRAY_SIZE(theDistCalcProcs) == DISTANCE_CALCULATION_TYPE_COUNT, "Incorrect array size"); // NOTE: This *DEPENDS* on the order of the geometry enum defines static CollideTestProc theCollideTestProcs[] = @@ -974,6 +975,7 @@ static CollideTestProc theCollideTestProcs[] = collideTest_Box_Cylinder, collideTest_Box_Box }; +static_assert(ARRAY_SIZE(theCollideTestProcs) == GEOMETRY_NUM_TYPES * GEOMETRY_NUM_TYPES, "Incorrect array size"); //----------------------------------------------------------------------------- // Public Data diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SimpleObjectIterator.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SimpleObjectIterator.cpp index 1e2156204bf..47882477131 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SimpleObjectIterator.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SimpleObjectIterator.cpp @@ -58,6 +58,8 @@ SimpleObjectIterator::Clump::~Clump() //============================================================================= SimpleObjectIterator::SimpleObjectIterator() { + static_assert(ARRAY_SIZE(theClumpCompareProcs) == ITER_ORDER_TYPE_COUNT, "Incorrect array size"); + m_firstClump = nullptr; m_curClump = nullptr; m_clumpCount = 0; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp index 5e966094ef7..cd8fda43588 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp @@ -55,6 +55,7 @@ static const char* statenames[] = "ST_REGROUPING", ///< Wanting failed, so hang out at base until something changes. Still on autopilot, but resting. "ST_DOCKING" ///< Docking substates are running, wait for them to finish }; +static_assert(ARRAY_SIZE(statenames) == ST_COUNT, "Incorrect array size"); #endif enum { diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp index c583de7dba3..b9ec1019b33 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp @@ -58,37 +58,41 @@ // PUBLIC ///////////////////////////////////////////////////////////////////////////////////////// -static const ModelConditionFlagType theOpeningFlags[DOOR_COUNT_MAX] = +static const ModelConditionFlagType theOpeningFlags[] = { MODELCONDITION_DOOR_1_OPENING, MODELCONDITION_DOOR_2_OPENING, MODELCONDITION_DOOR_3_OPENING, MODELCONDITION_DOOR_4_OPENING }; +static_assert(ARRAY_SIZE(theOpeningFlags) == DOOR_COUNT_MAX, "Incorrect array size"); -static const ModelConditionFlagType theClosingFlags[DOOR_COUNT_MAX] = +static const ModelConditionFlagType theClosingFlags[] = { MODELCONDITION_DOOR_1_CLOSING, MODELCONDITION_DOOR_2_CLOSING, MODELCONDITION_DOOR_3_CLOSING, MODELCONDITION_DOOR_4_CLOSING }; +static_assert(ARRAY_SIZE(theClosingFlags) == DOOR_COUNT_MAX, "Incorrect array size"); -static const ModelConditionFlagType theWaitingOpenFlags[DOOR_COUNT_MAX] = +static const ModelConditionFlagType theWaitingOpenFlags[] = { MODELCONDITION_DOOR_1_WAITING_OPEN, MODELCONDITION_DOOR_2_WAITING_OPEN, MODELCONDITION_DOOR_3_WAITING_OPEN, MODELCONDITION_DOOR_4_WAITING_OPEN }; +static_assert(ARRAY_SIZE(theWaitingOpenFlags) == DOOR_COUNT_MAX, "Incorrect array size"); -static const ModelConditionFlagType theWaitingToCloseFlags[DOOR_COUNT_MAX] = +static const ModelConditionFlagType theWaitingToCloseFlags[] = { MODELCONDITION_DOOR_1_WAITING_TO_CLOSE, MODELCONDITION_DOOR_2_WAITING_TO_CLOSE, MODELCONDITION_DOOR_3_WAITING_TO_CLOSE, MODELCONDITION_DOOR_4_WAITING_TO_CLOSE }; +static_assert(ARRAY_SIZE(theWaitingToCloseFlags) == DOOR_COUNT_MAX, "Incorrect array size"); //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpectreGunshipDeploymentUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpectreGunshipDeploymentUpdate.cpp index 40ddaf1f49a..ce6d51763fb 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpectreGunshipDeploymentUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpectreGunshipDeploymentUpdate.cpp @@ -84,7 +84,7 @@ static const char* const TheGunshipCreateLocTypeNames[] = "CREATE_AT_EDGE_FARTHEST_FROM_TARGET", nullptr }; -static_assert(ARRAY_SIZE(TheGunshipCreateLocTypeNames) == GUNSHIP_CREATE_LOC_COUNT + 1, "Wrong array size"); +static_assert(ARRAY_SIZE(TheGunshipCreateLocTypeNames) == GUNSHIP_CREATE_LOC_COUNT + 1, "Incorrect array size"); static Real zero = 0.0f; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StructureCollapseUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StructureCollapseUpdate.cpp index 74d7471c902..8d2c955567d 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StructureCollapseUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StructureCollapseUpdate.cpp @@ -59,7 +59,7 @@ static const char *const TheStructureCollapsePhaseNames[] = nullptr }; -static_assert(ARRAY_SIZE(TheStructureCollapsePhaseNames) == SC_PHASE_COUNT + 1, "Wrong array size"); +static_assert(ARRAY_SIZE(TheStructureCollapsePhaseNames) == SC_PHASE_COUNT + 1, "Incorrect array size"); //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp index a94ccaf4902..bec32267fd6 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp @@ -365,12 +365,18 @@ void WeaponSet::updateWeaponSet(const Object* obj) //------------------------------------------------------------------------------------------------- /*static*/ ModelConditionFlags WeaponSet::getModelConditionForWeaponSlot(WeaponSlotType wslot, WeaponSetConditionType a) { - static const ModelConditionFlagType Nothing[WEAPONSLOT_COUNT] = { MODELCONDITION_INVALID, MODELCONDITION_INVALID, MODELCONDITION_INVALID }; - static const ModelConditionFlagType Firing[WEAPONSLOT_COUNT] = { MODELCONDITION_FIRING_A, MODELCONDITION_FIRING_B, MODELCONDITION_FIRING_C }; - static const ModelConditionFlagType Betweening[WEAPONSLOT_COUNT] = { MODELCONDITION_BETWEEN_FIRING_SHOTS_A, MODELCONDITION_BETWEEN_FIRING_SHOTS_B, MODELCONDITION_BETWEEN_FIRING_SHOTS_C }; - static const ModelConditionFlagType Reloading[WEAPONSLOT_COUNT] = { MODELCONDITION_RELOADING_A, MODELCONDITION_RELOADING_B, MODELCONDITION_RELOADING_C }; - static const ModelConditionFlagType PreAttack[WEAPONSLOT_COUNT] = { MODELCONDITION_PREATTACK_A, MODELCONDITION_PREATTACK_B, MODELCONDITION_PREATTACK_C }; - static const ModelConditionFlagType* Lookup[WSF_COUNT] = { Nothing, Firing, Betweening, Reloading, PreAttack }; + static const ModelConditionFlagType Nothing[] = { MODELCONDITION_INVALID, MODELCONDITION_INVALID, MODELCONDITION_INVALID }; + static const ModelConditionFlagType Firing[] = { MODELCONDITION_FIRING_A, MODELCONDITION_FIRING_B, MODELCONDITION_FIRING_C }; + static const ModelConditionFlagType Betweening[] = { MODELCONDITION_BETWEEN_FIRING_SHOTS_A, MODELCONDITION_BETWEEN_FIRING_SHOTS_B, MODELCONDITION_BETWEEN_FIRING_SHOTS_C }; + static const ModelConditionFlagType Reloading[] = { MODELCONDITION_RELOADING_A, MODELCONDITION_RELOADING_B, MODELCONDITION_RELOADING_C }; + static const ModelConditionFlagType PreAttack[] = { MODELCONDITION_PREATTACK_A, MODELCONDITION_PREATTACK_B, MODELCONDITION_PREATTACK_C }; + static const ModelConditionFlagType* Lookup[] = { Nothing, Firing, Betweening, Reloading, PreAttack }; + static_assert(ARRAY_SIZE(Nothing) == WEAPONSLOT_COUNT, "Incorrect array size"); + static_assert(ARRAY_SIZE(Firing) == WEAPONSLOT_COUNT, "Incorrect array size"); + static_assert(ARRAY_SIZE(Betweening) == WEAPONSLOT_COUNT, "Incorrect array size"); + static_assert(ARRAY_SIZE(Reloading) == WEAPONSLOT_COUNT, "Incorrect array size"); + static_assert(ARRAY_SIZE(PreAttack) == WEAPONSLOT_COUNT, "Incorrect array size"); + static_assert(ARRAY_SIZE(Lookup) == WSF_COUNT, "Incorrect array size"); ModelConditionFlags flags; // defaults to all clear @@ -378,7 +384,8 @@ void WeaponSet::updateWeaponSet(const Object* obj) if (f != MODELCONDITION_INVALID) flags.set(f); - static const ModelConditionFlagType Using[WEAPONSLOT_COUNT] = { MODELCONDITION_USING_WEAPON_A, MODELCONDITION_USING_WEAPON_B, MODELCONDITION_USING_WEAPON_C }; + static const ModelConditionFlagType Using[] = { MODELCONDITION_USING_WEAPON_A, MODELCONDITION_USING_WEAPON_B, MODELCONDITION_USING_WEAPON_C }; + static_assert(ARRAY_SIZE(Using) == WEAPONSLOT_COUNT, "Incorrect array size"); if (a != WSF_NONE) flags.set(Using[wslot]); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/Scripts.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/Scripts.cpp index ad2e04c85d0..7ce07488278 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/Scripts.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/Scripts.cpp @@ -57,6 +57,7 @@ #include "Common/Xfer.h" #include "GameClient/ShellHooks.h" +#include "GameClient/View.h" #include "GameLogic/AI.h" #include "GameLogic/Object.h" @@ -128,6 +129,7 @@ void SignalUIInteraction(Int interaction) // in a meaningful way. If there are new entries, add them to the end, rather than the middle. const char *Surfaces[] = { "Ground", "Air", "Ground or Air" }; const char *ShakeIntensities[] = { "Subtle", "Normal", "Strong", "Severe", "Cine_Extreme", "Cine_Insane" }; +static_assert(ARRAY_SIZE(ShakeIntensities) == View::SHAKE_COUNT, "Incorrect array size"); enum { K_SCRIPT_LIST_DATA_VERSION_1 = 1, K_SCRIPT_GROUP_DATA_VERSION_1 = 1, diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp index 6001e9a0496..56f31137a58 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp @@ -28,7 +28,7 @@ W3DBufferManager *TheW3DBufferManager=nullptr; //singleton -static int FVFTypeIndexList[W3DBufferManager::MAX_FVF]= +static int FVFTypeIndexList[]= { D3DFVF_XYZ, D3DFVF_XYZ|D3DFVF_DIFFUSE, @@ -49,6 +49,7 @@ static int FVFTypeIndexList[W3DBufferManager::MAX_FVF]= D3DFVF_XYZRHW|D3DFVF_TEX2, D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX2 }; +static_assert(ARRAY_SIZE(FVFTypeIndexList) == W3DBufferManager::MAX_FVF, "Incorrect array size"); Int W3DBufferManager::getDX8Format(VBM_FVF_TYPES format) { diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/part_ldr.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/part_ldr.cpp index 9209bd3c9c4..9c9589ddd06 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/part_ldr.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/part_ldr.cpp @@ -57,10 +57,11 @@ ParticleEmitterLoaderClass _ParticleEmitterLoader; // This array is declared in "W3D_File.h" -const char *EMITTER_TYPE_NAMES[EMITTER_TYPEID_COUNT] = +const char *EMITTER_TYPE_NAMES[] = { "Default" }; +static_assert(ARRAY_SIZE(EMITTER_TYPE_NAMES) == EMITTER_TYPEID_COUNT, "Incorrect array size"); /////////////////////////////////////////////////////////////////////////////////// diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp index a9361a543d5..0b3f94952ab 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp @@ -375,15 +375,16 @@ class Blend bool useAlpha; }; -const Blend srcBlendLUT[ShaderClass::SRCBLEND_MAX] = +const Blend srcBlendLUT[] = { Blend(D3DBLEND_ZERO, false), Blend(D3DBLEND_ONE, false), Blend(D3DBLEND_SRCALPHA, true), Blend(D3DBLEND_DESTCOLOR, true) }; +static_assert(ARRAY_SIZE(srcBlendLUT) == ShaderClass::SRCBLEND_MAX, "Incorrect array size"); -const Blend dstBlendLUT[ShaderClass::DSTBLEND_MAX] = +const Blend dstBlendLUT[] = { Blend(D3DBLEND_ZERO, false), Blend(D3DBLEND_ONE, false), @@ -392,6 +393,7 @@ const Blend dstBlendLUT[ShaderClass::DSTBLEND_MAX] = Blend(D3DBLEND_SRCALPHA, true), Blend(D3DBLEND_INVSRCALPHA, true) }; +static_assert(ARRAY_SIZE(dstBlendLUT) == ShaderClass::DSTBLEND_MAX, "Incorrect array size"); /*********************************************************************************************** diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/w3d_file.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/w3d_file.h index 7b2ca93741a..f074318ef80 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/w3d_file.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/w3d_file.h @@ -1126,7 +1126,7 @@ typedef enum SURFACE_TYPE_MAX // NOTE: if you add a surface type, add it to the SurfaceEffects.INI file! } W3D_SURFACE_TYPES; -const char * const SURFACE_TYPE_STRINGS[SURFACE_TYPE_MAX] = +const char * const SURFACE_TYPE_STRINGS[] = { "Light Metal", "Heavy Metal", @@ -1161,6 +1161,7 @@ const char * const SURFACE_TYPE_STRINGS[SURFACE_TYPE_MAX] = "Underwater Dirt", "Underwater Tiberium Dirt", }; +static_assert(ARRAY_SIZE(SURFACE_TYPE_STRINGS) == SURFACE_TYPE_MAX, "Incorrect array size"); ///////////////////////////////////////////////////////////////////////////////////////////// // Flags for the Mesh Attributes member @@ -1792,7 +1793,7 @@ enum // The definition of this string array can be found in // Part_Ldr.cpp. Please update this array accordingly. // -extern const char *EMITTER_TYPE_NAMES[EMITTER_TYPEID_COUNT]; +extern const char *EMITTER_TYPE_NAMES[]; struct W3dEmitterHeaderStruct { diff --git a/GeneralsMD/Code/Tools/GUIEdit/Source/Properties.cpp b/GeneralsMD/Code/Tools/GUIEdit/Source/Properties.cpp index c1473cfc0ab..8be5cf62a1e 100644 --- a/GeneralsMD/Code/Tools/GUIEdit/Source/Properties.cpp +++ b/GeneralsMD/Code/Tools/GUIEdit/Source/Properties.cpp @@ -375,6 +375,7 @@ ImageAndColorInfo imageAndColorTable[] = { 0, IDENTIFIER_INVALID, nullptr, nullptr, nullptr, 0 } }; +static_assert(ARRAY_SIZE(imageAndColorTable) == NUM_STATE_IDENTIFIERS, "Incorrect array size"); // PUBLIC DATA //////////////////////////////////////////////////////////////// diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp index f2fe2bc5621..c6595576fcc 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/DrawObject.cpp @@ -1781,7 +1781,8 @@ void DrawObject::updateVBWithWeaponRange(MapObject *pMapObj, CameraClass* camera return; } - const unsigned long colors[WEAPONSLOT_COUNT] = {0xFF00FF00, 0xFFE0F00A, 0xFFFF0000}; // Green, Yellow, Red + const unsigned long colors[] = {0xFF00FF00, 0xFFE0F00A, 0xFFFF0000}; // Green, Yellow, Red + static_assert(ARRAY_SIZE(colors) == WEAPONSLOT_COUNT, "Incorrect array size"); Coord3D pos = *pMapObj->getLocation(); diff --git a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp index 9de7548202f..f385061ae8a 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp @@ -2109,6 +2109,7 @@ static void writeRawDict( FILE *theLogFile, const char* nm, const Dict* d ) Dict::DataType t = d->getNthType(i); const char* typenames[] = { "Bool", "int", "float", "ascii", "unicode" }; + static_assert(ARRAY_SIZE(typenames) == Dict::DICT_TYPE_COUNT, "Incorrect array size"); fprintf(theLogFile, "Entry %d is %s: %s = ",i,typenames[t], kname.str()); switch(t) @@ -2154,6 +2155,7 @@ void CWorldBuilderDoc::OnDumpDocToText() { MapObject *pMapObj = nullptr; const char* vetStrings[] = {"Green", "Regular", "Veteran", "Elite"}; + static_assert(ARRAY_SIZE(vetStrings) == LEVEL_COUNT, "Incorrect array size"); const char* aggroStrings[] = {"Passive", "Normal", "Guard", "Hunt", "Aggressive", "Sleep"}; AsciiString noOwner = "No Owner"; static FILE *theLogFile = nullptr; diff --git a/GeneralsMD/Code/Tools/wdump/chunk_d.cpp b/GeneralsMD/Code/Tools/wdump/chunk_d.cpp index 7c7933c9f61..0e4889686dd 100644 --- a/GeneralsMD/Code/Tools/wdump/chunk_d.cpp +++ b/GeneralsMD/Code/Tools/wdump/chunk_d.cpp @@ -220,6 +220,16 @@ void ChunkTableClass::AddItem(CListCtrl *list, int &Counter, const char *name, W static const char * _dithermask[] = { "Disable", "Enable" }; static const char * _shademodel[] = { "Smooth", "Flat" }; static const char * _alphatest[] = { "Alpha Test Disable", "Alpha Test Enable" }; + static_assert(ARRAY_SIZE(_depth_compare) == W3DSHADER_DEPTHCOMPARE_PASS_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_depth_mask) == W3DSHADER_DEPTHMASK_WRITE_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_destblend) == W3DSHADER_DESTBLENDFUNC_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_prigradient) == W3DSHADER_PRIGRADIENT_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_secgradient) == W3DSHADER_SECGRADIENT_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_srcblend) == W3DSHADER_SRCBLENDFUNC_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_texturing) == W3DSHADER_TEXTURING_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_detailcolor) == W3DSHADER_DETAILCOLORFUNC_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_detailalpha) == W3DSHADER_DETAILALPHAFUNC_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_alphatest) == W3DSHADER_ALPHATEST_MAX, "Incorrect array size"); int counter = 0; char label[256]; @@ -264,6 +274,8 @@ void ChunkTableClass::AddItem(CListCtrl *list, int &Counter, const char *name, W static const char * _detailalpha[] = { "Disable","Detail","Scale","InvScale" }; static const char * _dithermask[] = { "Disable", "Enable" }; static const char * _shademodel[] = { "Smooth", "Flat" }; + static_assert(ARRAY_SIZE(_depth_mask) == W3DSHADER_DEPTHMASK_WRITE_MAX, "Incorrect array size"); + static_assert(ARRAY_SIZE(_texturing) == W3DSHADER_TEXTURING_MAX, "Incorrect array size"); int counter = 0; char label[256]; @@ -1499,6 +1511,7 @@ void ChunkTableClass::List_W3D_CHUNK_ANIMATION_CHANNEL(ChunkItem *Item, CListCtr "Z Rotation", "Quaternion" }; + static_assert(ARRAY_SIZE(_chntypes) == ANIM_CHANNEL_Q + 1, "Incorrect array size"); W3dAnimChannelStruct *data = (W3dAnimChannelStruct *) Item->Data; @@ -1530,6 +1543,7 @@ void ChunkTableClass::List_W3D_CHUNK_BIT_CHANNEL(ChunkItem *Item, CListCtrl *lis { "Visibility", }; + static_assert(ARRAY_SIZE(_chntypes) == BIT_CHANNEL_VIS + 1, "Incorrect array size"); W3dBitChannelStruct *data = (W3dBitChannelStruct *) Item->Data; From be8105be3f48d9433846ce76cedba613fc8ac8d0 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Tue, 29 Sep 2026 20:54:52 +0200 Subject: [PATCH 3/3] chore: Add static asserts to verify the size of arrays for enum bit flags --- Core/GameEngine/Include/Common/AudioEventInfo.h | 4 ++++ Core/GameEngine/Include/GameClient/ControlBar.h | 3 +++ Core/GameEngine/Include/GameClient/Gadget.h | 1 + Core/GameEngine/Include/GameClient/GameWindow.h | 7 ++++--- Core/GameEngine/Include/GameClient/Image.h | 2 ++ Core/GameEngine/Include/GameClient/MetaEvent.h | 3 +++ Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp | 2 ++ .../Source/GameClient/GUI/GameWindowManagerScript.cpp | 2 ++ GeneralsMD/Code/GameEngine/Include/GameClient/Shadow.h | 5 ++++- .../Code/GameEngine/Include/GameLogic/LocomotorSet.h | 5 ++++- .../Code/GameEngine/Include/GameLogic/Module/AIUpdate.h | 3 +++ .../GameEngine/Include/GameLogic/Module/StealthUpdate.h | 3 +++ GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h | 8 +++++++- .../Source/GameLogic/Object/ObjectCreationList.cpp | 5 ++++- 14 files changed, 46 insertions(+), 7 deletions(-) diff --git a/Core/GameEngine/Include/Common/AudioEventInfo.h b/Core/GameEngine/Include/Common/AudioEventInfo.h index 741ffeacc90..00a49a205d2 100644 --- a/Core/GameEngine/Include/Common/AudioEventInfo.h +++ b/Core/GameEngine/Include/Common/AudioEventInfo.h @@ -70,6 +70,8 @@ enum SoundType CPP_11(: Int) ST_ALLIES = 0x0040, ST_ENEMIES = 0x0080, ST_EVERYONE = 0x0100, + + SOUND_TYPE_END // keep after the last named flag }; extern const char *const theAudioControlNames[]; @@ -80,6 +82,8 @@ enum AudioControl CPP_11(: Int) AC_ALL = 0x0004, AC_POSTDELAY = 0x0008, AC_INTERRUPT = 0x0010, + + AUDIO_CONTROL_END // keep after the last named flag }; class DynamicAudioEventInfo; diff --git a/Core/GameEngine/Include/GameClient/ControlBar.h b/Core/GameEngine/Include/GameClient/ControlBar.h index 446277a13be..edf19ad4aca 100644 --- a/Core/GameEngine/Include/GameClient/ControlBar.h +++ b/Core/GameEngine/Include/GameClient/ControlBar.h @@ -99,6 +99,8 @@ enum CommandOption CPP_11(: Int) USES_MINE_CLEARING_WEAPONSET= 0x00200000, // uses the special mine-clearing weaponset, even if not current CAN_USE_WAYPOINTS = 0x00400000, // button has option to use a waypoint path MUST_BE_STOPPED = 0x00800000, // Unit must be stopped in order to be able to use button. + + COMMAND_OPTION_END // keep after the last named flag }; #ifdef DEFINE_COMMAND_OPTION_NAMES @@ -135,6 +137,7 @@ static const char *const TheCommandOptionNames[] = nullptr }; +static_assert(1 << (ARRAY_SIZE(TheCommandOptionNames) - 2) == COMMAND_OPTION_END - 1, "Incorrect array size"); #endif // end DEFINE_COMMAND_OPTION_NAMES // convenient bit masks to group some command options together diff --git a/Core/GameEngine/Include/GameClient/Gadget.h b/Core/GameEngine/Include/GameClient/Gadget.h index 30c9d45206c..41bc396ed8e 100644 --- a/Core/GameEngine/Include/GameClient/Gadget.h +++ b/Core/GameEngine/Include/GameClient/Gadget.h @@ -105,6 +105,7 @@ enum GWS_TAB_PANE = 0x00004000, GWS_COMBO_BOX = 0x00008000, + GWS_END, // keep after the last named flag GWS_ALL_SLIDER = GWS_VERT_SLIDER | GWS_HORZ_SLIDER, // for convenience diff --git a/Core/GameEngine/Include/GameClient/GameWindow.h b/Core/GameEngine/Include/GameClient/GameWindow.h index e96c94c96a0..e15e6408cdf 100644 --- a/Core/GameEngine/Include/GameClient/GameWindow.h +++ b/Core/GameEngine/Include/GameClient/GameWindow.h @@ -153,7 +153,6 @@ enum WinInputReturnCode CPP_11(: Int) enum { - // when you edit this, remember to edit WindowStatusNames[] WIN_STATUS_NONE = 0x00000000, // No status bits set at all WIN_STATUS_ACTIVE = 0x00000001, // At the top of the window list WIN_STATUS_TOGGLE = 0x00000002, // If set, click to toggle @@ -181,9 +180,11 @@ enum WIN_STATUS_FLASHING = 0x00800000, // Used for buttons that do cameo flashes. WIN_STATUS_ALWAYS_COLOR = 0x01000000, // Never render these buttons using greyscale renderer when button disabled. WIN_STATUS_ON_MOUSE_DOWN = 0x02000000, // Pushbutton triggers on mouse down. - WIN_STATUS_SHORTCUT_BUTTON = 0x04000000, // Oh god... this is a total hack for shortcut buttons to handle rendering text top left corner... - // when you edit this, remember to edit WindowStatusNames[] + WIN_STATUS_END, // keep after the last named flag + + // Code only flags without a name in WindowStatusNames[] + WIN_STATUS_SHORTCUT_BUTTON = 0x04000000, // Oh god... this is a total hack for shortcut buttons to handle rendering text top left corner... }; diff --git a/Core/GameEngine/Include/GameClient/Image.h b/Core/GameEngine/Include/GameClient/Image.h index 07b72c91928..3d35ba5b652 100644 --- a/Core/GameEngine/Include/GameClient/Image.h +++ b/Core/GameEngine/Include/GameClient/Image.h @@ -47,6 +47,7 @@ typedef enum IMAGE_STATUS_ROTATED_90_CLOCKWISE = 0x00000001, // image should be treated as rotated IMAGE_STATUS_RAW_TEXTURE = 0x00000002, // image struct contains raw texture data + IMAGE_STATUS_END // keep after the last named flag } ImageStatus; #ifdef DEFINE_IMAGE_STATUS_NAMES static const char *const imageStatusNames[] = @@ -55,6 +56,7 @@ static const char *const imageStatusNames[] = "RAW_TEXTURE", nullptr }; +static_assert(1 << (ARRAY_SIZE(imageStatusNames) - 2) == IMAGE_STATUS_END - 1, "Incorrect array size"); #endif // end DEFINE_IMAGE_STATUS_NAMES //------------------------------------------------------------------------------------------------- diff --git a/Core/GameEngine/Include/GameClient/MetaEvent.h b/Core/GameEngine/Include/GameClient/MetaEvent.h index db6f2175370..4cacec9ce3e 100644 --- a/Core/GameEngine/Include/GameClient/MetaEvent.h +++ b/Core/GameEngine/Include/GameClient/MetaEvent.h @@ -320,6 +320,8 @@ enum CommandUsableInType CPP_11(: Int) COMMANDUSABLE_GAME = (1 << 1), // Command is usable when not in Shell COMMANDUSABLE_OBSERVER = (1 << 2), // TheSuperHackers @feature Command is usable when observing + COMMAND_USABLE_IN_TYPE_END, // keep after the last named flag + COMMANDUSABLE_EVERYWHERE = ~0, }; @@ -331,6 +333,7 @@ static const char* const TheCommandUsableInNames[] = nullptr }; +static_assert(1 << (ARRAY_SIZE(TheCommandUsableInNames) - 2) == COMMAND_USABLE_IN_TYPE_END - 1, "Incorrect array size"); // ------------------------------------------------------------------------------- class MetaMapRec : public MemoryPoolObject diff --git a/Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp b/Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp index 2420542bee7..d42e2e7cc4d 100644 --- a/Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp +++ b/Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp @@ -203,6 +203,7 @@ const char *const theSoundTypeNames[] = "EVERYONE", nullptr }; +static_assert(1 << (ARRAY_SIZE(theSoundTypeNames) - 2) == SOUND_TYPE_END - 1, "Incorrect array size"); const char *const theAudioControlNames[] = { @@ -213,4 +214,5 @@ const char *const theAudioControlNames[] = "INTERRUPT", nullptr }; +static_assert(1 << (ARRAY_SIZE(theAudioControlNames) - 2) == AUDIO_CONTROL_END - 1, "Incorrect array size"); diff --git a/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp b/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp index db071f8e966..18119a8984d 100644 --- a/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp +++ b/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp @@ -144,6 +144,7 @@ const char *const WindowStatusNames[] = { "ACTIVE", "TOGGLE", "DRAGABLE", "ENABL "USE_OVERLAY_STATES", "NOT_READY", "FLASHING", "ALWAYS_COLOR", "ON_MOUSE_DOWN", /*"SHORTCUT_BUTTON",*/ nullptr }; +static_assert(1 << (ARRAY_SIZE(WindowStatusNames) - 2) == WIN_STATUS_END - 1, "Incorrect array size"); const char *const WindowStyleNames[] = { "PUSHBUTTON", "RADIOBUTTON", "CHECKBOX", "VERTSLIDER", "HORZSLIDER", "SCROLLLISTBOX", @@ -152,6 +153,7 @@ const char *const WindowStyleNames[] = { "PUSHBUTTON", "RADIOBUTTON", "CHECKBOX" "TABSTOP", "TABCONTROL", "TABPANE", "COMBOBOX", nullptr }; +static_assert(1 << (ARRAY_SIZE(WindowStyleNames) - 2) == GWS_END - 1, "Incorrect array size"); // Implement a stack to keep track of parent/child nested window descriptions. static GameWindow *windowStack[ WIN_STACK_DEPTH ]; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Shadow.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Shadow.h index 0bcef0ea4f3..c6ce8947671 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Shadow.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Shadow.h @@ -44,7 +44,9 @@ enum ShadowType CPP_11(: Int) SHADOW_DYNAMIC_PROJECTION = 0x00000008, //extra setting for shadows which need dynamic updates SHADOW_DIRECTIONAL_PROJECTION = 0x00000010, //extra setting for shadow decals that rotate with sun direction SHADOW_ALPHA_DECAL = 0x00000020, //not really for shadows but for other decal uses. Alpha blended. - SHADOW_ADDITIVE_DECAL = 0x00000040 //not really for shadows but for other decal uses. Additive blended. + SHADOW_ADDITIVE_DECAL = 0x00000040, //not really for shadows but for other decal uses. Additive blended. + + SHADOW_TYPE_END // keep after the last named flag }; #ifdef DEFINE_SHADOW_NAMES static const char* const TheShadowNames[] = @@ -58,6 +60,7 @@ static const char* const TheShadowNames[] = "SHADOW_ADDITIVE_DECAL", nullptr }; +static_assert(1 << (ARRAY_SIZE(TheShadowNames) - 2) == SHADOW_TYPE_END - 1, "Incorrect array size"); #endif // end DEFINE_SHADOW_NAMES #define MAX_SHADOW_LIGHTS 1 //maximum number of shadow casting light sources in scene - support for more than 1 has been dropped from most code. diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/LocomotorSet.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/LocomotorSet.h index 111368d37d0..3422672652d 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/LocomotorSet.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/LocomotorSet.h @@ -49,7 +49,9 @@ enum LocomotorSurfaceType CPP_11(: Int) LOCOMOTORSURFACE_WATER = (1 << 1), ///< water area LOCOMOTORSURFACE_CLIFF = (1 << 2), ///< steep altitude change LOCOMOTORSURFACE_AIR = (1 << 3), ///< airborne - LOCOMOTORSURFACE_RUBBLE = (1 << 4) ///< building rubble + LOCOMOTORSURFACE_RUBBLE = (1 << 4), ///< building rubble + + LOCOMOTOR_SURFACE_TYPE_END // keep after the last named flag }; typedef Int LocomotorSurfaceTypeMask; @@ -68,6 +70,7 @@ static const char *const TheLocomotorSurfaceTypeNames[] = nullptr }; +static_assert(1 << (ARRAY_SIZE(TheLocomotorSurfaceTypeNames) - 2) == LOCOMOTOR_SURFACE_TYPE_END - 1, "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h index 4aa0483c815..7edc4d90c5b 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h @@ -118,6 +118,8 @@ enum AutoAcquireStates CPP_11(: Int) AAS_Idle_No = 0x04, AAS_Idle_Not_While_Attacking = 0x08, AAS_Idle_Attack_Buildings = 0x10, + + AUTO_ACQUIRE_STATES_END // keep after the last named flag }; #ifdef DEFINE_AUTOACQUIRE_NAMES @@ -131,6 +133,7 @@ static const char *const TheAutoAcquireEnemiesNames[] = nullptr }; +static_assert(1 << (ARRAY_SIZE(TheAutoAcquireEnemiesNames) - 2) == AUTO_ACQUIRE_STATES_END - 1, "Incorrect array size"); #endif diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h index 60d7f465e76..4e973efd0f5 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h @@ -50,6 +50,8 @@ enum STEALTH_NOT_WHILE_TAKING_DAMAGE = 0x00000080, STEALTH_NOT_WHILE_RIDERS_ATTACKING = 0x00000100, + STEALTH_LEVEL_END, // keep after the last named flag + STEALTH_NOT_WHILE_FIRING_WEAPON = (STEALTH_NOT_WHILE_FIRING_PRIMARY | STEALTH_NOT_WHILE_FIRING_SECONDARY | STEALTH_NOT_WHILE_FIRING_TERTIARY), }; @@ -67,6 +69,7 @@ static const char *const TheStealthLevelNames[] = "RIDERS_ATTACKING", nullptr }; +static_assert(1 << (ARRAY_SIZE(TheStealthLevelNames) - 2) == STEALTH_LEVEL_END - 1, "Incorrect array size"); #endif #define INVALID_OPACITY -1.0f diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h index c5997707ba7..b1512fa1811 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Weapon.h @@ -117,6 +117,8 @@ enum WeaponAffectsMaskType CPP_11(: Int) WEAPON_KILLS_SELF = 0x10, // ensures that it's not possible to survive self damage WEAPON_DOESNT_AFFECT_SIMILAR = 0x20, // Doesn't affect others that are the same as us (like other terrorists for a terrorist bomb to prevent chain reaction) WEAPON_DOESNT_AFFECT_AIRBORNE = 0x40, // Radius damage doesn't affect airborne units, unless they are the primary target. (used for poison fields.) + + WEAPON_AFFECTS_MASK_TYPE_END // keep after the last named flag }; //#ifdef DEFINE_WEAPONAFFECTSMASK_NAMES ; Removed protection so other classes can use these strings... not sure why this was protected in the 1st place @@ -131,6 +133,7 @@ static const char *const TheWeaponAffectsMaskNames[] = "NOT_AIRBORNE", nullptr }; +static_assert(1 << (ARRAY_SIZE(TheWeaponAffectsMaskNames) - 2) == WEAPON_AFFECTS_MASK_TYPE_END - 1, "Incorrect array size"); //#endif //------------------------------------------------------------------------------------------------- @@ -146,7 +149,9 @@ enum WeaponCollideMaskType CPP_11(: Int) WEAPON_COLLIDE_WALLS = 0x0020, WEAPON_COLLIDE_SMALL_MISSILES = 0x0040, //All missiles are also projectiles! WEAPON_COLLIDE_BALLISTIC_MISSILES = 0x0080, //All missiles are also projectiles! - WEAPON_COLLIDE_CONTROLLED_STRUCTURES = 0x0100 //this is "ONLY structures belonging to the projectile's controller". + WEAPON_COLLIDE_CONTROLLED_STRUCTURES = 0x0100, //this is "ONLY structures belonging to the projectile's controller". + + WEAPON_COLLIDE_MASK_TYPE_END // keep after the last named flag }; #ifdef DEFINE_WEAPONCOLLIDEMASK_NAMES @@ -163,6 +168,7 @@ static const char *const TheWeaponCollideMaskNames[] = "CONTROLLED_STRUCTURES", nullptr }; +static_assert(1 << (ARRAY_SIZE(TheWeaponCollideMaskNames) - 2) == WEAPON_COLLIDE_MASK_TYPE_END - 1, "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp index 284efc8fcbf..9c51a955a67 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp @@ -693,7 +693,9 @@ enum DebrisDisposition CPP_11(: Int) RANDOM_FORCE = 0x00000020, FLOATING = 0x00000040, INHERIT_VELOCITY = 0x00000080, - WHIRLING = 0x00000100 + WHIRLING = 0x00000100, + + DEBRIS_DISPOSITION_END // keep after the last named flag }; static const char* const DebrisDispositionNames[] = @@ -709,6 +711,7 @@ static const char* const DebrisDispositionNames[] = "WHIRLING", nullptr }; +static_assert(1 << (ARRAY_SIZE(DebrisDispositionNames) - 2) == DEBRIS_DISPOSITION_END - 1, "Incorrect array size"); std::vector debrisModelNamesGlobalHack;