summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurausukun <lord.uber1@gmail.com>2021-07-03 17:18:41 -0400
committerKurausukun <lord.uber1@gmail.com>2021-07-03 17:18:41 -0400
commitff94d49a45ef605cfaed1268aa5a230958e25cd9 (patch)
tree34ce55ebbd3a33ea4db7153e203e70fa441cd146
parentee0f35b8663acc5c1e1eb28074ad5917783afd17 (diff)
add SAFE_DIV macro and usages
-rw-r--r--include/global.h8
-rw-r--r--src/battle_anim_mons.c2
-rw-r--r--src/battle_script_commands.c4
-rw-r--r--src/field_effect.c10
-rw-r--r--src/sprite.c2
5 files changed, 14 insertions, 12 deletions
diff --git a/include/global.h b/include/global.h
index 1d12fdae9..f7abcc23d 100644
--- a/include/global.h
+++ b/include/global.h
@@ -73,6 +73,14 @@
#define abs(x) (((x) < 0) ? -(x) : (x))
#endif
+// Used in cases where division by 0 can occur in the retail version.
+// Avoids invalid opcodes on some emulators, and the otherwise UB.
+#ifdef UBFIX
+#define SAFE_DIV(a, b) ((b) ? (a) / (b) : 0)
+#else
+#define SAFE_DIV(a, b) ((a) / (b))
+#endif
+
// There are many quirks in the source code which have overarching behavioral differences from
// a number of other files. For example, diploma.c seems to declare rodata before each use while
// other files declare out of order and must be at the beginning. There are also a number of
diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c
index c47a29976..a62694834 100644
--- a/src/battle_anim_mons.c
+++ b/src/battle_anim_mons.c
@@ -1706,7 +1706,7 @@ void SetBattlerSpriteYOffsetFromOtherYScale(u8 spriteId, u8 otherSpriteId)
{
s32 var = 64 - GetBattlerYDeltaFromSpriteId(otherSpriteId) * 2;
u16 matrix = gSprites[spriteId].oam.matrixNum;
- s32 var2 = (var << 8) / gOamMatrices[matrix].d;
+ s32 var2 = SAFE_DIV((var << 8), gOamMatrices[matrix].d);
if (var2 > 128)
var2 = 128;
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index ee9251017..c6ab568ff 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -3108,7 +3108,7 @@ static void atk23_getexp(void)
calculatedExp = gBaseStats[gBattleMons[gBattlerFainted].species].expYield * gBattleMons[gBattlerFainted].level / 7;
if (viaExpShare) // at least one mon is getting exp via exp share
{
- *exp = calculatedExp / 2 / viaSentIn;
+ *exp = SAFE_DIV(calculatedExp / 2, viaSentIn);
if (*exp == 0)
*exp = 1;
gExpShareExp = calculatedExp / 2 / viaExpShare;
@@ -3117,7 +3117,7 @@ static void atk23_getexp(void)
}
else
{
- *exp = calculatedExp / viaSentIn;
+ *exp = SAFE_DIV(calculatedExp, viaSentIn);
if (*exp == 0)
*exp = 1;
gExpShareExp = 0;
diff --git a/src/field_effect.c b/src/field_effect.c
index 4ccf50b0b..206b695b0 100644
--- a/src/field_effect.c
+++ b/src/field_effect.c
@@ -3668,14 +3668,8 @@ static void Task_MoveDeoxysRock_Step(u8 taskId)
data[5] = sprite->pos1.y << 4;
// UB: Possible divide by zero
- #ifdef UBFIX
- #define DIVISOR (data[8] ? data[8] : 1);
- #else
- #define DIVISOR (data[8])
- #endif
-
- data[6] = ((data[2] << 4) - data[4]) / DIVISOR;
- data[7] = ((data[3] << 4) - data[5]) / DIVISOR;
+ data[6] = SAFE_DIV(((data[2] << 4) - data[4]), data[8]);
+ data[7] = SAFE_DIV(((data[3] << 4) - data[5]), data[8]);
data[0]++;
// fallthrough
case 1:
diff --git a/src/sprite.c b/src/sprite.c
index af03aaf11..972fd932d 100644
--- a/src/sprite.c
+++ b/src/sprite.c
@@ -1333,7 +1333,7 @@ void ApplyAffineAnimFrameRelativeAndUpdateMatrix(u8 matrixNum, struct AffineAnim
s16 ConvertScaleParam(s16 scale)
{
s32 val = 0x10000;
- return val / scale;
+ return SAFE_DIV(val, scale);
}
void GetAffineAnimFrame(u8 matrixNum, struct Sprite *sprite, struct AffineAnimFrameCmd *frameCmd)