From 80ff66bcb2f577118cc7ad55f223f7f180a94b86 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 (#3389) 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. --- GeneralsMD/Code/Tools/wdump/chunk_d.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/GeneralsMD/Code/Tools/wdump/chunk_d.cpp b/GeneralsMD/Code/Tools/wdump/chunk_d.cpp index 34225f77100..9306922c821 100644 --- a/GeneralsMD/Code/Tools/wdump/chunk_d.cpp +++ b/GeneralsMD/Code/Tools/wdump/chunk_d.cpp @@ -243,7 +243,9 @@ void ChunkTableClass::AddItem(CListCtrl *list, int &Counter, const char *name, W "Disable", "Modulate", "Add", - "Bump-Environment" + "Bump-Environment", + "Bump-Environment Luminance", + "Modulate 2X" }; static const char * _secgradient[] = { "Disable", @@ -268,7 +270,11 @@ void ChunkTableClass::AddItem(CListCtrl *list, int &Counter, const char *name, W "Sub", "SubR", "Blend", - "DetailBlend" + "DetailBlend", + "AddSigned", + "AddSigned2X", + "Scale2X", + "ModAlphaAddColor" }; static const char * _detailalpha[] = { "Disable", From 1dd072c2a95ea4462a8d617b70f74ae76cb4971c 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 (#3389) 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. --- 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/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/Compression.h | 8 +++-- .../Source/Compression/CompressionManager.cpp | 16 ++++++---- Core/Libraries/Source/Lib/Debug.cpp | 3 +- Core/Libraries/Source/Lib/Include/Lib/Debug.h | 2 +- .../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 | 18 +++++++---- .../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 ++++--- .../Object/Update/StructureCollapseUpdate.cpp | 2 +- .../Source/GameLogic/Object/WeaponSet.cpp | 25 +++++++++++---- .../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 + .../WorldBuilder/src/WorldBuilderDoc.cpp | 2 ++ .../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 | 25 +++++++++++---- .../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 ++++++++ 74 files changed, 258 insertions(+), 111 deletions(-) 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/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 87b6e56d470..7dcc353e0f1 100644 --- a/Core/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Core/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -1267,7 +1267,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 @@ -1324,6 +1324,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 28c52bfeb23..04a7fd0a411 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/Compression.h b/Core/Libraries/Source/Compression/Compression.h index af88776db7f..2a8e26f3d73 100644 --- a/Core/Libraries/Source/Compression/Compression.h +++ b/Core/Libraries/Source/Compression/Compression.h @@ -24,8 +24,7 @@ enum CompressionType { - COMPRESSION_MIN = 0, - COMPRESSION_NONE = COMPRESSION_MIN, + COMPRESSION_NONE, COMPRESSION_REFPACK, COMPRESSION_NOXLZH, COMPRESSION_ZLIB1, @@ -39,7 +38,10 @@ enum CompressionType COMPRESSION_ZLIB9, COMPRESSION_BTREE, COMPRESSION_HUFF, - COMPRESSION_MAX = COMPRESSION_HUFF, + + COMPRESSION_COUNT, + COMPRESSION_MIN = COMPRESSION_NONE, + COMPRESSION_MAX = COMPRESSION_COUNT - 1, }; class CompressionManager diff --git a/Core/Libraries/Source/Compression/CompressionManager.cpp b/Core/Libraries/Source/Compression/CompressionManager.cpp index b90d0531c3b..26bf3c55a37 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_COUNT, "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_COUNT, "Incorrect array size"); return s_decompressionNames[compType]; } @@ -358,7 +360,7 @@ struct CompData { public: Int origSize; - Int compressedSize[COMPRESSION_MAX+1]; + Int compressedSize[COMPRESSION_COUNT]; }; void DoCompressTest() @@ -366,9 +368,9 @@ void DoCompressTest() Int i; - PerfGather *s_compressGathers[COMPRESSION_MAX+1]; - PerfGather *s_decompressGathers[COMPRESSION_MAX+1]; - for (i = 0; i < COMPRESSION_MAX+1; ++i) + PerfGather *s_compressGathers[COMPRESSION_COUNT]; + PerfGather *s_decompressGathers[COMPRESSION_COUNT]; + for (i = 0; i < COMPRESSION_COUNT; ++i) { s_compressGathers[i] = new PerfGather(CompressionManager::getCompressionNameByType((CompressionType)i)); s_decompressGathers[i] = new PerfGather(CompressionManager::getDecompressionNameByType((CompressionType)i)); @@ -486,7 +488,7 @@ void DoCompressTest() PerfGather::resetAll(); CopyFile( "AAAPerfStats.csv", "AAACompressPerfStats.csv", FALSE ); - for (i = 0; i < COMPRESSION_MAX+1; ++i) + for (i = 0; i < COMPRESSION_COUNT; ++i) { delete s_compressGathers[i]; s_compressGathers[i] = nullptr; diff --git a/Core/Libraries/Source/Lib/Debug.cpp b/Core/Libraries/Source/Lib/Debug.cpp index 2d89a4a5b6a..379fad43aae 100644 --- a/Core/Libraries/Source/Lib/Debug.cpp +++ b/Core/Libraries/Source/Lib/Debug.cpp @@ -111,9 +111,10 @@ static bool theLogCriticalSectionInitialized = false; 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/Libraries/Source/Lib/Include/Lib/Debug.h b/Core/Libraries/Source/Lib/Include/Lib/Debug.h index e68c7cd6100..42f45b420cf 100644 --- a/Core/Libraries/Source/Lib/Include/Lib/Debug.h +++ b/Core/Libraries/Source/Lib/Include/Lib/Debug.h @@ -169,7 +169,7 @@ 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/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/Generals/Code/GameEngine/Include/GameLogic/Locomotor.h b/Generals/Code/GameEngine/Include/GameLogic/Locomotor.h index a81c973b582..acc902bfb87 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Locomotor.h +++ b/Generals/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/Generals/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h index 3f48e1774a3..647fc7b62ed 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/SupplyTruckAIUpdate.h @@ -113,7 +113,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/Generals/Code/GameEngine/Include/GameLogic/ObjectIter.h b/Generals/Code/GameEngine/Include/GameLogic/ObjectIter.h index c0d43739217..aa85cdc2280 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/ObjectIter.h +++ b/Generals/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/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h b/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h index e16147bfe84..c9fc020c3a3 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h +++ b/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h @@ -150,7 +150,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/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h b/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h index a4a611486fb..b1bec5d0293 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h +++ b/Generals/Code/GameEngine/Include/GameLogic/WeaponSet.h @@ -75,15 +75,19 @@ static_assert(ARRAY_SIZE(TheWeaponSlotTypeNamesLookupList) == WEAPONSLOT_COUNT + //------------------------------------------------------------------------------------------------- #ifdef DEFINE_WEAPONCONDITIONMAP -static const ModelConditionFlagType TheWeaponSetTypeToModelConditionTypeMap[WEAPONSET_COUNT] = +static const ModelConditionFlagType TheWeaponSetTypeToModelConditionTypeMap[] = { - MODELCONDITION_WEAPONSET_VETERAN, - MODELCONDITION_WEAPONSET_ELITE, - MODELCONDITION_WEAPONSET_HERO, - MODELCONDITION_WEAPONSET_PLAYER_UPGRADE, - MODELCONDITION_WEAPONSET_CRATEUPGRADE_ONE, - MODELCONDITION_WEAPONSET_CRATEUPGRADE_TWO + /*WEAPONSET_VETERAN*/ MODELCONDITION_WEAPONSET_VETERAN, + /*WEAPONSET_ELITE*/ MODELCONDITION_WEAPONSET_ELITE, + /*WEAPONSET_HERO*/ MODELCONDITION_WEAPONSET_HERO, + /*WEAPONSET_PLAYER_UPGRADE*/ MODELCONDITION_WEAPONSET_PLAYER_UPGRADE, + /*WEAPONSET_CRATEUPGRADE_ONE*/ MODELCONDITION_WEAPONSET_CRATEUPGRADE_ONE, + /*WEAPONSET_CRATEUPGRADE_TWO*/ MODELCONDITION_WEAPONSET_CRATEUPGRADE_TWO, + /*WEAPONSET_VEHICLE_HIJACK*/ MODELCONDITION_INVALID, + /*WEAPONSET_CARBOMB*/ MODELCONDITION_INVALID, + /*WEAPONSET_MINE_CLEARING_DETAIL*/ MODELCONDITION_INVALID, }; +static_assert(ARRAY_SIZE(TheWeaponSetTypeToModelConditionTypeMap) == WEAPONSET_COUNT, "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/Common/RTS/Handicap.cpp b/Generals/Code/GameEngine/Source/Common/RTS/Handicap.cpp index 85420402741..a9eda01d4ac 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/Handicap.cpp +++ b/Generals/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/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp b/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp index e2d2aa74cec..36b99f5c77c 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/Generals/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/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index bbf625088b0..ccbbba80be1 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -6227,6 +6227,7 @@ void InGameUI::drawPlayerInfoList() 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/Generals/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp index 58aedc79d8d..2848113e67f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp +++ b/Generals/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/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp index eb2ab685ea2..cc60991baf2 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp @@ -112,7 +112,7 @@ ObjectID TheObjectIDToDebug = INVALID_ID; #endif // ------------------------------------------------------------------------------------------------ -static const ModelConditionFlags s_allWeaponFireFlags[WEAPONSLOT_COUNT] = +static const ModelConditionFlags s_allWeaponFireFlags[] = { MAKE_MODELCONDITION_MASK5( MODELCONDITION_FIRING_A, @@ -136,6 +136,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); @@ -4346,7 +4347,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, @@ -4354,6 +4355,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/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp index 30d4f40b3a0..ed5a0cef691 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp @@ -926,6 +926,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[] = @@ -940,6 +941,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/Generals/Code/GameEngine/Source/GameLogic/Object/SimpleObjectIterator.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/SimpleObjectIterator.cpp index 1aa7772e0e2..362c361cb01 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/SimpleObjectIterator.cpp +++ b/Generals/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/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp index 9d544810cfa..2a8c0e66ab9 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp @@ -53,6 +53,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 //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp index 50292c62045..ddf30134414 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp +++ b/Generals/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/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StructureCollapseUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StructureCollapseUpdate.cpp index 6e09b1e201c..0b61cbfda64 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StructureCollapseUpdate.cpp +++ b/Generals/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/Generals/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp index 2597d553bbb..6b17ce12b7d 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp @@ -357,34 +357,44 @@ 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] = { + 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[WEAPONSLOT_COUNT] = { + static const ModelConditionFlagType Betweening[] = { MODELCONDITION_BETWEEN_FIRING_SHOTS_A, MODELCONDITION_BETWEEN_FIRING_SHOTS_B, MODELCONDITION_BETWEEN_FIRING_SHOTS_C }; - static const ModelConditionFlagType Reloading[WEAPONSLOT_COUNT] = { + static const ModelConditionFlagType Reloading[] = { MODELCONDITION_RELOADING_A, MODELCONDITION_RELOADING_B, MODELCONDITION_RELOADING_C }; - static const ModelConditionFlagType PreAttack[WEAPONSLOT_COUNT] = { + static const ModelConditionFlagType PreAttack[] = { MODELCONDITION_PREATTACK_A, MODELCONDITION_PREATTACK_B, MODELCONDITION_PREATTACK_C }; - static const ModelConditionFlagType* Lookup[WSF_COUNT] = { + 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 @@ -392,11 +402,12 @@ void WeaponSet::updateWeaponSet(const Object* obj) if (f != MODELCONDITION_INVALID) flags.set(f); - static const ModelConditionFlagType Using[WEAPONSLOT_COUNT] = { + 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/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/Scripts.cpp b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/Scripts.cpp index 5f9e2caedce..8e50e281ee4 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/Scripts.cpp +++ b/Generals/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" @@ -138,6 +139,7 @@ const char *ShakeIntensities[] = { "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/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp index 908c8b94f5b..8a4449fdb89 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp +++ b/Generals/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/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_ldr.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_ldr.cpp index af907b9a156..8c560356784 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/part_ldr.cpp +++ b/Generals/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/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp index e77adfd67b9..4ee3902a745 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp @@ -374,15 +374,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), @@ -391,6 +392,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/Generals/Code/Libraries/Source/WWVegas/WW3D2/w3d_file.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/w3d_file.h index 20296423eb5..35588ab84b0 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/w3d_file.h +++ b/Generals/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/Generals/Code/Tools/GUIEdit/Source/Properties.cpp b/Generals/Code/Tools/GUIEdit/Source/Properties.cpp index 69ac8b1b4a5..0ff8ab605a4 100644 --- a/Generals/Code/Tools/GUIEdit/Source/Properties.cpp +++ b/Generals/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/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp index ab55b631062..868f3717437 100644 --- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp @@ -2057,6 +2057,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) @@ -2102,6 +2103,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/GameEngine/Include/GameLogic/Locomotor.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Locomotor.h index 0f347393098..50de6e739ab 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 6c805b221a6..a51a4934fa3 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 19a61d50ea6..3136edbf55d 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 accc4d52eb2..f8d89a0d9d2 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -6360,6 +6360,7 @@ void InGameUI::drawPlayerInfoList() 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 659ad9a9a49..17ec7f81eb0 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 51fa2e4ad61..9c25521dd91 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp @@ -121,7 +121,7 @@ ObjectID TheObjectIDToDebug = INVALID_ID; #endif // ------------------------------------------------------------------------------------------------ -static const ModelConditionFlags s_allWeaponFireFlags[WEAPONSLOT_COUNT] = +static const ModelConditionFlags s_allWeaponFireFlags[] = { MAKE_MODELCONDITION_MASK5( MODELCONDITION_FIRING_A, @@ -145,6 +145,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); @@ -4907,7 +4908,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, @@ -4915,6 +4916,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 df41e0c8c44..9d548fd0f5e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp @@ -930,6 +930,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[] = @@ -944,6 +945,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 b117ad68ffb..3a2d490af55 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 1fa309ee8a8..05a1619ff5e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/WeaponSet.cpp @@ -365,34 +365,44 @@ 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] = { + 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[WEAPONSLOT_COUNT] = { + static const ModelConditionFlagType Betweening[] = { MODELCONDITION_BETWEEN_FIRING_SHOTS_A, MODELCONDITION_BETWEEN_FIRING_SHOTS_B, MODELCONDITION_BETWEEN_FIRING_SHOTS_C }; - static const ModelConditionFlagType Reloading[WEAPONSLOT_COUNT] = { + static const ModelConditionFlagType Reloading[] = { MODELCONDITION_RELOADING_A, MODELCONDITION_RELOADING_B, MODELCONDITION_RELOADING_C }; - static const ModelConditionFlagType PreAttack[WEAPONSLOT_COUNT] = { + static const ModelConditionFlagType PreAttack[] = { MODELCONDITION_PREATTACK_A, MODELCONDITION_PREATTACK_B, MODELCONDITION_PREATTACK_C }; - static const ModelConditionFlagType* Lookup[WSF_COUNT] = { + 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 @@ -400,11 +410,12 @@ void WeaponSet::updateWeaponSet(const Object* obj) if (f != MODELCONDITION_INVALID) flags.set(f); - static const ModelConditionFlagType Using[WEAPONSLOT_COUNT] = { + 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 6b4a9824435..2703db7a634 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" @@ -139,6 +140,7 @@ const char *ShakeIntensities[] = { "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 65953d7e6ff..1d1f87658af 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp @@ -374,15 +374,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), @@ -391,6 +392,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 5fea2fc87eb..1e1e57c8b9d 100644 --- a/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp +++ b/GeneralsMD/Code/Tools/WorldBuilder/src/WorldBuilderDoc.cpp @@ -2114,6 +2114,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) @@ -2159,6 +2160,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 9306922c821..3c3528d091b 100644 --- a/GeneralsMD/Code/Tools/wdump/chunk_d.cpp +++ b/GeneralsMD/Code/Tools/wdump/chunk_d.cpp @@ -294,6 +294,16 @@ void ChunkTableClass::AddItem(CListCtrl *list, int &Counter, const char *name, W "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]; @@ -394,6 +404,8 @@ void ChunkTableClass::AddItem(CListCtrl *list, int &Counter, const char *name, W "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]; @@ -1629,6 +1641,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; @@ -1660,6 +1673,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 b813b6d599d9fba3758d55d36d0d1f1883697dc1 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 (#3389) --- 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 +++ .../Source/Common/INI/INIAudioEventInfo.cpp | 2 ++ .../GameClient/GUI/GameWindowManagerScript.cpp | 2 ++ .../Source/Lib/Include/Lib/BaseFunctions.h | 17 +++++++++++++++++ .../Code/GameEngine/Include/GameClient/Shadow.h | 5 ++++- .../GameEngine/Include/GameLogic/LocomotorSet.h | 5 ++++- .../Include/GameLogic/Module/AIUpdate.h | 3 +++ .../Include/GameLogic/Module/StealthUpdate.h | 4 ++++ .../Code/GameEngine/Include/GameLogic/Weapon.h | 8 +++++++- .../GameLogic/Object/ObjectCreationList.cpp | 5 ++++- .../Code/GameEngine/Include/GameClient/Shadow.h | 5 ++++- .../GameEngine/Include/GameLogic/LocomotorSet.h | 5 ++++- .../Include/GameLogic/Module/AIUpdate.h | 3 +++ .../Include/GameLogic/Module/StealthUpdate.h | 3 +++ .../Code/GameEngine/Include/GameLogic/Weapon.h | 8 +++++++- .../GameLogic/Object/ObjectCreationList.cpp | 5 ++++- 21 files changed, 89 insertions(+), 11 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..8544f6d5e15 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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheCommandOptionNames) - 1, COMMAND_OPTION_END), "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..df75aa3bd1e 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(equalsEnumBitFlagsCount(ARRAY_SIZE(imageStatusNames) - 1, IMAGE_STATUS_END), "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..2a663da82c8 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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheCommandUsableInNames) - 1, COMMAND_USABLE_IN_TYPE_END), "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 d305876daf2..1180bad23cd 100644 --- a/Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp +++ b/Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp @@ -204,6 +204,7 @@ const char *const theSoundTypeNames[] = "EVERYONE", nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(theSoundTypeNames) - 1, SOUND_TYPE_END), "Incorrect array size"); const char *const theAudioControlNames[] = { @@ -214,4 +215,5 @@ const char *const theAudioControlNames[] = "INTERRUPT", nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(theAudioControlNames) - 1, AUDIO_CONTROL_END), "Incorrect array size"); diff --git a/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp b/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp index 707a2af254e..4484289b143 100644 --- a/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp +++ b/Core/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp @@ -166,6 +166,7 @@ const char *const WindowStatusNames[] = { /*"SHORTCUT_BUTTON",*/ nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(WindowStatusNames) - 1, WIN_STATUS_END), "Incorrect array size"); const char *const WindowStyleNames[] = { "PUSHBUTTON", @@ -186,6 +187,7 @@ const char *const WindowStyleNames[] = { "COMBOBOX", nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(WindowStyleNames) - 1, GWS_END), "Incorrect array size"); // Implement a stack to keep track of parent/child nested window descriptions. static GameWindow *windowStack[ WIN_STACK_DEPTH ]; diff --git a/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h b/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h index eee6095b4c1..0ba363dbfa7 100644 --- a/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h +++ b/Core/Libraries/Source/Lib/Include/Lib/BaseFunctions.h @@ -104,3 +104,20 @@ __forceinline float fast_float_ceil(float f) #define FAST_REAL_TRUNC(x) fast_float_trunc(x) #define FAST_REAL_CEIL(x) fast_float_ceil(x) #define FAST_REAL_FLOOR(x) fast_float_floor(x) + +//------------------------------------------------------------------------------------------------- +// Checking whether a size matches the bit flags count from an enum definition: +// enum MyEnum +// { +// MyEnumValue1 = 1<<0, +// MyEnumValue2 = 1<<1, +// MyEnumValue3 = 1<<2, +// MyEnumEnd +// } +// static_assert(equalsEnumBitFlagsCount(3, MyEnumEnd), "Incorrect size"); +// +template +constexpr inline Bool equalsEnumBitFlagsCount(size_t expectedSize, EnumType bitFlagsEnd) +{ + return 1 << (expectedSize - 1) == static_cast(bitFlagsEnd) - 1; +} diff --git a/Generals/Code/GameEngine/Include/GameClient/Shadow.h b/Generals/Code/GameEngine/Include/GameClient/Shadow.h index bb726502afe..896f21257dd 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Shadow.h +++ b/Generals/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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheShadowNames) - 1, SHADOW_TYPE_END), "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/Generals/Code/GameEngine/Include/GameLogic/LocomotorSet.h b/Generals/Code/GameEngine/Include/GameLogic/LocomotorSet.h index e7c107ecf08..d45f7f3bae2 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/LocomotorSet.h +++ b/Generals/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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheLocomotorSurfaceTypeNames) - 1, LOCOMOTOR_SURFACE_TYPE_END), "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h index 8050b13518a..5d9567430cc 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h @@ -117,6 +117,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 @@ -130,6 +132,7 @@ static const char *const TheAutoAcquireEnemiesNames[] = nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(TheAutoAcquireEnemiesNames) - 1, AUTO_ACQUIRE_STATES_END), "Incorrect array size"); #endif diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h index e4c746dbae5..3a79c892c23 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/StealthUpdate.h @@ -45,6 +45,9 @@ enum STEALTH_NOT_WHILE_FIRING_PRIMARY = 0x00000008, STEALTH_NOT_WHILE_FIRING_SECONDARY = 0x00000010, STEALTH_NOT_WHILE_FIRING_TERTIARY = 0x00000020, + + 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), }; @@ -59,6 +62,7 @@ static const char *const TheStealthLevelNames[] = "FIRING_TERTIARY", nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(TheStealthLevelNames) - 1, STEALTH_LEVEL_END), "Incorrect array size"); #endif #define INVALID_OPACITY -1.0f diff --git a/Generals/Code/GameEngine/Include/GameLogic/Weapon.h b/Generals/Code/GameEngine/Include/GameLogic/Weapon.h index 6f5f44336c4..c0e7b61ff9f 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Weapon.h +++ b/Generals/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 @@ -131,6 +133,7 @@ static const char *const TheWeaponAffectsMaskNames[] = "NOT_AIRBORNE", nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(TheWeaponAffectsMaskNames) - 1, WEAPON_AFFECTS_MASK_TYPE_END), "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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheWeaponCollideMaskNames) - 1, WEAPON_COLLIDE_MASK_TYPE_END), "Incorrect array size"); #endif //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp index 67530b45360..e7ffb67d143 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp @@ -684,7 +684,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[] = @@ -700,6 +702,7 @@ static const char* const DebrisDispositionNames[] = "WHIRLING", nullptr }; +static_assert(equalsEnumBitFlagsCount(ARRAY_SIZE(DebrisDispositionNames) - 1, DEBRIS_DISPOSITION_END), "Incorrect array size"); std::vector debrisModelNamesGlobalHack; diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Shadow.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Shadow.h index 0bcef0ea4f3..48871f8d849 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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheShadowNames) - 1, SHADOW_TYPE_END), "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..1b8bf4faf96 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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheLocomotorSurfaceTypeNames) - 1, LOCOMOTOR_SURFACE_TYPE_END), "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..3e14cb2a8b7 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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheAutoAcquireEnemiesNames) - 1, AUTO_ACQUIRE_STATES_END), "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..87b6f1725f9 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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheStealthLevelNames) - 1, STEALTH_LEVEL_END), "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..4883b783e33 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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheWeaponAffectsMaskNames) - 1, WEAPON_AFFECTS_MASK_TYPE_END), "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(equalsEnumBitFlagsCount(ARRAY_SIZE(TheWeaponCollideMaskNames) - 1, WEAPON_COLLIDE_MASK_TYPE_END), "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 9c01e74915b..192807ed940 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(equalsEnumBitFlagsCount(ARRAY_SIZE(DebrisDispositionNames) - 1, DEBRIS_DISPOSITION_END), "Incorrect array size"); std::vector debrisModelNamesGlobalHack;