From 9ab3ae9aaa82fd3c80ae290fb36d99e98eeb1327 Mon Sep 17 00:00:00 2001 From: Mateon1 Date: Wed, 13 Nov 2024 19:36:23 +0100 Subject: [PATCH] Math refactoring/cleanup --- asm/code_800F990.s | 4 +- include/math.h | 2 +- include/number_util.h | 7 ++ src/code_806FDF4.c | 2 +- src/code_8077274_1.c | 4 +- src/data/math.h | 10 ++- src/math.c | 159 +++++++++++++++++++++--------------------- tmp/gettile.cocci | 42 ----------- 8 files changed, 96 insertions(+), 134 deletions(-) delete mode 100644 tmp/gettile.cocci diff --git a/asm/code_800F990.s b/asm/code_800F990.s index 1fa0545f6..711c1a5d2 100644 --- a/asm/code_800F990.s +++ b/asm/code_800F990.s @@ -609,7 +609,7 @@ _0800FE3C: lsls r0, 8 str r0, [sp, 0x10] add r0, sp, 0xC - bl sub_800A0B0 + bl Atan2_4096 adds r2, r0, 0 ldr r0, [sp, 0xC] cmp r0, 0 @@ -1294,7 +1294,7 @@ _08010392: str r0, [sp, 0xC] str r3, [sp, 0x10] add r0, sp, 0xC - bl sub_800A0B0 + bl Atan2_4096 ldr r1, _08010474 adds r3, r0, r1 cmp r3, 0 diff --git a/include/math.h b/include/math.h index 2fdb563ec..74f659d2d 100644 --- a/include/math.h +++ b/include/math.h @@ -41,7 +41,7 @@ void F48_16_SDiv(s48_16 *dst, s48_16 *a, s48_16 *b); void F48_16_SMul(s48_16 *dst, s48_16 *a, s48_16 *b); s24_8 FP24_8_Hypot(s24_8 x, s24_8 y); -void FP48_16_FromS32(s48_16 *dst, u32); +void FP48_16_FromS32(s48_16 *dst, s32 src); u32 FP48_16_ToS32(s48_16 *a); void FP48_16_FromF248(s48_16 *a, s24_8 b); bool8 FP48_16_SLessThan(s48_16 *a, s48_16 *b); diff --git a/include/number_util.h b/include/number_util.h index d2e6741ed..ed5c06d0e 100644 --- a/include/number_util.h +++ b/include/number_util.h @@ -22,6 +22,10 @@ typedef struct s24_8 { s32 raw; } s24_8; +#define F248_ZERO ((s24_8){}) +#define F248_ONE ((s24_8){0x100}) +#define F248_MAX ((s24_8){0x7FFFFFFF}) + /** * This type represents a signed 48.16 fixed-point number, where the 48 most * significant bits are the integer part and the 16 least significant bits are @@ -32,6 +36,9 @@ typedef struct s48_16 s32 hi; u32 lo; // some math.c funcs require this to be a u32, but other funcs check if it's negative (aka >= INT32_MAX) } s48_16; +#define F4816_ZERO ((s48_16){}) +#define F4816_ONE ((s48_16){0, 0x10000}) +#define F4816_MAX ((s48_16){0x7FFFFFFF, 0xFFFFFFFF}) FixedPoint FixedPoint_Add(FixedPoint a, FixedPoint b); FixedPoint FixedPoint_Subtract(FixedPoint a, FixedPoint b); diff --git a/src/code_806FDF4.c b/src/code_806FDF4.c index 553ffa59b..134ea7ce6 100644 --- a/src/code_806FDF4.c +++ b/src/code_806FDF4.c @@ -133,7 +133,7 @@ void sub_806F500(void) temp->unk140[6] = 0; temp->unk150 = 0; temp->unk158 = 0; - temp->unk15C = IntToF248(0); + temp->unk15C = F248_ZERO; temp->unk160 = 0; temp->unk161 = 0; temp->unk162 = 0; diff --git a/src/code_8077274_1.c b/src/code_8077274_1.c index 51b78451a..98a093482 100644 --- a/src/code_8077274_1.c +++ b/src/code_8077274_1.c @@ -1027,11 +1027,11 @@ void sub_8079E34(Entity * pokemon, Entity * target, bool8 param_3) statChanged = TRUE; } if (!F248EqualsInt(entityInfo->offensiveMultipliers[index], 1)) { - entityInfo->offensiveMultipliers[index] = IntToF248(1); + entityInfo->offensiveMultipliers[index] = F248_ONE; statChanged = TRUE; } if (!F248EqualsInt(entityInfo->defensiveMultipliers[index], 1)) { - entityInfo->defensiveMultipliers[index] = IntToF248(1); + entityInfo->defensiveMultipliers[index] = F248_ONE; statChanged = TRUE; } } diff --git a/src/data/math.h b/src/data/math.h index b563999e1..fff6c880d 100644 --- a/src/data/math.h +++ b/src/data/math.h @@ -1,5 +1,3 @@ -// gFastMod3Lookup - const u8 gFastMod3Lookup[0x100] = { 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0 }; @@ -9,8 +7,8 @@ const u8 gFastDiv3Lookup[0x100] = { }; -// gFastSinLookup[i] = floor(256 * sin(iπ / 2048)) -static const s16 gFastSinLookup[] = { +// sFastSinLookup[i] = floor(256 * sin(iπ / 2048)) +static const s16 sFastSinLookup[] = { 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 9, @@ -141,8 +139,8 @@ static const s16 gFastSinLookup[] = { 255, 255, 255, 255, 255, 255, 255, 255, }; - -const u32 gFastUnknownFn1Lookup[] = { +// sFastAtan2Lookup256[256*y/x] = atan2(x,y) for x>y>=0, in units of 2π/256 +static const u32 sFastAtan2Lookup256[] = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, diff --git a/src/math.c b/src/math.c index a63c1cf94..1f43fec47 100644 --- a/src/math.c +++ b/src/math.c @@ -3,6 +3,7 @@ #include "math.h" #include "data/math.h" +#include "structs/str_position.h" static void F48_16_UDiv(s48_16 *, s48_16 *, s48_16 *); static void F48_16_UMul(s48_16 *, s48_16 *, s48_16 *); @@ -32,13 +33,13 @@ s32 sin_4096(s32 x) { switch (x & 0xc00) { case 0x000: - return gFastSinLookup[x & 0x3ff]; + return sFastSinLookup[x & 0x3ff]; case 0x400: - return gFastSinLookup[0x3ff - (x & 0x3ff)]; + return sFastSinLookup[0x3ff - (x & 0x3ff)]; case 0x800: - return -gFastSinLookup[x & 0x3ff]; + return -sFastSinLookup[x & 0x3ff]; case 0xc00: - return -gFastSinLookup[0x3ff - (x & 0x3ff)]; + return -sFastSinLookup[0x3ff - (x & 0x3ff)]; } return 0; @@ -48,13 +49,13 @@ s32 cos_4096(s32 x) { switch (x & 0xc00) { case 0x000: - return gFastSinLookup[0x3ff - (x & 0x3ff)]; + return sFastSinLookup[0x3ff - (x & 0x3ff)]; case 0x400: - return -gFastSinLookup[x & 0x3ff]; + return -sFastSinLookup[x & 0x3ff]; case 0x800: - return -gFastSinLookup[0x3ff - (x & 0x3ff)]; + return -sFastSinLookup[0x3ff - (x & 0x3ff)]; case 0xc00: - return gFastSinLookup[x & 0x3ff]; + return sFastSinLookup[x & 0x3ff]; } return 0; @@ -172,7 +173,7 @@ static s24_8 u24_8_mul(s24_8 x, s24_8 y) u32 round_up; if (x.raw == 0 || y.raw == 0) - return (s24_8){0}; + return F248_ZERO; x_h = 0; x_l = x.raw; @@ -241,10 +242,10 @@ static s24_8 u24_8_div(s24_8 x, s24_8 y) s32 temp; if (y.raw == 0) - return (s24_8){INT32_MAX}; + return F248_MAX; if (x.raw == 0) - return (s24_8){0}; + return F248_ZERO; r7 = (u32)x.raw >> 24; r6 = x.raw << 8; @@ -298,7 +299,7 @@ UNUSED s24_8 FP24_8_Pow(s24_8 x, s32 y) if (uVar1 < 0) uVar1 = -uVar1; - sVar1 = IntToF248(1); + sVar1 = F248_ONE; for (; uVar1 != 0; uVar1 >>= 1) { if (uVar1 & 1) @@ -310,7 +311,7 @@ UNUSED s24_8 FP24_8_Pow(s24_8 x, s32 y) if (y >= 0) return sVar1; - return s24_8_div(IntToF248(1), sVar1); + return s24_8_div(F248_ONE, sVar1); } s24_8 FP24_8_Hypot(s24_8 x, s24_8 y) @@ -348,21 +349,18 @@ s24_8 FP24_8_Hypot(s24_8 x, s24_8 y) return r5; } -void FP48_16_FromS32(s48_16 *param_1, u32 param_2) +void FP48_16_FromS32(s48_16 *dst, s32 src) { -#ifndef NONMATCHING - register u32 temp asm("r4"); + dst->hi = (src & ~0xFFFFu) >> 16; + dst->lo = (src & 0xFFFFu) << 16; + + // BUG: Should be checking top bit of src, or using dst->hi here (see FP48_16_FromF248) +#ifdef BUGFIX + if (dst->hi & 0x8000) #else - u32 temp; + if (src & 0x8000) #endif - - temp = 0xFFFF0000; - param_1->hi = param_2 >> 16; - param_1->lo = param_2 << 16; - - if (param_2 & 0x8000) - param_1->hi |= temp; - + dst->hi |= ~0xFFFF; } u32 FP48_16_ToS32(s48_16 *a) @@ -398,118 +396,119 @@ void FP48_16_FromF248(s48_16 *a, s24_8 b) a->hi &= 0x7f; } -s32 sub_800A0B0(s48_16 *a) +// returns 12-bit angle +s32 Atan2_4096(PixelPos *a) { - s32 r2; - s32 r3; + s32 y; + s32 x; s32 idx; s32 divi; - r2 = a->lo; - r3 = a->hi; - if (r2 == 0 && r3 == 0) + y = a->y; + x = a->x; + if (y == 0 && x == 0) return 0; - if (r2 > 0) { - if (r3 > 0) { - if (r2 < r3) { - divi = r3 / 256; + if (y > 0) { + if (x > 0) { + if (y < x) { + divi = F248ToInt((s24_8){x}); if (divi == 0) return 0x200; - idx = r2 / divi; + idx = y / divi; if (idx > 0xFF) idx = 0xFF; - - return gFastUnknownFn1Lookup[idx] << 4; + + return sFastAtan2Lookup256[idx] << 4; } - else { // r2 >= r3 - divi = r2 / 256; + else { // y >= x + divi = F248ToInt((s24_8){y}); if (divi == 0) return 0x200; - idx = r3 / divi; + idx = x / divi; if (idx > 0xFF) idx = 0xFF; - - return (0x40 - gFastUnknownFn1Lookup[idx]) << 4; + + return (0x40 - sFastAtan2Lookup256[idx]) << 4; } } - else { // r3 <= 0 - r3 = -r3; - if (r2 < r3) { - divi = r3 / 256; + else { // x <= 0 + x = -x; + if (y < x) { + divi = F248ToInt((s24_8){x}); if (divi == 0) return 0x600; - idx = r2 / divi; + idx = y / divi; if (idx > 0xFF) idx = 0xFF; - - return (0x80 - gFastUnknownFn1Lookup[idx]) << 4; + + return (0x80 - sFastAtan2Lookup256[idx]) << 4; } - else { // r2 >= r3 - divi = r2 / 256; + else { // y >= x + divi = F248ToInt((s24_8){y}); if (divi == 0) return 0x600; - idx = r3 / divi; + idx = x / divi; if (idx > 0xFF) idx = 0xFF; - - return (gFastUnknownFn1Lookup[idx] + 0x40) << 4; + + return (sFastAtan2Lookup256[idx] + 0x40) << 4; } } } - else { // r2 <= 0 - r2 = -r2; - if (r3 > 0) { - if (r2 < r3) { - divi = r3 / 256; + else { // y <= 0 + y = -y; + if (x > 0) { + if (y < x) { + divi = F248ToInt((s24_8){x}); if (divi == 0) return 0xE00; - idx = r2 / divi; + idx = y / divi; if (idx > 0xFF) idx = 0xFF; - - return (0x100 - gFastUnknownFn1Lookup[idx]) << 4; + + return (0x100 - sFastAtan2Lookup256[idx]) << 4; } - else { // r2 >= r3 - divi = r2 / 256; + else { // y >= x + divi = F248ToInt((s24_8){y}); if (divi == 0) return 0xE00; - idx = r3 / divi; + idx = x / divi; if (idx > 0xFF) idx = 0xFF; - - return (gFastUnknownFn1Lookup[idx] + 0xC0) << 4; + + return (sFastAtan2Lookup256[idx] + 0xC0) << 4; } } - else { // r3 <= 0 - r3 = -r3; - if (r2 < r3) { - divi = r3 / 256; + else { // x <= 0 + x = -x; + if (y < x) { + divi = F248ToInt((s24_8){x}); if (divi == 0) return 0xA00; - idx = r2 / divi; + idx = y / divi; if (idx > 0xFF) idx = 0xFF; - - return (gFastUnknownFn1Lookup[idx] + 0x80) << 4; + + return (sFastAtan2Lookup256[idx] + 0x80) << 4; } - else { // r2 >= r3 - divi = r2 / 256; + else { // y >= x + divi = F248ToInt((s24_8){y}); if (divi == 0) return 0xA00; - idx = r3 / divi; + idx = x / divi; if (idx > 0xFF) idx = 0xFF; - - return (0xC0 - gFastUnknownFn1Lookup[idx]) << 4; + + return (0xC0 - sFastAtan2Lookup256[idx]) << 4; } } } diff --git a/tmp/gettile.cocci b/tmp/gettile.cocci deleted file mode 100644 index ce7dc37b0..000000000 --- a/tmp/gettile.cocci +++ /dev/null @@ -1,42 +0,0 @@ -@ r1 disable optional_qualifier exists @ -identifier tile; -@@ -- Tile *tile; -++ const Tile *tile; - ... - tile = GetTile(...) -@ r2 disable optional_qualifier exists @ -identifier tile; -@@ -- Tile *tile -++ const Tile *tile - = GetTile(...); -@ decls disable optional_qualifier @ -identifier tile; -@@ -( - Tile *tile; -| - Tile *tile = ...; -) -@ mutated depends on decls exists @ -identifier decls.tile; -assignment operator op; -identifier f; -@@ -( - tile->f op ...; -| - f(<+... tile ...+>) -) -@ notmutated depends on decls && !mutated disable optional_qualifier @ -identifier decls.tile; -@@ -( -- Tile *tile; -++ const Tile *tile; -| -- Tile *tile -++ const Tile *tile - = ...; -)