diff --git a/asm/math.s b/asm/math.s index 03bf69661..b74ecdb99 100644 --- a/asm/math.s +++ b/asm/math.s @@ -5,634 +5,6 @@ .text - thumb_func_start sub_800A088 -sub_800A088: - push {lr} - adds r2, r0, 0 - lsls r0, r1, 8 - str r0, [r2, 0x4] - asrs r1, 24 - str r1, [r2] - movs r0, 0x80 - ands r0, r1 - cmp r0, 0 - beq _0800A0A4 - movs r0, 0x80 - negs r0, r0 - orrs r1, r0 - b _0800A0A8 -_0800A0A4: - movs r0, 0x7F - ands r1, r0 -_0800A0A8: - str r1, [r2] - pop {r0} - bx r0 - thumb_func_end sub_800A088 - - thumb_func_start sub_800A0B0 -sub_800A0B0: - push {lr} - ldr r2, [r0, 0x4] - ldr r3, [r0] - cmp r2, 0 - bne _0800A0C2 - cmp r3, 0 - bne _0800A0C2 - movs r0, 0 - b _0800A254 -_0800A0C2: - cmp r2, 0 - ble _0800A18C - cmp r3, 0 - ble _0800A124 - cmp r2, r3 - bge _0800A0F0 - asrs r1, r3, 8 - cmp r1, 0 - beq _0800A0FE - adds r0, r2, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A0E2 - movs r2, 0xFF -_0800A0E2: - ldr r0, _0800A0EC - lsls r1, r2, 2 - adds r1, r0 - ldr r0, [r1] - b _0800A252 - .align 2, 0 -_0800A0EC: .4byte gFastUnknownFn1Lookup -_0800A0F0: - adds r1, r2, 0 - cmp r2, 0 - bge _0800A0F8 - adds r1, 0xFF -_0800A0F8: - asrs r1, 8 - cmp r1, 0 - bne _0800A104 -_0800A0FE: - movs r0, 0x80 - lsls r0, 2 - b _0800A254 -_0800A104: - adds r0, r3, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A112 - movs r2, 0xFF -_0800A112: - ldr r1, _0800A120 - lsls r0, r2, 2 - adds r0, r1 - ldr r1, [r0] - movs r0, 0x40 - b _0800A250 - .align 2, 0 -_0800A120: .4byte gFastUnknownFn1Lookup -_0800A124: - negs r3, r3 - cmp r2, r3 - bge _0800A158 - adds r1, r3, 0 - cmp r3, 0 - bge _0800A132 - adds r1, 0xFF -_0800A132: - asrs r1, 8 - cmp r1, 0 - beq _0800A166 - adds r0, r2, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A146 - movs r2, 0xFF -_0800A146: - ldr r1, _0800A154 - lsls r0, r2, 2 - adds r0, r1 - ldr r1, [r0] - movs r0, 0x80 - b _0800A250 - .align 2, 0 -_0800A154: .4byte gFastUnknownFn1Lookup -_0800A158: - adds r1, r2, 0 - cmp r2, 0 - bge _0800A160 - adds r1, 0xFF -_0800A160: - asrs r1, 8 - cmp r1, 0 - bne _0800A16C -_0800A166: - movs r0, 0xC0 - lsls r0, 3 - b _0800A254 -_0800A16C: - adds r0, r3, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A17A - movs r2, 0xFF -_0800A17A: - ldr r0, _0800A188 - lsls r1, r2, 2 - adds r1, r0 - ldr r0, [r1] - adds r0, 0x40 - b _0800A252 - .align 2, 0 -_0800A188: .4byte gFastUnknownFn1Lookup -_0800A18C: - negs r2, r2 - cmp r3, 0 - ble _0800A1F0 - cmp r2, r3 - bge _0800A1BC - asrs r1, r3, 8 - cmp r1, 0 - beq _0800A1CA - adds r0, r2, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A1AA - movs r2, 0xFF -_0800A1AA: - ldr r1, _0800A1B8 - lsls r0, r2, 2 - adds r0, r1 - ldr r1, [r0] - movs r0, 0x80 - lsls r0, 1 - b _0800A250 - .align 2, 0 -_0800A1B8: .4byte gFastUnknownFn1Lookup -_0800A1BC: - adds r1, r2, 0 - cmp r2, 0 - bge _0800A1C4 - adds r1, 0xFF -_0800A1C4: - asrs r1, 8 - cmp r1, 0 - bne _0800A1D0 -_0800A1CA: - movs r0, 0xE0 - lsls r0, 4 - b _0800A254 -_0800A1D0: - adds r0, r3, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A1DE - movs r2, 0xFF -_0800A1DE: - ldr r0, _0800A1EC - lsls r1, r2, 2 - adds r1, r0 - ldr r0, [r1] - adds r0, 0xC0 - b _0800A252 - .align 2, 0 -_0800A1EC: .4byte gFastUnknownFn1Lookup -_0800A1F0: - negs r3, r3 - cmp r2, r3 - bge _0800A224 - adds r1, r3, 0 - cmp r3, 0 - bge _0800A1FE - adds r1, 0xFF -_0800A1FE: - asrs r1, 8 - cmp r1, 0 - beq _0800A232 - adds r0, r2, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A212 - movs r2, 0xFF -_0800A212: - ldr r0, _0800A220 - lsls r1, r2, 2 - adds r1, r0 - ldr r0, [r1] - adds r0, 0x80 - b _0800A252 - .align 2, 0 -_0800A220: .4byte gFastUnknownFn1Lookup -_0800A224: - adds r0, r2, 0 - cmp r0, 0 - bge _0800A22C - adds r0, 0xFF -_0800A22C: - asrs r1, r0, 8 - cmp r1, 0 - bne _0800A238 -_0800A232: - movs r0, 0xA0 - lsls r0, 4 - b _0800A254 -_0800A238: - adds r0, r3, 0 - bl __divsi3 - adds r2, r0, 0 - cmp r2, 0xFF - ble _0800A246 - movs r2, 0xFF -_0800A246: - ldr r1, _0800A258 - lsls r0, r2, 2 - adds r0, r1 - ldr r1, [r0] - movs r0, 0xC0 -_0800A250: - subs r0, r1 -_0800A252: - lsls r0, 4 -_0800A254: - pop {r1} - bx r1 - .align 2, 0 -_0800A258: .4byte gFastUnknownFn1Lookup - thumb_func_end sub_800A0B0 - -// invert signed lex pair - thumb_func_start sub_800A25C -sub_800A25C: - push {lr} - adds r1, r0, 0 - ldr r0, [r1] - mvns r2, r0 - str r2, [r1] - ldr r0, [r1, 0x4] - mvns r0, r0 - adds r0, 0x1 - str r0, [r1, 0x4] - cmp r0, 0 - bne _0800A276 - adds r0, r2, 0x1 - str r0, [r1] -_0800A276: - pop {r0} - bx r0 - thumb_func_end sub_800A25C - -// absolute value of signed lex pair - thumb_func_start sub_800A27C -sub_800A27C: - push {lr} - adds r1, r0, 0 - ldr r0, [r1] - cmp r0, 0 - bge _0800A29A - mvns r2, r0 - str r2, [r1] - ldr r0, [r1, 0x4] - mvns r0, r0 - adds r0, 0x1 - str r0, [r1, 0x4] - cmp r0, 0 - bne _0800A29A - adds r0, r2, 0x1 - str r0, [r1] -_0800A29A: - pop {r0} - bx r0 - thumb_func_end sub_800A27C - - thumb_func_start sub_800A2A0 -sub_800A2A0: - push {lr} - adds r1, r0, 0 - ldr r0, [r1] - cmp r0, 0 - bne _0800A2B4 - ldr r0, [r1, 0x4] - cmp r0, 0 - bne _0800A2B4 - movs r0, 0x1 - b _0800A2B6 -_0800A2B4: - movs r0, 0 -_0800A2B6: - pop {r1} - bx r1 - thumb_func_end sub_800A2A0 - - thumb_func_start sub_800A2BC -sub_800A2BC: - push {lr} - adds r2, r0, 0 - adds r3, r1, 0 - ldr r1, [r2] - ldr r0, [r3] - cmp r1, r0 - bne _0800A2D6 - ldr r1, [r2, 0x4] - ldr r0, [r3, 0x4] - cmp r1, r0 - bne _0800A2D6 - movs r0, 0x1 - b _0800A2D8 -_0800A2D6: - movs r0, 0 -_0800A2D8: - pop {r1} - bx r1 - thumb_func_end sub_800A2BC - - thumb_func_start sub_800A2DC -sub_800A2DC: - push {lr} - ldr r0, [r0] - cmp r0, 0 - blt _0800A2E8 - movs r0, 0 - b _0800A2EA -_0800A2E8: - movs r0, 0x1 -_0800A2EA: - pop {r1} - bx r1 - thumb_func_end sub_800A2DC - - thumb_func_start sub_800A2F0 -sub_800A2F0: - push {r4,r5,lr} - adds r3, r0, 0 - adds r2, r1, 0 - ldr r4, [r3] - lsrs r1, r4, 31 - ldr r5, [r2] - cmp r5, 0 - bge _0800A304 - movs r0, 0x2 - orrs r1, r0 -_0800A304: - cmp r1, 0x1 - beq _0800A326 - cmp r1, 0x1 - ble _0800A314 - cmp r1, 0x2 - beq _0800A32A - cmp r1, 0x3 - beq _0800A32E -_0800A314: - ldr r1, [r3, 0x4] - ldr r3, [r2, 0x4] - adds r0, r4, 0 - adds r2, r5, 0 - bl u32_pair_less_than - lsls r0, 24 - lsrs r0, 24 - b _0800A346 -_0800A326: - movs r0, 0x1 - b _0800A346 -_0800A32A: - movs r0, 0 - b _0800A346 -_0800A32E: - ldr r1, [r3, 0x4] - ldr r3, [r2, 0x4] - adds r0, r4, 0 - adds r2, r5, 0 - bl u32_pair_less_than - movs r1, 0 - lsls r0, 24 - cmp r0, 0 - bne _0800A344 - movs r1, 0x1 -_0800A344: - adds r0, r1, 0 -_0800A346: - pop {r4,r5} - pop {r1} - bx r1 - thumb_func_end sub_800A2F0 - - thumb_func_start sub_800A34C -sub_800A34C: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x18 - adds r6, r0, 0 - ldr r0, [r1] - str r0, [sp] - ldr r0, [r1, 0x4] - str r0, [sp, 0x4] - ldr r0, [r2] - str r0, [sp, 0x8] - ldr r0, [r2, 0x4] - add r5, sp, 0x8 - str r0, [r5, 0x4] - mov r0, sp - bl sub_800A2DC - lsls r0, 24 - lsrs r0, 24 - mov r8, r0 - mov r10, r8 - adds r0, r5, 0 - bl sub_800A2DC - lsls r0, 24 - lsrs r7, r0, 24 - mov r9, r7 - mov r0, sp - bl sub_800A2A0 - lsls r0, 24 - lsrs r4, r0, 24 - cmp r4, 0 - beq _0800A39A - movs r0, 0 - str r0, [r6] - b _0800A3DE -_0800A39A: - adds r0, r5, 0 - bl sub_800A2A0 - lsls r0, 24 - cmp r0, 0 - beq _0800A3AC - str r4, [r6] - str r4, [r6, 0x4] - b _0800A3E0 -_0800A3AC: - mov r0, r8 - cmp r0, 0 - beq _0800A3B8 - mov r0, sp - bl sub_800A25C -_0800A3B8: - cmp r7, 0 - beq _0800A3C2 - adds r0, r5, 0 - bl sub_800A25C -_0800A3C2: - add r4, sp, 0x10 - adds r0, r4, 0 - mov r1, sp - adds r2, r5, 0 - bl sub_800A4E4 - cmp r10, r9 - beq _0800A3D8 - adds r0, r4, 0 - bl sub_800A25C -_0800A3D8: - ldr r0, [sp, 0x10] - str r0, [r6] - ldr r0, [r4, 0x4] -_0800A3DE: - str r0, [r6, 0x4] -_0800A3E0: - add sp, 0x18 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_800A34C - - thumb_func_start sub_800A3F0 -sub_800A3F0: - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x18 - adds r6, r0, 0 - ldr r0, [r1] - str r0, [sp] - ldr r0, [r1, 0x4] - str r0, [sp, 0x4] - ldr r0, [r2] - str r0, [sp, 0x8] - ldr r0, [r2, 0x4] - add r5, sp, 0x8 - str r0, [r5, 0x4] - mov r0, sp - bl sub_800A2DC - lsls r0, 24 - lsrs r0, 24 - mov r8, r0 - mov r10, r8 - adds r0, r5, 0 - bl sub_800A2DC - lsls r0, 24 - lsrs r7, r0, 24 - mov r9, r7 - adds r0, r5, 0 - bl sub_800A2A0 - lsls r0, 24 - lsrs r4, r0, 24 - cmp r4, 0 - beq _0800A448 - ldr r0, _0800A444 - str r0, [r6] - movs r0, 0x1 - negs r0, r0 - b _0800A48C - .align 2, 0 -_0800A444: .4byte 0x7fffffff -_0800A448: - mov r0, sp - bl sub_800A2A0 - lsls r0, 24 - cmp r0, 0 - beq _0800A45A - str r4, [r6] - str r4, [r6, 0x4] - b _0800A48E -_0800A45A: - mov r0, r8 - cmp r0, 0 - beq _0800A466 - mov r0, sp - bl sub_800A25C -_0800A466: - cmp r7, 0 - beq _0800A470 - adds r0, r5, 0 - bl sub_800A25C -_0800A470: - add r4, sp, 0x10 - adds r0, r4, 0 - mov r1, sp - adds r2, r5, 0 - bl sub_800A5A4 - cmp r10, r9 - beq _0800A486 - adds r0, r4, 0 - bl sub_800A25C -_0800A486: - ldr r0, [sp, 0x10] - str r0, [r6] - ldr r0, [r4, 0x4] -_0800A48C: - str r0, [r6, 0x4] -_0800A48E: - add sp, 0x18 - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_800A3F0 - - thumb_func_start sub_800A4A0 -sub_800A4A0: - push {r4,r5,lr} - sub sp, 0x10 - adds r5, r0, 0 - ldr r0, [r5] - str r0, [sp] - ldr r0, [r5, 0x4] - str r0, [sp, 0x4] - mov r0, sp - bl sub_800A2A0 - lsls r0, 24 - cmp r0, 0 - beq _0800A4C0 - movs r0, 0 - str r0, [r5] - b _0800A4D8 -_0800A4C0: - mov r0, sp - bl sub_800A27C - add r4, sp, 0x8 - adds r0, r4, 0 - mov r1, sp - mov r2, sp - bl sub_800A4E4 - ldr r0, [sp, 0x8] - str r0, [r5] - ldr r0, [r4, 0x4] -_0800A4D8: - str r0, [r5, 0x4] - add sp, 0x10 - pop {r4,r5} - pop {r0} - bx r0 - thumb_func_end sub_800A4A0 - thumb_func_start sub_800A4E4 sub_800A4E4: push {r4-r7,lr} diff --git a/include/math.h b/include/math.h index dc3b96a63..e7984eae1 100644 --- a/include/math.h +++ b/include/math.h @@ -2,6 +2,7 @@ #define GUARD_MATH_H #include "gba/types.h" +#include "number_util.h" /** * This type represents a signed 24.8 fixed-point number, where the 24 most @@ -17,19 +18,6 @@ typedef s32 s24_8; */ typedef u32 u24_8; -/** - * This function computes a value modulo 3, using a lookup table for values less - * than 0x100. - * - * @warning This function performs an invalid memory access if x < 0. - * Hopefully it's never actually used. - * - * @param[in] x The value to get modulo 3. Must be non-negative. - * - * @return The value of x modulo 3. - */ -u32 fast_mod_3(s32 x); - /** * This function computes the sine of the absolute value of `x` using a lookup * table. The period of the function is `4096`, and the range is `[-256, 256]`. @@ -52,23 +40,6 @@ s32 sin_abs_4096(s32 x); */ s32 cos_4096(s32 x); -/** - * This function lexicographically compares two pairs of u32s. - * - * @note The call signature of this might change if it makes sense to pack the - * inputs into a struct representing, say, a 64-bit unsigned integer. Doing - * so does affect the generated assembly; the current approach is the simplest - * match. - * - * @param[in] x_hi The high 32 bits of the first pair. - * @param[in] x_lo The low 32 bits of the first pair. - * @param[in] y_hi The high 32 bits of the second pair. - * @param[in] y_lo The low 32 bits of the second pair. - * - * @return `TRUE` if `x < y`, `FALSE` otherwise. - */ -bool8 u32_pair_less_than(u32 x_hi, u32 x_lo, u32 y_hi, u32 y_lo); - /** * This function multiplies two signed 24.8 fixed-point numbers. * @@ -79,35 +50,9 @@ 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); -/** - * This function divides two signed 24.8 fixed-point numbers. - * - * @param[in] x The dividend. - * @param[in] y The divisor. - * - * @returns The quotient `x/y` as a signed 24.8 fixed-point number. - */ -s32 s24_8_div(s32 x, s32 y); - -/** - * This function multiplies two unsigned 24.8 fixed-point numbers. - * - * @param[in] x The first factor. - * @param[in] y The second factor. - * - * @return The product `x*y` as an unsigned 24.8 fixed-point number. - */ -u24_8 u24_8_mul(u24_8 x, u24_8 y); - -/** - * This function divides two unsigned 24.8 fixed-point numbers. - * - * @param[in] x The first factor. - * @param[in] y The second factor. - * - * @return The quotient `x/y` as an unsigned 24.8 fixed-point number. - */ -u24_8 u24_8_div(u24_8 x, u24_8 y); - +s32 sub_8009FB8(s32 x, s32 y); +void sub_800A020(unkStruct_80943A8 *, u32); +bool8 sub_800A2A0(unkStruct_80943A8 *a); +void sub_800A34C(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 *b); #endif // GUARD_MATH_H diff --git a/include/number_util.h b/include/number_util.h index e3e7b4a1a..484cfda5c 100644 --- a/include/number_util.h +++ b/include/number_util.h @@ -7,7 +7,7 @@ typedef struct FixedPoint s16 unk2; } FixedPoint; -struct unkStruct_80943A8 +typedef struct unkStruct_80943A8 { s32 s0; s32 s4; @@ -19,8 +19,8 @@ FixedPoint FixedPoint_Min(FixedPoint a, FixedPoint b); FixedPoint FixedPoint_Max(FixedPoint a, FixedPoint b); FixedPoint sub_8094370(FixedPoint param_1, FixedPoint param_2); FixedPoint IntToFixedPoint(s32 a); -FixedPoint FixedPoint_SetFromUnk(struct unkStruct_80943A8* param_1); +FixedPoint FixedPoint_SetFromUnk(unkStruct_80943A8* param_1); FixedPoint FixedPoint_Div(FixedPoint a, FixedPoint b); s32 FixedPointToInt(FixedPoint a); // Always rounded up -#endif +#endif \ No newline at end of file diff --git a/src/code_800558C.c b/src/code_800558C.c index b62d47d72..0fb2ad381 100644 --- a/src/code_800558C.c +++ b/src/code_800558C.c @@ -3,6 +3,7 @@ #include "bg_palette_buffer.h" #include "code_800558C.h" #include "cpu.h" +#include "math.h" #include "sprite.h" extern u8 gUnknown_2026E38; @@ -27,10 +28,6 @@ extern const s16 gUnknown_80B816A[16 * 10]; extern const s16 gUnknown_80B82AA[16 * 10]; extern const s16 gUnknown_80B83EA[16 * 10]; -// code_8009804.s -extern s32 sin_abs_4096(s32); -extern s32 cos_4096(s32); - static void sub_800561C(struct axMapSprite *, s32, s32, const RGB *); const RGB *sub_8005674(struct axMapSprite *, s32); diff --git a/src/code_8073CF0.c b/src/code_8073CF0.c index 07f3b9dae..d77590a29 100644 --- a/src/code_8073CF0.c +++ b/src/code_8073CF0.c @@ -32,6 +32,7 @@ #include "dungeon_message.h" #include "code_8077274_1.h" #include "dungeon_pokemon_attributes.h" +#include "math.h" extern bool8 sub_8044B28(void); extern void sub_8075708(Entity *entity); @@ -45,7 +46,6 @@ extern void sub_805229C(void); extern void sub_807E8F0(Entity *); extern void sub_80444F4(Entity *pokemon); extern void sub_807D148(Entity *pokemon, Entity *r1, u32 r2, Position *r3); -extern void sub_800A34C(struct unkStruct_80943A8 *, struct unkStruct_80943A8 *, const u8 *); extern void sub_80420B8(Entity *pokemon); extern void sub_8041C4C(Entity *pokemon, u32 r1); extern void sub_805E804(void); @@ -105,7 +105,7 @@ extern const s16 gUnknown_80F4F74; extern const s16 gUnknown_80F4FC2; extern const s16 gUnknown_80F4F76; extern const s16 gUnknown_80F4F36; -extern const u8 gUnknown_80F54F4[][8]; +extern unkStruct_80943A8 gUnknown_80F54F4[8]; extern const s32 gUnknown_80F60DC[]; extern const Position gUnknown_80F4D44[]; @@ -309,7 +309,7 @@ void sub_8074094(Entity *entity) } if (entityInfo->isTeamLeader) { - struct unkStruct_80943A8 sp8, sp10; + unkStruct_80943A8 sp8, sp10; FixedPoint var_38; FixedPoint bellyBefore; bool8 sound; @@ -336,7 +336,7 @@ void sub_8074094(Entity *entity) sp8.s0 = 0; sp8.s4 = 6554; - sub_800A34C(&sp10, &sp8, gUnknown_80F54F4[r4]); + sub_800A34C(&sp10, &sp8, &gUnknown_80F54F4[r4]); if (entityInfo->unk153 > 1) sp10.s4 += (gUnknown_80F60DC[entityInfo->unk153] << 0x10); entityInfo->unk153 = 0; diff --git a/src/code_809D148.c b/src/code_809D148.c index 40766ab76..4de71dd82 100644 --- a/src/code_809D148.c +++ b/src/code_809D148.c @@ -1,5 +1,6 @@ #include "global.h" #include "other_random.h" +#include "math.h" #include "memory.h" struct unkStruct_809D158 @@ -261,7 +262,6 @@ extern s32 sub_80AC448(s16 a0, struct unkStruct_809D158 *a1); extern s32 sub_80AD360(s16 a0, struct unkStruct_809D158 *a1); extern void sub_800290C(struct unkStruct_809D158 *a0, s32 a1); extern void sub_8002934(struct unkStruct_809D158 *a0, struct unkStruct_809D158 *a1, struct unkStruct_809D158 *a2, u32 a3, u32 a4); -extern s32 sub_8009FB8(s32 a0, s32 a1); extern bool8 sub_80A579C(struct unkStruct_809D158 *a0, struct unkStruct_809D158 *a1); void sub_809D25C(void) diff --git a/src/math.c b/src/math.c index 4bec769f8..701db6667 100644 --- a/src/math.c +++ b/src/math.c @@ -4,14 +4,34 @@ #include "data/math.h" -u32 fast_mod_3(s32 x) { +u24_8 u24_8_div(u24_8, u24_8); +u24_8 u24_8_mul(u24_8, u24_8); +bool8 u32_pair_less_than(u32, u32, u32, u32); + +void sub_800A5A4(unkStruct_80943A8 *, unkStruct_80943A8 *, unkStruct_80943A8 *); +void sub_800A4E4(unkStruct_80943A8 *, unkStruct_80943A8 *, unkStruct_80943A8 *); + +/** + * This function computes a value modulo 3, using a lookup table for values less + * than 0x100. + * + * @warning This function performs an invalid memory access if x < 0. + * Hopefully it's never actually used. + * + * @param[in] x The value to get modulo 3. Must be non-negative. + * + * @return The value of x modulo 3. + */ +UNUSED u32 fast_mod_3(s32 x) +{ if (x < 0x100) { return gFastMod3Lookup[x]; } return x % 3; } -s32 sin_abs_4096(s32 x) { +s32 sin_abs_4096(s32 x) +{ switch (x & 0xc00) { case 0x000: return gFastSinLookup[x & 0x3ff]; @@ -25,7 +45,8 @@ s32 sin_abs_4096(s32 x) { return 0; } -s32 cos_4096(s32 x) { +s32 cos_4096(s32 x) +{ switch (x & 0xc00) { case 0x000: return gFastSinLookup[0x3ff - (x & 0x3ff)]; @@ -39,19 +60,34 @@ s32 cos_4096(s32 x) { return 0; } -bool8 u32_pair_less_than(u32 x_hi, u32 x_lo, u32 y_hi, u32 y_lo) { - if ((u32)x_hi < (u32)y_hi) { +/** + * This function lexicographically compares two pairs of u32s. + * + * @note The call signature of this might change if it makes sense to pack the + * inputs into a struct representing, say, a 64-bit unsigned integer. Doing + * so does affect the generated assembly; the current approach is the simplest + * match. + * + * @param[in] x_hi The high 32 bits of the first pair. + * @param[in] x_lo The low 32 bits of the first pair. + * @param[in] y_hi The high 32 bits of the second pair. + * @param[in] y_lo The low 32 bits of the second pair. + * + * @return `TRUE` if `x < y`, `FALSE` otherwise. + */ +bool8 u32_pair_less_than(u32 x_hi, u32 x_lo, u32 y_hi, u32 y_lo) +{ + if (x_hi < y_hi) return TRUE; - } else if ((u32)x_hi > (u32)y_hi) { + if (x_hi > y_hi) return FALSE; - } else if (x_lo >= y_lo) { + if (x_lo >= y_lo) return FALSE; - } else { - return TRUE; - } + return TRUE; } -s24_8 s24_8_mul(s24_8 x, s24_8 y) { +s24_8 s24_8_mul(s24_8 x, s24_8 y) +{ s24_8 ret; bool8 sgn0 = x < 0; bool8 sgn1 = y < 0; @@ -76,7 +112,16 @@ s24_8 s24_8_mul(s24_8 x, s24_8 y) { return ret; } -s24_8 s24_8_div(s24_8 x, s24_8 y) { // signed division +/** + * This function divides two signed 24.8 fixed-point numbers. + * + * @param[in] x The dividend. + * @param[in] y The divisor. + * + * @returns The quotient `x/y` as a signed 24.8 fixed-point number. + */ +s24_8 s24_8_div(s24_8 x, s24_8 y) +{ s24_8 ret; bool8 sgn0 = x < 0; bool8 sgn1 = y < 0; @@ -101,7 +146,16 @@ s24_8 s24_8_div(s24_8 x, s24_8 y) { // signed division return ret; } -u24_8 u24_8_mul(u24_8 x, u24_8 y) { +/** + * This function multiplies two unsigned 24.8 fixed-point numbers. + * + * @param[in] x The first factor. + * @param[in] y The second factor. + * + * @return The product `x*y` as an unsigned 24.8 fixed-point number. + */ +u24_8 u24_8_mul(u24_8 x, u24_8 y) +{ // We need 64 bits for intermediate steps of the multiplication. u32 x_h, x_l; u32 y_h, y_l; @@ -158,6 +212,14 @@ u24_8 u24_8_mul(u24_8 x, u24_8 y) { return out_l; } +/** + * This function divides two unsigned 24.8 fixed-point numbers. + * + * @param[in] x The first factor. + * @param[in] y The second factor. + * + * @return The quotient `x/y` as an unsigned 24.8 fixed-point number. + */ u24_8 u24_8_div(u24_8 x, u24_8 y) { bool8 bVar1; @@ -174,7 +236,7 @@ u24_8 u24_8_div(u24_8 x, u24_8 y) s32 save; if (y == 0) { - return 0x7fffffff; + return INT32_MAX; } else if (x == 0) { return 0; @@ -228,7 +290,7 @@ u24_8 u24_8_div(u24_8 x, u24_8 y) return r9; } -s32 sub_8009F68(s32 x, s32 y) +UNUSED s32 sub_8009F68(s32 x, s32 y) { s32 uVar1; s32 sVar1; @@ -286,7 +348,7 @@ s32 sub_8009FB8(s32 x, s32 y) return r5; } -void sub_800A020(s32 *param_1, u32 param_2) +void sub_800A020(unkStruct_80943A8 *param_1, u32 param_2) { #ifndef NONMATCHING register u32 temp asm("r4"); @@ -295,10 +357,10 @@ void sub_800A020(s32 *param_1, u32 param_2) #endif temp = 0xffff0000; - param_1[0] = param_2 >> 0x10; - param_1[1] = param_2 << 0x10; + param_1->s0 = param_2 >> 0x10; + param_1->s4 = param_2 << 0x10; if ((param_2 & 0x8000) != 0) { - param_1[0] |= temp; + param_1->s0 |= temp; } } @@ -323,3 +385,296 @@ UNUSED u32 sub_800A068(u32 *param_1) } return uVar1; } + +void sub_800A088(u32 *a, s32 b) +{ + a[1] = b << 8; + a[0] = b >> 24; + + if (a[0] & 0x80) + a[0] |= ~0x7F; + else + a[0] &= 0x7f; +} + +s32 sub_800A0B0(unkStruct_80943A8 *a) +{ + s32 r2; + s32 r3; + s32 idx; + s32 divi; + + r2 = a->s4; + r3 = a->s0; + if (r2 == 0 && r3 == 0) + return 0; + + if (r2 > 0) { + if (r3 > 0) { + if (r2 < r3) { + divi = r3 / 256; + if (divi == 0) + return 0x200; + + idx = r2 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return gFastUnknownFn1Lookup[idx] << 4; + } + else { // r2 >= r3 + divi = r2 / 256; + if (divi == 0) + return 0x200; + + idx = r3 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return (0x40 - gFastUnknownFn1Lookup[idx]) << 4; + } + } + else { // r3 <= 0 + r3 = -r3; + if (r2 < r3) { + divi = r3 / 256; + if (divi == 0) + return 0x600; + + idx = r2 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return (0x80 - gFastUnknownFn1Lookup[idx]) << 4; + } + else { // r2 >= r3 + divi = r2 / 256; + if (divi == 0) + return 0x600; + + idx = r3 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return (gFastUnknownFn1Lookup[idx] + 0x40) << 4; + } + } + } + else { // r2 <= 0 + r2 = -r2; + if (r3 > 0) { + if (r2 < r3) { + divi = r3 / 256; + if (divi == 0) + return 0xE00; + + idx = r2 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return (0x100 - gFastUnknownFn1Lookup[idx]) << 4; + } + else { // r2 >= r3 + divi = r2 / 256; + if (divi == 0) + return 0xE00; + + idx = r3 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return (gFastUnknownFn1Lookup[idx] + 0xC0) << 4; + } + } + else { // r3 <= 0 + r3 = -r3; + if (r2 < r3) { + divi = r3 / 256; + if (divi == 0) + return 0xA00; + + idx = r2 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return (gFastUnknownFn1Lookup[idx] + 0x80) << 4; + } + else { // r2 >= r3 + divi = r2 / 256; + if (divi == 0) + return 0xA00; + + idx = r3 / divi; + if (idx > 0xFF) + idx = 0xFF; + + return (0xC0 - gFastUnknownFn1Lookup[idx]) << 4; + } + } + } +} + +static void sub_800A25C(unkStruct_80943A8 *a) +{ + a->s0 = ~a->s0; + a->s4 = ~a->s4 + 1; + if (a->s4 == 0) { + a->s0++; + } +} + +void sub_800A27C(unkStruct_80943A8 *a) +{ + if (a->s0 < 0) { + a->s0 = ~a->s0; + a->s4 = ~a->s4 + 1; + if (a->s4 == 0) { + a->s0++; + } + } +} + +bool8 sub_800A2A0(unkStruct_80943A8 *a) +{ + if (a->s0 == 0 && a->s4 == 0) + return TRUE; + return FALSE; +} + +UNUSED bool8 F48_16_AreEqual(unkStruct_80943A8 *a, unkStruct_80943A8 *b) +{ + if (a->s0 == b->s0 && a->s4 == b->s4) + return TRUE; + return FALSE; +} + +static bool8 sub_800A2DC(unkStruct_80943A8 *a) +{ + if (a->s0 < 0) + return TRUE; + return FALSE; +} + +bool8 sub_800A2F0(unkStruct_80943A8 *a, unkStruct_80943A8 *b) +{ + s32 r1; + u32 a0; + s32 b0; + + a0 = a->s0; + r1 = a0 >> 31; + + b0 = b->s0; + if (b0 < 0) + r1 |= 2; + + switch (r1) { + case 0: + default: + return u32_pair_less_than(a0, a->s4, b0, b->s4); + case 1: + return TRUE; + case 2: + return FALSE; + case 3: + return !u32_pair_less_than(a0, a->s4, b0, b->s4); + } +} + +void sub_800A34C(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 *b) +{ + bool8 aIsNegative; + bool8 bIsNegative; + unkStruct_80943A8 aa; + unkStruct_80943A8 bb; + unkStruct_80943A8 res; + + aa.s0 = a->s0; + aa.s4 = a->s4; + bb.s0 = b->s0; + bb.s4 = b->s4; + aIsNegative = sub_800A2DC(&aa); + bIsNegative = sub_800A2DC(&bb); + + if (sub_800A2A0(&aa)) { + dst->s0 = 0; + dst->s4 = 0; + } + else if (sub_800A2A0(&bb)) { + dst->s0 = 0; + dst->s4 = 0; + } + else { + if (aIsNegative) + sub_800A25C(&aa); + + if (bIsNegative) + sub_800A25C(&bb); + + sub_800A4E4(&res, &aa, &bb); + if (aIsNegative != bIsNegative) + sub_800A25C(&res); + + dst->s0 = res.s0; + dst->s4 = res.s4; + } +} + +void sub_800A3F0(unkStruct_80943A8 *dst, unkStruct_80943A8 *a, unkStruct_80943A8 *b) +{ + bool8 aIsNegative; + bool8 bIsNegative; + unkStruct_80943A8 aa; + unkStruct_80943A8 bb; + unkStruct_80943A8 res; + + aa.s0 = a->s0; + aa.s4 = a->s4; + bb.s0 = b->s0; + bb.s4 = b->s4; + aIsNegative = sub_800A2DC(&aa); + bIsNegative = sub_800A2DC(&bb); + + if (sub_800A2A0(&bb)) { + dst->s0 = INT32_MAX; + dst->s4 = -1; + } + else if (sub_800A2A0(&aa)) { + dst->s0 = 0; + dst->s4 = 0; + } + else { + if (aIsNegative) + sub_800A25C(&aa); + + if (bIsNegative) + sub_800A25C(&bb); + + sub_800A5A4(&res, &aa, &bb); + if (aIsNegative != bIsNegative) + sub_800A25C(&res); + + dst->s0 = res.s0; + dst->s4 = res.s4; + } +} + +void sub_800A4A0(unkStruct_80943A8 *a) +{ + unkStruct_80943A8 aa; + unkStruct_80943A8 res; + + aa.s0 = a->s0; + aa.s4 = a->s4; + + if (sub_800A2A0(&aa)) { + a->s0 = 0; + a->s4 = 0; + } + else { + sub_800A27C(&aa); + sub_800A4E4(&res, &aa, &aa); + a->s0 = res.s0; + a->s4 = res.s4; + } +} \ No newline at end of file diff --git a/src/number_util.c b/src/number_util.c index 6e693455c..185774045 100644 --- a/src/number_util.c +++ b/src/number_util.c @@ -84,7 +84,7 @@ FixedPoint IntToFixedPoint(s32 a) return p; } -FixedPoint FixedPoint_SetFromUnk(struct unkStruct_80943A8* param_1) +FixedPoint FixedPoint_SetFromUnk(unkStruct_80943A8* param_1) { FixedPoint s; diff --git a/src/type_effectiveness.c b/src/type_effectiveness.c index 5cfd3cf60..e86858dfd 100644 --- a/src/type_effectiveness.c +++ b/src/type_effectiveness.c @@ -8,37 +8,38 @@ #include "dungeon_message.h" #include "dungeon_pokemon_attributes.h" #include "dungeon_util.h" +#include "math.h" #include "status.h" #include "type_chart.h" #include "weather.h" u32 gUnknown_8106EFC[] = { 0x00, 0x00 }; -u8 gUnknown_8106F04[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }; -u8 gUnknown_8106F0C[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 }; -u8 gUnknown_8106F14[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00 }; -u8 gUnknown_8106F1C[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00 }; +unkStruct_80943A8 gUnknown_8106F04 = { 0x0, 0x10000 }; +unkStruct_80943A8 gUnknown_8106F0C = { 0x0, 0x20000 }; +unkStruct_80943A8 gUnknown_8106F14 = { 0x0, 0x18000 }; +unkStruct_80943A8 gUnknown_8106F1C = { 0x0, 0x8000 }; u8 gUnknown_8106F24[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x01, 0x00 }; -u8 gUnknown_8106F3C[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00}; -u8 gUnknown_8106F44[] = {0x00, 0x00, 0x00, 0x00, 0x66, 0xe6, 0x00, 0x00}; -u8 gUnknown_8106F4C[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00}; +unkStruct_80943A8 gUnknown_8106F3C = {0x0, 0x8000}; +unkStruct_80943A8 gUnknown_8106F44 = {0x0, 0xE666}; +unkStruct_80943A8 gUnknown_8106F4C = {0x0, 0x18000}; struct dumb_struct { - u8 *unk0[NUM_EFFECTIVENESS]; + unkStruct_80943A8 *unk0[NUM_EFFECTIVENESS]; }; struct dumb_struct gUnknown_8106F54 = { - gUnknown_8106F3C, // IMMUNE - gUnknown_8106F44, // RESIST - gUnknown_8106F04, // NEUTRAL - gUnknown_8106F4C, // SUPER + &gUnknown_8106F3C, // IMMUNE + &gUnknown_8106F44, // RESIST + &gUnknown_8106F04, // NEUTRAL + &gUnknown_8106F4C, // SUPER }; -u8 gUnknown_8106F64[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00}; +unkStruct_80943A8 gUnknown_8106F64 = {0x0, 0xC000}; u32 gTypeEffectivenessMultipliers[] = {0, 1, 2, 4}; @@ -63,12 +64,9 @@ extern const s32 gUnknown_80F54B4[NUM_EFFECTIVENESS][NUM_EFFECTIVENESS]; void sub_80428D8(Entity *); void sub_8042978(Entity *); void sub_804298C(Entity *); -bool8 sub_800A2A0(s32 *); -void sub_800A34C(s32 *, s32 *, const u8 *); -void sub_800A020(s32 *, u32); void sub_80428EC(Entity *); -bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct unkStruct_806D010 *param_5) +bool8 sub_806E100(unkStruct_80943A8 *param_1, Entity *pokemon, Entity *target, u8 type, struct unkStruct_806D010 *param_5) { bool8 torrentFlag; bool8 overgrowFlag; @@ -94,7 +92,7 @@ bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct normalOrFightingType = FALSE; pokemonInfo = GetEntInfo(pokemon); targetInfo = GetEntInfo(target); - sub_800A020(param_1,1); + sub_800A020(param_1, 1); param_5->unkD = 0; param_5->unkE = 0; hasWonderGuard = FALSE; @@ -130,13 +128,13 @@ bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct bVar4 = TRUE; if ((param_5->effectiveness != EFFECTIVENESS_SUPER) && (bVar4 = FALSE, hasWonderGuard)) { temp = gUnknown_8106EFC[1]; - param_1[0] = gUnknown_8106EFC[0]; - param_1[1] = temp; + param_1->s0 = gUnknown_8106EFC[0]; + param_1->s4 = temp; } if (((type == TYPE_FIRE) || (type == TYPE_ICE)) && (HasAbility(target,ABILITY_THICK_FAT))) { gDungeon->unk134.unk16D = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F1C); + sub_800A34C(param_1,param_1, &gUnknown_8106F1C); } if ((type == TYPE_FIRE) && (GetFlashFireStatus(target) != FLASH_FIRE_STATUS_NONE)) { gDungeon->unk134.fill16E[0] = TRUE; @@ -159,7 +157,7 @@ bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct torrentVisualFlag = SetVisualFlags(pokemonInfo,0x80,torrentFlag); if (torrentFlag) { gDungeon->unk134.fill16E[2] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F0C); + sub_800A34C(param_1,param_1, &gUnknown_8106F0C); } if (torrentVisualFlag) { sub_80428EC(pokemon); @@ -171,7 +169,7 @@ bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct overgrowVisualFlag = SetVisualFlags(pokemonInfo,2,overgrowFlag); if (overgrowFlag) { gDungeon->unk134.fill16E[3] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F0C); + sub_800A34C(param_1,param_1, &gUnknown_8106F0C); } if (overgrowVisualFlag) { sub_80428D8(pokemon); @@ -183,7 +181,7 @@ bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct swarmVisualFlag = SetVisualFlags(pokemonInfo,0x10,swarmFlag); if (swarmFlag) { gDungeon->unk134.fill16E[4] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F0C); + sub_800A34C(param_1,param_1, &gUnknown_8106F0C); } if (swarmVisualFlag) { sub_8042978(pokemon); @@ -195,7 +193,7 @@ bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct blazeVisualFlag = SetVisualFlags(pokemonInfo,0x20,blazeFlag); if (blazeFlag) { gDungeon->unk134.fill16E[5] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F0C); + sub_800A34C(param_1,param_1, &gUnknown_8106F0C); } if (blazeVisualFlag) { sub_804298C(pokemon); @@ -204,44 +202,44 @@ bool8 sub_806E100(s32 *param_1, Entity *pokemon, Entity *target, u8 type, struct } if (!(sub_800A2A0(param_1)) && (MonsterIsType(pokemon, type))) { gDungeon->unk134.fill16E[6] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F14); + sub_800A34C(param_1,param_1, &gUnknown_8106F14); } weather = GetApparentWeather(pokemon); if (weather == WEATHER_SUNNY) { if (type == TYPE_FIRE) { gDungeon->unk134.unk16C = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F14); + sub_800A34C(param_1,param_1, &gUnknown_8106F14); } else if (type == TYPE_WATER) { gDungeon->unk134.unk16C = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F1C); + sub_800A34C(param_1,param_1, &gUnknown_8106F1C); } } if (weather == WEATHER_RAIN) { if (type == TYPE_FIRE) { gDungeon->unk134.unk16B = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F1C); + sub_800A34C(param_1,param_1, &gUnknown_8106F1C); } else if (type == TYPE_WATER) { gDungeon->unk134.unk16B = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F14); + sub_800A34C(param_1,param_1, &gUnknown_8106F14); } } if ((weather == WEATHER_CLOUDY) && (type != TYPE_NORMAL)) { - sub_800A34C(param_1,param_1, gUnknown_8106F64); + sub_800A34C(param_1,param_1, &gUnknown_8106F64); gDungeon->unk134.unk16A = TRUE; } if (((gDungeon->weather.mudSportTurns != 0) || (weather == WEATHER_FOG)) && (type == TYPE_ELECTRIC)) { gDungeon->unk134.fill16E[7] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F1C); + sub_800A34C(param_1,param_1, &gUnknown_8106F1C); } if ((gDungeon->weather.waterSportTurns != 0) && (type == TYPE_FIRE)) { gDungeon->unk134.fill16E[8] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F1C); + sub_800A34C(param_1,param_1, &gUnknown_8106F1C); } if ((type == TYPE_ELECTRIC) && (pokemonInfo->charging.chargingStatus == STATUS_CHARGING)) { gDungeon->unk134.fill16E[9] = TRUE; - sub_800A34C(param_1,param_1,gUnknown_8106F0C); + sub_800A34C(param_1,param_1, &gUnknown_8106F0C); } } return bVar4;