From 0c367cecf7ff5236dc8e2005fffae254c400a1fc Mon Sep 17 00:00:00 2001 From: Clownacy Date: Thu, 3 Sep 2020 21:05:14 +0100 Subject: [PATCH] Add FIX_MAJOR_BUGS option This one specifically fixes bugs that either invoke undefined behaviour or cause memory leaks. Essentially, they affect stability. Bugs that just affect gameplay will remain covered by FIX_BUGS. --- CMakeLists.txt | 5 +++++ Makefile | 6 +++++- README.md | 2 ++ src/Back.cpp | 2 +- src/Bullet.cpp | 4 ++-- src/Caret.cpp | 22 +++++++++++----------- src/Draw.cpp | 4 ++-- src/Ending.cpp | 2 +- src/Game.cpp | 2 +- src/Input.cpp | 2 +- src/MycParam.cpp | 4 ++-- src/NpChar.cpp | 2 +- src/NpcAct000.cpp | 2 +- src/NpcAct120.cpp | 6 +++--- src/NpcAct140.cpp | 2 +- src/NpcAct180.cpp | 2 +- src/Organya.cpp | 4 ++-- src/Sound.cpp | 12 ++++++------ src/TextScr.cpp | 6 +++--- 19 files changed, 51 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1993a927..19dd3df6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ set(ASSETS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/assets") option(JAPANESE "Enable the Japanese-language build (instead of the unofficial Aeon Genesis English translation)" OFF) option(FIX_BUGS "Fix various bugs in the game" OFF) +option(FIX_MAJOR_BUGS "Fix bugs that invoke undefined behaviour or cause memory leaks" OFF) option(DEBUG_SAVE "Re-enable the dummied-out 'Debug Save' option, and the ability to drag-and-drop save files onto the window" OFF) option(LTO "Enable link-time optimisation" OFF) @@ -169,6 +170,10 @@ if(FIX_BUGS) target_compile_definitions(CSE2 PRIVATE FIX_BUGS) endif() +if(FIX_BUGS OR FIX_MAJOR_BUGS) + target_compile_definitions(CSE2 PRIVATE FIX_MAJOR_BUGS) +endif() + if(DEBUG_SAVE) target_compile_definitions(CSE2 PRIVATE DEBUG_SAVE) endif() diff --git a/Makefile b/Makefile index fea71fa1..8cdec4a1 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,11 @@ endif FILENAME ?= $(FILENAME_DEF) ifeq ($(FIX_BUGS), 1) - ALL_CXXFLAGS += -DFIX_BUGS + ALL_CXXFLAGS += -DFIX_BUGS -DFIX_MAJOR_BUGS +else + ifeq ($(FIX_MAJOR_BUGS), 1) + ALL_CXXFLAGS += -DFIX_MAJOR_BUGS + endif endif ifeq ($(DEBUG_SAVE), 1) diff --git a/README.md b/README.md index b63977c6..9bf32c49 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Name | Function --------|-------- `-DJAPANESE=ON` | Enable the Japanese-language build (instead of the unofficial Aeon Genesis English translation) `-DFIX_BUGS=ON` | Fix various bugs in the game +`-DFIX_MAJOR_BUGS=ON` | Fix bugs that invoke undefined behaviour or cause memory leaks `-DDEBUG_SAVE=ON` | Re-enable [the dummied-out 'Debug Save' option](https://tcrf.net/Cave_Story#Debug_Save), and the ability to drag-and-drop save files onto the window `-DLTO=ON` | Enable link-time optimisation `-DMSVC_LINK_STATIC_RUNTIME=ON` | Link the static MSVC runtime library, to reduce the number of required DLL files (Visual Studio only) @@ -108,6 +109,7 @@ Name | Function --------|-------- `JAPANESE=1` | Enable the Japanese-language build (instead of the unofficial Aeon Genesis English translation) `FIX_BUGS=1` | Fix various bugs in the game +`FIX_MAJOR_BUGS=1` | Fix bugs that invoke undefined behaviour or cause memory leaks `DEBUG_SAVE=1` | Re-enable [the dummied-out 'Debug Save' option](https://tcrf.net/Cave_Story#Debug_Save), and the ability to drag-and-drop save files onto the window `RELEASE=1` | Compile a release build (optimised, stripped, etc.) `STATIC=1` | Produce a statically-linked executable (so you don't need to bundle DLL files) diff --git a/src/Back.cpp b/src/Back.cpp index fbe44788..fe8d652a 100644 --- a/src/Back.cpp +++ b/src/Back.cpp @@ -36,7 +36,7 @@ BOOL InitBack(const char *fName, int type) // Check if this is a valid bitmap file if (bmp_header_buffer[0] != 0x4D42) // 'MB' (we use hex here to prevent a compiler warning) { -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS // The original game forgets to close fp fclose(fp); #endif diff --git a/src/Bullet.cpp b/src/Bullet.cpp index cbba5918..ec9afd69 100644 --- a/src/Bullet.cpp +++ b/src/Bullet.cpp @@ -1644,7 +1644,7 @@ void ActBullet_Edge(BULLET *bul) if (bul->ani_no > 4) { bul->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcLeft' and 'rcRight', even though it's now too high #endif } @@ -2182,7 +2182,7 @@ void ActBullet_SpurTail(BULLET *bul, int level) if (bul->ani_no > 2) { bul->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // Avoid accessing the RECT arrays with an out-of-bounds index #endif } diff --git a/src/Caret.cpp b/src/Caret.cpp index 057b58d7..6480035f 100644 --- a/src/Caret.cpp +++ b/src/Caret.cpp @@ -105,7 +105,7 @@ void ActCaret01(CARET *crt) if (++crt->ani_no > 3) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcLeft' and 'rcRight', even though it's now too high #endif } @@ -155,7 +155,7 @@ void ActCaret02(CARET *crt) if (crt->ani_no > 3) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect_left', even though it's now too high #endif } @@ -173,7 +173,7 @@ void ActCaret02(CARET *crt) if (crt->ani_no > 3) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect_right', even though it's now too high #endif } @@ -208,7 +208,7 @@ void ActCaret03(CARET *crt) if (++crt->ani_no > 3) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect', even though it's now too high #endif } @@ -242,7 +242,7 @@ void ActCaret04(CARET *crt) if (++crt->ani_no > 2) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect', even though it's now too high #endif } @@ -273,7 +273,7 @@ void ActCaret05(CARET *crt) if (crt->ani_no > 6) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect', even though it's now too high #endif } @@ -306,7 +306,7 @@ void ActCaret07(CARET *crt) if (++crt->ani_no > 6) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcLeft', even though it's now too high #endif } @@ -432,7 +432,7 @@ void ActCaret11(CARET *crt) if (++crt->ani_no > 6) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcRight', even though it's now too high #endif } @@ -456,7 +456,7 @@ void ActCaret12(CARET *crt) if (++crt->ani_no > 1) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcLeft', even though it's now too high #endif } @@ -531,7 +531,7 @@ void ActCaret14(CARET *crt) if (++crt->ani_no > 4) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect', even though it's now too high #endif } @@ -557,7 +557,7 @@ void ActCaret15(CARET *crt) if (++crt->ani_no > 3) { crt->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcLeft', even though it's now too high #endif } diff --git a/src/Draw.cpp b/src/Draw.cpp index 4261ba1e..bd79cc60 100644 --- a/src/Draw.cpp +++ b/src/Draw.cpp @@ -273,7 +273,7 @@ BOOL MakeSurface_Resource(const char *name, SurfaceID surf_no) surf[surf_no]->SetColorKey(DDCKEY_SRCBLT, &ddcolorkey); surf[surf_no]->SetClipper(clipper); -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS DeleteObject(handle); #endif @@ -414,7 +414,7 @@ BOOL ReloadBitmap_Resource(const char *name, SurfaceID surf_no) surf[surf_no]->SetColorKey(DDCKEY_SRCBLT, &ddcolorkey); surf[surf_no]->SetClipper(clipper); -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS DeleteObject(handle); #endif diff --git a/src/Ending.cpp b/src/Ending.cpp index ac7cec78..18695022 100644 --- a/src/Ending.cpp +++ b/src/Ending.cpp @@ -249,7 +249,7 @@ BOOL StartCreditScript(void) fread(Credit.pData, 1, Credit.size, fp); EncryptionBinaryData2((unsigned char*)Credit.pData, Credit.size); -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS // The original game forgot to close the file fclose(fp); #endif diff --git a/src/Game.cpp b/src/Game.cpp index 907a3a5c..583310f4 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -560,7 +560,7 @@ static int ModeAction(HWND hWnd) ActBullet(); ActCaret(); MoveFrame3(); -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS // ActFlash uses frame_x and frame_y uninitialised GetFramePosition(&frame_x, &frame_y); #endif diff --git a/src/Input.cpp b/src/Input.cpp index 95e3a2a9..f2db63cd 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -151,7 +151,7 @@ BOOL CALLBACK EnumDevices_Callback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) directinput_objects->device = _joystick; char string[0x100]; -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS sprintf(string, "DeviceGUID = %08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", lpddi->guidInstance.Data1, lpddi->guidInstance.Data2, lpddi->guidInstance.Data3, lpddi->guidInstance.Data4[0], lpddi->guidInstance.Data4[1], lpddi->guidInstance.Data4[2], lpddi->guidInstance.Data4[3], lpddi->guidInstance.Data4[4], lpddi->guidInstance.Data4[5], lpddi->guidInstance.Data4[6], lpddi->guidInstance.Data4[7]); #else sprintf(string, "DeviceGUID = %x\n", lpddi->guidInstance); // Tries to print a struct as an int diff --git a/src/MycParam.cpp b/src/MycParam.cpp index 20385f29..fd02d7d9 100644 --- a/src/MycParam.cpp +++ b/src/MycParam.cpp @@ -110,7 +110,7 @@ void DamageMyChar(int damage) #ifdef FIX_BUGS if (!(g_GameFlags & 2)) #else - // I'm preeeetty sure this is a typo. The Linux port optimised it out. + // I'm preeeetty sure this is a typo. The Linux port optimised this entire check out. if (!(g_GameFlags | 2)) #endif return; @@ -272,7 +272,7 @@ void PutArmsEnergy(BOOL flash) int lv = gArmsData[gSelectedArms].level - 1; -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS // When the player has no weapons, the default level is 0, which becomes -1. // Catch it, and set it to 0 instead, so the following array-accesses aren't // out-of-bounds. diff --git a/src/NpChar.cpp b/src/NpChar.cpp index 934400c6..c63dd784 100644 --- a/src/NpChar.cpp +++ b/src/NpChar.cpp @@ -70,7 +70,7 @@ BOOL LoadEvent(const char *path_event) fread(code, 1, 4, fp); if (memcmp(code, gPassPixEve, 3) != 0) { -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS // The original game forgot to close the file here fclose(fp); #endif diff --git a/src/NpcAct000.cpp b/src/NpcAct000.cpp index b4e8f107..22488511 100644 --- a/src/NpcAct000.cpp +++ b/src/NpcAct000.cpp @@ -59,7 +59,7 @@ void ActNpc001(NPCHAR *npc) if (npc->xm < -0x600) npc->xm = -0x600; #else - // Limit speed (except pixel applied it to the X position) + // Limit speed (except Pixel applied it to the X position) if (npc->x < -0x600) npc->x = -0x600; #endif diff --git a/src/NpcAct120.cpp b/src/NpcAct120.cpp index cd21959e..f8b3ce1d 100644 --- a/src/NpcAct120.cpp +++ b/src/NpcAct120.cpp @@ -590,7 +590,7 @@ void ActNpc127(NPCHAR *npc) if (++npc->ani_no > 2) { npc->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcH' and 'rcV', even though it's now too high #endif } @@ -656,7 +656,7 @@ void ActNpc128(NPCHAR *npc) if (++npc->ani_no > 4) { npc->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rcLeft' and co., even though it's now too high #endif } @@ -717,7 +717,7 @@ void ActNpc129(NPCHAR *npc) if (++npc->ani_no > 2) { npc->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect', even though it's now too high #endif } diff --git a/src/NpcAct140.cpp b/src/NpcAct140.cpp index c3873690..68fc4389 100644 --- a/src/NpcAct140.cpp +++ b/src/NpcAct140.cpp @@ -753,7 +753,7 @@ void ActNpc146(NPCHAR *npc) { SetDestroyNpChar(npc->x, npc->y, 0x1000, 8); npc->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect', even though it's now too high #endif } diff --git a/src/NpcAct180.cpp b/src/NpcAct180.cpp index 0b630116..c7646495 100644 --- a/src/NpcAct180.cpp +++ b/src/NpcAct180.cpp @@ -1429,7 +1429,7 @@ void ActNpc199(NPCHAR *npc) if (npc->ani_no > 4) { npc->cond = 0; - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS return; // The code below will use 'ani_no' to access 'rect', even though it's now too high #endif } diff --git a/src/Organya.cpp b/src/Organya.cpp index 069d7a59..d60035bb 100644 --- a/src/Organya.cpp +++ b/src/Organya.cpp @@ -212,9 +212,9 @@ BOOL MakeSoundObject8(signed char *wavep, signed char track, signed char pipi) if (hr != DS_OK) { -#ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS free(wp); // The updated Organya source code includes this fix -#endif + #endif return FALSE; } diff --git a/src/Sound.cpp b/src/Sound.cpp index 668f35d6..0816ca65 100644 --- a/src/Sound.cpp +++ b/src/Sound.cpp @@ -40,10 +40,10 @@ BOOL InitDirectSound(HWND hwnd) if (DirectSoundCreate(NULL, &lpDS, NULL) != DS_OK) { lpDS = NULL; -#ifndef FIX_BUGS + #ifndef FIX_BUGS // This makes absolutely no sense here StartOrganya(lpDS, "Org\\Wave.dat"); -#endif + #endif return FALSE; } @@ -165,7 +165,7 @@ BOOL LoadSoundObject(LPCSTR file_name, int no) for (i = 0; i < 58; i++) fread(&check_box[i], sizeof(char), 1, fp); // Holy hell, this is inefficient -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS // The original code forgets to close 'fp' if (check_box[0] != 'R' || check_box[1] != 'I' || check_box[2] != 'F' || check_box[3] != 'F') { @@ -186,7 +186,7 @@ BOOL LoadSoundObject(LPCSTR file_name, int no) DWORD *wp; wp = (DWORD*)malloc(file_size); // ファイルのワークスペースを作る (Create a file workspace) -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS if (wp == NULL) { fclose(fp); @@ -211,7 +211,7 @@ BOOL LoadSoundObject(LPCSTR file_name, int no) if (lpDS->CreateSoundBuffer(&dsbd, &lpSECONDARYBUFFER[no], NULL) != DS_OK) { -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS free(wp); // The updated Organya source code includes this fix #endif return FALSE; @@ -225,7 +225,7 @@ BOOL LoadSoundObject(LPCSTR file_name, int no) if (hr != DS_OK) { -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS free(wp); // The updated Organya source code includes this fix #endif return FALSE; diff --git a/src/TextScr.cpp b/src/TextScr.cpp index 40c5735d..1ad813c4 100644 --- a/src/TextScr.cpp +++ b/src/TextScr.cpp @@ -678,7 +678,7 @@ int TextScriptProc(void) x = GetTextScriptNo(gTS.p_read + 9); gNumberTextScript[0] = x; - #ifndef FIX_BUGS + #ifndef FIX_MAJOR_BUGS // z is uninitialised. Probably a leftover from copypasting this from elsewhere. gNumberTextScript[1] = z; #endif @@ -898,7 +898,7 @@ int TextScriptProc(void) x = GetTextScriptNo(gTS.p_read + 4); z = GetTextScriptNo(gTS.p_read + 9); - #ifdef FIX_BUGS + #ifdef FIX_MAJOR_BUGS // Some versions of the Waterway TSC script contain a bug: //