From 4e8cd33eacd3b3e8a251557e98400056c3a149ab Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Thu, 16 Feb 2023 03:41:31 +0000 Subject: [PATCH 01/27] Some general sound code cleanup: Removed unused functions and variables, marked internally-used-only functions and variables as static and removed stray semicolons after functions. --- common/audio.h | 8 -- common/soundio.cpp | 187 +++++++++++++------------------------- common/soundio_null.cpp | 71 ++++++--------- common/soundio_openal.cpp | 151 ++++++++++-------------------- 4 files changed, 140 insertions(+), 277 deletions(-) diff --git a/common/audio.h b/common/audio.h index f8fe92ff..b292518a 100644 --- a/common/audio.h +++ b/common/audio.h @@ -118,13 +118,9 @@ typedef enum /*=========================================================================*/ /* The following prototypes are for the file: SOUNDIO.CPP */ /*=========================================================================*/ -int File_Stream_Sample(char const* filename, bool real_time_start = false); int File_Stream_Sample_Vol(char const* filename, int volume, bool real_time_start = false); void Sound_Callback(void); -void maintenance_callback(void); void* Load_Sample(char const* filename); -int Load_Sample_Into_Buffer(char const* filename, void* buffer, int size); -int Sample_Read(int fh, void* buffer, int size); void Free_Sample(void const* sample); bool Audio_Init(int bits_per_sample, bool stereo, int rate, bool reverse_channels); void Sound_End(void); @@ -133,13 +129,9 @@ bool Sample_Status(int handle); bool Is_Sample_Playing(void const* sample); void Stop_Sample_Playing(void const* sample); int Play_Sample(void const* sample, int priority = 0xFF, int volume = 0xFF, signed short panloc = 0x0); -int Play_Sample_Handle(void const* sample, int priority, int volume, signed short panloc, int id); -int Set_Sound_Vol(int volume); int Set_Score_Vol(int volume); void Fade_Sample(int handle, int ticks); -int Get_Free_Sample_Handle(int priority); int Get_Digi_Handle(void); -int Sample_Length(void const* sample); void Restore_Sound_Buffers(void); bool Set_Primary_Buffer_Format(void); bool Start_Primary_Sound_Buffer(bool forced); diff --git a/common/soundio.cpp b/common/soundio.cpp index d49e5b97..01a68ba5 100644 --- a/common/soundio.cpp +++ b/common/soundio.cpp @@ -37,44 +37,47 @@ enum INVALID_FILE_HANDLE = -1, }; -bool ReverseChannels; -LockedDataType LockedData; +static bool ReverseChannels; +static LockedDataType LockedData; LPDIRECTSOUND SoundObject; -LPDIRECTSOUNDBUFFER DumpBuffer; +static LPDIRECTSOUNDBUFFER DumpBuffer; LPDIRECTSOUNDBUFFER PrimaryBufferPtr; -WAVEFORMATEX DsBuffFormat; -WAVEFORMATEX PrimaryBuffFormat; -DSBUFFERDESC BufferDesc; -DSBUFFERDESC PrimaryBufferDesc; -CRITICAL_SECTION GlobalAudioCriticalSection; -void* SoundThreadHandle; -bool SoundThreadActive; -bool StartingFileStream; -MemoryFlagType StreamBufferFlag; +static WAVEFORMATEX DsBuffFormat; +static WAVEFORMATEX PrimaryBuffFormat; +static DSBUFFERDESC BufferDesc; +static DSBUFFERDESC PrimaryBufferDesc; +static CRITICAL_SECTION GlobalAudioCriticalSection; +static void* SoundThreadHandle; +static bool SoundThreadActive; +static bool StartingFileStream; +static MemoryFlagType StreamBufferFlag; //int Misc; -UINT SoundTimerHandle; -void* FileStreamBuffer; -bool volatile AudioDone; +static UINT SoundTimerHandle; +static void* FileStreamBuffer; +static bool volatile AudioDone; SFX_Type SoundType; Sample_Type SampleType; // Forward declare some internal functions. bool Attempt_Audio_Restore(LPDIRECTSOUNDBUFFER sound_buffer); +static int Get_Free_Sample_Handle(int priority); +static int Play_Sample_Handle(void const* sample, int priority, int volume, signed short panloc, int id); +static int Sample_Read(int fh, void* buffer, int size); void CALLBACK Sound_Timer_Callback(UINT uID = 0, UINT uMsg = 0, DWORD_PTR dwUser = 0, DWORD_PTR dw1 = 0, DWORD_PTR dw2 = 0); -int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void** dest, int size); -int Sample_Copy(SampleTrackerType* st, - void** source, - int* ssize, - void** alternate, - int* altsize, - void* dest, - int size, - SCompressType sound_comp, - void* trailer, - int16_t* trailersize); - -int Convert_HMI_To_Direct_Sound_Volume(int vol) +static int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void** dest, int size); +static int Sample_Copy(SampleTrackerType* st, + void** source, + int* ssize, + void** alternate, + int* altsize, + void* dest, + int size, + SCompressType sound_comp, + void* trailer, + int16_t* trailersize); + +static int Convert_HMI_To_Direct_Sound_Volume(int vol) { // Complete silence. if (vol <= 0) { @@ -94,7 +97,7 @@ int Convert_HMI_To_Direct_Sound_Volume(int vol) return int(-(v + -1.0)); } -void Maintenance_Callback() +static void Maintenance_Callback() { SampleTrackerType* st = LockedData.SampleTracker; HRESULT ret; @@ -260,7 +263,7 @@ void Maintenance_Callback() } } -void Init_Locked_Data() +static void Init_Locked_Data() { LockedData.DigiHandle = INVALID_AUDIO_HANDLE; LockedData.ServiceSomething = 0; @@ -273,7 +276,7 @@ void Init_Locked_Data() LockedData._int = 0; } -bool File_Callback(short id, short* odd, void** buffer, int* size) +static bool File_Callback(short id, short* odd, void** buffer, int* size) { if (id == INVALID_AUDIO_HANDLE) { return false; @@ -384,11 +387,11 @@ bool File_Callback(short id, short* odd, void** buffer, int* size) return false; } -int __cdecl Stream_Sample_Vol(void* buffer, - int size, - bool (*callback)(short int, short int*, void**, int*), - int volume, - int handle) +static int __cdecl Stream_Sample_Vol(void* buffer, + int size, + bool (*callback)(short int, short int*, void**, int*), + int volume, + int handle) { if (AudioDone || buffer == nullptr || size == 0 || LockedData.DigiHandle == INVALID_AUDIO_HANDLE) { return INVALID_AUDIO_HANDLE; @@ -414,12 +417,7 @@ int __cdecl Stream_Sample_Vol(void* buffer, return playid; } -int File_Stream_Sample(const char* filename, bool real_time_start) -{ - return File_Stream_Sample_Vol(filename, VOLUME_MAX, real_time_start); -} - -void File_Stream_Preload(int index) +static void File_Stream_Preload(int index) { SampleTrackerType* st = &LockedData.SampleTracker[index]; int maxnum = (LockedData.StreamBufferCount / 2) + 4; @@ -598,25 +596,7 @@ void* Load_Sample(char const* filename) return data; } -long Load_Sample_Into_Buffer(char const* filename, void* buffer, long size) -{ - if (buffer == nullptr || size == 0 || LockedData.DigiHandle == INVALID_AUDIO_HANDLE || !filename - || !Find_File(filename)) { - return 0; - } - - int handle = Open_File(filename, 1); - - if (handle == INVALID_FILE_HANDLE) { - return 0; - } - - int sample_size = Sample_Read(handle, buffer, size); - Close_File(handle); - return sample_size; -} - -int Sample_Read(int fh, void* buffer, int size) +static int Sample_Read(int fh, void* buffer, int size) { if (buffer == nullptr || fh == INVALID_AUDIO_HANDLE || size <= sizeof(AUDHeaderType)) { return 0; @@ -641,7 +621,7 @@ void Free_Sample(void const* sample) } } -void CALLBACK Sound_Timer_Callback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) +static void CALLBACK Sound_Timer_Callback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { if (!AudioDone) { EnterCriticalSection(&GlobalAudioCriticalSection); @@ -650,7 +630,7 @@ void CALLBACK Sound_Timer_Callback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_ } } -void Sound_Thread(void* a1) +static void Sound_Thread(void* a1) { // TODO : Find a alternative solution, this is the original code, and likely causes lockups on modern systems. DuplicateHandle( @@ -677,7 +657,7 @@ bool Set_Primary_Buffer_Format() return false; } -int Print_Sound_Error(char* sound_error, void* window) +static int Print_Sound_Error(char* sound_error, void* window) { return MessageBoxA((HWND)window, sound_error, "DirectSound Audio Error", MB_OK | MB_ICONWARNING); } @@ -979,7 +959,7 @@ void Stop_Sample_Playing(void const* sample) } } -int Get_Free_Sample_Handle(int priority) +static int Get_Free_Sample_Handle(int priority) { int index = 0; @@ -1029,7 +1009,7 @@ int Play_Sample(void const* sample, int priority, int volume, signed short panlo return Play_Sample_Handle(sample, priority, volume, panloc, Get_Free_Sample_Handle(priority)); } -bool Attempt_Audio_Restore(LPDIRECTSOUNDBUFFER sound_buffer) +static bool Attempt_Audio_Restore(LPDIRECTSOUNDBUFFER sound_buffer) { HRESULT return_code = 0; DWORD play_status = 0; @@ -1050,7 +1030,7 @@ bool Attempt_Audio_Restore(LPDIRECTSOUNDBUFFER sound_buffer) return return_code != DSERR_BUFFERLOST; } -int Attempt_To_Play_Buffer(int id) +static int Attempt_To_Play_Buffer(int id) { HRESULT return_code; SampleTrackerType* st = &LockedData.SampleTracker[id]; @@ -1093,7 +1073,7 @@ int Attempt_To_Play_Buffer(int id) } extern bool Any_Locked(); -int Play_Sample_Handle(void const* sample, int priority, int volume, signed short panloc, int id) +static int Play_Sample_Handle(void const* sample, int priority, int volume, signed short panloc, int id) { HRESULT return_code; DWORD status; @@ -1323,13 +1303,6 @@ void Restore_Sound_Buffers() } } -int Set_Sound_Vol(int vol) -{ - int oldvol = LockedData.SoundVolume; - LockedData.SoundVolume = vol; - return oldvol; -} - int Set_Score_Vol(int volume) { int old = LockedData.ScoreVolume; @@ -1360,49 +1333,11 @@ void Fade_Sample(int index, int ticks) } } -void Unfade_Sample(int index, int ticks) -{ - if (Sample_Status(index)) { - SampleTrackerType* st = &LockedData.SampleTracker[index]; - - if (ticks > 0 && !st->Loading) { - st->Reducer -= ((st->Volume / ticks) + 1); - } else { - st->Reducer = 0; - } - } -} - int Get_Digi_Handle() { return LockedData.DigiHandle; } -unsigned Sample_Length(void* sample) -{ - if (sample == nullptr) { - return 0; - } - - AUDHeaderType header; - memcpy(&header, sample, sizeof(header)); - unsigned time = header.UncompSize; - - if (header.Flags & 2) { - time /= 2; - } - - if (header.Flags & 1) { - time /= 2; - } - - if (header.Rate / 60 > 0) { - time /= header.Rate / 60; - } - - return time; -} - bool Start_Primary_Sound_Buffer(bool forced) { if (PrimaryBufferPtr == nullptr || !GameInFocus) { @@ -1440,7 +1375,7 @@ void Stop_Primary_Sound_Buffer() } } -void Suspend_Audio_Thread() +static void Suspend_Audio_Thread() { if (SoundThreadActive) { timeKillEvent(SoundTimerHandle); @@ -1449,7 +1384,7 @@ void Suspend_Audio_Thread() } } -void Resume_Audio_Thread() +static void Resume_Audio_Thread() { if (!SoundThreadActive) { SoundTimerHandle = timeSetEvent(TIMER_DELAY, TIMER_RESOLUTION, Sound_Timer_Callback, SoundThreadActive, 1); @@ -1457,7 +1392,7 @@ void Resume_Audio_Thread() } } -int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void** dest, int size) +static int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void** dest, int size) { int out = 0; @@ -1498,16 +1433,16 @@ int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void* return out; } -int Sample_Copy(SampleTrackerType* st, - void** source, - int* ssize, - void** alternate, - int* altsize, - void* dest, - int size, - SCompressType scomp, - void* trailer, - int16_t* trailersize) +static int Sample_Copy(SampleTrackerType* st, + void** source, + int* ssize, + void** alternate, + int* altsize, + void* dest, + int size, + SCompressType scomp, + void* trailer, + int16_t* trailersize) { int datasize = 0; diff --git a/common/soundio_null.cpp b/common/soundio_null.cpp index 1e01680d..afbd6600 100644 --- a/common/soundio_null.cpp +++ b/common/soundio_null.cpp @@ -6,80 +6,67 @@ bool StreamLowImpact = false; SFX_Type SoundType; Sample_Type SampleType; -int File_Stream_Sample(char const* filename, bool real_time_start) -{ - return 1; -}; int File_Stream_Sample_Vol(char const* filename, int volume, bool real_time_start) { return 1; -}; -void Sound_Callback(void){}; -void maintenance_callback(void){}; +} +void Sound_Callback(void) +{ +} void* Load_Sample(char const* filename) { return nullptr; -}; -int Load_Sample_Into_Buffer(char const* filename, void* buffer, int size) -{ - return 0; } -int Sample_Read(int fh, void* buffer, int size) +void Free_Sample(void const* sample) { - return 0; -}; -void Free_Sample(void const* sample){}; +} bool Audio_Init(int bits_per_sample, bool stereo, int rate, bool reverse_channels) { return 0; -}; -void Sound_End(void){}; -void Stop_Sample(int handle){}; +} +void Sound_End(void) +{ +} +void Stop_Sample(int handle) +{ +} bool Sample_Status(int handle) { return 0; -}; +} bool Is_Sample_Playing(void const* sample) { return 0; -}; -void Stop_Sample_Playing(void const* sample){}; -int Play_Sample(void const* sample, int priority, int volume, signed short panloc) +} +void Stop_Sample_Playing(void const* sample) { - return 1; -}; -int Play_Sample_Handle(void const* sample, int priority, int volume, signed short panloc, int id) +} +int Play_Sample(void const* sample, int priority, int volume, signed short panloc) { return 1; -}; -int Set_Sound_Vol(int volume) -{ - return 0; -}; +} int Set_Score_Vol(int volume) { return 0; -}; -void Fade_Sample(int handle, int ticks){}; -int Get_Free_Sample_Handle(int priority) +} +void Fade_Sample(int handle, int ticks) { - return 1; -}; +} int Get_Digi_Handle(void) { return 1; } -int Sample_Length(void const* sample) +void Restore_Sound_Buffers(void) { - return 0; -}; -void Restore_Sound_Buffers(void){}; +} bool Set_Primary_Buffer_Format(void) { return 0; -}; +} bool Start_Primary_Sound_Buffer(bool forced) { return 0; -}; -void Stop_Primary_Sound_Buffer(void){}; +} +void Stop_Primary_Sound_Buffer(void) +{ +} diff --git a/common/soundio_openal.cpp b/common/soundio_openal.cpp index 46d0d0df..669d91be 100644 --- a/common/soundio_openal.cpp +++ b/common/soundio_openal.cpp @@ -203,24 +203,26 @@ struct LockedDataType unsigned SoundVolume; unsigned ScoreVolume; int VolumeLock; -} LockedData; +}; void (*Audio_Focus_Loss_Function)() = nullptr; +static struct LockedDataType LockedData; SFX_Type SoundType; Sample_Type SampleType; -void* FileStreamBuffer = nullptr; +static void* FileStreamBuffer = nullptr; bool StreamLowImpact = false; -bool StartingFileStream = false; -bool volatile AudioDone = false; +static bool StartingFileStream = false; +static bool volatile AudioDone = false; ALCcontext* OpenALContext = nullptr; extern bool GameInFocus; static uint8_t ChunkBuffer[BUFFER_CHUNK_SIZE]; -unsigned int SoundTimerHandle; - bool Any_Locked(); // From each games winstub.cpp at the moment. -void Maintenance_Callback(); +static int Get_Free_Sample_Handle(int priority); +static void Maintenance_Callback(); +static int Play_Sample_Handle(const void* sample, int priority, int volume, signed short panloc, int id); +static int Sample_Read(int fh, void* buffer, int size); static ALenum Get_OpenAL_Format(int bits, int channels) { @@ -282,7 +284,7 @@ static void Init_Locked_Data() LockedData.ScoreVolume = VOLUME_MAX; } -int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void** dest, int size) +static int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void** dest, int size) { int out = 0; @@ -323,16 +325,16 @@ int Simple_Copy(void** source, int* ssize, void** alternate, int* altsize, void* return out; } -int Sample_Copy(SampleTrackerType* st, - void** source, - int* ssize, - void** alternate, - int* altsize, - void* dest, - int size, - SCompressType scomp, - void* trailer, - int16_t* trailersize) +static int Sample_Copy(SampleTrackerType* st, + void** source, + int* ssize, + void** alternate, + int* altsize, + void* dest, + int size, + SCompressType scomp, + void* trailer, + int16_t* trailersize) { int datasize = 0; @@ -411,12 +413,8 @@ int Sample_Copy(SampleTrackerType* st, return datasize; } -int File_Stream_Sample(const char* filename, bool real_time_start) -{ - return File_Stream_Sample_Vol(filename, VOLUME_MAX, real_time_start); -} - -int Stream_Sample_Vol(void* buffer, int size, bool (*callback)(short, short*, void**, int*), int volume, int handle) +static int +Stream_Sample_Vol(void* buffer, int size, bool (*callback)(short, short*, void**, int*), int volume, int handle) { if (AudioDone || buffer == nullptr || size == 0 || LockedData.DigiHandle == INVALID_AUDIO_HANDLE) { return INVALID_AUDIO_HANDLE; @@ -442,7 +440,7 @@ int Stream_Sample_Vol(void* buffer, int size, bool (*callback)(short, short*, vo return playid; } -bool File_Callback(short id, short* odd, void** buffer, int* size) +static bool File_Callback(short id, short* odd, void** buffer, int* size) { if (id == INVALID_AUDIO_HANDLE) { return false; @@ -510,7 +508,7 @@ bool File_Callback(short id, short* odd, void** buffer, int* size) return false; } -void File_Stream_Preload(int index) +static void File_Stream_Preload(int index) { SampleTrackerType* st = &LockedData.SampleTracker[index]; int maxnum = (LockedData.StreamBufferCount / 2) + 4; @@ -611,7 +609,7 @@ int File_Stream_Sample_Vol(char const* filename, int volume, bool real_time_star } return INVALID_AUDIO_HANDLE; -}; +} void Sound_Callback() { @@ -663,9 +661,9 @@ void Sound_Callback() } } } -}; +} -void Maintenance_Callback() +static void Maintenance_Callback() { if (AudioDone) { return; @@ -760,7 +758,7 @@ void Maintenance_Callback() --LockedData.VolumeLock; } -}; +} void* Load_Sample(char const* filename) { @@ -784,27 +782,9 @@ void* Load_Sample(char const* filename) } return data; -}; - -int Load_Sample_Into_Buffer(char const* filename, void* buffer, int size) -{ - if (buffer == nullptr || size == 0 || LockedData.DigiHandle == INVALID_AUDIO_HANDLE || !filename - || !Find_File(filename)) { - return 0; - } - - int handle = Open_File(filename, 1); - - if (handle == INVALID_FILE_HANDLE) { - return 0; - } - - int sample_size = Sample_Read(handle, buffer, size); - Close_File(handle); - return sample_size; } -int Sample_Read(int fh, void* buffer, int size) +static int Sample_Read(int fh, void* buffer, int size) { if (buffer == nullptr || fh == INVALID_AUDIO_HANDLE || size <= sizeof(AUDHeaderType)) { return 0; @@ -819,14 +799,14 @@ int Sample_Read(int fh, void* buffer, int size) memcpy(buffer, &header, sizeof(AUDHeaderType)); return actual_bytes_read; -}; +} void Free_Sample(const void* sample) { if (sample != nullptr) { free((void*)sample); } -}; +} bool Audio_Init(int bits_per_sample, bool stereo, int rate, bool reverse_channels) { @@ -886,7 +866,7 @@ bool Audio_Init(int bits_per_sample, bool stereo, int rate, bool reverse_channel AudioDone = false; return true; -}; +} void Sound_End() { @@ -914,7 +894,7 @@ void Sound_End() } AudioDone = true; -}; +} void Stop_Sample(int index) { @@ -953,7 +933,7 @@ void Stop_Sample(int index) st->QueueBuffer = nullptr; } } -}; +} bool Sample_Status(int index) { @@ -983,7 +963,7 @@ bool Sample_Status(int index) alGetSourcei(st->OpenALSource, AL_SOURCE_STATE, &val); return val == AL_PLAYING; -}; +} bool Is_Sample_Playing(const void* sample) { @@ -998,7 +978,7 @@ bool Is_Sample_Playing(const void* sample) } return false; -}; +} void Stop_Sample_Playing(const void* sample) { @@ -1010,14 +990,14 @@ void Stop_Sample_Playing(const void* sample) } } } -}; +} int Play_Sample(const void* sample, int priority, int volume, signed short panloc) { return Play_Sample_Handle(sample, priority, volume, panloc, Get_Free_Sample_Handle(priority)); -}; +} -int Attempt_To_Play_Buffer(int id) +static int Attempt_To_Play_Buffer(int id) { SampleTrackerType* st = &LockedData.SampleTracker[id]; @@ -1029,7 +1009,7 @@ int Attempt_To_Play_Buffer(int id) return id; } -int Play_Sample_Handle(const void* sample, int priority, int volume, signed short panloc, int id) +static int Play_Sample_Handle(const void* sample, int priority, int volume, signed short panloc, int id) { if (Any_Locked()) { return INVALID_AUDIO_HANDLE; @@ -1160,15 +1140,7 @@ int Play_Sample_Handle(const void* sample, int priority, int volume, signed shor } return INVALID_AUDIO_HANDLE; -}; - -int Set_Sound_Vol(int volume) -{ - - int oldvol = LockedData.SoundVolume; - LockedData.SoundVolume = volume; - return oldvol; -}; +} int Set_Score_Vol(int volume) { @@ -1184,7 +1156,7 @@ int Set_Score_Vol(int volume) } return old; -}; +} void Fade_Sample(int index, int ticks) { @@ -1197,9 +1169,9 @@ void Fade_Sample(int index, int ticks) Stop_Sample(index); } } -}; +} -int Get_Free_Sample_Handle(int priority) +static int Get_Free_Sample_Handle(int priority) { int index = 0; @@ -1242,44 +1214,21 @@ int Get_Free_Sample_Handle(int priority) LockedData.SampleTracker[index].IsScore = false; return index; -}; +} int Get_Digi_Handle() { return LockedData.DigiHandle; } -int Sample_Length(const void* sample) +void Restore_Sound_Buffers() { - if (sample == nullptr) { - return 0; - } - - AUDHeaderType header; - memcpy(&header, sample, sizeof(header)); - unsigned time = header.UncompSize; - - if (header.Flags & 2) { - time /= 2; - } - - if (header.Flags & 1) { - time /= 2; - } - - if (header.Rate / 60 > 0) { - time /= header.Rate / 60; - } - - return time; -}; - -void Restore_Sound_Buffers(){}; +} bool Set_Primary_Buffer_Format() { return true; -}; +} bool Start_Primary_Sound_Buffer(bool forced) { @@ -1290,7 +1239,7 @@ bool Start_Primary_Sound_Buffer(bool forced) alcProcessContext(OpenALContext); return true; -}; +} void Stop_Primary_Sound_Buffer() { @@ -1301,4 +1250,4 @@ void Stop_Primary_Sound_Buffer() if (OpenALContext != nullptr) { alcSuspendContext(OpenALContext); } -}; +} From f52d4d225ea1f32cd27afe65af14a65ceef9f07e Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Sun, 5 Mar 2023 07:49:29 +0000 Subject: [PATCH 02/27] Endian fixes for the Red Alert lobby networking code. --- common/connect.cpp | 2 + common/connect.h | 7 +++ redalert/ipxgconn.cpp | 8 ++- redalert/ipxgconn.h | 7 +++ redalert/ipxmgr.cpp | 31 +++++++++ redalert/ipxmgr.h | 4 ++ redalert/session.h | 136 +++++++++++++++++++++++++++++++++------ redalert/special.h | 143 +++++++++++++++++++++++++----------------- 8 files changed, 259 insertions(+), 79 deletions(-) diff --git a/common/connect.cpp b/common/connect.cpp index 7b8b8848..13b3386d 100644 --- a/common/connect.cpp +++ b/common/connect.cpp @@ -225,6 +225,8 @@ int ConnectionClass::Send_Packet(void* buf, int buflen, int ack_req) ((CommHeaderType*)PacketBuf)->PacketID = NumSendNoAck; } + SwapCommHeaderType((CommHeaderType*)PacketBuf); + /*------------------------------------------------------------------------ Now build the packet ------------------------------------------------------------------------*/ diff --git a/common/connect.h b/common/connect.h index 1a14f9d8..03dc2445 100644 --- a/common/connect.h +++ b/common/connect.h @@ -100,6 +100,7 @@ ********************************* Includes ********************************** */ #include "combuf.h" +#include "endianness.h" /* ********************************** Defines ********************************** @@ -122,6 +123,12 @@ typedef struct unsigned int PacketID; } CommHeaderType; +inline void SwapCommHeaderType(CommHeaderType* cht) +{ + cht->MagicNumber = le16toh(cht->MagicNumber); + cht->PacketID = le32toh(cht->PacketID); +} + /* ***************************** Class Declaration ***************************** */ diff --git a/redalert/ipxgconn.cpp b/redalert/ipxgconn.cpp index f6a09d6d..dcd0ee2a 100644 --- a/redalert/ipxgconn.cpp +++ b/redalert/ipxgconn.cpp @@ -143,6 +143,8 @@ int IPXGlobalConnClass::Send_Packet(void* buf, int buflen, IPXAddressClass* addr ------------------------------------------------------------------------*/ ((GlobalHeaderType*)PacketBuf)->ProductID = ProductID; + SwapGlobalHeaderType((GlobalHeaderType*)PacketBuf); + /*------------------------------------------------------------------------ Set this packet's destination address. If no address is specified, use a Broadcast address (which IPXAddressClass's default constructor creates). @@ -253,6 +255,7 @@ int IPXGlobalConnClass::Receive_Packet(void* buf, int buflen, IPXAddressClass* a ackpacket.Header.Code = PACKET_ACK; ackpacket.Header.PacketID = packet->Header.PacketID; ackpacket.ProductID = ProductID; + SwapGlobalHeaderType(&ackpacket); Send((char*)&ackpacket, sizeof(GlobalHeaderType), address, sizeof(IPXAddressClass)); } @@ -288,7 +291,8 @@ int IPXGlobalConnClass::Receive_Packet(void* buf, int buflen, IPXAddressClass* a /*............................................................... If ACK is for this entry, mark it ...............................................................*/ - if (packet->Header.PacketID == entry_data->Header.PacketID && entry_data->Header.Code == PACKET_DATA_ACK) { + if (packet->Header.PacketID == le32toh(entry_data->Header.PacketID) + && entry_data->Header.Code == PACKET_DATA_ACK) { send_entry->IsACK = 1; break; } @@ -361,7 +365,7 @@ int IPXGlobalConnClass::Get_Packet(void* buf, int* buflen, IPXAddressClass* addr memcpy(buf, rec_entry->Buffer + sizeof(GlobalHeaderType), packetlen); } (*buflen) = packetlen; - (*product_id) = packet->ProductID; + (*product_id) = le16toh(packet->ProductID); (*address) = (*((IPXAddressClass*)(rec_entry->ExtraBuffer))); return (1); diff --git a/redalert/ipxgconn.h b/redalert/ipxgconn.h index 49be3659..5172752e 100644 --- a/redalert/ipxgconn.h +++ b/redalert/ipxgconn.h @@ -75,6 +75,7 @@ #ifndef IPXGLOBALCONN_H #define IPXGLOBALCONN_H +#include "common/endianness.h" #include "ipxconn.h" /* @@ -94,6 +95,12 @@ typedef struct unsigned short ProductID; } GlobalHeaderType; +inline void SwapGlobalHeaderType(GlobalHeaderType* ght) +{ + SwapCommHeaderType(&ght->Header); + ght->ProductID = le16toh(ght->ProductID); +} + /* ***************************** Class Declaration ***************************** */ diff --git a/redalert/ipxmgr.cpp b/redalert/ipxmgr.cpp index 87fef43c..0a884594 100644 --- a/redalert/ipxmgr.cpp +++ b/redalert/ipxmgr.cpp @@ -739,6 +739,19 @@ int IPXManagerClass::Send_Global_Message(void* buf, int buflen, int ack_req, IPX } /* end of Send_Global_Message */ +int IPXManagerClass::Send_Global_Message(GlobalPacketType* buf, int buflen, int ack_req, IPXAddressClass* address) +{ + int rc; + + SwapGlobalPacketType(buf, true); + + rc = Send_Global_Message((void*)buf, buflen, ack_req, address); + + SwapGlobalPacketType(buf, false); + + return rc; +} /* end of Send_Global_Message */ + /*************************************************************************** * IPXManagerClass::Get_Global_Message -- polls the Global Message queue * * * @@ -769,6 +782,20 @@ int IPXManagerClass::Get_Global_Message(void* buf, int* buflen, IPXAddressClass* } /* end of Get_Global_Message */ +int IPXManagerClass::Get_Global_Message(GlobalPacketType* buf, + int* buflen, + IPXAddressClass* address, + unsigned short* product_id) +{ + int rc; + + rc = Get_Global_Message((void*)buf, buflen, address, product_id); + + SwapGlobalPacketType(buf, false); + + return rc; +} /* end of Get_Global_Message */ + /*************************************************************************** * IPXManagerClass::Send_Private_Message -- Sends a Private Message * * * @@ -962,6 +989,9 @@ int IPXManagerClass::Service(void) address = *((IPXAddressClass*)temp_address); packet = (CommHeaderType*)CurDataBuf; + + SwapCommHeaderType(packet); + if (packet->MagicNumber == GlobalChannel->Magic_Num()) { /* @@ -1067,6 +1097,7 @@ int IPXManagerClass::Service(void) packet goes into the Global Queue, or into one of the Private Queues .....................................................................*/ packet = (CommHeaderType*)CurDataBuf; + SwapCommHeaderType(packet); if (packet->MagicNumber == GlobalChannel->Magic_Num()) { /*.................................................................. Put the packet in the Global Queue diff --git a/redalert/ipxmgr.h b/redalert/ipxmgr.h index 5e23f995..408a84f0 100644 --- a/redalert/ipxmgr.h +++ b/redalert/ipxmgr.h @@ -121,6 +121,8 @@ #include "common/ipxaddr.h" #include "connmgr.h" +struct GlobalPacketType; + /* ********************************** Defines ********************************** */ @@ -186,7 +188,9 @@ class IPXManagerClass : public ConnManClass This is how the application sends & receives messages. .....................................................................*/ int Send_Global_Message(void* buf, int buflen, int ack_req = 0, IPXAddressClass* address = NULL); + int Send_Global_Message(GlobalPacketType* buf, int buflen, int ack_req = 0, IPXAddressClass* address = NULL); int Get_Global_Message(void* buf, int* buflen, IPXAddressClass* address, unsigned short* product_id); + int Get_Global_Message(GlobalPacketType* buf, int* buflen, IPXAddressClass* address, unsigned short* product_id); virtual int Send_Private_Message(void* buf, int buflen, int ack_req = 1, int conn_id = CONNECTION_NONE); virtual int Get_Private_Message(void* buf, int* buflen, int* conn_id); diff --git a/redalert/session.h b/redalert/session.h index 6b1f5f00..e157e7dd 100644 --- a/redalert/session.h +++ b/redalert/session.h @@ -36,6 +36,7 @@ #include "common/ipxaddr.h" #include "common/bitfields.h" +#include "common/endianness.h" #include "msglist.h" #include "connect.h" #include "version.h" @@ -321,7 +322,7 @@ typedef struct #ifdef WOLAPI_INTEGRATION char ShortFileName[13]; // Name of scenario file to expect from host #else - char ShortFileName[12]; // Name of scenario file to expect from host + char ShortFileName[12]; // Name of scenario file to expect from host #endif unsigned char FileDigest[32]; // Digest of scenario file to expect from host // ajw - This is not necessarily null-terminated. @@ -361,7 +362,18 @@ typedef struct GlobalPacketType { struct BITFIELD_STRUCT { - unsigned int IsOpen : 1; // 1 = game is open for joining + union + { + unsigned int Bitfield; + + struct + { +#ifdef __BIG_ENDIAN__ + unsigned int Unused : 31; +#endif + unsigned int IsOpen : 1; // 1 = game is open for joining + }; + }; } GameInfo; struct { @@ -374,25 +386,42 @@ typedef struct GlobalPacketType } PlayerInfo; struct BITFIELD_STRUCT { - char Scenario[DESCRIP_MAX]; // Scenario Name - unsigned int Credits; // player's credits - 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? - 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 Version; // version # common to all players - unsigned int FileLength; // Length of scenario file to expect from host. + char Scenario[DESCRIP_MAX]; // Scenario Name + unsigned int Credits; // player's credits + union + { + unsigned int Bitfield; + + struct + { +#ifdef __BIG_ENDIAN__ + unsigned int Unused : 27; + unsigned int OfficialScenario : 1; // Is this scenario an official Westwood one? + unsigned int IsGhosties : 1; // 1 = ghosts are allowed + unsigned int IsGoodies : 1; // 1 = goodies are allowed + unsigned int IsTiberium : 1; // 1 = tiberium is allowed + unsigned int IsBases : 1; // 1 = bases are allowed +#else + 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? +#endif + }; + }; + 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 Version; // version # common to all players + 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 - char ShortFileName[12]; // Name of scenario file to expect from host + char ShortFileName[12]; // Name of scenario file to expect from host #endif unsigned char FileDigest[32]; // Digest of scenario file to expect from host // ajw - This is not necessarily null-terminated. @@ -419,6 +448,77 @@ typedef struct GlobalPacketType }; } GlobalPacketType; #pragma pack(pop) + +inline void SwapGlobalPacketType(GlobalPacketType* gpt, bool sending) +{ + enum NetCommandType command; + + if (sending) { + command = gpt->Command; + } else { + command = (enum NetCommandType)le32toh(gpt->Command); + } + + gpt->Command = (enum NetCommandType)le32toh(gpt->Command); + + switch (command) { + case NET_QUERY_GAME: + break; + + case NET_ANSWER_GAME: + gpt->GameInfo.Bitfield = le32toh(gpt->GameInfo.Bitfield); + break; + + case NET_QUERY_PLAYER: + break; + + case NET_ANSWER_PLAYER: + case NET_QUERY_JOIN: + case NET_CONFIRM_JOIN: + gpt->PlayerInfo.NameCRC = le32toh(gpt->PlayerInfo.NameCRC); + gpt->PlayerInfo.MinVersion = le32toh(gpt->PlayerInfo.MinVersion); + gpt->PlayerInfo.MaxVersion = le32toh(gpt->PlayerInfo.MaxVersion); + gpt->PlayerInfo.CheatCheck = le32toh(gpt->PlayerInfo.CheatCheck); + break; + + case NET_CHAT_ANNOUNCE: + gpt->Chat.ID = le32toh(gpt->Chat.ID); + break; + + case NET_CHAT_REQUEST: + break; + + case NET_REJECT_JOIN: + gpt->Reject.Why = le32toh(gpt->Reject.Why); + break; + + case NET_GAME_OPTIONS: + gpt->ScenarioInfo.Credits = le32toh(gpt->ScenarioInfo.Credits); + gpt->ScenarioInfo.Bitfield = le32toh(gpt->ScenarioInfo.Bitfield); + gpt->ScenarioInfo.Seed = le32toh(gpt->ScenarioInfo.Seed); + gpt->ScenarioInfo.Special.Bitfield = le32toh(gpt->ScenarioInfo.Special.Bitfield); + gpt->ScenarioInfo.GameSpeed = le32toh(gpt->ScenarioInfo.GameSpeed); + gpt->ScenarioInfo.Version = le32toh(gpt->ScenarioInfo.Version); + gpt->ScenarioInfo.FileLength = le32toh(gpt->ScenarioInfo.FileLength); + break; + + case NET_SIGN_OFF: + break; + + case NET_GO: + case NET_LOADGAME: + gpt->ResponseTime.OneWay = le32toh(gpt->ResponseTime.OneWay); + break; + + case NET_MESSAGE: + gpt->Message.NameCRC = le32toh(gpt->Message.NameCRC); + break; + + case NET_PING: + break; + } +} + //........................................................................... // For finding sync bugs; filled in by the engine when certain conditions // are met; the pointers allow examination of objects in the debugger. diff --git a/redalert/special.h b/redalert/special.h index 3f5fe03f..78dbeb8f 100644 --- a/redalert/special.h +++ b/redalert/special.h @@ -36,6 +36,7 @@ #define SPECIAL_H #include "common/bitfields.h" +#include "common/endianness.h" #pragma pack(push, 1) class BITFIELD_STRUCT SpecialClass @@ -47,65 +48,89 @@ class BITFIELD_STRUCT SpecialClass */ void Init(void); - /* - ** If the shroud should regenerated, then this flag will be true. - */ - unsigned IsShadowGrow : 1; - - /* - ** Controls the speedy build option -- used for testing. - */ - unsigned IsSpeedBuild : 1; - - /* - ** If from install, then play the special installation movie and - ** skip asking them what type of game they want to play. - */ - unsigned IsFromInstall : 1; - - /* - ** If capture the flag mode is on, this flag will be true. With this - ** flag enabled, then the flag is initially placed at the start of - ** the scenario. - */ - unsigned IsCaptureTheFlag : 1; - - /* - ** This flags controls whether weapons are inert. An inert weapon doesn't do any - ** damage. Effectively, if this is true, then the units never die. - */ - unsigned IsInert : 1; - - /* - ** If wheeled vehicles should do a 3-point turn when rotating in place, then - ** this flag is true. - */ - unsigned IsThreePoint : 1; - - /* - ** If Tiberium is allowed to spread and grow, then these flags will be true. - ** These are duplicated from the rules.ini file and also controlled by the - ** multiplayer dialog box. - */ - unsigned IsTGrowth : 1; - unsigned IsTSpread : 1; - - /* - ** If this flag is true, then the construction yard can undeploy back into an MCV. - ** Used to override the rules setting. - */ - unsigned UseMCVDeploy : 1; - unsigned IsMCVDeploy : 1; - - /* - ** New anti-griefing early win mode. ST - 1/31/2020 3:42PM - */ - unsigned IsEarlyWin : 1; - - /* - ** New modern balance setting. - */ - unsigned ModernBalance : 1; + union + { + unsigned Bitfield; + + struct + { +#ifdef __BIG_ENDIAN__ + unsigned int Unused : 20; + unsigned ModernBalance : 1; + unsigned IsEarlyWin : 1; + unsigned IsMCVDeploy : 1; + unsigned UseMCVDeploy : 1; + unsigned IsTSpread : 1; + unsigned IsTGrowth : 1; + unsigned IsThreePoint : 1; + unsigned IsInert : 1; + unsigned IsCaptureTheFlag : 1; + unsigned IsFromInstall : 1; + unsigned IsSpeedBuild : 1; + unsigned IsShadowGrow : 1; +#else + /* + ** If the shroud should regenerated, then this flag will be true. + */ + unsigned IsShadowGrow : 1; + + /* + ** Controls the speedy build option -- used for testing. + */ + unsigned IsSpeedBuild : 1; + + /* + ** If from install, then play the special installation movie and + ** skip asking them what type of game they want to play. + */ + unsigned IsFromInstall : 1; + + /* + ** If capture the flag mode is on, this flag will be true. With this + ** flag enabled, then the flag is initially placed at the start of + ** the scenario. + */ + unsigned IsCaptureTheFlag : 1; + + /* + ** This flags controls whether weapons are inert. An inert weapon doesn't do any + ** damage. Effectively, if this is true, then the units never die. + */ + unsigned IsInert : 1; + + /* + ** If wheeled vehicles should do a 3-point turn when rotating in place, then + ** this flag is true. + */ + unsigned IsThreePoint : 1; + + /* + ** If Tiberium is allowed to spread and grow, then these flags will be true. + ** These are duplicated from the rules.ini file and also controlled by the + ** multiplayer dialog box. + */ + unsigned IsTGrowth : 1; + unsigned IsTSpread : 1; + + /* + ** If this flag is true, then the construction yard can undeploy back into an MCV. + ** Used to override the rules setting. + */ + unsigned UseMCVDeploy : 1; + unsigned IsMCVDeploy : 1; + + /* + ** New anti-griefing early win mode. ST - 1/31/2020 3:42PM + */ + unsigned IsEarlyWin : 1; + + /* + ** New modern balance setting. + */ + unsigned ModernBalance : 1; +#endif + }; + }; }; #pragma pack(pop) From f4cc9b03e3294bdb01a35b027a500ecb9ac11f49 Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Mon, 6 Mar 2023 06:37:08 +0000 Subject: [PATCH 03/27] WWKeyboardClass' KeyState buffer is Win32 only, so mark it as such. --- common/wwkeyboard.cpp | 31 +++++++++++++++++-------------- common/wwkeyboard.h | 2 ++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/common/wwkeyboard.cpp b/common/wwkeyboard.cpp index b7f2d683..8020d1f2 100644 --- a/common/wwkeyboard.cpp +++ b/common/wwkeyboard.cpp @@ -88,7 +88,10 @@ WWKeyboardClass::WWKeyboardClass(void) , Tail(0) , DownSkip(0) { +#if defined(_WIN32) memset(KeyState, '\0', sizeof(KeyState)); +#endif + memset(DownState, '\0', sizeof(DownState)); } @@ -297,19 +300,6 @@ KeyASCIIType WWKeyboardClass::To_ASCII(unsigned short key) return KA_NONE; } - /* - ** Set the KeyState buffer to reflect the shift bits stored in the key value. - */ - if (key & WWKEY_SHIFT_BIT) { - KeyState[VK_SHIFT] = 0x80; - } - if (key & WWKEY_CTRL_BIT) { - KeyState[VK_CONTROL] = 0x80; - } - if (key & WWKEY_ALT_BIT) { - KeyState[VK_MENU] = 0x80; - } - /* ** Ask windows to translate the key into an ASCII equivalent. */ @@ -330,9 +320,21 @@ KeyASCIIType WWKeyboardClass::To_ASCII(unsigned short key) return sdl_keymap[key]; } #elif defined(_WIN32) + /* + ** Set the KeyState buffer to reflect the shift bits stored in the key value. + */ + if (key & WWKEY_SHIFT_BIT) { + KeyState[VK_SHIFT] = 0x80; + } + if (key & WWKEY_CTRL_BIT) { + KeyState[VK_CONTROL] = 0x80; + } + if (key & WWKEY_ALT_BIT) { + KeyState[VK_MENU] = 0x80; + } + scancode = MapVirtualKeyA(key & 0xFF, 0); result = ToAscii((UINT)(key & 0xFF), (UINT)scancode, (PBYTE)KeyState, (LPWORD)buffer, (UINT)0); -#endif /* ** Restore the KeyState buffer back to pristine condition. @@ -346,6 +348,7 @@ KeyASCIIType WWKeyboardClass::To_ASCII(unsigned short key) if (key & WWKEY_ALT_BIT) { KeyState[VK_MENU] = 0; } +#endif /* ** If Windows could not perform the translation as expected, then diff --git a/common/wwkeyboard.h b/common/wwkeyboard.h index e49f364a..a18c047a 100644 --- a/common/wwkeyboard.h +++ b/common/wwkeyboard.h @@ -900,7 +900,9 @@ class WWKeyboardClass ** This is a keyboard state array that is used to aid in translating ** KN_ keys into KA_ keys. */ +#if defined(_WIN32) unsigned char KeyState[256]; +#endif /* ** This is the circular keyboard holding buffer. It holds the VK key and From da253d3718af2f359eb8ba1549c4d162c4b0dd57 Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Mon, 6 Mar 2023 08:16:04 +0000 Subject: [PATCH 04/27] Fixes to the framelimiter to make it more accurate. This change improves the accuracy of the framelimiter so it yields the expected result. Before this change, it was impossible to actually achieve the default maximum framerate of 120 FPS. Please note that the Windows code does not have a sleep function with a high enough granularity to take advantage of the improved precision, so Windows builds will still have an imprecise FPS cap. --- common/framelimit.cpp | 13 +++++++------ common/mssleep.h | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/common/framelimit.cpp b/common/framelimit.cpp index 8a202af5..64105dcd 100644 --- a/common/framelimit.cpp +++ b/common/framelimit.cpp @@ -48,12 +48,13 @@ void Frame_Limiter(FrameLimitFlags flags) #else auto frame_end = std::chrono::steady_clock::now(); #endif - int64_t _ms_per_tick = 1000 / Settings.Video.FrameLimit; - auto remaining = - _ms_per_tick - std::chrono::duration_cast(frame_end - frame_start).count(); - if (remaining > 0) { - ms_sleep(unsigned(remaining)); + unsigned int min_frame_time = 1000000 / Settings.Video.FrameLimit; + auto cur_frame_time = std::chrono::duration_cast(frame_end - frame_start).count(); + if (cur_frame_time < min_frame_time) { + frame_start += std::chrono::microseconds{min_frame_time}; + us_sleep(min_frame_time - cur_frame_time); + } else { + frame_start = frame_end; } - frame_start = std::chrono::steady_clock::now(); } } diff --git a/common/mssleep.h b/common/mssleep.h index ef0dc26d..9f7c8a66 100644 --- a/common/mssleep.h +++ b/common/mssleep.h @@ -16,6 +16,21 @@ #include #endif +/** + * Yield the current thread for at least us microseconds. + */ +static inline void us_sleep(unsigned us) +{ +#ifdef _WIN32 + Sleep((us + 999) / 1000); +#else + struct timespec ts; + ts.tv_sec = us / 1000000; + ts.tv_nsec = (us % 1000000) * 1000; + nanosleep(&ts, NULL); +#endif +} + /** * Yield the current thread for at least ms milliseconds. */ From e260535a24a05ccdb9fe6b1f1ad7c4d88f2474ed Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Mon, 6 Mar 2023 08:46:54 +0000 Subject: [PATCH 05/27] Endian fixes for the PKey encryption/decryption. The PKey crypto code simply treats the data to be encrypted or decrypted as one single BigInt and copies the data into a BigInt verbatim. However, a BigInt simply consists of a number of 32 bit integers in the native endian format, so the data copied to/from the BigInt needs to be byteswapped on big endian systems to yield the same result as on little endian systems. --- common/pk.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/common/pk.cpp b/common/pk.cpp index 85be286f..281d9d97 100644 --- a/common/pk.cpp +++ b/common/pk.cpp @@ -286,9 +286,21 @@ int PKey::Encrypt(void const* source, int slen, void* dest) const ** Perform the encryption of the block. */ BigInt temp = 0; + unsigned int* tempui = temp; + int i; + memmove(&temp, source, Plain_Block_Size()); + + for (i = 0; i < (Plain_Block_Size() + 3) / 4; i++) { + tempui[i] = htole32(tempui[i]); + } + temp = temp.exp_b_mod_c(Exponent, Modulus); + for (i = 0; i < (Crypt_Block_Size() + 3) / 4; i++) { + tempui[i] = le32toh(tempui[i]); + } + /* ** Move the cypher block to the destination. */ @@ -327,6 +339,8 @@ int PKey::Decrypt(void const* source, int slen, void* dest) const { int total = 0; BigInt temp; + unsigned int* tempui = temp; + int i; /* ** Decrypt the source data in full blocks. Partial blocks are not processed in any way. @@ -338,8 +352,17 @@ int PKey::Decrypt(void const* source, int slen, void* dest) const */ temp = 0; memmove(&temp, source, Crypt_Block_Size()); + + for (i = 0; i < (Crypt_Block_Size() + 3) / 4; i++) { + tempui[i] = le32toh(tempui[i]); + } + temp = temp.exp_b_mod_c(Exponent, Modulus); + for (i = 0; i < (Plain_Block_Size() + 3) / 4; i++) { + tempui[i] = htole32(tempui[i]); + } + /* ** Move the cypher block to the destination. */ From 297556c69e861e41264b06c9a125232c76cc0d42 Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Fri, 10 Mar 2023 07:45:53 +0000 Subject: [PATCH 06/27] Only compile connect.cpp when networking is enabled. --- common/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 949ee609..f6042f1e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -26,7 +26,6 @@ set(COMMON_SRC crc.cpp crew.cpp cstraw.cpp - connect.cpp debugstring.cpp delay.cpp dipthong.cpp @@ -157,6 +156,7 @@ endif() if(NETWORKING) list(APPEND COMMONV_SRC + connect.cpp ipxaddr.cpp wsproto.cpp wspudp.cpp From ac7f03eff1c557fa98d858cb8800d537dcb2d9fa Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Tue, 14 Mar 2023 10:31:10 +0000 Subject: [PATCH 07/27] Fixed Find_File_Data_Posix::GetTime() to work on files outside the current directory. --- common/file_posix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/file_posix.cpp b/common/file_posix.cpp index 387512f9..534f576b 100644 --- a/common/file_posix.cpp +++ b/common/file_posix.cpp @@ -56,7 +56,7 @@ unsigned int Find_File_Data_Posix::GetTime() const return 0; } struct stat buf = {0}; - if (stat(DirEntry->d_name, &buf) != 0) { + if (stat(FullName, &buf) != 0) { return false; } return buf.st_mtime; From 8419431c778ceeff7b294fa6f03eb101234d7d38 Mon Sep 17 00:00:00 2001 From: Mark Olsen Date: Fri, 10 Mar 2023 06:06:09 +0000 Subject: [PATCH 08/27] Endian fixes for the multiprecision code. The code mostly uses multiprecision integers built up from arrays of 32 bit integers, but will in some cases interchangably treat said arrays as having 16 bit components instead, expecting to read the least significant bytes at lower address and most significant bytes at higher addresses. This change introduces two helper functions to emulate this behaviour - Get_HalfWord() and Set_HalfWord() - which are used instead of directly accessing the 32 bit integer arrays with 16 bit pointers. XMP_Encode() also got endian fixes that are unrelated to the above. --- common/mp.cpp | 163 ++++++++++++++++++++++++++++++++++++++++---------- common/mp.h | 2 +- 2 files changed, 133 insertions(+), 32 deletions(-) diff --git a/common/mp.cpp b/common/mp.cpp index f2af8a46..fdeef76a 100644 --- a/common/mp.cpp +++ b/common/mp.cpp @@ -87,6 +87,33 @@ #include #include "mp.h" #include "memrev.h" +#include "endianness.h" + +#ifdef __BIG_ENDIAN__ +#define HALFWORD_0 1 +#define HALFWORD_1 0 +#else +#define HALFWORD_0 0 +#define HALFWORD_1 1 +#endif + +static inline uint16_t Get_HalfWord(const uint16_t* base, size_t offset) +{ +#ifdef __BIG_ENDIAN__ + return base[offset ^ 1]; +#else + return base[offset]; +#endif +} + +static inline void Set_HalfWord(uint16_t* base, size_t offset, uint16_t value) +{ +#ifdef __BIG_ENDIAN__ + base[offset ^ 1] = value; +#else + base[offset] = value; +#endif +} /*********************************************************************************************** * _Byte_Precision -- Determines the number of bytes significant in long integer. * @@ -306,11 +333,27 @@ unsigned XMP_Encode(unsigned char* to, unsigned tobytes, digit const* from, int //#pragma warning 364 9 unsigned XMP_Encode(unsigned char* to, digit const* from, int precision) { + int i; +#ifdef __BIG_ENDIAN__ + digit from_copy[precision]; +#endif + assert(to != NULL); assert(from != NULL); assert(precision > 0); bool is_negative = XMP_Is_Negative(from, precision); + +#ifdef __BIG_ENDIAN__ + if (sizeof(digit) == 4) { + for (i = 0; i < precision; i++) { + from_copy[i] = le32toh(from[i]); + } + } + + from = from_copy; +#endif + unsigned char filler = (unsigned char)(is_negative ? 0xff : 0); unsigned char* number_ptr; @@ -381,6 +424,12 @@ void XMP_Signed_Decode(digit* result, const unsigned char* from, int frombytes, for (index = 0; index < frombytes; index++) { *--dest = *from++; } + + if (sizeof(digit) == 4) { + for (index = 0; index < precision; index++) { + result[index] = le32toh(result[index]); + } + } } /*********************************************************************************************** @@ -1068,18 +1117,58 @@ bool XMP_Add_Int(digit* result, const digit* left_number, digit right_number, bo * HISTORY: * * 07/01/1996 JLB : Created. * *=============================================================================================*/ +bool XMP_Sub(uint16_t* result, + size_t result_offset, + const uint16_t* left_number, + size_t left_number_offset, + const digit* right_number, + bool borrow, + int precision) +{ + bool ret; + +#ifdef __BIG_ENDIAN__ + uint16_t temp_left_number[precision * 2]; + uint16_t temp_result[precision * 2]; + size_t i; + + for (i = 0; i < precision * 2; i++) { + Set_HalfWord(temp_left_number, i, Get_HalfWord(left_number, left_number_offset + i)); + } + + ret = XMP_Sub((digit*)temp_result, (const digit*)temp_left_number, right_number, borrow, precision); + + for (i = 0; i < precision * 2; i++) { + Set_HalfWord(result, result_offset + i, Get_HalfWord(temp_result, i)); + } +#else + ret = XMP_Sub((digit*)(result + result_offset), + (const digit*)(left_number + left_number_offset), + right_number, + borrow, + precision); +#endif + + return ret; +} + bool XMP_Sub(digit* result, const digit* left_number, const digit* right_number, bool borrow, int precision) { const uint16_t* left_number_ptr = (const uint16_t*)left_number; + size_t left_number_offset = 0; const uint16_t* right_number_ptr = (const uint16_t*)right_number; + size_t right_number_offset = 0; uint16_t* result_ptr = (uint16_t*)result; + size_t result_offset = 0; precision *= 2; while (precision--) { - digit x = (digit)*left_number_ptr - (digit)*right_number_ptr - (digit)borrow; - right_number_ptr++; - left_number_ptr++; - *result_ptr++ = (uint16_t)x; + digit x = (digit)Get_HalfWord(left_number_ptr, left_number_offset) + - (digit)Get_HalfWord(right_number_ptr, right_number_offset) - (digit)borrow; + right_number_offset++; + left_number_offset++; + Set_HalfWord(result_ptr, result_offset, x); + result_offset++; borrow = (((1L << 16) & x) != 0L); } return (borrow); @@ -1748,18 +1837,23 @@ void XMP_Decode_ASCII(char const* str, digit* mpn, int precision) * HISTORY: * * 07/02/1996 JLB : Created. * *=============================================================================================*/ -void XMP_Hybrid_Mul(uint16_t* prod, uint16_t* multiplicand, uint16_t multiplier, int precision) +void XMP_Hybrid_Mul(uint16_t* prod, + size_t prod_offset, + uint16_t* multiplicand, + size_t multiplicand_offset, + uint16_t multiplier, + int precision) { uint32_t carry = 0; for (int i = 0; i < precision; ++i) { - uint32_t p = (uint32_t)multiplier * *multiplicand++; - p += *prod + carry; - *prod++ = (uint16_t)p; + uint32_t p = (uint32_t)multiplier * Get_HalfWord(multiplicand, multiplicand_offset++); + p += Get_HalfWord(prod, prod_offset) + carry; + Set_HalfWord(prod, prod_offset++, (uint16_t)p); carry = p >> 16; } /* Add carry to the next higher word of product / dividend */ - *prod += (uint16_t)carry; + Set_HalfWord(prod, prod_offset, Get_HalfWord(prod, prod_offset) + (uint16_t)carry); } /*********************************************************************************************** @@ -1791,12 +1885,17 @@ void XMP_Double_Mul(digit* prod, const digit* multiplicand, const digit* multipl */ XMP_Init(prod, 0, precision * 2); - const uint16_t* multiplier_ptr = (const uint16_t*)multiplier; - uint16_t* product_ptr = (uint16_t*)prod; + size_t multiplier_offset = 0; + size_t product_offset = 0; // Multiply multiplicand by each word in multiplier, accumulating prod. for (int i = 0; i < precision * 2; ++i) { - XMP_Hybrid_Mul(product_ptr++, (uint16_t*)multiplicand, *multiplier_ptr++, precision * 2); + XMP_Hybrid_Mul((uint16_t*)prod, + product_offset++, + (uint16_t*)multiplicand, + 0, + Get_HalfWord((const uint16_t*)multiplier, multiplier_offset++), + precision * 2); } } @@ -1867,8 +1966,8 @@ int XMP_Prepare_Modulus(const digit* n_modulus, int precision) _modulus_shift--; /* now 0 <= _modulus_shift <= 16 */ } uint16_t* mpm = (uint16_t*)_mod_quotient; - _reciprical_low_digit = *mpm++; - _reciprical_high_digit = *mpm; + _reciprical_low_digit = Get_HalfWord(mpm, 0); + _reciprical_high_digit = Get_HalfWord(mpm, 1); return 0; } @@ -1928,9 +2027,10 @@ int XMP_Mod_Mult(digit* prod, const digit* multiplicand, const digit* multiplier int nqd = dmi + 1 - _modulus_sub_precision; // number of quotient digits remaining to be generated /* Set msb, lsb, and normal ptrs of dividend */ - uint16_t* dmph = - ((uint16_t*)_double_staging_number) + dmi + 1; // points to one higher than precision would indicate - uint16_t* dmpl = dmph - _modulus_sub_precision; + size_t dmph_offset = dmi + 1; + uint16_t* dmph = (uint16_t*)_double_staging_number; + size_t dmpl_offset = dmph_offset - _modulus_sub_precision; + uint16_t* dmpl = dmph; /* ** Divide loop. @@ -1942,20 +2042,19 @@ int XMP_Mod_Mult(digit* prod, const digit* multiplicand, const digit* multiplier ** modulus to get the proper negative remainder. */ for (; nqd; nqd--) { - --dmph; - --dmpl; + --dmph_offset; + --dmpl_offset; - uint16_t q = mp_quo_digit(dmph); // trial quotient digit + uint16_t q = mp_quo_digit(dmph, dmph_offset); // trial quotient digit if (q > 0) { - XMP_Hybrid_Mul(dmpl, (uint16_t*)_scratch_modulus, q, precision * 2); + XMP_Hybrid_Mul(dmpl, dmpl_offset, (uint16_t*)_scratch_modulus, 0, q, precision * 2); /* Perform correction if q too large. ** This rarely occurs. */ - if (!(*dmph & SEMI_UPPER_MOST_BIT)) { - uint16_t* dmp = dmpl; - if (XMP_Sub((uint32_t*)dmp, (uint32_t*)dmp, _scratch_modulus, false, precision)) { - (*dmph)--; + if (!(Get_HalfWord(dmph, dmph_offset) & SEMI_UPPER_MOST_BIT)) { + if (XMP_Sub(dmpl, dmpl_offset, dmpl, dmpl_offset, _scratch_modulus, false, precision)) { + Set_HalfWord(dmph, dmph_offset, Get_HalfWord(dmph, dmph_offset) - 1); } } } @@ -2024,7 +2123,7 @@ void XMP_Mod_Mult_Clear(int precision) ** three MULTUNITs at dividend by the upper two MULTUNITs of the ** modulus. */ -uint16_t mp_quo_digit(uint16_t* dividend) +uint16_t mp_quo_digit(uint16_t* dividend, size_t dividend_offset) { uint32_t q, q0, q1, q2; @@ -2033,17 +2132,19 @@ uint16_t mp_quo_digit(uint16_t* dividend) * The last terms of q1 and q2 perform upward rounding, which is * needed to guarantee that the result not be too small. */ - q1 = (dividend[-2] ^ SEMI_MASK) * (uint32_t)_reciprical_high_digit + _reciprical_high_digit; - q2 = (dividend[-1] ^ SEMI_MASK) * (uint32_t)_reciprical_low_digit + (1L << 16); + q1 = (Get_HalfWord(dividend, dividend_offset - 2) ^ SEMI_MASK) * (uint32_t)_reciprical_high_digit + + _reciprical_high_digit; + q2 = (Get_HalfWord(dividend, dividend_offset - 1) ^ SEMI_MASK) * (uint32_t)_reciprical_low_digit + (1L << 16); q0 = (q1 >> 1) + (q2 >> 1) + 1; /* Compute the middle significant product group. */ - q1 = (dividend[-1] ^ SEMI_MASK) * (uint32_t)_reciprical_high_digit; - q2 = (dividend[0] ^ SEMI_MASK) * (uint32_t)_reciprical_low_digit; + q1 = (Get_HalfWord(dividend, dividend_offset - 1) ^ SEMI_MASK) * (uint32_t)_reciprical_high_digit; + q2 = (Get_HalfWord(dividend, dividend_offset) ^ SEMI_MASK) * (uint32_t)_reciprical_low_digit; q = (q0 >> 16) + (q1 >> 1) + (q2 >> 1) + 1; /* Compute the most significant term and add in the others */ - q = (q >> (16 - 2)) + (((dividend[0] ^ SEMI_MASK) * (uint32_t)_reciprical_high_digit) << 1); + q = (q >> (16 - 2)) + + (((Get_HalfWord(dividend, dividend_offset) ^ SEMI_MASK) * (uint32_t)_reciprical_high_digit) << 1); q >>= _modulus_shift; /* Prevent overflow and then wipe out the intermediate results. */ diff --git a/common/mp.h b/common/mp.h index 20eb1b91..64fd07c9 100644 --- a/common/mp.h +++ b/common/mp.h @@ -84,7 +84,7 @@ void XMP_Double_Mul(digit* prod, const digit* multiplicand, const digit* multipl int xmp_stage_modulus(const digit* n_modulus, int precision); int XMP_Mod_Mult(digit* prod, const digit* multiplicand, const digit* multiplier, int precision); void XMP_Mod_Mult_Clear(int precision); -uint16_t mp_quo_digit(uint16_t* dividend); +uint16_t mp_quo_digit(uint16_t* dividend, size_t dividend_offset); int xmp_exponent_mod(digit* expout, const digit* expin, const digit* exponent_ptr, const digit* modulus, int precision); bool XMP_Is_Small_Prime(const digit* candidate, int precision); bool XMP_Small_Divisors_Test(const digit* candidate, int precision); From 4c9c50c9fb8f1479c6aad252f67307b5e670f6cc Mon Sep 17 00:00:00 2001 From: OmniBlade Date: Sat, 8 Jan 2022 23:53:39 +0000 Subject: [PATCH 09/27] [RA] Fixes engineer capture in partial alliance. Fixes issue where if a player2 was allied with player1, but not vice versa, player1 would not be able to capture player2 buildings. Enables existing WW patch for the issue. --- redalert/defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redalert/defines.h b/redalert/defines.h index 129687a2..22b218bf 100644 --- a/redalert/defines.h +++ b/redalert/defines.h @@ -102,7 +102,7 @@ //#define FIXIT_FAST_LOAD // Enables faster INI loading // These fixes will cause the game to go out of sync. -//#define FIXIT_ENGINEER_CAPTURE // If building not allied, will still capture if engineer not allied with building. +#define FIXIT_ENGINEER_CAPTURE // If building allied, will still capture if engineer not allied with building. //#define FIXIT_HELI_LANDING // Fixes so new helicopters land at free helipad //#define FIXIT_MINE_PASSABLE // Fixes units not driving onto mines From e57652a54782258e7ab6ce19ccdc9e40187beeda Mon Sep 17 00:00:00 2001 From: ChthonVII Date: Thu, 3 Feb 2022 22:14:04 +0900 Subject: [PATCH 10/27] bugfix not being able to get another reveal create after getting a reveal crate followed by a darkness crate. --- redalert/cell.cpp | 1 + tiberiandawn/cell.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/redalert/cell.cpp b/redalert/cell.cpp index 9240c978..744ace5f 100644 --- a/redalert/cell.cpp +++ b/redalert/cell.cpp @@ -2477,6 +2477,7 @@ bool CellClass::Goodie_Check(FootClass* object) if (object->House->IsHuman) { Map.Shroud_The_Map(object->House); } + object->House->IsVisionary = false; break; /* diff --git a/tiberiandawn/cell.cpp b/tiberiandawn/cell.cpp index dd0ecf76..c7ad7f49 100644 --- a/tiberiandawn/cell.cpp +++ b/tiberiandawn/cell.cpp @@ -2170,6 +2170,7 @@ bool CellClass::Goodie_Check(FootClass* object, bool check_steel) } Map.Flag_To_Redraw(true); } + object->House->IsVisionary = false; break; } /* From ffd40774f7bd2b751833cfde10670f1f82b4e18f Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 14 Mar 2024 15:28:10 +0100 Subject: [PATCH 11/27] Remove unneeded include of --- common/paths_posix.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/common/paths_posix.cpp b/common/paths_posix.cpp index f45d187d..030fee12 100644 --- a/common/paths_posix.cpp +++ b/common/paths_posix.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include From 61196b3c6011a37694ea583ff42599f2bb7720e2 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 14 Mar 2024 14:43:36 +0100 Subject: [PATCH 12/27] Fix compilation of the editors when using SDL1 SHIFT-HOME and HOME have the same values for SDL1; use CTRL-HOME instead --- redalert/mapedit.cpp | 4 ++++ tiberiandawn/mapedit.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/redalert/mapedit.cpp b/redalert/mapedit.cpp index 4a12e09e..59fa8d92 100644 --- a/redalert/mapedit.cpp +++ b/redalert/mapedit.cpp @@ -772,10 +772,14 @@ void MapEditClass::AI(KeyNumType& input, int x, int y) input = KN_NONE; break; +#if (KN_HOME | KN_SHIFT_BIT) != KN_HOME /* ** SHIFT-HOME: set new Home Cell position */ case ((int)KN_HOME | (int)KN_SHIFT_BIT): +#else + case ((int)KN_HOME | (int)KN_CTRL_BIT): +#endif if (CurrentCell != 0) { /* diff --git a/tiberiandawn/mapedit.cpp b/tiberiandawn/mapedit.cpp index a46334fa..04708fb3 100644 --- a/tiberiandawn/mapedit.cpp +++ b/tiberiandawn/mapedit.cpp @@ -858,10 +858,14 @@ void MapEditClass::AI(KeyNumType& input, int x, int y) input = KN_NONE; break; +#if (KN_HOME | KN_SHIFT_BIT) != KN_HOME /*--------------------------------------------------------------------- SHIFT-HOME: set new Home Cell position ---------------------------------------------------------------------*/ case ((int)KN_HOME | (int)KN_SHIFT_BIT): +#else + case ((int)KN_HOME | (int)KN_CTRL_BIT): +#endif /* ** Unflag the old Home Cell, if there are no other waypoints ** pointing to it From 18eea91a81c01811cab2c5549253133b068208ef Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Wed, 20 Mar 2024 09:43:44 +0100 Subject: [PATCH 13/27] Fix a wrong extern definition --- common/alloc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/alloc.cpp b/common/alloc.cpp index 3338d910..ee6de9ea 100644 --- a/common/alloc.cpp +++ b/common/alloc.cpp @@ -56,7 +56,7 @@ static size_t TotalRam = 0; static unsigned int Memory_Calls = 0; void (*Memory_Error)(void) = NULL; -extern void (*Memory_Error_Exit)(char* string) = NULL; +void (*Memory_Error_Exit)(char* string) = NULL; /*************************************************************************** * Alloc -- Allocates system RAM. * From d0fb60f5d45a9c4de8b70cd4b738592c1757425a Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Wed, 20 Mar 2024 13:17:59 +0100 Subject: [PATCH 14/27] Include in files that need it Without this, operations on fixed values are miscompiled on big-endian machines --- common/fixed.h | 1 + tiberiandawn/defines.h | 1 + 2 files changed, 2 insertions(+) diff --git a/common/fixed.h b/common/fixed.h index e79a99db..b8da0b45 100644 --- a/common/fixed.h +++ b/common/fixed.h @@ -36,6 +36,7 @@ #define FIXED_H #include +#include "endianness.h" /* ** This is a very simple fixed point class that functions like a regular integral type. However diff --git a/tiberiandawn/defines.h b/tiberiandawn/defines.h index f69fc694..82ff91d8 100644 --- a/tiberiandawn/defines.h +++ b/tiberiandawn/defines.h @@ -35,6 +35,7 @@ #define DEFINES_H #include "common/bitfields.h" +#include "common/endianness.h" /********************************************************************** ** If defined, then the advanced balancing features will be enabled From d5d959a938f4740fa4083897e219e4a8aa26bbb6 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Wed, 20 Mar 2024 13:23:15 +0100 Subject: [PATCH 15/27] Fix a printf format TriggerClass::Write_INI "Data" is a int, not a long int --- tiberiandawn/trigger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tiberiandawn/trigger.cpp b/tiberiandawn/trigger.cpp index 7fabbac2..477634bd 100644 --- a/tiberiandawn/trigger.cpp +++ b/tiberiandawn/trigger.cpp @@ -1192,7 +1192,7 @@ void TriggerClass::Write_INI(CCINIClass& ini, bool refresh) } sprintf(buf, - "%s,%s,%ld,%s,%s,%d", + "%s,%s,%d,%s,%s,%d", TriggerClass::Name_From_Event(trigger->Event), TriggerClass::Name_From_Action(trigger->Action), trigger->Data, From 1279a0141bc25905ad693491838ac6c3dab12fa4 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Wed, 20 Mar 2024 10:20:14 +0100 Subject: [PATCH 16/27] Avoid undefined behaviour when deleting a void * --- common/bfiofile.cpp | 2 +- common/mixfile.h | 6 +++--- redalert/event.cpp | 2 +- redalert/init.cpp | 4 ++-- redalert/msgbox.cpp | 2 +- redalert/queue.cpp | 6 +++--- redalert/stats.cpp | 2 +- tiberiandawn/ending.cpp | 4 ++-- tiberiandawn/init.cpp | 4 ++-- tiberiandawn/msgbox.cpp | 2 +- tiberiandawn/stats.cpp | 2 +- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/common/bfiofile.cpp b/common/bfiofile.cpp index ff688985..8b80ec73 100644 --- a/common/bfiofile.cpp +++ b/common/bfiofile.cpp @@ -320,7 +320,7 @@ void BufferIOFileClass::Free(void) { if (Buffer) { if (IsAllocated) { - delete[] Buffer; + delete[] static_cast(Buffer); IsAllocated = false; } diff --git a/common/mixfile.h b/common/mixfile.h index 61d8ccc8..3a4f3604 100644 --- a/common/mixfile.h +++ b/common/mixfile.h @@ -653,7 +653,7 @@ template bool MixFileClass::Cache(Buffer const* b */ int actual = straw->Get(Data, DataSize); if (actual != DataSize) { - delete[] Data; + delete[] static_cast(Data); Data = NULL; file.Error(EIO); return (false); @@ -670,7 +670,7 @@ template bool MixFileClass::Cache(Buffer const* b sha.Result(digest2); fstraw.Get(digest1, sizeof(digest1)); if (memcmp(digest1, digest2, sizeof(digest1)) != 0) { - delete[] Data; + delete[] static_cast(Data); Data = NULL; return (false); } @@ -702,7 +702,7 @@ template bool MixFileClass::Cache(Buffer const* b template void MixFileClass::Free(void) { if (Data != NULL && IsAllocated) { - delete[] Data; + delete[] static_cast(Data); } Data = NULL; IsAllocated = false; diff --git a/redalert/event.cpp b/redalert/event.cpp index 30139439..ab298b04 100644 --- a/redalert/event.cpp +++ b/redalert/event.cpp @@ -901,7 +901,7 @@ void EventClass::Execute(void) printf("%d\n", ((char*)Data.Variable.Pointer)[i]); } if (ID != PlayerPtr->ID) { - delete[] Data.Variable.Pointer; + delete[] static_cast(Data.Variable.Pointer); } break; diff --git a/redalert/init.cpp b/redalert/init.cpp index 0650af75..558360c0 100644 --- a/redalert/init.cpp +++ b/redalert/init.cpp @@ -2910,7 +2910,7 @@ void Free_Heaps(void) */ for (int index = 0; index < ARRAY_SIZE(SpeechBuffer); index++) { if (SpeechBuffer[index]) { - delete[] SpeechBuffer[index]; + delete[] static_cast(SpeechBuffer[index]); SpeechBuffer[index] = NULL; } } @@ -2928,4 +2928,4 @@ void Free_Heaps(void) delete InterpolationTable; InterpolationTable = NULL; } -} \ No newline at end of file +} diff --git a/redalert/msgbox.cpp b/redalert/msgbox.cpp index 64b811f6..98fa248b 100644 --- a/redalert/msgbox.cpp +++ b/redalert/msgbox.cpp @@ -442,7 +442,7 @@ int WWMessageBox::Process(const char* msg, const char* b1txt, const char* b2txt, } SeenBuff.Unlock(); - delete[] back; + delete[] static_cast(back); back = NULL; Show_Mouse(); } diff --git a/redalert/queue.cpp b/redalert/queue.cpp index 5db08d27..ed429d87 100644 --- a/redalert/queue.cpp +++ b/redalert/queue.cpp @@ -2870,7 +2870,7 @@ static int Extract_Uncompressed_Events(void* buf, int bufsize) if (!DoList.Add(*event)) { if (event->Type == EventClass::ADDPLAYER) { - delete[] event->Data.Variable.Pointer; + delete[] static_cast(event->Data.Variable.Pointer); } return (-1); } @@ -3035,7 +3035,7 @@ static int Extract_Compressed_Events(void* buf, int bufsize) if (!DoList.Add(eventdata)) { if (eventdata.Type == EventClass::ADDPLAYER) { - delete[] eventdata.Data.Variable.Pointer; + delete[] static_cast(eventdata.Data.Variable.Pointer); } return (-1); } @@ -4399,4 +4399,4 @@ void Check_Mirror(void) #endif } // end of Check_Mirror -/*************************** end of queue.cpp ******************************/ \ No newline at end of file +/*************************** end of queue.cpp ******************************/ diff --git a/redalert/stats.cpp b/redalert/stats.cpp index b90ec5d4..f1fef53a 100644 --- a/redalert/stats.cpp +++ b/redalert/stats.cpp @@ -829,7 +829,7 @@ void Send_Statistics_Packet(void) /* ** Tidy up */ - delete[] packet; + delete[] static_cast(packet); GameStatisticsPacketSent = true; #endif // INTERNET_OFF diff --git a/tiberiandawn/ending.cpp b/tiberiandawn/ending.cpp index a907c153..8c7a0367 100644 --- a/tiberiandawn/ending.cpp +++ b/tiberiandawn/ending.cpp @@ -246,8 +246,8 @@ void Nod_Ending(void) Play_Movie("CC2TEASE"); - delete[] localpal; + delete[] static_cast(localpal); delete TextPrintBuffer; BlitList.Clear(); } -#endif \ No newline at end of file +#endif diff --git a/tiberiandawn/init.cpp b/tiberiandawn/init.cpp index e1cced9f..ce2a979f 100644 --- a/tiberiandawn/init.cpp +++ b/tiberiandawn/init.cpp @@ -635,7 +635,7 @@ void Uninit_Game(void) { Map.Free_Cells(); - delete[] SpeechBuffer; + delete[] static_cast(SpeechBuffer); CCFileClass::Clear_Search_Drives(); MFCD::Free_All(); @@ -2075,7 +2075,7 @@ void Parse_INI_File(void) Fetch working pointer to the INI staging buffer. Make sure that the buffer is cleared out before proceeding. ------------------------------------------------------------------------*/ - buffer = (char*)_ShapeBuffer; + buffer = _ShapeBuffer; memset(buffer, '\0', _ShapeBufferSize); /*------------------------------------------------------------------------ diff --git a/tiberiandawn/msgbox.cpp b/tiberiandawn/msgbox.cpp index 4f7ff2dc..fb74f871 100644 --- a/tiberiandawn/msgbox.cpp +++ b/tiberiandawn/msgbox.cpp @@ -447,7 +447,7 @@ int WWMessageBox::Process(const char* msg, const char* b1txt, const char* b2txt, } SeenBuff.Unlock(); - delete[] back; + delete[] static_cast(back); back = NULL; Show_Mouse(); } diff --git a/tiberiandawn/stats.cpp b/tiberiandawn/stats.cpp index 53f0f69e..57c04823 100644 --- a/tiberiandawn/stats.cpp +++ b/tiberiandawn/stats.cpp @@ -593,7 +593,7 @@ void Send_Statistics_Packet(void) ** Tidy up */ CCDebugString("C&C95 - About to delete packet memory.\n"); - delete[] packet; + delete[] static_cast(packet); GameStatisticsPacketSent = true; CCDebugString("C&C95 - Returning from Send_Statistics_Packet.\n"); From 77e2da04a83dc8c1afa1dc92dd48239375c2179e Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 14 Mar 2024 14:40:17 +0100 Subject: [PATCH 17/27] Fix compliation of some test programs They refer to stderr etc. but fail to include --- tests/face.cpp | 1 + tests/fading.cpp | 1 + tests/lcw.cpp | 1 + tests/rect.cpp | 1 + tests/xordelta.cpp | 1 + 5 files changed, 5 insertions(+) diff --git a/tests/face.cpp b/tests/face.cpp index 1b723d7c..9da4e6d2 100644 --- a/tests/face.cpp +++ b/tests/face.cpp @@ -1,5 +1,6 @@ #include "common/face.h" +#include #include #include diff --git a/tests/fading.cpp b/tests/fading.cpp index e47035bc..bb46d45e 100644 --- a/tests/fading.cpp +++ b/tests/fading.cpp @@ -1,5 +1,6 @@ #include "common/fading.h" +#include #include #include #include diff --git a/tests/lcw.cpp b/tests/lcw.cpp index 410db3d0..e5cb7e22 100644 --- a/tests/lcw.cpp +++ b/tests/lcw.cpp @@ -1,5 +1,6 @@ #include "common/lcw.h" +#include #include #include #include diff --git a/tests/rect.cpp b/tests/rect.cpp index fc91a73b..349644b1 100644 --- a/tests/rect.cpp +++ b/tests/rect.cpp @@ -1,5 +1,6 @@ #include "common/rect.h" +#include #include #include diff --git a/tests/xordelta.cpp b/tests/xordelta.cpp index 2e961d9a..a3af9f75 100644 --- a/tests/xordelta.cpp +++ b/tests/xordelta.cpp @@ -1,5 +1,6 @@ #include "common/xordelta.h" +#include #include #include #include From 4ed8f34bd1fa9e3a9e2720b44079f6fb26b3b669 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Sat, 23 Mar 2024 15:18:39 +0100 Subject: [PATCH 18/27] Include also in base64 Without this, base64 decoder (used to encode/decrypt the PKeys) does not work, resulting in division by zero --- common/base64.cpp | 3 ++- common/mp.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/common/base64.cpp b/common/base64.cpp index e14f1e84..66947822 100644 --- a/common/base64.cpp +++ b/common/base64.cpp @@ -36,6 +36,7 @@ #include "base64.h" #include +#include "endianness.h" /* ** This is the magic padding character used to fill out the encoded data to a multiple of @@ -425,4 +426,4 @@ implementations. within base64-encoded parts of multipart entities because no hyphen characters are used in the base64 encoding. -*/ \ No newline at end of file +*/ diff --git a/common/mp.cpp b/common/mp.cpp index fdeef76a..e064cb23 100644 --- a/common/mp.cpp +++ b/common/mp.cpp @@ -265,6 +265,8 @@ void XMP_DER_Decode(digit* result, unsigned char const* input, int precision) } } +#ifndef __BIG_ENDIAN__ +// FIXME: does not for work big-endian /*********************************************************************************************** * XMP_Encode -- Encode MP number into buffer. * * * @@ -308,6 +310,7 @@ unsigned XMP_Encode(unsigned char* to, unsigned tobytes, digit const* from, int return (tobytes); } +#endif /*********************************************************************************************** * XMP_Encode -- Encode MP number into buffer as compactly as possible. * @@ -358,7 +361,8 @@ unsigned XMP_Encode(unsigned char* to, digit const* from, int precision) unsigned char* number_ptr; unsigned char* const end = (unsigned char*)from; - for (number_ptr = (unsigned char*)end + precision - 1; number_ptr > (unsigned char*)end; number_ptr--) { + for (number_ptr = (unsigned char*)end + precision * sizeof(digit) - 1; number_ptr > (unsigned char*)end; + number_ptr--) { if (*number_ptr != filler) break; } @@ -922,6 +926,8 @@ unsigned XMP_Count_Bits(const digit* number, int precision) return (total_bit_count); } +#ifndef __BIG_ENDIAN__ +// FIXME: does not work for big-endian /*********************************************************************************************** * XMP_Count_Bytes -- Counts the number of precision bytes in MP number. * * * @@ -951,6 +957,7 @@ int XMP_Count_Bytes(const digit* number, int precision) } return (count); } +#endif /*********************************************************************************************** * XMP_Move -- Assign one MP number to another. * From 0d6fee7b431746640b7c08b8db663e3730e1be29 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 14 Mar 2024 14:38:40 +0100 Subject: [PATCH 19/27] Make OPENAL optional also on non-windows platforms There are some system where OPENAL is not available --- CMakeLists.txt | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77ae270d..3ce8dad3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,19 +33,9 @@ if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Windows") option(WIN9X "Enable support for Windows 95/98/ME." OFF) option(DSOUND "Enable DirectSound audio. (deprecated)" OFF) option(DDRAW "Enable DirectDraw video backend. (deprecated)" OFF) - option(SDL1 "Enable SDL1 video backend." OFF) - option(SDL2 "Enable SDL2 video backend." ON) - option(OPENAL "Enable OpenAL audio backend." ON) add_feature_info(Windows9x WIN9X "Windows 95/98/ME support" OFF) add_feature_info(DirectSound DSOUND "DirectSound audio backend (deprecated)") add_feature_info(DirectDraw DDRAW "DirectDraw video backend (deprecated)") - add_feature_info(SDL1 SDL1 "SDL1 video backend") - add_feature_info(SDL2 SDL2 "SDL2 video backend") - add_feature_info(OpenAL OPENAL "OpenAL audio backend") -else() - add_feature_info(SDL1 SDL1 "SDL1 video backend") - add_feature_info(SDL2 SDL2 "SDL2 video backend") - set(OPENAL TRUE) endif() if(APPLE OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") @@ -56,6 +46,9 @@ if(APPLE OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif() endif() +add_feature_info(SDL1 SDL1 "SDL1 video backend") +add_feature_info(SDL2 SDL2 "SDL2 video backend") +add_feature_info(OpenAL OPENAL "OpenAL audio backend") add_feature_info(RemasterTD BUILD_REMASTERTD, "Remastered Tiberian Dawn dll") add_feature_info(RemasterRA BUILD_REMASTERRA "Remastered Red Alert dll") add_feature_info(VanillaTD BUILD_VANILLATD "Tiberian Dawn executable") From dcfe358efacb19329272f0f41264671c6ce35cb5 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 21 Mar 2024 13:56:38 +0100 Subject: [PATCH 20/27] Avoid operator ++ on bool --- common/vqatask.cpp | 2 +- redalert/ending.cpp | 2 +- tiberiandawn/ending.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/vqatask.cpp b/common/vqatask.cpp index 390558fc..28f9dc50 100644 --- a/common/vqatask.cpp +++ b/common/vqatask.cpp @@ -117,7 +117,7 @@ VQAErrorType VQA_Play(VQAHandle* handle, VQAPlayMode mode) } if (data->Flags & VQA_DATA_FLAG_VIDEO_MEMORY_SET) { - ++VQAMovieDone; + VQAMovieDone = true; } else { rc = (VQAErrorType)VQA_LoadFrame(handle); diff --git a/redalert/ending.cpp b/redalert/ending.cpp index a0f778d1..08768bcb 100644 --- a/redalert/ending.cpp +++ b/redalert/ending.cpp @@ -105,7 +105,7 @@ void Nod_Ending(void) bool printedtext = false; while (!done) { if (!printedtext && !Is_Sample_Playing(kanefinl)) { - printedtext++; + printedtext = true; Alloc_Object(new ScorePrintClass(Text_String(TXT_SEL_TARGET), 0, 180, _tanpal)); mouseshown = true; Show_Mouse(); diff --git a/tiberiandawn/ending.cpp b/tiberiandawn/ending.cpp index 8c7a0367..f622399f 100644 --- a/tiberiandawn/ending.cpp +++ b/tiberiandawn/ending.cpp @@ -159,7 +159,7 @@ void Nod_Ending(void) bool printedtext = false; while (!done) { if (!printedtext && !Is_Sample_Playing(kanefinl)) { - printedtext++; + printedtext = true; Alloc_Object(new ScorePrintClass(Text_String(TXT_SEL_TARGET), 0, 180, _tanpal)); mouseshown = true; Show_Mouse(); @@ -177,7 +177,7 @@ void Nod_Ending(void) int mousex = Keyboard->MouseQX; int mousey = Keyboard->MouseQY; if (mousey >= 22 * factor && mousey <= 177 * factor) { - done++; + done = true; if (mousex < 160 * factor && mousey < 100 * factor) selection = 2; if (mousex < 160 * factor && mousey >= 100 * factor) From b2038569d3d1ff4ac17ad20b45a746095db08830 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Wed, 20 Mar 2024 10:28:35 +0100 Subject: [PATCH 21/27] Avoid redefinition of __USE_POSIX199309/_POSIX_C_SOURCE On glibc systems, they are already defined in which is pulled in by any system header. Defining such macros in header files is too late. --- common/mssleep.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/mssleep.h b/common/mssleep.h index 9f7c8a66..eb1f8ebc 100644 --- a/common/mssleep.h +++ b/common/mssleep.h @@ -11,8 +11,12 @@ #elif defined(_WIN32) #include #else /* Assuming recent posix*/ -#define __USE_POSIX199309 +#ifndef __USE_POSIX199309 +#define __USE_POSIX199309 1 +#endif +#ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199309L +#endif #include #endif From 4f4e5066a01a0bab631490994d5606d932bb3d7d Mon Sep 17 00:00:00 2001 From: Walter Barrett Date: Wed, 27 Mar 2024 09:13:37 -0400 Subject: [PATCH 22/27] Implement Texture_Fill_Rect --- common/graphicsviewport.cpp | 12 ++++++++++++ common/graphicsviewport.h | 15 +-------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/common/graphicsviewport.cpp b/common/graphicsviewport.cpp index 987affe8..063a721f 100644 --- a/common/graphicsviewport.cpp +++ b/common/graphicsviewport.cpp @@ -980,3 +980,15 @@ void GraphicViewPortClass::Draw_Rect(int x1_pixel, int y1_pixel, int x2_pixel, i Draw_Line(x2_pixel, y1_pixel, x2_pixel, y2_pixel, color); Unlock(); } + +void GraphicViewPortClass::Texture_Fill_Rect(int xpos, int ypos, int width, int height, unsigned char* shape_pointer, int source_width, int source_height) +{ + if (Lock()) { + for (int y = ypos; y < ypos + height; y++) { + for (int x = xpos; x < xpos + width; x++) { + LogicPage->Put_Pixel(x, y, *(shape_pointer + ((y % source_height) * source_width) + (x % source_width))); + } + } + Unlock(); + } +} diff --git a/common/graphicsviewport.h b/common/graphicsviewport.h index 7a310a42..5ccb878d 100644 --- a/common/graphicsviewport.h +++ b/common/graphicsviewport.h @@ -289,20 +289,7 @@ class GraphicViewPortClass void Remap(int sx, int sy, int width, int height, void* remap); void Remap(void* remap); void Draw_Stamp(void const* icondata, int icon, int x_pixel, int y_pixel, void const* remap, int clip_window); - - // PG_TO_FIX - // This seems to be missing. Might not be needed anyway since it looks like it's only used for UI drawing. ST - - // 12/17/2018 6:11PM - void Texture_Fill_Rect(int xpos, - int ypos, - int width, - int height, - void const* shape_pointer, - int source_width, - int source_height) - { - return; - } + void Texture_Fill_Rect(int xpos, int ypos, int width, int height, unsigned char* shape_pointer, int source_width, int source_height); // This doesnt seem to exist anywhere?? - Steve T 9/26/95 6:05PM // VOID Grey_Out_Region(int x, int y, int width, int height, int color); From 20387694fd9cc6707df40d022db75fb87c1ba4cd Mon Sep 17 00:00:00 2001 From: Walter Barrett Date: Wed, 27 Mar 2024 09:16:02 -0400 Subject: [PATCH 23/27] TD: Selectable button style --- common/graphicsviewport.cpp | 11 +++++++-- common/graphicsviewport.h | 8 ++++++- common/settings.cpp | 15 ++++++++++++ common/settings.h | 1 + tiberiandawn/dialog.cpp | 47 ++++++++++++++++++++++++------------- 5 files changed, 63 insertions(+), 19 deletions(-) diff --git a/common/graphicsviewport.cpp b/common/graphicsviewport.cpp index 063a721f..bcdc7b8b 100644 --- a/common/graphicsviewport.cpp +++ b/common/graphicsviewport.cpp @@ -981,12 +981,19 @@ void GraphicViewPortClass::Draw_Rect(int x1_pixel, int y1_pixel, int x2_pixel, i Unlock(); } -void GraphicViewPortClass::Texture_Fill_Rect(int xpos, int ypos, int width, int height, unsigned char* shape_pointer, int source_width, int source_height) +void GraphicViewPortClass::Texture_Fill_Rect(int xpos, + int ypos, + int width, + int height, + unsigned char* shape_pointer, + int source_width, + int source_height) { if (Lock()) { for (int y = ypos; y < ypos + height; y++) { for (int x = xpos; x < xpos + width; x++) { - LogicPage->Put_Pixel(x, y, *(shape_pointer + ((y % source_height) * source_width) + (x % source_width))); + LogicPage->Put_Pixel( + x, y, *(shape_pointer + ((y % source_height) * source_width) + (x % source_width))); } } Unlock(); diff --git a/common/graphicsviewport.h b/common/graphicsviewport.h index 5ccb878d..26c62b01 100644 --- a/common/graphicsviewport.h +++ b/common/graphicsviewport.h @@ -289,7 +289,13 @@ class GraphicViewPortClass void Remap(int sx, int sy, int width, int height, void* remap); void Remap(void* remap); void Draw_Stamp(void const* icondata, int icon, int x_pixel, int y_pixel, void const* remap, int clip_window); - void Texture_Fill_Rect(int xpos, int ypos, int width, int height, unsigned char* shape_pointer, int source_width, int source_height); + void Texture_Fill_Rect(int xpos, + int ypos, + int width, + int height, + unsigned char* shape_pointer, + int source_width, + int source_height); // This doesnt seem to exist anywhere?? - Steve T 9/26/95 6:05PM // VOID Grey_Out_Region(int x, int y, int width, int height, int color); diff --git a/common/settings.cpp b/common/settings.cpp index bff02b6d..3b14cfcc 100644 --- a/common/settings.cpp +++ b/common/settings.cpp @@ -1,3 +1,4 @@ +#include "wwstd.h" #include "settings.h" #include "ini.h" #include "miscasm.h" @@ -36,6 +37,8 @@ SettingsClass::SettingsClass() void SettingsClass::Load(INIClass& ini) { + char buf[128]; + /* ** Mouse settings */ @@ -77,6 +80,15 @@ void SettingsClass::Load(INIClass& ini) if (Video.Boxing || Mouse.RawInput || Mouse.ControllerEnabled) { Video.HardwareCursor = false; } + + ini.Get_String("Video", "ButtonStyle", "Default", buf, sizeof(buf)); + if (!stricmp(buf, "Gold")) { + Video.ButtonStyle = 1; + } else if (!stricmp(buf, "Classic") || !stricmp(buf, "DOS")) { + Video.ButtonStyle = 0; + } else { + Video.ButtonStyle = -1; + } } void SettingsClass::Save(INIClass& ini) @@ -111,4 +123,7 @@ void SettingsClass::Save(INIClass& ini) ** VQA and WSA interpolation mode 0 = scanlines, 1 = vertical doubling, 2 = linear */ ini.Put_Int("Video", "InterpolationMode", Video.InterpolationMode); + + ini.Put_String( + "Video", "ButtonStyle", Video.ButtonStyle == -1 ? "Default" : (Video.ButtonStyle == 1 ? "Gold" : "Classic")); } diff --git a/common/settings.h b/common/settings.h index cd2b4ea3..304127b5 100644 --- a/common/settings.h +++ b/common/settings.h @@ -33,6 +33,7 @@ class SettingsClass int InterpolationMode; bool HardwareCursor; bool DOSMode; + int ButtonStyle; std::string Scaler; std::string Driver; std::string PixelFormat; diff --git a/tiberiandawn/dialog.cpp b/tiberiandawn/dialog.cpp index f1843961..acf06cb5 100644 --- a/tiberiandawn/dialog.cpp +++ b/tiberiandawn/dialog.cpp @@ -44,6 +44,7 @@ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "function.h" +#include "settings.h" /*********************************************************************************************** * Dialog_Box -- draws a dialog background box * @@ -93,10 +94,8 @@ extern void CC_Texture_Fill(void const* shapefile, int shapenum, int xpos, int y void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled) { - static BoxStyleType const ButtonColors[BOXSTYLE_COUNT] = { - + static BoxStyleType const ButtonColorsClassic[BOXSTYLE_COUNT] = { // Filler, Shadow, Hilite, Corner colors - {LTGREY, WHITE, DKGREY, LTGREY}, // 0 Button is down. {LTGREY, DKGREY, WHITE, LTGREY}, // 1 Button is up w/border. {LTBLUE, BLUE, LTCYAN, LTBLUE}, // 2 Raised blue. @@ -105,29 +104,45 @@ void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled) {LTGREY, DKGREY, WHITE, LTGREY}, // 5 Button is up w/arrows. {CC_GREEN_BKGD, CC_LIGHT_GREEN, CC_GREEN_SHADOW, CC_GREEN_CORNERS}, // 6 Button is down. {CC_GREEN_BKGD, CC_GREEN_SHADOW, CC_LIGHT_GREEN, CC_GREEN_CORNERS}, // 7 Button is up w/border. - // {CC_GREEN_BKGD, 14, 12, 13}, // 6 Button is down. - // {CC_GREEN_BKGD, 12, 14, 13}, // 7 Button is up w/border. - {DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down. - {DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up. - {BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 10 List box. - {BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 11 Menu box. - // {BLACK, 14, 14, BLACK}, // 10 List box. - // {BLACK, 14, 14, BLACK}, // 11 Menu box. + {DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down. + {DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up. + {BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 10 List box. + {BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 11 Menu box. + }; + + static BoxStyleType const ButtonColorsGold[BOXSTYLE_COUNT] = { + // Filler, Shadow, Hilite, Corner colors + {LTGREY, WHITE, DKGREY, LTGREY}, // 0 Button is down. + {LTGREY, DKGREY, WHITE, LTGREY}, // 1 Button is up w/border. + {LTBLUE, BLUE, LTCYAN, LTBLUE}, // 2 Raised blue. + {DKGREY, WHITE, BLACK, DKGREY}, // 3 Button is disabled down. + {DKGREY, BLACK, WHITE, LTGREY}, // 4 Button is disabled up. + {LTGREY, DKGREY, WHITE, LTGREY}, // 5 Button is up w/arrows. + {CC_GREEN_BKGD, 14, 12, 13}, // 6 Button is down. + {CC_GREEN_BKGD, 12, 14, 13}, // 7 Button is up w/border. + {DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down. + {DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up. + {BLACK, 14, 14, BLACK}, // 10 List box. + {BLACK, 14, 14, BLACK}, // 11 Menu box. }; + bool useGoldStyle; + if (Settings.Video.ButtonStyle == -1) { + useGoldStyle = !Settings.Video.DOSMode; + } else { + useGoldStyle = Settings.Video.ButtonStyle == 1; + } + w--; h--; - BoxStyleType const& style = ButtonColors[up]; + BoxStyleType const& style = useGoldStyle ? ButtonColorsGold[up] : ButtonColorsClassic[up]; if (filled) { - /* - if (style.Filler == CC_GREEN_BKGD) { + if (useGoldStyle && style.Filler == CC_GREEN_BKGD) { CC_Texture_Fill(MFCD::Retrieve("BTEXTURE.SHP"), InMainLoop, x, y, w, h); } else { LogicPage->Fill_Rect(x, y, x + w, y + h, style.Filler); } - */ - LogicPage->Fill_Rect(x, y, x + w, y + h, style.Filler); } switch (up) { From 8688c7a9bcf101fd5675312144461179a619eec0 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 14 Mar 2024 14:53:00 +0100 Subject: [PATCH 24/27] Avoid use of ftime() and fix overflow of unsigned int ftime() is an obsolete interface, and may not be present on all platforms. Also, multiplying a time_t by 1000 will overflow the range of an unsigned 32-bit int. --- common/connect.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/common/connect.cpp b/common/connect.cpp index 13b3386d..191336b3 100644 --- a/common/connect.cpp +++ b/common/connect.cpp @@ -44,7 +44,7 @@ #include //#include -#include +#include #include #include "connect.h" @@ -227,6 +227,8 @@ int ConnectionClass::Send_Packet(void* buf, int buflen, int ack_req) SwapCommHeaderType((CommHeaderType*)PacketBuf); + SwapCommHeaderType((CommHeaderType*)PacketBuf); + /*------------------------------------------------------------------------ Now build the packet ------------------------------------------------------------------------*/ @@ -747,7 +749,6 @@ int ConnectionClass::Service_Receive_Queue(void) *=========================================================================*/ unsigned int ConnectionClass::Time(void) { - static struct timeb mytime; // DOS time unsigned int msec; #ifdef WWLIB32_H @@ -764,23 +765,19 @@ unsigned int ConnectionClass::Time(void) /*------------------------------------------------------------------------ Otherwise, use the DOS timer ------------------------------------------------------------------------*/ - else { - ftime(&mytime); - msec = (unsigned int)mytime.time * 1000 + (unsigned int)mytime.millitm; - return ((msec / 100) * 6); - } #else /*------------------------------------------------------------------------ If the Westwood library isn't being used, use the DOS timer. ------------------------------------------------------------------------*/ - ftime(&mytime); - msec = (unsigned int)mytime.time * 1000 + (unsigned int)mytime.millitm; - return ((msec / 100) * 6); - #endif + static auto epoch = std::chrono::steady_clock::now().time_since_epoch(); + auto now = std::chrono::steady_clock::now().time_since_epoch(); + msec = unsigned(std::chrono::duration_cast(now - epoch).count()); + + return ((msec / 100) * 6); } /* end of Time */ /*************************************************************************** From 5e9160e9a335c8abf14249fa1729ca8642b75f75 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 21 Mar 2024 14:04:36 +0100 Subject: [PATCH 25/27] Fix warnings "arithmetic on NULL" --- redalert/cell.cpp | 6 +++--- redalert/mapedplc.cpp | 4 ++-- redalert/mapedsel.cpp | 6 +++--- redalert/object.cpp | 4 ++-- redalert/team.cpp | 20 ++++++++++---------- redalert/vessel.cpp | 2 +- tiberiandawn/mapedplc.cpp | 4 ++-- tiberiandawn/mapedsel.cpp | 6 +++--- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/redalert/cell.cpp b/redalert/cell.cpp index 744ace5f..e3067afa 100644 --- a/redalert/cell.cpp +++ b/redalert/cell.cpp @@ -396,8 +396,8 @@ void CellClass::Redraw_Objects(bool forced) #else optr->Mark(MARK_CHANGE); #endif - if (optr->Next != NULL && !optr->Next->IsActive) { - optr->Next = NULL; + if (optr->Next != nullptr && !optr->Next->IsActive) { + optr->Next = nullptr; } optr = optr->Next; } @@ -604,7 +604,7 @@ void CellClass::Occupy_Down(ObjectClass* object) */ if (object->What_Am_I() == RTTI_BUILDING && Cell_Occupier()) { optr = Cell_Occupier(); - while (optr->Next != NULL) { + while (optr->Next != nullptr) { assert(optr != object); assert(optr->What_Am_I() != RTTI_BUILDING); optr = optr->Next; diff --git a/redalert/mapedplc.cpp b/redalert/mapedplc.cpp index a9781c47..776ad8f3 100644 --- a/redalert/mapedplc.cpp +++ b/redalert/mapedplc.cpp @@ -942,13 +942,13 @@ int MapEditClass::Place_Object(void) if (Is_Spot_Free(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()))) { obj_coord = Closest_Free_Spot(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y())); } else { - obj_coord = NULL; + obj_coord = 0; } /* ** No free spots; don't place the object */ - if (obj_coord == NULL) { + if (obj_coord == 0) { // ScenarioInit--; return (-1); } diff --git a/redalert/mapedsel.cpp b/redalert/mapedsel.cpp index cb555aa1..64935c24 100644 --- a/redalert/mapedsel.cpp +++ b/redalert/mapedsel.cpp @@ -464,7 +464,7 @@ int MapEditClass::Move_Grabbed_Object(void) */ ((InfantryClass*)GrabbedObject)->Clear_Occupy_Bit(GrabbedObject->Coord); } else { - new_coord = NULL; + new_coord = 0; } } else { @@ -483,10 +483,10 @@ int MapEditClass::Move_Grabbed_Object(void) ** Try to place object at new coordinate */ if (GrabbedObject->Can_Enter_Cell(Coord_Cell(new_coord)) != MOVE_OK) { - new_coord = NULL; + new_coord = 0; } } - if (new_coord != NULL) { + if (new_coord != 0) { /* ** If this object is part of the AI's Base list, change the coordinate diff --git a/redalert/object.cpp b/redalert/object.cpp index bc08208c..529044c2 100644 --- a/redalert/object.cpp +++ b/redalert/object.cpp @@ -1335,7 +1335,7 @@ void ObjectClass::Debug_Dump(MonoClass* mono) const { mono->Set_Cursor(1, 1); mono->Printf("%-18.18s", Text_String(Full_Name())); - if (Next != NULL) { + if (Next != nullptr) { mono->Set_Cursor(20, 5); mono->Printf("%08X", Next->As_Target()); } @@ -2451,4 +2451,4 @@ BuildingClass* ObjectTypeClass::Who_Can_Build_Me(bool intheory, bool legal, Hous } } return (anybuilding); -} \ No newline at end of file +} diff --git a/redalert/team.cpp b/redalert/team.cpp index 287c0ef7..a4b902be 100644 --- a/redalert/team.cpp +++ b/redalert/team.cpp @@ -98,7 +98,7 @@ static inline bool _Is_It_Breathing(FootClass const* object) ** If the object is not present or appears to be dead, then it ** certainly isn't an active member of the team. */ - if (object == NULL || !object->IsActive || object->Strength == 0) + if (object == nullptr || !object->IsActive || object->Strength == 0) return (false); /* @@ -292,7 +292,7 @@ void TeamClass::operator delete(void* ptr) TeamClass::~TeamClass(void) { if (GameActive && Class.Is_Valid()) { - while (Member != NULL) { + while (Member != nullptr) { Remove(Member); } Class->Number--; @@ -306,7 +306,7 @@ TeamClass::~TeamClass(void) if (Trigger->AttachCount == 0) { delete (TriggerClass*)Trigger; } - Trigger = NULL; + Trigger = nullptr; } } } @@ -677,7 +677,7 @@ void TeamClass::AI(void) ** If there are no members of the team and the team has reached ** full strength at one time, then delete the team. */ - if (Member == NULL && IsHasBeen) { + if (Member == nullptr && IsHasBeen) { /* ** If this team had no members (i.e., the team object wasn't terminated by some @@ -718,7 +718,7 @@ void TeamClass::AI(void) break; case TMISSION_MOVE: - if ((unsigned)mission->Data.Value < WAYPT_COUNT && Member != NULL) { + if ((unsigned)mission->Data.Value < WAYPT_COUNT && Member != nullptr) { FootClass* leader = Fetch_A_Leader(); CELL movecell = Scen.Waypoint[mission->Data.Value]; if (!Is_Leaving_Map()) { @@ -757,7 +757,7 @@ void TeamClass::AI(void) /* ** Perform mission of the team. This depends on the mission list. */ - if (Member != NULL && IsMoving && !IsReforming && !IsUnderStrength) { + if (Member != nullptr && IsMoving && !IsReforming && !IsUnderStrength) { /* ** If the current Target has been dealt with but the mission target @@ -912,7 +912,7 @@ bool TeamClass::Add(FootClass* obj) ** Actually add the object to the team. */ Quantity[typeindex]++; - obj->IsInitiated = (Member == NULL); + obj->IsInitiated = (Member == nullptr); obj->Member = Member; Member = obj; obj->Team = this; @@ -1144,7 +1144,7 @@ bool TeamClass::Remove(FootClass* obj, int typeindex) ** team captain. Mark the center location of the team as invalid so that ** it will be centered around the captain. */ - if (!initiated && Member != NULL) { + if (!initiated && Member != nullptr) { Member->IsInitiated = true; Zone = TARGET_NONE; } @@ -1639,7 +1639,7 @@ void TeamClass::Coordinate_Attack(void) ** can "attack" an empty cell and this is perfectly ok (paratrooper drop and parabombs ** are prime examples). */ - if (Is_Target_Cell(Target) && Member != NULL && Fetch_A_Leader()->What_Am_I() != RTTI_AIRCRAFT) { + if (Is_Target_Cell(Target) && Member != nullptr && Fetch_A_Leader()->What_Am_I() != RTTI_AIRCRAFT) { CellClass* cellptr = &Map[As_Cell(Target)]; TemplateType tt = cellptr->TType; if (cellptr->Cell_Object()) { @@ -2671,7 +2671,7 @@ int TeamClass::TMission_Formation(void) *=============================================================================================*/ int TeamClass::TMission_Attack(void) { - if (!Target_Legal(MissionTarget) && Member != NULL) { + if (!Target_Legal(MissionTarget) && Member != nullptr) { TeamMissionClass const* mission = &Class->MissionList[CurrentMission]; /* diff --git a/redalert/vessel.cpp b/redalert/vessel.cpp index 3414f746..5c3c1d79 100644 --- a/redalert/vessel.cpp +++ b/redalert/vessel.cpp @@ -718,7 +718,7 @@ void VesselClass::Per_Cell_Process(PCPType why) CELL cell = Coord_Cell(Adjacent_Cell(Center_Coord(), face)); SmartPtr whom; whom = Map[cell].Cell_Building(); - if (whom != NULL && ((*whom == STRUCT_SHIP_YARD) || (*whom == STRUCT_SUB_PEN))) { + if (whom != nullptr && ((*whom == STRUCT_SHIP_YARD) || (*whom == STRUCT_SUB_PEN))) { // MBL 04.27.2020: Make only audible to the correct player // if (IsOwnedByPlayer) Speak(VOX_REPAIRING); diff --git a/tiberiandawn/mapedplc.cpp b/tiberiandawn/mapedplc.cpp index c32f7ff5..4743621c 100644 --- a/tiberiandawn/mapedplc.cpp +++ b/tiberiandawn/mapedplc.cpp @@ -1171,13 +1171,13 @@ int MapEditClass::Place_Object(void) if (Is_Spot_Free(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()))) { obj_coord = Closest_Free_Spot(Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y())); } else { - obj_coord = NULL; + obj_coord = 0; } /* ................ No free spots; don't place the object ................ */ - if (obj_coord == NULL) { + if (obj_coord == 0) { // ScenarioInit--; return (-1); } diff --git a/tiberiandawn/mapedsel.cpp b/tiberiandawn/mapedsel.cpp index 1212f2c8..8812de43 100644 --- a/tiberiandawn/mapedsel.cpp +++ b/tiberiandawn/mapedsel.cpp @@ -481,7 +481,7 @@ int MapEditClass::Move_Grabbed_Object(void) // Map[Coord_Cell(GrabbedObject->Coord)].Flag.Composite &= // ~(1 << CellClass::Spot_Index(GrabbedObject->Coord)); } else { - new_coord = NULL; + new_coord = 0; } } else { @@ -500,10 +500,10 @@ int MapEditClass::Move_Grabbed_Object(void) ................ Try to place object at new coordinate ................ */ if (GrabbedObject->Can_Enter_Cell(Coord_Cell(new_coord)) != MOVE_OK) { - new_coord = NULL; + new_coord = 0; } } - if (new_coord != NULL) { + if (new_coord != 0) { /* ** If this object is part of the AI's Base list, change the coordinate ** in the Base's Node list. From cc994a40cb0676877b1c0352974323c3b6d5cb0b Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Fri, 29 Mar 2024 03:29:35 +0100 Subject: [PATCH 26/27] Remove accidently duplicated call to SwapCommHeaderType This slipped in from commit https://github.com/TheAssemblyArmada/Vanilla-Conquer/commit/8688c7a9bcf101fd5675312144461179a619eec0 --- common/connect.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/connect.cpp b/common/connect.cpp index 191336b3..3a3f5c46 100644 --- a/common/connect.cpp +++ b/common/connect.cpp @@ -227,8 +227,6 @@ int ConnectionClass::Send_Packet(void* buf, int buflen, int ack_req) SwapCommHeaderType((CommHeaderType*)PacketBuf); - SwapCommHeaderType((CommHeaderType*)PacketBuf); - /*------------------------------------------------------------------------ Now build the packet ------------------------------------------------------------------------*/ From 5071cd6f6b8c8858bf9005a7e4fe985ab29ad4c2 Mon Sep 17 00:00:00 2001 From: Thorsten Otto Date: Thu, 14 Mar 2024 15:34:28 +0100 Subject: [PATCH 27/27] Define _GNU_SOURCE to get a definition of FNM_CASEFOLD --- common/file_posix.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/file_posix.cpp b/common/file_posix.cpp index 534f576b..233ba0f9 100644 --- a/common/file_posix.cpp +++ b/common/file_posix.cpp @@ -1,3 +1,6 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include "file.h" #include