ref: 4d3aae328b42973321849ad8dd04dcf2f29459f4
parent: 41f699fcea5ee95ad459972bdf46b705ab2219dd
parent: 220f48a98bf44365b8d45cdfb5d48e0080fe92d6
author: Clownacy <Clownacy@users.noreply.github.com>
date: Tue Jul 7 19:50:43 EDT 2020
Merge branch 'accurate' into portable
--- a/src/Bullet.cpp
+++ b/src/Bullet.cpp
@@ -1643,7 +1643,9 @@
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;
--- a/src/Caret.cpp
+++ b/src/Caret.cpp
@@ -71,10 +71,13 @@
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 @@
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 @@
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 @@
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 @@
{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 @@
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 @@
++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 @@
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 @@
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 @@
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 @@
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 @@
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
}
}
--- a/src/MycParam.cpp
+++ b/src/MycParam.cpp
@@ -273,8 +273,14 @@
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;
--- a/src/NpcAct120.cpp
+++ b/src/NpcAct120.cpp
@@ -585,10 +585,13 @@
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 @@
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 @@
{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 @@
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
}
}
--- a/src/NpcAct140.cpp
+++ b/src/NpcAct140.cpp
@@ -753,7 +753,9 @@
{
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;
--- a/src/NpcAct180.cpp
+++ b/src/NpcAct180.cpp
@@ -1428,7 +1428,9 @@
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;