diff --git a/CMakeLists.txt b/CMakeLists.txt index d41b069b..74d3d478 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,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" ON) option(DEBUG_SAVE "Re-enable the ability to drag-and-drop save files onto the window" OFF) option(DOCONFIG "Compile a DoConfig clone tool - not useful for console ports" ON) option(LANCZOS_RESAMPLER "Use Lanczos filtering for audio resampling instead of linear-interpolation (Lanczos is more performance-intensive, but higher quality)" OFF) @@ -265,6 +266,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/src/Back.cpp b/src/Back.cpp index 825163c7..0e8727a2 100644 --- a/src/Back.cpp +++ b/src/Back.cpp @@ -29,7 +29,7 @@ BOOL InitBack(const char *fName, int type) if (fgetc(fp) != 'B' || fgetc(fp) != 'M') { -#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/Ending.cpp b/src/Ending.cpp index b2b9c3be..7f93cbaf 100644 --- a/src/Ending.cpp +++ b/src/Ending.cpp @@ -250,7 +250,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 56186994..7cab4319 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -562,7 +562,7 @@ static int ModeAction(void) 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/MycParam.cpp b/src/MycParam.cpp index b3aa2070..d057c48c 100644 --- a/src/MycParam.cpp +++ b/src/MycParam.cpp @@ -112,7 +112,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; @@ -274,7 +274,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 e2495bc3..c6fdf32e 100644 --- a/src/NpChar.cpp +++ b/src/NpChar.cpp @@ -71,7 +71,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/Sound.cpp b/src/Sound.cpp index 3544dba1..188edd0e 100644 --- a/src/Sound.cpp +++ b/src/Sound.cpp @@ -37,10 +37,10 @@ BOOL InitDirectSound(void) if (!audio_backend_initialised) { -#ifndef FIX_BUGS + #ifndef FIX_BUGS // This makes absolutely no sense here StartOrganya("Org/Wave.dat"); -#endif + #endif return FALSE; } @@ -140,7 +140,7 @@ BOOL LoadSoundObject(const char *file_name, int no) // fread(&check_box[i], sizeof(char), 1, fp); // Holy hell, this is inefficient fread(check_box, 1, 58, fp); -#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') { @@ -161,7 +161,7 @@ BOOL LoadSoundObject(const char *file_name, int no) unsigned char *wp; wp = (unsigned char*)malloc(file_size); // ファイルのワークスペースを作る (Create a file workspace) -#ifdef FIX_BUGS +#ifdef FIX_MAJOR_BUGS if (wp == NULL) { fclose(fp); @@ -208,7 +208,7 @@ BOOL LoadSoundObject(const char *file_name, int no) if (lpSECONDARYBUFFER[no] == NULL) { -#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 00f8077b..06339a01 100644 --- a/src/TextScr.cpp +++ b/src/TextScr.cpp @@ -680,7 +680,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 @@ -905,6 +905,32 @@ int TextScriptProc(void) x = GetTextScriptNo(gTS.p_read + 4); z = GetTextScriptNo(gTS.p_read + 9); + #ifdef FIX_MAJOR_BUGS + // Some versions of the Waterway TSC script contain a bug: + //