600 lines of math.s

This commit is contained in:
Kermalis
2024-11-04 18:48:18 -05:00
parent 6d4e2c2a07
commit 5f02fed1c5
9 changed files with 421 additions and 754 deletions

View File

@@ -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}

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;