From 25efe1ca671ad4cb59ad6f80abd1cd263af79836 Mon Sep 17 00:00:00 2001 From: Kermalis <29823718+Kermalis@users.noreply.github.com> Date: Tue, 5 Nov 2024 09:43:47 -0500 Subject: [PATCH] Finish math.s --- asm/math.s | 251 ----------------------------- include/number_util.h | 2 +- ld_script.txt | 1 - src/ground_script_1.c | 2 +- src/math.c | 366 ++++++++++++++++++++++++++++-------------- 5 files changed, 245 insertions(+), 377 deletions(-) delete mode 100644 asm/math.s diff --git a/asm/math.s b/asm/math.s deleted file mode 100644 index d6a14e917..000000000 --- a/asm/math.s +++ /dev/null @@ -1,251 +0,0 @@ - #include "asm/constants/gba_constants.inc" - #include "asm/macros.inc" - - .syntax unified - - .text - - thumb_func_start sub_800A6D0 -sub_800A6D0: - push {r4,lr} - adds r4, r0, 0 - ldr r3, [r1] - ldr r0, [r2] - adds r3, r0 - ldr r1, [r1, 0x4] - ldr r0, [r2, 0x4] - adds r0, r1, r0 - cmp r0, r1 - bcs _0800A6E6 - adds r3, 0x1 -_0800A6E6: - str r3, [r4] - str r0, [r4, 0x4] - pop {r4} - pop {r0} - bx r0 - thumb_func_end sub_800A6D0 - - thumb_func_start sub_800A6F0 -sub_800A6F0: - push {r4,lr} - adds r4, r0, 0 - ldr r3, [r1] - ldr r0, [r2] - subs r3, r0 - ldr r1, [r1, 0x4] - ldr r0, [r2, 0x4] - subs r0, r1, r0 - cmp r0, r1 - bls _0800A706 - subs r3, 0x1 -_0800A706: - str r3, [r4] - str r0, [r4, 0x4] - pop {r4} - pop {r0} - bx r0 - thumb_func_end sub_800A6F0 - - thumb_func_start sub_800A710 -sub_800A710: - push {r4-r7,lr} - mov r7, r8 - push {r7} - sub sp, 0x18 - mov r8, r0 - adds r6, r2, 0 - ldr r0, [r1] - str r0, [sp] - ldr r0, [r1, 0x4] - str r0, [sp, 0x4] - adds r4, r6, 0 - cmp r6, 0 - bge _0800A72C - negs r4, r6 -_0800A72C: - movs r0, 0 - str r0, [sp, 0x8] - movs r1, 0x80 - lsls r1, 9 - add r0, sp, 0x8 - str r1, [r0, 0x4] - adds r7, r0, 0 - cmp r4, 0 - beq _0800A75E - adds r5, r7, 0 -_0800A740: - movs r0, 0x1 - ands r0, r4 - cmp r0, 0 - beq _0800A752 - adds r0, r5, 0 - adds r1, r5, 0 - mov r2, sp - bl sub_800A34C -_0800A752: - mov r0, sp - bl sub_800A4A0 - asrs r4, 1 - cmp r4, 0 - bne _0800A740 -_0800A75E: - cmp r6, 0 - bge _0800A776 - movs r0, 0 - str r0, [sp, 0x10] - movs r0, 0x80 - lsls r0, 9 - add r1, sp, 0x10 - str r0, [r1, 0x4] - adds r0, r7, 0 - adds r2, r7, 0 - bl sub_800A3F0 -_0800A776: - ldr r0, [sp, 0x8] - mov r1, r8 - str r0, [r1] - ldr r0, [r7, 0x4] - str r0, [r1, 0x4] - add sp, 0x18 - pop {r3} - mov r8, r3 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_800A710 - - thumb_func_start sub_800A78C -sub_800A78C: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x20 - mov r10, r0 - ldr r0, [r1] - ldr r1, [r1, 0x4] - str r0, [sp] - str r1, [sp, 0x4] - ldr r0, [r2] - ldr r1, [r2, 0x4] - str r0, [sp, 0x8] - str r1, [sp, 0xC] - mov r0, sp - bl sub_800A27C - add r4, sp, 0x8 - adds r0, r4, 0 - bl sub_800A27C - mov r0, sp - adds r1, r4, 0 - bl sub_800A2F0 - lsls r0, 24 - mov r8, r4 - cmp r0, 0 - beq _0800A7DC - ldr r2, [sp] - ldr r3, [sp, 0x4] - str r2, [sp, 0x10] - str r3, [sp, 0x14] - ldr r0, [sp, 0x8] - ldr r1, [sp, 0xC] - str r0, [sp] - str r1, [sp, 0x4] - str r2, [sp, 0x8] - str r3, [sp, 0xC] -_0800A7DC: - mov r0, r8 - bl sub_800A2A0 - lsls r0, 24 - cmp r0, 0 - bne _0800A878 - movs r0, 0 - mov r9, r0 - add r7, sp, 0x10 - add r6, sp, 0x18 - b _0800A800 -_0800A7F2: - mov r0, r8 - mov r1, r8 - adds r2, r7, 0 - bl sub_800A34C - movs r2, 0x1 - add r9, r2 -_0800A800: - adds r4, r7, 0 - mov r1, r8 - adds r0, r4, 0 - mov r2, sp - bl sub_800A3F0 - adds r0, r4, 0 - bl sub_800A4A0 - ldr r0, [sp, 0x10] - str r0, [sp, 0x18] - ldr r1, [r4, 0x4] - movs r0, 0x80 - lsls r0, 11 - adds r1, r0 - adds r5, r6, 0 - str r1, [r5, 0x4] - ldr r0, [r4, 0x4] - cmp r1, r0 - bcs _0800A82E - ldr r0, [sp, 0x18] - adds r0, 0x1 - str r0, [sp, 0x18] -_0800A82E: - adds r0, r4, 0 - adds r1, r4, 0 - adds r2, r5, 0 - bl sub_800A3F0 - adds r0, r5, 0 - mov r1, sp - adds r2, r4, 0 - bl sub_800A34C - ldr r0, [sp, 0x18] - lsls r1, r0, 1 - str r1, [sp, 0x18] - ldr r0, [r5, 0x4] - cmp r0, 0 - bge _0800A854 - movs r0, 0x1 - orrs r1, r0 - str r1, [sp, 0x18] -_0800A854: - ldr r0, [r6, 0x4] - lsls r0, 1 - str r0, [r6, 0x4] - ldr r2, [sp, 0x4] - ldr r1, [sp] - ldr r0, [sp, 0x18] - adds r1, r0 - str r1, [sp] - ldr r0, [r6, 0x4] - adds r0, r2, r0 - str r0, [sp, 0x4] - cmp r2, r0 - bls _0800A872 - adds r0, r1, 0x1 - str r0, [sp] -_0800A872: - mov r2, r9 - cmp r2, 0x2 - bne _0800A7F2 -_0800A878: - ldr r0, [sp] - ldr r1, [sp, 0x4] - mov r2, r10 - str r0, [r2] - str r1, [r2, 0x4] - add sp, 0x20 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_800A78C - - .align 2, 0 @ Don't pad with nop. diff --git a/include/number_util.h b/include/number_util.h index 8f85eedef..468aae34b 100644 --- a/include/number_util.h +++ b/include/number_util.h @@ -10,7 +10,7 @@ typedef struct FixedPoint typedef struct unkStruct_80943A8 { s32 s0; - u32 s4; // sub_800A5A4 requires this to be a u32, but other funcs check if it's negative... + u32 s4; // some math.c funcs require this to be a u32, but other funcs check if it's negative (aka >= INT32_MAX) } unkStruct_80943A8; FixedPoint FixedPoint_Add(FixedPoint a, FixedPoint b); diff --git a/ld_script.txt b/ld_script.txt index 77ff0e155..bac993ca0 100755 --- a/ld_script.txt +++ b/ld_script.txt @@ -69,7 +69,6 @@ SECTIONS { src/code_8009804.o(.text); asm/code_8009804.o(.text); src/math.o(.text); - asm/math.o(.text); src/file_system.o(.text); src/decompress.o(.text); src/main.o(.text); diff --git a/src/ground_script_1.c b/src/ground_script_1.c index 412efd5ea..502fad518 100644 --- a/src/ground_script_1.c +++ b/src/ground_script_1.c @@ -12,6 +12,7 @@ #include "code_8097670.h" #include "exclusive_pokemon.h" #include "items.h" +#include "math.h" #ifndef NONMATCHING #define GROUND_SCRIPT_INCOMPLETE_DECLARATIONS @@ -52,7 +53,6 @@ char sub_8002984(s32, u8); u32 VecDirection8Radial(); u32 SizedDeltaDirection4(); u8 SizedDeltaDirection8(Position32*, Position32*, Position32*, Position32*); -s32 sub_8009FB8(); bool8 sub_8021700(s32); bool8 sub_802FCF0(void); diff --git a/src/math.c b/src/math.c index 6194c4294..8ab0ee17b 100644 --- a/src/math.c +++ b/src/math.c @@ -6,7 +6,6 @@ static u24_8 u24_8_div(u24_8, u24_8); static u24_8 u24_8_mul(u24_8, u24_8); -static bool8 u32_pair_less_than(u32, u32, u32, u32); static void sub_800A5A4(unkStruct_80943A8 *, unkStruct_80943A8 *, unkStruct_80943A8 *); static void sub_800A4E4(unkStruct_80943A8 *, unkStruct_80943A8 *, unkStruct_80943A8 *); @@ -24,9 +23,9 @@ static void sub_800A4E4(unkStruct_80943A8 *, unkStruct_80943A8 *, unkStruct_8094 */ UNUSED u32 fast_mod_3(s32 x) { - if (x < 0x100) { + if (x < 0x100) return gFastMod3Lookup[x]; - } + return x % 3; } @@ -42,6 +41,7 @@ s32 sin_abs_4096(s32 x) case 0xc00: return -gFastSinLookup[0x3ff - (x & 0x3ff)]; } + return 0; } @@ -57,6 +57,7 @@ s32 cos_4096(s32 x) case 0xc00: return gFastSinLookup[x & 0x3ff]; } + return 0; } @@ -89,26 +90,29 @@ static bool8 u32_pair_less_than(u32 x_hi, u32 x_lo, u32 y_hi, u32 y_lo) s24_8 s24_8_mul(s24_8 x, s24_8 y) { s24_8 ret; - bool8 sgn0 = x < 0; - bool8 sgn1 = y < 0; + bool8 sgn0; + bool8 sgn1; - if (x == 0) { - return 0; - } - if (y == 0) { - return 0; - } + sgn0 = x < 0; + sgn1 = y < 0; - if (sgn0) { + if (x == 0) + return 0; + + if (y == 0) + return 0; + + if (sgn0) x = -x; - } - if (sgn1) { + + if (sgn1) y = -y; - } + ret = u24_8_mul(x, y); - if (sgn0 != sgn1) { + + if (sgn0 != sgn1) ret = -ret; - } + return ret; } @@ -120,29 +124,32 @@ s24_8 s24_8_mul(s24_8 x, s24_8 y) * * @returns The quotient `x/y` as a signed 24.8 fixed-point number. */ -s24_8 s24_8_div(s24_8 x, s24_8 y) +static s24_8 s24_8_div(s24_8 x, s24_8 y) { s24_8 ret; - bool8 sgn0 = x < 0; - bool8 sgn1 = y < 0; + bool8 sgn0; + bool8 sgn1; - if (y == 0) { + sgn0 = x < 0; + sgn1 = y < 0; + + if (y == 0) return INT32_MAX; - } - if (x == 0) { - return 0; - } - if (sgn0) { + if (x == 0) + return 0; + + if (sgn0) x = -x; - } - if (sgn1) { + + if (sgn1) y = -y; - } + ret = u24_8_div(x, y); - if (sgn0 != sgn1) { + + if (sgn0 != sgn1) ret = -ret; - } + return ret; } @@ -165,9 +172,8 @@ static u24_8 u24_8_mul(u24_8 x, u24_8 y) u32 high_bit_mask; u32 round_up; - if (x == 0 || y == 0) { + if (x == 0 || y == 0) return 0; - } x_h = 0; x_l = x; @@ -175,35 +181,36 @@ static u24_8 u24_8_mul(u24_8 x, u24_8 y) y_l = y; out_h = 0; out_l = 0; - high_bit_mask = 0x80 << 0x18; // high bit of u32 + high_bit_mask = 0x80 << 24; // high bit of u32 for (i = 0; i < 64; ++i) { u32 prev_out_l = out_l; u32 y_bit = 1; y_bit &= y_l; + if (y_bit) { out_l += x_l; out_h += x_h; - if (prev_out_l > out_l) { + + if (prev_out_l > out_l) ++out_h; - } } y_l >>= 1; - if (y_h & 1) { + if (y_h & 1) y_l |= high_bit_mask; - } + y_h >>= 1; x_h <<= 1; - if (x_l & high_bit_mask) { + if (x_l & high_bit_mask) x_h |= 1; - } - do {x_l <<= 1;} while(0); // wtf moment + + do {x_l <<= 1;} while(0); // Fakematch? } - round_up = (out_l >> 0x7) & 1; - out_l = (out_l >> 0x8) | (out_h << 0x18); + round_up = (out_l >> 7) & 1; + out_l = (out_l >> 8) | (out_h << 24); if (round_up) { ++out_l; @@ -222,27 +229,25 @@ static u24_8 u24_8_mul(u24_8 x, u24_8 y) */ static u24_8 u24_8_div(u24_8 x, u24_8 y) { - bool8 bVar1; - u32 r9; - u32 r2; - u32 r4; - u32 r5; - u32 r6; - u32 r7; - u32 r8; - int counter; - s32 sl; - s32 flag; - s32 save; - - if (y == 0) { - return INT32_MAX; - } - else if (x == 0) { - return 0; - } - else { - r7 = x >> 0x18; + bool8 bVar1; + u32 r9; + u32 r2; + u32 r4; + u32 r5; + u32 r6; + u32 r7; + u32 r8; + s32 i; + s32 sl; + s32 temp; + + if (y == 0) + return INT32_MAX; + + if (x == 0) + return 0; + + r7 = x >> 24; r6 = x << 8; sl = y; r9 = 0; @@ -251,43 +256,38 @@ static u24_8 u24_8_div(u24_8 x, u24_8 y) r2 = 0; r8 = 1; - - for(counter = 0x3f; counter >= 0; counter--) - { - r5 <<= 1; - if ((r4 & 0x80000000) != 0) { - r5 |= r8; - } - flag = -2; - r4 <<= 1; - if ((r7 & 0x80000000) != 0) { - r4 |= r8; - } - r7 <<= 1; - if ((r6 & 0x80000000) != 0) { - r7 |= r8; - } - r6 <<= 1; - r6 &= flag; - if (u32_pair_less_than(r5,r4,0,sl) == 0) { - save = r4; - bVar1 = 1; - r4 = r4 - sl; - r5 = r5 - r2; // WHY???? - if (save < r4) { - r5--; + for (i = 0; i < 64; i++) { + r5 <<= 1; + if (r4 & 0x80000000) + r5 |= r8; + + r4 = (r4 << 1) & ~0x1; + if (r7 & 0x80000000) + r4 |= r8; + + r7 <<= 1; + if (r6 & 0x80000000) + r7 |= r8; + + r6 = (r6 << 1) & ~0x1; + + if (!u32_pair_less_than(r5, r4, 0, sl)) { + temp = r4; + bVar1 = TRUE; + r4 -= sl; + r5 -= r2; + if (temp < r4) + r5--; } - } - else { - bVar1 = 0; - } - r9 <<= 1; - if (bVar1) { - r9 |= r8; - } + else + bVar1 = FALSE; + + r9 <<= 1; + if (bVar1) + r9 |= r8; } - } - return r9; + + return r9; } UNUSED s32 sub_8009F68(s32 x, s32 y) @@ -296,55 +296,56 @@ UNUSED s32 sub_8009F68(s32 x, s32 y) s32 sVar1; uVar1 = y; - if (y < 0) { - uVar1 = -y; - } + if (uVar1 < 0) + uVar1 = -uVar1; + sVar1 = 0x100; + for (; uVar1 != 0; uVar1 >>= 1) { - if ((uVar1 & 1) != 0) { + if (uVar1 & 1) sVar1 = s24_8_mul(sVar1, x); - } + x = s24_8_mul(x, x); } - if (y >= 0) { + + if (y >= 0) return sVar1; - } - else - return s24_8_div(0x100,sVar1); + + return s24_8_div(0x100, sVar1); } s32 sub_8009FB8(s32 x, s32 y) { s32 r4; - s32 counter; - + s32 i; s32 r5; s32 r6; r5 = x; r6 = y; - if (r5 < 0) { + if (r5 < 0) r5 = -r5; - } - if (r6 < 0) { + + if (r6 < 0) r6 = -r6; - } + if (r5 < r6) { r4 = r5; r5 = r6; r6 = r4; } + if (r6 != 0) { - for(counter = 2; counter >= 0; counter--) - { - r4 = s24_8_div(r6,r5); - r4 = s24_8_mul(r4,r4); - r4 = s24_8_div(r4,r4 + 0x400); - r5 = r5 + s24_8_mul(r5,r4) * 2; - r6 = s24_8_mul(r6,r4); + for (i = 2; i >= 0; i--) { + r4 = s24_8_div(r6, r5); + r4 = s24_8_mul(r4, r4); + r4 = s24_8_div(r4, r4 + 0x400); + r5 += s24_8_mul(r5, r4) * 2; + r6 = s24_8_mul(r6, r4); } } + return r5; } @@ -524,7 +525,7 @@ static void sub_800A25C(unkStruct_80943A8 *a) a->s0++; } -void sub_800A27C(unkStruct_80943A8 *a) +static void sub_800A27C(unkStruct_80943A8 *a) { if (a->s0 < 0) { a->s0 = ~a->s0; @@ -660,7 +661,7 @@ void sub_800A3F0(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 } } -void sub_800A4A0(unkStruct_80943A8 *a) +static void sub_800A4A0(unkStruct_80943A8 *a) { unkStruct_80943A8 aa; unkStruct_80943A8 res; @@ -750,6 +751,7 @@ static void sub_800A4E4(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_ } } +// Similar to u24_8_div static void sub_800A5A4(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 *b) { s32 temp; @@ -821,4 +823,122 @@ static void sub_800A5A4(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_ dst->s0 = spC; dst->s4 = r9; } +} + +void sub_800A6D0(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 *b) +{ + s32 s0; + u32 s4; + + s0 = a->s0 + b->s0; + s4 = a->s4 + b->s4; + if (s4 < a->s4) + s0++; + + dst->s0 = s0; + dst->s4 = s4; +} + +void sub_800A6F0(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 *b) +{ + s32 s0; + u32 s4; + + s0 = a->s0 - b->s0; + s4 = a->s4 - b->s4; + if (s4 > a->s4) + s0--; + + dst->s0 = s0; + dst->s4 = s4; +} + +// Similar to sub_8009F68 +UNUSED void sub_800A710(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, s32 b) +{ + unkStruct_80943A8 aa; + s32 bb; + unkStruct_80943A8 res; + + aa.s0 = a->s0; + aa.s4 = a->s4; + bb = b; + if (bb < 0) + bb = -bb; + + res.s0 = 0; + res.s4 = 0x10000; + + for (; bb != 0; bb >>= 1) { + if (bb & 1) + sub_800A34C(&res, &res, &aa); + + sub_800A4A0(&aa); + } + + if (b < 0) { + unkStruct_80943A8 idk; + idk.s0 = 0; + idk.s4 = 0x10000; + sub_800A3F0(&res, &idk, &res); + } + + dst->s0 = res.s0; + dst->s4 = res.s4; +} + +// Similar to sub_8009FB8 +UNUSED void sub_800A78C(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 *b) +{ + u32 temp; + s32 i; + unkStruct_80943A8 sp0; + unkStruct_80943A8 sp8; + unkStruct_80943A8 sp10; + unkStruct_80943A8 sp18; + + sp0 = *a; + sp8 = *b; + sub_800A27C(&sp0); + sub_800A27C(&sp8); + + if (sub_800A2F0(&sp0, &sp8)) { + sp10 = sp0; + sp0 = sp8; + sp8 = sp10; + } + + if (!sub_800A2A0(&sp8)) { + i = 0; + goto deez; // Fakematch cuz ya (https://decomp.me/scratch/2TCrJ) + + while (i != 2) { + sub_800A34C(&sp8, &sp8, &sp10); + i++; +deez: + + sub_800A3F0(&sp10, &sp8, &sp0); + sub_800A4A0(&sp10); + sp18.s0 = sp10.s0; + sp18.s4 = sp10.s4 + 0x40000; + + if (sp18.s4 < sp10.s4) + sp18.s0++; + + sub_800A3F0(&sp10, &sp10, &sp18); + sub_800A34C(&sp18, &sp0, &sp10); + sp18.s0 <<= 1; + if ((s32)sp18.s4 < 0) + sp18.s0 |= 0x1; + + sp18.s4 <<= 1; + temp = sp0.s4; + sp0.s0 += sp18.s0; + sp0.s4 = temp + sp18.s4; + if (temp > sp0.s4) + sp0.s0++; + } + } + + *dst = sp0; } \ No newline at end of file