Skip to content

Commit b6699ff

Browse files
committed
attribute(ms_struct) is only valid for x86
1 parent 77e2da0 commit b6699ff

12 files changed

Lines changed: 535 additions & 212 deletions

File tree

common/bitfields.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616
/*
1717
* Use this macro to mark a structure to be packed in an MSVC compatible way.
1818
*/
19-
#if defined __clang__ || defined __GNUC__
20-
#define BITFIELD_STRUCT __attribute__((ms_struct))
19+
#if (defined __clang__ || defined __GNUC__) && (defined(__i386__) || defined(__x86_64__))
20+
#define BITFIELD_STRUCT __attribute__((ms_struct))
21+
#define HAVE_MS_BITFIELDS 1
22+
#elif defined(_MSC_VER)
23+
#define BITFIELD_STRUCT
24+
#define HAVE_MS_BITFIELDS 1
2125
#else
2226
#define BITFIELD_STRUCT
27+
#define HAVE_MS_BITFIELDS 0
2328
#endif
2429

2530
#endif /* COMMON_BITFIELDS_H */

common/combuf.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@
5656
/*---------------------------------------------------------------------------
5757
This is one output queue entry
5858
---------------------------------------------------------------------------*/
59-
#pragma pack(push, 1)
60-
typedef struct BITFIELD_STRUCT
59+
typedef struct
6160
{
6261
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
6362
unsigned int IsACK : 1; // 1 = ACK received for this packet
@@ -73,7 +72,7 @@ typedef struct BITFIELD_STRUCT
7372
/*---------------------------------------------------------------------------
7473
This is one input queue entry
7574
---------------------------------------------------------------------------*/
76-
typedef struct BITFIELD_STRUCT
75+
typedef struct
7776
{
7877
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
7978
unsigned int IsRead : 1; // 1 = caller has read this entry
@@ -83,7 +82,6 @@ typedef struct BITFIELD_STRUCT
8382
int ExtraLen; // size of extra data
8483
char* ExtraBuffer; // extra data buffer
8584
} ReceiveQueueType;
86-
#pragma pack(pop)
8785

8886
/*
8987
***************************** Class Declaration *****************************

redalert/defines.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -539,11 +539,10 @@ typedef int TARGET;
539539

540540
#define TARGET_MANTISSA 24 // Bits of value precision.
541541
#define TARGET_EXPONENT 8
542-
#pragma pack(push, 1)
543542
typedef union
544543
{
545544
TARGET Target;
546-
struct BITFIELD_STRUCT
545+
struct
547546
{
548547
#ifdef __BIG_ENDIAN__
549548
unsigned Exponent : TARGET_EXPONENT;
@@ -554,7 +553,6 @@ typedef union
554553
#endif
555554
} Sub;
556555
} TARGET_COMPOSITE;
557-
#pragma pack(pop)
558556
inline TARGET Build_Target(RTTIType kind, int value)
559557
{
560558
TARGET_COMPOSITE target;

redalert/ipxgconn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ typedef struct
9393
{
9494
CommHeaderType Header;
9595
unsigned short ProductID;
96+
unsigned short pad;
9697
} GlobalHeaderType;
9798

9899
inline void SwapGlobalHeaderType(GlobalHeaderType* ght)

redalert/session.h

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -299,26 +299,47 @@ typedef struct
299299
{
300300
struct BITFIELD_STRUCT
301301
{
302-
HousesType House; // player's House
303-
PlayerColorType Color; // player's color or SIGNOFF ID
304-
unsigned int MinVersion; // min version this game supports
305-
unsigned int MaxVersion; // max version this game supports
306-
char Scenario[DESCRIP_MAX]; // Scenario name
307-
unsigned int Credits; // player's credits
302+
HousesType House; // player's House
303+
PlayerColorType Color; // player's color or SIGNOFF ID
304+
unsigned int MinVersion; // min version this game supports
305+
unsigned int MaxVersion; // max version this game supports
306+
char Scenario[DESCRIP_MAX]; // Scenario name
307+
unsigned int Credits; // player's credits
308+
#if HAVE_MS_BITFIELDS
308309
unsigned int IsBases : 1; // 1 = bases are allowed
309310
unsigned int IsTiberium : 1; // 1 = tiberium is allowed
310311
unsigned int IsGoodies : 1; // 1 = goodies are allowed
311312
unsigned int IsGhosties : 1; // 1 = ghosts are allowed
312313
unsigned int OfficialScenario : 1; // Is this scenario an official Westwood one?
313-
int CheatCheck; // Unique ID of "rules.ini" file.
314-
unsigned char BuildLevel; // buildable level
315-
unsigned char UnitCount; // max # units
316-
unsigned char AIPlayers; // # of AI players allowed
317-
int Seed; // random number seed
318-
SpecialClass Special; // command-line options
319-
unsigned int GameSpeed; // Game Speed
320-
unsigned int ResponseTime; // packet response time
321-
unsigned int FileLength; // Length of scenario file to expect from host.
314+
#else
315+
/*
316+
** simulate effects of attribute((ms_struct))
317+
*/
318+
#ifdef __BIG_ENDIAN__
319+
unsigned int : 27;
320+
unsigned int OfficialScenario : 1;
321+
unsigned int IsGhosties : 1;
322+
unsigned int IsGoodies : 1;
323+
unsigned int IsTiberium : 1;
324+
unsigned int IsBases : 1;
325+
#else
326+
unsigned int IsBases : 1;
327+
unsigned int IsTiberium : 1;
328+
unsigned int IsGoodies : 1;
329+
unsigned int IsGhosties : 1;
330+
unsigned int OfficialScenario : 1;
331+
unsigned int : 27;
332+
#endif
333+
#endif
334+
int CheatCheck; // Unique ID of "rules.ini" file.
335+
unsigned char BuildLevel; // buildable level
336+
unsigned char UnitCount; // max # units
337+
unsigned char AIPlayers; // # of AI players allowed
338+
int Seed; // random number seed
339+
SpecialClass Special; // command-line options
340+
unsigned int GameSpeed; // Game Speed
341+
unsigned int ResponseTime; // packet response time
342+
unsigned int FileLength; // Length of scenario file to expect from host.
322343
#ifdef WOLAPI_INTEGRATION
323344
char ShortFileName[13]; // Name of scenario file to expect from host
324345
#else

redalert/special.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class BITFIELD_STRUCT SpecialClass
5555
struct
5656
{
5757
#ifdef __BIG_ENDIAN__
58-
unsigned int Unused : 20;
58+
unsigned int : 20;
5959
unsigned ModernBalance : 1;
6060
unsigned IsEarlyWin : 1;
6161
unsigned IsMCVDeploy : 1;
@@ -128,10 +128,13 @@ class BITFIELD_STRUCT SpecialClass
128128
** New modern balance setting.
129129
*/
130130
unsigned ModernBalance : 1;
131+
#if !HAVE_MS_BITFIELDS
132+
unsigned int : 20;
133+
#endif
131134
#endif
132135
};
133136
};
134137
};
135138
#pragma pack(pop)
136139

137-
#endif
140+
#endif

tests/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,15 @@ target_include_directories(test_drawbuff PUBLIC .. ../common)
7272
target_compile_definitions(test_drawbuff PUBLIC TRUE_FALSE_DEFINED ENGLISH $<$<CONFIG:DEBUG>:_DEBUG> _WINDOWS _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE WINSOCK_IPX)
7373
target_link_libraries(test_drawbuff PUBLIC commonv ${STATIC_LIBS})
7474
add_test(NAME drawbuff COMMAND ${TARGET_SYSTEM_EMULATOR} $<TARGET_FILE:test_drawbuff>)
75+
76+
add_executable(test_structsizetd structsizetd.cpp)
77+
target_compile_definitions(test_structsizetd PUBLIC $<$<CONFIG:Debug>:_DEBUG> ${VANILLA_DEFS} MEGAMAPS)
78+
target_include_directories(test_structsizetd PUBLIC .. ../common)
79+
target_link_libraries(test_structsizetd PUBLIC commonv ${STATIC_LIBS})
80+
add_test(NAME structsizetd COMMAND ${TARGET_SYSTEM_EMULATOR} $<TARGET_FILE:test_structsizetd>)
81+
82+
add_executable(test_structsizera structsizera.cpp)
83+
target_compile_definitions(test_structsizera PUBLIC $<$<CONFIG:Debug>:_DEBUG> ${VANILLA_DEFS})
84+
target_include_directories(test_structsizera PUBLIC .. ../common)
85+
target_link_libraries(test_structsizera PUBLIC commonv ${STATIC_LIBS})
86+
add_test(NAME structsizera COMMAND ${TARGET_SYSTEM_EMULATOR} $<TARGET_FILE:test_structsizera>)

tests/drawbuff.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
bool GameInFocus;
1212
int ScreenWidth;
1313
int WindowList[9][9];
14-
extern "C" char* _ShapeBuffer = 0;
1514
WWKeyboardClass* Keyboard;
1615

1716
void Process_Network()

tests/structsizera.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "redalert/function.h"
2+
3+
#include <stdint.h>
4+
#include <string.h>
5+
#include <stdio.h>
6+
7+
#include "common/mixfile.h"
8+
#include "common/vqaloader.h"
9+
#include "common/filepcx.h"
10+
11+
#pragma pack(push, 2)
12+
typedef struct
13+
{
14+
int16_t count;
15+
int32_t size;
16+
} FileHeader;
17+
#pragma pack(pop)
18+
19+
int main(void)
20+
{
21+
int ret = 0;
22+
23+
#define check_size(T, n) \
24+
if (sizeof(T) != n) { \
25+
fprintf(stderr, "sizeof(" #T "): should be %d, but is %d\n", n, (int)sizeof(T)); \
26+
ret |= 1; \
27+
}
28+
#undef check_size
29+
#define check_size(T, n) static_assert(sizeof(T) == n)
30+
#define check_offset(T, m, n) static_assert(__builtin_offsetof(T, m) == n)
31+
32+
check_size(MFCD::SubBlock, 12);
33+
check_size(FileHeader, 6);
34+
check_size(AUDHeaderType, 12);
35+
check_size(COORDINATE, 4);
36+
check_size(COORD_COMPOSITE, 4);
37+
check_size(CELL, 2);
38+
check_size(CELL_COMPOSITE, 2);
39+
check_size(TARGET, 4);
40+
check_size(TARGET_COMPOSITE, 4);
41+
check_size(Cursor, 10);
42+
check_size(Shape_Type, 26);
43+
check_size(ShapeBlock_Type, 2);
44+
check_size(VQASND1Header, 4);
45+
check_size(VQASN2JHeader, 6);
46+
check_size(VQAHeader, 42);
47+
check_size(SpecialClass, 4);
48+
check_size(EventClass, 20);
49+
check_offset(EventClass, Data, 5);
50+
check_offset(EventClass, Data.MegaMission.Mission, 9);
51+
check_offset(EventClass, Data.MegaMission.Target, 10);
52+
check_size(SerialPacketType, 150);
53+
check_offset(SerialPacketType, ScenarioInfo, 17);
54+
check_offset(SerialPacketType, ScenarioInfo.MinVersion, 19);
55+
check_offset(SerialPacketType, ScenarioInfo.Credits, 71);
56+
check_offset(SerialPacketType, ScenarioInfo.CheatCheck, 79);
57+
check_offset(SerialPacketType, ScenarioInfo.FileDigest, 118);
58+
check_size(GlobalPacketType, 141);
59+
check_offset(GlobalPacketType, GameInfo, 16);
60+
check_size(IControl_Type, 40);
61+
check_size(CompHeaderType, 8);
62+
check_size(RGB, 3);
63+
check_size(PCX_HEADER, 128);
64+
check_size(CommHeaderType, 8);
65+
check_size(IPXAddressClass, 10);
66+
check_size(GlobalHeaderType, 12);
67+
68+
#undef check_size
69+
#undef check_offset
70+
71+
return ret;
72+
}

tests/structsizetd.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "tiberiandawn/function.h"
2+
#include "tiberiandawn/tile.h"
3+
4+
#include <stdint.h>
5+
#include <string.h>
6+
#include <stdio.h>
7+
8+
#include "common/mixfile.h"
9+
#include "common/vqaloader.h"
10+
#include "common/filepcx.h"
11+
12+
#pragma pack(push, 2)
13+
typedef struct
14+
{
15+
int16_t count;
16+
int32_t size;
17+
} FileHeader;
18+
#pragma pack(pop)
19+
20+
int main(void)
21+
{
22+
int ret = 0;
23+
24+
#define check_size(T, n) \
25+
if (sizeof(T) != n) { \
26+
fprintf(stderr, "sizeof(" #T "): should be %d, but is %d\n", n, (int)sizeof(T)); \
27+
ret |= 1; \
28+
}
29+
#undef check_size
30+
#define check_size(T, n) static_assert(sizeof(T) == n)
31+
#define check_offset(T, m, n) static_assert(__builtin_offsetof(T, m) == n)
32+
33+
check_size(MFCD::SubBlock, 12);
34+
check_size(FileHeader, 6);
35+
check_size(AUDHeaderType, 12);
36+
check_size(COORDINATE, 4);
37+
check_size(COORD_COMPOSITE, 4);
38+
check_size(CELL, 2);
39+
check_size(CELL_COMPOSITE, 2);
40+
check_size(TARGET, 4);
41+
check_size(TARGET_COMPOSITE, 4);
42+
check_size(Cursor, 10);
43+
check_size(Shape_Type, 26);
44+
check_size(ShapeBlock_Type, 2);
45+
check_size(VQASND1Header, 4);
46+
check_size(VQASN2JHeader, 6);
47+
check_size(VQAHeader, 42);
48+
check_size(SpecialClass, 16);
49+
check_size(EventClass, 22);
50+
check_offset(EventClass, Data, 6);
51+
check_offset(EventClass, Data.MegaMission.Mission, 10);
52+
check_offset(EventClass, Data.MegaMission.Target, 11);
53+
check_size(SerialPacketType, 88);
54+
check_offset(SerialPacketType, Credits, 21);
55+
check_offset(SerialPacketType, BuildLevel, 29);
56+
check_offset(SerialPacketType, BuildLevel, 29);
57+
check_size(GlobalPacketType, 48);
58+
check_offset(GlobalPacketType, GameInfo, 13);
59+
check_offset(GlobalPacketType, ScenarioInfo, 13);
60+
check_offset(GlobalPacketType, ScenarioInfo.Credits, 14);
61+
check_offset(GlobalPacketType, ScenarioInfo.Seed, 24);
62+
check_size(IControl_Type, 32);
63+
check_size(CompHeaderType, 8);
64+
check_size(RGB, 3);
65+
check_size(PCX_HEADER, 128);
66+
check_size(CommHeaderType, 8);
67+
check_size(IPXAddressClass, 10);
68+
check_size(GlobalHeaderType, 20);
69+
70+
#undef check_size
71+
#undef check_offset
72+
73+
return ret;
74+
}

0 commit comments

Comments
 (0)