Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attribute(ms_struct) is only valid for x86 #980

Open
wants to merge 1 commit into
base: vanilla
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions common/bitfields.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@
/*
* Use this macro to mark a structure to be packed in an MSVC compatible way.
*/
#if defined __clang__ || defined __GNUC__
#define BITFIELD_STRUCT __attribute__((ms_struct))
#if (defined __clang__ || defined __GNUC__) && (defined(__i386__) || defined(__x86_64__))
#define BITFIELD_STRUCT __attribute__((ms_struct))
#define HAVE_MS_BITFIELDS 1
#elif defined(_MSC_VER)
#define BITFIELD_STRUCT
#define HAVE_MS_BITFIELDS 1
#else
#define BITFIELD_STRUCT
#define HAVE_MS_BITFIELDS 0
#endif

#endif /* COMMON_BITFIELDS_H */
6 changes: 2 additions & 4 deletions common/combuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@
/*---------------------------------------------------------------------------
This is one output queue entry
---------------------------------------------------------------------------*/
#pragma pack(push, 1)
typedef struct BITFIELD_STRUCT
typedef struct
{
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
unsigned int IsACK : 1; // 1 = ACK received for this packet
Expand All @@ -73,7 +72,7 @@ typedef struct BITFIELD_STRUCT
/*---------------------------------------------------------------------------
This is one input queue entry
---------------------------------------------------------------------------*/
typedef struct BITFIELD_STRUCT
typedef struct
{
unsigned int IsActive : 1; // 1 = this entry is ready to be processed
unsigned int IsRead : 1; // 1 = caller has read this entry
Expand All @@ -83,7 +82,6 @@ typedef struct BITFIELD_STRUCT
int ExtraLen; // size of extra data
char* ExtraBuffer; // extra data buffer
} ReceiveQueueType;
#pragma pack(pop)

/*
***************************** Class Declaration *****************************
Expand Down
4 changes: 1 addition & 3 deletions redalert/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,11 +539,10 @@ typedef int TARGET;

#define TARGET_MANTISSA 24 // Bits of value precision.
#define TARGET_EXPONENT 8
#pragma pack(push, 1)
typedef union
{
TARGET Target;
struct BITFIELD_STRUCT
struct
{
#ifdef __BIG_ENDIAN__
unsigned Exponent : TARGET_EXPONENT;
Expand All @@ -554,7 +553,6 @@ typedef union
#endif
} Sub;
} TARGET_COMPOSITE;
#pragma pack(pop)
inline TARGET Build_Target(RTTIType kind, int value)
{
TARGET_COMPOSITE target;
Expand Down
1 change: 1 addition & 0 deletions redalert/ipxgconn.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ typedef struct
{
CommHeaderType Header;
unsigned short ProductID;
unsigned short pad;
} GlobalHeaderType;

inline void SwapGlobalHeaderType(GlobalHeaderType* ght)
Expand Down
51 changes: 36 additions & 15 deletions redalert/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,26 +299,47 @@ typedef struct
{
struct BITFIELD_STRUCT
{
HousesType House; // player's House
PlayerColorType Color; // player's color or SIGNOFF ID
unsigned int MinVersion; // min version this game supports
unsigned int MaxVersion; // max version this game supports
char Scenario[DESCRIP_MAX]; // Scenario name
unsigned int Credits; // player's credits
HousesType House; // player's House
PlayerColorType Color; // player's color or SIGNOFF ID
unsigned int MinVersion; // min version this game supports
unsigned int MaxVersion; // max version this game supports
char Scenario[DESCRIP_MAX]; // Scenario name
unsigned int Credits; // player's credits
#if HAVE_MS_BITFIELDS
unsigned int IsBases : 1; // 1 = bases are allowed
unsigned int IsTiberium : 1; // 1 = tiberium is allowed
unsigned int IsGoodies : 1; // 1 = goodies are allowed
unsigned int IsGhosties : 1; // 1 = ghosts are allowed
unsigned int OfficialScenario : 1; // Is this scenario an official Westwood one?
int CheatCheck; // Unique ID of "rules.ini" file.
unsigned char BuildLevel; // buildable level
unsigned char UnitCount; // max # units
unsigned char AIPlayers; // # of AI players allowed
int Seed; // random number seed
SpecialClass Special; // command-line options
unsigned int GameSpeed; // Game Speed
unsigned int ResponseTime; // packet response time
unsigned int FileLength; // Length of scenario file to expect from host.
#else
/*
** simulate effects of attribute((ms_struct))
*/
#ifdef __BIG_ENDIAN__
unsigned int : 27;
unsigned int OfficialScenario : 1;
unsigned int IsGhosties : 1;
unsigned int IsGoodies : 1;
unsigned int IsTiberium : 1;
unsigned int IsBases : 1;
#else
unsigned int IsBases : 1;
unsigned int IsTiberium : 1;
unsigned int IsGoodies : 1;
unsigned int IsGhosties : 1;
unsigned int OfficialScenario : 1;
unsigned int : 27;
#endif
#endif
int CheatCheck; // Unique ID of "rules.ini" file.
unsigned char BuildLevel; // buildable level
unsigned char UnitCount; // max # units
unsigned char AIPlayers; // # of AI players allowed
int Seed; // random number seed
SpecialClass Special; // command-line options
unsigned int GameSpeed; // Game Speed
unsigned int ResponseTime; // packet response time
unsigned int FileLength; // Length of scenario file to expect from host.
#ifdef WOLAPI_INTEGRATION
char ShortFileName[13]; // Name of scenario file to expect from host
#else
Expand Down
7 changes: 5 additions & 2 deletions redalert/special.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class BITFIELD_STRUCT SpecialClass
struct
{
#ifdef __BIG_ENDIAN__
unsigned int Unused : 20;
unsigned int : 20;
unsigned ModernBalance : 1;
unsigned IsEarlyWin : 1;
unsigned IsMCVDeploy : 1;
Expand Down Expand Up @@ -128,10 +128,13 @@ class BITFIELD_STRUCT SpecialClass
** New modern balance setting.
*/
unsigned ModernBalance : 1;
#if !HAVE_MS_BITFIELDS
unsigned int : 20;
#endif
#endif
};
};
};
#pragma pack(pop)

#endif
#endif
12 changes: 12 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,15 @@ target_include_directories(test_drawbuff PUBLIC .. ../common)
target_compile_definitions(test_drawbuff PUBLIC TRUE_FALSE_DEFINED ENGLISH $<$<CONFIG:DEBUG>:_DEBUG> _WINDOWS _CRT_SECURE_NO_DEPRECATE _CRT_NONSTDC_NO_DEPRECATE WINSOCK_IPX)
target_link_libraries(test_drawbuff PUBLIC commonv ${STATIC_LIBS})
add_test(NAME drawbuff COMMAND ${TARGET_SYSTEM_EMULATOR} $<TARGET_FILE:test_drawbuff>)

add_executable(test_structsizetd structsizetd.cpp)
target_compile_definitions(test_structsizetd PUBLIC $<$<CONFIG:Debug>:_DEBUG> ${VANILLA_DEFS} MEGAMAPS)
target_include_directories(test_structsizetd PUBLIC .. ../common)
target_link_libraries(test_structsizetd PUBLIC commonv ${STATIC_LIBS})
add_test(NAME structsizetd COMMAND ${TARGET_SYSTEM_EMULATOR} $<TARGET_FILE:test_structsizetd>)

add_executable(test_structsizera structsizera.cpp)
target_compile_definitions(test_structsizera PUBLIC $<$<CONFIG:Debug>:_DEBUG> ${VANILLA_DEFS})
target_include_directories(test_structsizera PUBLIC .. ../common)
target_link_libraries(test_structsizera PUBLIC commonv ${STATIC_LIBS})
add_test(NAME structsizera COMMAND ${TARGET_SYSTEM_EMULATOR} $<TARGET_FILE:test_structsizera>)
1 change: 0 additions & 1 deletion tests/drawbuff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
bool GameInFocus;
int ScreenWidth;
int WindowList[9][9];
extern "C" char* _ShapeBuffer = 0;
WWKeyboardClass* Keyboard;

void Process_Network()
Expand Down
72 changes: 72 additions & 0 deletions tests/structsizera.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "redalert/function.h"

#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include "common/mixfile.h"
#include "common/vqaloader.h"
#include "common/filepcx.h"

#pragma pack(push, 2)
typedef struct
{
int16_t count;
int32_t size;
} FileHeader;
#pragma pack(pop)

int main(void)
{
int ret = 0;

#define check_size(T, n) \
if (sizeof(T) != n) { \
fprintf(stderr, "sizeof(" #T "): should be %d, but is %d\n", n, (int)sizeof(T)); \
ret |= 1; \
}
#undef check_size
#define check_size(T, n) static_assert(sizeof(T) == n, "sizeof(" #T ") != " #n)
#define check_offset(T, m, n) static_assert(__builtin_offsetof(T, m) == n, "offsetof(" #T "." #m ") != " #n)

check_size(MFCD::SubBlock, 12);
check_size(FileHeader, 6);
check_size(AUDHeaderType, 12);
check_size(COORDINATE, 4);
check_size(COORD_COMPOSITE, 4);
check_size(CELL, 2);
check_size(CELL_COMPOSITE, 2);
check_size(TARGET, 4);
check_size(TARGET_COMPOSITE, 4);
check_size(Cursor, 10);
check_size(Shape_Type, 26);
check_size(ShapeBlock_Type, 2);
check_size(VQASND1Header, 4);
check_size(VQASN2JHeader, 6);
check_size(VQAHeader, 42);
check_size(SpecialClass, 4);
check_size(EventClass, 20);
check_offset(EventClass, Data, 5);
check_offset(EventClass, Data.MegaMission.Mission, 9);
check_offset(EventClass, Data.MegaMission.Target, 10);
check_size(SerialPacketType, 150);
check_offset(SerialPacketType, ScenarioInfo, 17);
check_offset(SerialPacketType, ScenarioInfo.MinVersion, 19);
check_offset(SerialPacketType, ScenarioInfo.Credits, 71);
check_offset(SerialPacketType, ScenarioInfo.CheatCheck, 79);
check_offset(SerialPacketType, ScenarioInfo.FileDigest, 118);
check_size(GlobalPacketType, 141);
check_offset(GlobalPacketType, GameInfo, 16);
check_size(IControl_Type, 40);
check_size(CompHeaderType, 8);
check_size(RGB, 3);
check_size(PCX_HEADER, 128);
check_size(CommHeaderType, 8);
check_size(IPXAddressClass, 10);
check_size(GlobalHeaderType, 12);

#undef check_size
#undef check_offset

return ret;
}
74 changes: 74 additions & 0 deletions tests/structsizetd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "tiberiandawn/function.h"
#include "tiberiandawn/tile.h"

#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include "common/mixfile.h"
#include "common/vqaloader.h"
#include "common/filepcx.h"

#pragma pack(push, 2)
typedef struct
{
int16_t count;
int32_t size;
} FileHeader;
#pragma pack(pop)

int main(void)
{
int ret = 0;

#define check_size(T, n) \
if (sizeof(T) != n) { \
fprintf(stderr, "sizeof(" #T "): should be %d, but is %d\n", n, (int)sizeof(T)); \
ret |= 1; \
}
#undef check_size
#define check_size(T, n) static_assert(sizeof(T) == n, "sizeof(" #T ") != " #n)
#define check_offset(T, m, n) static_assert(__builtin_offsetof(T, m) == n, "offsetof(" #T "." #m ") != " #n)

check_size(MFCD::SubBlock, 12);
check_size(FileHeader, 6);
check_size(AUDHeaderType, 12);
check_size(COORDINATE, 4);
check_size(COORD_COMPOSITE, 4);
check_size(CELL, 2);
check_size(CELL_COMPOSITE, 2);
check_size(TARGET, 4);
check_size(TARGET_COMPOSITE, 4);
check_size(Cursor, 10);
check_size(Shape_Type, 26);
check_size(ShapeBlock_Type, 2);
check_size(VQASND1Header, 4);
check_size(VQASN2JHeader, 6);
check_size(VQAHeader, 42);
check_size(SpecialClass, 16);
check_size(EventClass, 22);
check_offset(EventClass, Data, 6);
check_offset(EventClass, Data.MegaMission.Mission, 10);
check_offset(EventClass, Data.MegaMission.Target, 11);
check_size(SerialPacketType, 88);
check_offset(SerialPacketType, Credits, 21);
check_offset(SerialPacketType, BuildLevel, 29);
check_offset(SerialPacketType, BuildLevel, 29);
check_size(GlobalPacketType, 48);
check_offset(GlobalPacketType, GameInfo, 13);
check_offset(GlobalPacketType, ScenarioInfo, 13);
check_offset(GlobalPacketType, ScenarioInfo.Credits, 14);
check_offset(GlobalPacketType, ScenarioInfo.Seed, 24);
check_size(IControl_Type, 32);
check_size(CompHeaderType, 8);
check_size(RGB, 3);
check_size(PCX_HEADER, 128);
check_size(CommHeaderType, 8);
check_size(IPXAddressClass, 10);
check_size(GlobalHeaderType, 20);

#undef check_size
#undef check_offset

return ret;
}
Loading
Loading