diff --git a/src/Bullet.cpp b/src/Bullet.cpp index f3a95bb3..fde280c0 100644 --- a/src/Bullet.cpp +++ b/src/Bullet.cpp @@ -1643,7 +1643,9 @@ void ActBullet_Edge(BULLET *bul) if (bul->ani_no > 4) { bul->cond = 0; - return; // Prevent UB at rc[bul->ani_no] when bul->ani_no == 5 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcLeft' and 'rcRight', even though it's now too high + #endif } break; diff --git a/src/Caret.cpp b/src/Caret.cpp index 5e4293f0..e34a89ec 100644 --- a/src/Caret.cpp +++ b/src/Caret.cpp @@ -71,10 +71,13 @@ void ActCaret01(CARET *crt) if (++crt->ani_wait > 5) { crt->ani_wait = 0; + if (++crt->ani_no > 3) { crt->cond = 0; - return; // Prevent UB at rc[crt->ani_no] when crt->ani_no == 4 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcLeft' and 'rcRight', even though it's now too high + #endif } } @@ -121,7 +124,9 @@ void ActCaret02(CARET *crt) if (crt->ani_no > 3) { crt->cond = 0; - return; // Avoid unconditional UB at rect_left[crt->ani_no] + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect_left', even though it's now too high + #endif } crt->rect = rect_left[crt->ani_no]; @@ -137,7 +142,9 @@ void ActCaret02(CARET *crt) if (crt->ani_no > 3) { crt->cond = 0; - return; // Avoid unconditional UB at rect_right[crt->ani_no] + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect_right', even though it's now too high + #endif } crt->rect = rect_right[crt->ani_no]; @@ -165,10 +172,13 @@ void ActCaret03(CARET *crt) if (++crt->ani_wait > 2) { crt->ani_wait = 0; + if (++crt->ani_no > 3) { crt->cond = 0; - return; // Return now, or the access to rect[crt->ani_no] we do is UB + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect', even though it's now too high + #endif } } @@ -181,9 +191,11 @@ void ActCaret04(CARET *crt) {64, 32, 80, 48}, {80, 32, 96, 48}, {96, 32, 112, 48}, + {64, 48, 80, 64}, {80, 48, 96, 64}, {96, 48, 112, 64}, + {64, 64, 80, 80}, {80, 64, 96, 80}, {96, 64, 112, 80}, @@ -194,7 +206,12 @@ void ActCaret04(CARET *crt) crt->ani_wait = 0; if (++crt->ani_no > 2) + { crt->cond = 0; + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect', even though it's now too high + #endif + } } crt->rect = rect[(crt->direct * 3) + crt->ani_no]; @@ -218,15 +235,17 @@ void ActCaret05(CARET *crt) ++crt->ani_no; } - crt->x += 0x80; - crt->y -= 0x80; - if (crt->ani_no > 6) { crt->cond = 0; - return; // Return now, or the access to rect[crt->ani_no] we do is UB + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect', even though it's now too high + #endif } + crt->x += 0x80; + crt->y -= 0x80; + crt->rect = rect[crt->ani_no]; } @@ -249,7 +268,9 @@ void ActCaret07(CARET *crt) if (++crt->ani_no > 6) { crt->cond = 0; - return; // Prevent UB at rcLeft[crt->ani_no] when crt->ani_no == 6 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcLeft', even though it's now too high + #endif } } @@ -365,10 +386,13 @@ void ActCaret11(CARET *crt) if (++crt->ani_wait > 2) { crt->ani_wait = 0; + if (++crt->ani_no > 6) { crt->cond = 0; - return; // Avoid unconditional UB at rcRight[crt->ani_no] + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcRight', even though it's now too high + #endif } } @@ -385,10 +409,13 @@ void ActCaret12(CARET *crt) if (++crt->ani_wait > 2) { crt->ani_wait = 0; + if (++crt->ani_no > 1) { crt->cond = 0; - return; // Return now, or the access to rcLeft[crt->ani_no] we do is UB + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcLeft', even though it's now too high + #endif } } @@ -456,7 +483,9 @@ void ActCaret14(CARET *crt) if (++crt->ani_no > 4) { crt->cond = 0; - return; // Prevent UB at rect[crt->ani_no] when crt->ani_no == 5 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect', even though it's now too high + #endif } } @@ -479,7 +508,9 @@ void ActCaret15(CARET *crt) if (++crt->ani_no > 3) { crt->cond = 0; - return; // Prevent UB at rcLeft[crt->ani_no] when crt->ani_no == 4 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcLeft', even though it's now too high + #endif } } diff --git a/src/MycParam.cpp b/src/MycParam.cpp index 318630d6..4ccf7180 100644 --- a/src/MycParam.cpp +++ b/src/MycParam.cpp @@ -273,8 +273,14 @@ void PutArmsEnergy(BOOL flash) RECT rcExpFlash = {40, 80, 80, 88}; int lv = gArmsData[gSelectedArms].level - 1; - if (lv < 0) // Detect the case where the level is 0 (no weapon) - lv = 0; // Set lv to a safe value + +#ifdef FIX_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. + if (lv < 0) + lv = 0; +#endif int arms_code = gArmsData[gSelectedArms].code; int exp_now = gArmsData[gSelectedArms].exp; diff --git a/src/NpcAct120.cpp b/src/NpcAct120.cpp index 5bfc1eb0..801cbf0b 100644 --- a/src/NpcAct120.cpp +++ b/src/NpcAct120.cpp @@ -585,10 +585,13 @@ void ActNpc127(NPCHAR *npc) if (++npc->ani_wait > 0) { npc->ani_wait = 0; + if (++npc->ani_no > 2) { npc->cond = 0; - return; // Prevent UB at rc[npc->ani_no] when npc->ani_no == 3 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcH' and 'rcV', even though it's now too high + #endif } } @@ -652,7 +655,9 @@ void ActNpc128(NPCHAR *npc) if (++npc->ani_no > 4) { npc->cond = 0; - return; // Prevent UB at rc[npc->ani_no] when npc->ani_no == 5 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rcLeft' and co., even though it's now too high + #endif } switch (npc->direct) @@ -682,18 +687,23 @@ void ActNpc129(NPCHAR *npc) {0x80, 0x30, 0x90, 0x40}, {0x90, 0x30, 0xA0, 0x40}, {0xA0, 0x30, 0xB0, 0x40}, + {0x80, 0x40, 0x90, 0x50}, {0x90, 0x40, 0xA0, 0x50}, {0xA0, 0x40, 0xB0, 0x50}, + {0x80, 0x50, 0x90, 0x60}, {0x90, 0x50, 0xA0, 0x60}, {0xA0, 0x50, 0xB0, 0x60}, + {0xB0, 0x30, 0xC0, 0x40}, {0xC0, 0x30, 0xD0, 0x40}, {0xD0, 0x30, 0xE0, 0x40}, + {0xB0, 0x40, 0xC0, 0x50}, {0xC0, 0x40, 0xD0, 0x50}, {0xD0, 0x40, 0xE0, 0x50}, + {0xB0, 0x50, 0xC0, 0x60}, {0xC0, 0x50, 0xD0, 0x60}, {0xD0, 0x50, 0xE0, 0x60}, @@ -706,7 +716,9 @@ void ActNpc129(NPCHAR *npc) if (++npc->ani_no > 2) { npc->cond = 0; - return; // Prevent UB at rect[(npc->direct * 3) + npc->ani_no] when npc->direct == 5 and npc->ani_no == 3 + #ifdef FIX_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 4d718f57..1aae6938 100644 --- a/src/NpcAct140.cpp +++ b/src/NpcAct140.cpp @@ -753,7 +753,9 @@ void ActNpc146(NPCHAR *npc) { SetDestroyNpChar(npc->x, npc->y, 0x1000, 8); npc->cond = 0; - return; // Prevent UB at rect[npc->ani_no] when npc->ani_no == 5 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect', even though it's now too high + #endif } break; diff --git a/src/NpcAct180.cpp b/src/NpcAct180.cpp index 76f27294..cfb426ab 100644 --- a/src/NpcAct180.cpp +++ b/src/NpcAct180.cpp @@ -1428,7 +1428,9 @@ void ActNpc199(NPCHAR *npc) if (npc->ani_no > 4) { npc->cond = 0; - return; // Prevent UB at rect[npc->ani_no] when npc->ani_no == 5 + #ifdef FIX_BUGS + return; // The code below will use 'ani_no' to access 'rect', even though it's now too high + #endif } npc->x += npc->xm;