From 33d90d0f8d12fb68b822d26c55435e7200cd0255 Mon Sep 17 00:00:00 2001 From: cecilarmitais Date: Sun, 6 Sep 2026 12:46:31 -0700 Subject: [PATCH] Decomp the fixed-point helper cluster at the end of main_020504BC.s sub_02050EBC, SubFixedPoint, sub_02050F78, sub_02050FF8 and BinToDecFixedPoint are the last five functions in asm/main_020504BC.s and all operate on struct fixed_point (106 instructions). The next object in main.lsf is src/number_util.o, which already holds their sibling CeilFixedPoint, so extract_function.py merges rather than splits and main.lsf is unchanged. They are landed in reverse address order so each prepends above the last, leaving number_util.c in ascending address order with CeilFixedPoint last. sub_02050EBC and sub_02050F78 keep their sub_ names - this is decompilation, not identification. A 4-byte struct fixed_point is passed and returned by value in r0, packed as integer | fractional << 16. The stmdb sp!, {r0, r1, r2, r3} at entry is MWCC giving the argument registers stack homes so a by-value struct parameter can be addressed, and writing to the parameter reuses that home, which is why SubFixedPoint and sub_02050EBC modify their first argument and return it. The caller-side sub rX, sp, #4 idiom around these calls is compiler-generated, not a source construct: src/dungeon_ai_movement.c already emits it from a plain CeilFixedPoint(pokemon_info->belly). None of the five blocks carries a region directive, so one source serves all three regions. Authored by Claude (Opus 5) under human direction. Confirmed by a matching build: build/pmdsky.us/pmdsky.us.nds: OK. Co-Authored-By: Claude Opus 5 --- asm/include/main_020504BC.inc | 6 +- asm/main_020504BC.s | 127 ---------------------------------- include/number_util.h | 5 ++ src/number_util.c | 62 +++++++++++++++++ 4 files changed, 70 insertions(+), 130 deletions(-) diff --git a/asm/include/main_020504BC.inc b/asm/include/main_020504BC.inc index 86cffabb..2122160b 100644 --- a/asm/include/main_020504BC.inc +++ b/asm/include/main_020504BC.inc @@ -1,10 +1,8 @@ #pragma once -.public _0209E6BD -.public _022AB924 .public ADVENTURE_LOG_PTR .public ARM9_UNKNOWN_DATA__NA_209E6BC -.public ComputeSpecialCounters .public CONVERSION2_TYPE_TABLE +.public ComputeSpecialCounters .public Copy16BitsFrom .public Copy16BitsTo .public CopyNStringFromId @@ -16,3 +14,5 @@ .public StrncpySimpleNoPad .public StrncpySimpleNoPadSafe .public TEAM_NAME +.public _0209E6BD +.public _022AB924 diff --git a/asm/main_020504BC.s b/asm/main_020504BC.s index 87bc2710..f457bbaf 100644 --- a/asm/main_020504BC.s +++ b/asm/main_020504BC.s @@ -879,130 +879,3 @@ sub_02050E8C: ; 0x02050E8C bl CopyBitsFrom ldmia sp!, {r3, r4, r5, pc} arm_func_end sub_02050E8C - - arm_func_start sub_02050EBC -sub_02050EBC: ; 0x02050EBC - stmdb sp!, {r0, r1, r2, r3} - ldrsh r3, [sp, #2] - ldrsh r0, [sp, #6] - ldrsh r2, [sp] - ldrsh r1, [sp, #4] - add r0, r3, r0 - strh r0, [sp, #2] - ldrsh r0, [sp, #2] - add r1, r2, r1 - strh r1, [sp] - cmp r0, #0x3e8 - subge r0, r0, #0x3e8 - ldrgesh r1, [sp] - strgeh r0, [sp, #2] - addge r0, r1, #1 - strgeh r0, [sp] - ldrh r1, [sp, #2] - ldrh r0, [sp] - orr r0, r0, r1, lsl #16 - add sp, sp, #0x10 - bx lr - arm_func_end sub_02050EBC - - arm_func_start SubFixedPoint -SubFixedPoint: ; 0x02050F10 - stmdb sp!, {r0, r1, r2, r3} - ldrsh r3, [sp, #2] - ldrsh r0, [sp, #6] - ldrsh r2, [sp] - ldrsh r1, [sp, #4] - sub r0, r3, r0 - strh r0, [sp, #2] - ldrsh r0, [sp, #2] - sub r1, r2, r1 - strh r1, [sp] - cmp r0, #0 - addlt r0, r0, #0x3e8 - ldrltsh r1, [sp] - strlth r0, [sp, #2] - sublt r0, r1, #1 - strlth r0, [sp] - ldrsh r0, [sp] - cmp r0, #0 - movlt r0, #0 - strlth r0, [sp, #2] - strlth r0, [sp] - ldrh r1, [sp, #2] - ldrh r0, [sp] - orr r0, r0, r1, lsl #16 - add sp, sp, #0x10 - bx lr - arm_func_end SubFixedPoint - - arm_func_start sub_02050F78 -sub_02050F78: ; 0x02050F78 - stmdb sp!, {r0, r1, r2, r3} - stmdb sp!, {r3} - sub sp, sp, #4 - ldrsh r1, [sp, #8] - ldrsh r0, [sp, #0xc] - cmp r1, r0 - ldrgth r1, [sp, #0xe] - ldrgth r0, [sp, #0xc] - orrgt r0, r0, r1, lsl #16 - bgt _02050FE8 - ldrlth r1, [sp, #0xa] - ldrlth r0, [sp, #8] - orrlt r0, r0, r1, lsl #16 - blt _02050FE8 - ldrsh r1, [sp, #0xa] - ldrsh r0, [sp, #0xe] - cmp r1, r0 - ldrgth r1, [sp, #0xc] - ldrgth r0, [sp, #0xe] - strgth r1, [sp] - strgth r0, [sp, #2] - ldrleh r1, [sp, #8] - ldrleh r0, [sp, #0xa] - strleh r1, [sp] - strleh r0, [sp, #2] - ldrh r1, [sp, #2] - ldrh r0, [sp] - orr r0, r0, r1, lsl #16 -_02050FE8: - add sp, sp, #4 - ldmia sp!, {r3} - add sp, sp, #0x10 - bx lr - arm_func_end sub_02050F78 - - arm_func_start sub_02050FF8 -sub_02050FF8: ; 0x02050FF8 - stmdb sp!, {r3} - sub sp, sp, #4 - strh r0, [sp] - ldrh r0, [sp] - mov r1, #0 - strh r1, [sp, #2] - orr r0, r0, r1, lsl #16 - add sp, sp, #4 - ldmia sp!, {r3} - bx lr - arm_func_end sub_02050FF8 - - arm_func_start BinToDecFixedPoint -BinToDecFixedPoint: ; 0x02051020 - stmdb sp!, {r3} - sub sp, sp, #4 - ldr r2, [r0, #4] - mov r1, #0x3e8 - mov r0, r2, lsl #0x10 - mov r0, r0, lsr #0x10 - mul r1, r0, r1 - mov r2, r2, lsr #0x10 - mov r0, r1, lsr #0x10 - strh r2, [sp] - strh r0, [sp, #2] - ldrh r1, [sp, #2] - ldrh r0, [sp] - orr r0, r0, r1, lsl #16 - add sp, sp, #4 - ldmia sp!, {r3} - bx lr - arm_func_end BinToDecFixedPoint diff --git a/include/number_util.h b/include/number_util.h index e431e233..c0e9b1ea 100644 --- a/include/number_util.h +++ b/include/number_util.h @@ -3,6 +3,11 @@ #include "util.h" +struct fixed_point sub_02050EBC(struct fixed_point a, struct fixed_point b); +struct fixed_point SubFixedPoint(struct fixed_point a, struct fixed_point b); +struct fixed_point sub_02050F78(struct fixed_point a, struct fixed_point b); +struct fixed_point sub_02050FF8(s16 value); +struct fixed_point BinToDecFixedPoint(struct fixed_point_64 *val); s32 CeilFixedPoint(struct fixed_point val_fp); #endif //PMDSKY_NUMBER_UTIL_H diff --git a/src/number_util.c b/src/number_util.c index 95dfc4f0..78a66153 100644 --- a/src/number_util.c +++ b/src/number_util.c @@ -1,5 +1,67 @@ #include "number_util.h" +struct fixed_point sub_02050EBC(struct fixed_point a, struct fixed_point b) +{ + a.fractional += b.fractional; + a.integer += b.integer; + if (a.fractional >= 1000) + { + a.integer++; + a.fractional -= 1000; + } + return a; +} + +struct fixed_point SubFixedPoint(struct fixed_point a, struct fixed_point b) +{ + a.fractional -= b.fractional; + a.integer -= b.integer; + if (a.fractional < 0) + { + a.integer--; + a.fractional += 1000; + } + if (a.integer < 0) + { + a.fractional = 0; + a.integer = 0; + } + return a; +} + +struct fixed_point sub_02050F78(struct fixed_point a, struct fixed_point b) +{ + struct fixed_point result; + + if (a.integer > b.integer) + return b; + if (a.integer < b.integer) + return a; + + if (a.fractional > b.fractional) + result = b; + else + result = a; + + return result; +} + +struct fixed_point sub_02050FF8(s16 value) +{ + struct fixed_point result; + result.integer = value; + result.fractional = 0; + return result; +} + +struct fixed_point BinToDecFixedPoint(struct fixed_point_64 *val) +{ + struct fixed_point result; + result.integer = val->lower >> 16; + result.fractional = ((val->lower & 0xFFFF) * 1000) >> 16; + return result; +} + s32 CeilFixedPoint(struct fixed_point val_fp) { if (val_fp.integer == 0)