From 4afb9d6e168db32b424890466fe5904befb9303e Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 29 Jun 2024 12:36:03 +0200 Subject: [PATCH 1/3] sLib math, known symbols edition --- config/SOUE01/splits.txt | 7 ++ config/SOUE01/symbols.txt | 27 +++--- configure.py | 2 + include/rvl/OS.h | 1 + include/rvl/OS/OSCrc.h | 13 +++ include/s/README.txt | 2 +- include/s/s_Crc.h | 12 +++ include/s/s_Math.h | 18 ++++ src/s/s_Crc.cpp | 10 ++ src/s/s_Math.cpp | 157 ++++++++++++++++++++++++++++++++ src/toBeSorted/file_manager.cpp | 5 +- 11 files changed, 239 insertions(+), 15 deletions(-) create mode 100644 include/rvl/OS/OSCrc.h create mode 100644 include/s/s_Crc.h create mode 100644 include/s/s_Math.h create mode 100644 src/s/s_Crc.cpp create mode 100644 src/s/s_Math.cpp diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index fe294296..68b301b9 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -237,6 +237,13 @@ s/s_StateMethod.cpp: s/s_StateMethodUsr_FI.cpp: .text start:0x802DE540 end:0x802DE6EC +s/s_Crc.cpp: + .text start:0x802DE6F0 end:0x802DE6F4 + +s/s_Math.cpp: + .text start:0x802DE740 end:0x802DEEB0 + .sdata2 start:0x8057CC38 end:0x8057CC40 + s/s_Phase.cpp: .text start:0x802DEEB0 end:0x802DEF74 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 99db08ad..7ae38cd4 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -17198,28 +17198,29 @@ initializeStateLocalMethod__20sStateMethodUsr_FI_cFv = .text:0x802DE580; // type executeStateLocalMethod__20sStateMethodUsr_FI_cFv = .text:0x802DE5F0; // type:function size:0x4C finalizeStateLocalMethod__20sStateMethodUsr_FI_cFv = .text:0x802DE640; // type:function size:0x54 changeStateLocalMethod__20sStateMethodUsr_FI_cFRC12sStateIDIf_c = .text:0x802DE6A0; // type:function size:0x4C -fn_802DE6F0 = .text:0x802DE6F0; // type:function size:0x4 +calcCRC__4sCrcFPCvUl = .text:0x802DE6F0; // type:function size:0x4 fn_802DE700 = .text:0x802DE700; // type:function size:0x8 fn_802DE710 = .text:0x802DE710; // type:function size:0x2C fn_802DE740 = .text:0x802DE740; // type:function size:0x24 -fn_802DE770 = .text:0x802DE770; // type:function size:0xC0 +addCalc__4sLibFPfffff = .text:0x802DE770; // type:function size:0xC0 fn_802DE830 = .text:0x802DE830; // type:function size:0x44 fn_802DE880 = .text:0x802DE880; // type:function size:0x38 fn_802DE8C0 = .text:0x802DE8C0; // type:function size:0xC -fn_802DE8D0 = .text:0x802DE8D0; // type:function size:0x14 -fn_802DE8F0 = .text:0x802DE8F0; // type:function size:0xB4 -fn_802DE9B0 = .text:0x802DE9B0; // type:function size:0x5C +addCalcAngle__4sLibFPsssss = .text:0x802DE8D0; // type:function size:0x14 +addCalcAngleT__4sLibFPsssss_s = .text:0x802DE8F0; // type:function size:0xB4 +addCalcAngle__4sLibFPssss = .text:0x802DE9B0; // type:function size:0x10 +addCalcAngleT__4sLibFPssss_v = .text:0x802DE9C0; // type:function size:0x4C fn_802DEA10 = .text:0x802DEA10; // type:function size:0x164 fn_802DEB80 = .text:0x802DEB80; // type:function size:0x6C -fn_802DEBF0 = .text:0x802DEBF0; // type:function size:0xC -fn_802DEC00 = .text:0x802DEC00; // type:function size:0x58 -fn_802DEC60 = .text:0x802DEC60; // type:function size:0x4 -fn_802DEC70 = .text:0x802DEC70; // type:function size:0x50 -fn_802DECC0 = .text:0x802DECC0; // type:function size:0x4 -fn_802DECD0 = .text:0x802DECD0; // type:function size:0x64 +chase__4sLibFPsss = .text:0x802DEBF0; // type:function size:0xC +chaseT__4sLibFPsss_i = .text:0x802DEC00; // type:function size:0x58 +chase__4sLibFPiii = .text:0x802DEC60; // type:function size:0x4 +chaseT__4sLibFPiii_i = .text:0x802DEC70; // type:function size:0x50 +chase__4sLibFPfff = .text:0x802DECC0; // type:function size:0x4 +chaseT__4sLibFPfff_i = .text:0x802DECD0; // type:function size:0x64 fn_802DED40 = .text:0x802DED40; // type:function size:0x4 fn_802DED50 = .text:0x802DED50; // type:function size:0x50 -fn_802DEDA0 = .text:0x802DEDA0; // type:function size:0x64 +chaseAngle__4sLibFPsss = .text:0x802DEDA0; // type:function size:0x64 fn_802DEE10 = .text:0x802DEE10; // type:function size:0x98 __ct__8sPhase_cFPPFPv_Q28sPhase_c15METHOD_RESULT_ei = .text:0x802DEEB0; // type:function size:0x14 callMethod__8sPhase_cFPv = .text:0x802DEED0; // type:function size:0xA4 @@ -22102,7 +22103,7 @@ fn_803AFCD0 = .text:0x803AFCD0; // type:function size:0xEC __OSPlayTimeAlarmExpired = .text:0x803AFDC0; // type:function size:0xA0 scope:local __OSGetPlayTime = .text:0x803AFE60; // type:function size:0x1CC scope:global __OSInitPlayTime = .text:0x803B0030; // type:function size:0x158 scope:global -fn_803B0190 = .text:0x803B0190; // type:function size:0x134 +OSCalcCRC32 = .text:0x803B0190; // type:function size:0x134 fn_803B02D0 = .text:0x803B02D0; // type:function size:0x204 __init_user = .text:0x803B04E0; // type:function size:0x20 scope:global __init_cpp = .text:0x803B0500; // type:function size:0x48 scope:local diff --git a/configure.py b/configure.py index 8c85ecd1..6e94cf01 100644 --- a/configure.py +++ b/configure.py @@ -344,6 +344,8 @@ def nw4rLib(lib_name, objects, extra_cflags=[]): Object(Matching, "m/m_heap.cpp"), Object(NonMatching, "m/m_mtx.cpp"), Object(Matching, "m/m_pad.cpp"), + Object(Matching, "s/s_Crc.cpp"), + Object(NonMatching, "s/s_Math.cpp"), Object(Matching, "s/s_StateId.cpp"), Object(Matching, "s/s_StateMethod.cpp"), Object(Matching, "s/s_StateMethodUsr_FI.cpp"), diff --git a/include/rvl/OS.h b/include/rvl/OS.h index e2bdbce0..4604c7dd 100644 --- a/include/rvl/OS.h +++ b/include/rvl/OS.h @@ -12,6 +12,7 @@ extern "C" { #include "rvl/OS/OSAudioSystem.h" #include "rvl/OS/OSCache.h" #include "rvl/OS/OSContext.h" +#include "rvl/OS/OSCrc.h" #include "rvl/OS/OSError.h" #include "rvl/OS/OSExec.h" #include "rvl/OS/OSFastCast.h" diff --git a/include/rvl/OS/OSCrc.h b/include/rvl/OS/OSCrc.h new file mode 100644 index 00000000..5a24ef3e --- /dev/null +++ b/include/rvl/OS/OSCrc.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_OS_CRC_H +#define RVL_SDK_OS_CRC_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +u32 OSCalcCRC32(const void *, u32); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/s/README.txt b/include/s/README.txt index 5be519ee..00e8279e 100644 --- a/include/s/README.txt +++ b/include/s/README.txt @@ -1,4 +1,4 @@ -This library was ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib +The state system in this library was ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib with differences/modifications outlined below: ## No inline destructors diff --git a/include/s/s_Crc.h b/include/s/s_Crc.h new file mode 100644 index 00000000..044e7d99 --- /dev/null +++ b/include/s/s_Crc.h @@ -0,0 +1,12 @@ +#ifndef S_CRC_H +#define S_CRC_H + +#include + +namespace sCrc { + +u32 calcCRC(const void *ptr, u32 size); + +} // namespace sCrc + +#endif diff --git a/include/s/s_Math.h b/include/s/s_Math.h new file mode 100644 index 00000000..668f5056 --- /dev/null +++ b/include/s/s_Math.h @@ -0,0 +1,18 @@ +#ifndef S_MATH_H +#define S_MATH_H + +#include + +namespace sLib { + +float addCalc(float *value, float target, float ratio, float maxStepSize, float minStepSize); + +BOOL chase(short *value, short target, short stepSize); +BOOL chase(int *value, int target, int stepSize); +BOOL chase(float *value, float target, float stepSize); + +BOOL chaseAngle(short *value, short target, short stepSize); + +} // namespace sLib + +#endif diff --git a/src/s/s_Crc.cpp b/src/s/s_Crc.cpp new file mode 100644 index 00000000..3a1ab434 --- /dev/null +++ b/src/s/s_Crc.cpp @@ -0,0 +1,10 @@ +#include +#include + +namespace sCrc { + +u32 calcCRC(const void *ptr, u32 size) { + return OSCalcCRC32(ptr, size); +} + +} // namespace sCrc diff --git a/src/s/s_Math.cpp b/src/s/s_Math.cpp new file mode 100644 index 00000000..47855713 --- /dev/null +++ b/src/s/s_Math.cpp @@ -0,0 +1,157 @@ +#include +#include + +namespace sLib { + +extern "C" float fn_802DE740(float f1, float f2, float f3) { + float diff = f2 - f1; + if (f3 < 1.0f) { + return f2; + } + return f1 + diff / f3; +} + +float addCalc(float *value, float target, float ratio, float maxStepSize, float minStepSize) { + if (*value != target) { + float step = ratio * (target - *value); + if (step >= minStepSize || (step <= -minStepSize)) { + if (step > maxStepSize) { + step = maxStepSize; + } + if (step < -maxStepSize) { + step = -maxStepSize; + } + *value = *value + step; + } else if (step > 0.0f) { + if (step < minStepSize) { + *value = *value + minStepSize; + if (*value > target) { + *value = target; + } + } + } else if (step > -minStepSize) { + *value = *value + (-minStepSize); + if (*value < target) { + *value = target; + } + } + } + + float ret = target - *value; + if (ret > 0.0f) { + return ret; + } else { + return -ret; + } +} + +extern "C" void fn_802DE830(float *value, float target, float ratio, float maxStepSize) { + if (*value == target) { + return; + } + + float step = ratio * (target - *value); + if (step > maxStepSize) { + step = maxStepSize; + } else if (step < -maxStepSize) { + step = -maxStepSize; + } + *value += step; +} + +extern "C" void fn_802DE880(float *value, float p2, float p3) { + float step = *value * p2; + if (step > p3) { + step = p3; + } else if (step < -p3) { + step = -p3; + } + *value -= step; +} + +extern "C" int fn_802DE8C0(short a1, short a2) { + return abs((short)(a1 - a2)); +} + +template +BOOL chaseT(T *value, T target, T stepSize) { + if (*value == target) { + return 1; + } + + if (stepSize != 0) { + if (*value > target) { + stepSize = -stepSize; + } + + T step = *value + stepSize; + *value = step; + if (stepSize * (step - target) >= 0) { + *value = target; + return 1; + } + } + + return 0; +} + +template +T addCalcAngleT(T *p1, T p2, T p3, T p4, T p5) {} + +template +void addCalcAngleT(T *value, T target, T ratio, T maxStepSize) { + T diff = target - *value; + T step = diff / ratio; + if (step > maxStepSize) { + *value += maxStepSize; + } else if (step < -maxStepSize) { + *value -= maxStepSize; + } else { + *value += step; + } +} + +short addCalcAngle(short *a, short b, short c, short d, short e) { + return addCalcAngleT(a, b, c, d, e); +} + +void addCalcAngle(short *value, short target, short ratio, short maxStepSize) { + return addCalcAngleT(value, target, ratio, maxStepSize); +} + +// template BOOL chaseT(char*, char, char); + +BOOL chase(short *value, short target, short stepSize) { + return chaseT(value, target, stepSize); +} + +BOOL chase(int *value, int target, int stepSize) { + return chaseT(value, target, stepSize); +} + +BOOL chase(float *value, float target, float stepSize) { + return chaseT(value, target, stepSize); +} + +BOOL chaseAngle(short *value, short target, short stepSize) { + if (*value == target) { + return 1; + } + + if (stepSize != 0) { + if ((short)(*value - target) > 0) { + stepSize = -stepSize; + } + + short step = *value + stepSize; + *value = step; + if (stepSize * (short)(step - target) >= 0) { + *value = target; + return 1; + } + } + + return 0; +} + +} // namespace sLib diff --git a/src/toBeSorted/file_manager.cpp b/src/toBeSorted/file_manager.cpp index 1f6ea9e4..630161a5 100644 --- a/src/toBeSorted/file_manager.cpp +++ b/src/toBeSorted/file_manager.cpp @@ -1,6 +1,7 @@ #include "toBeSorted/file_manager.h" #include "f/f_base.h" #include +#include // clang-format off #include // clang-format on @@ -426,7 +427,9 @@ extern "C" void fn_800C01F0(); // todo flag managers /* 80011270 */ SaveFile *FileManager::getFileB() { return &mFileB; } -/* 80011280 */ u32 FileManager::calcFileCRC(const void *data, u32 length) {} +/* 80011280 */ u32 FileManager::calcFileCRC(const void *data, u32 length) { + return sCrc::calcCRC(data, length); +} /* 80011290 */ void FileManager::updateEmptyFiles() { updateEmptyFileFlags(); refreshSaveFileData(); From b4484db5d9ad5f7f0134c5a2832353a7a64af279 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 29 Jun 2024 16:56:11 +0200 Subject: [PATCH 2/3] sLib math some other guessed things --- config/SOUE01/symbols.txt | 12 +-- include/s/s_Math.h | 12 ++- src/s/s_Math.cpp | 174 +++++++++++++++++++++++++++++--------- 3 files changed, 149 insertions(+), 49 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 7ae38cd4..98f90ab3 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -17201,11 +17201,11 @@ changeStateLocalMethod__20sStateMethodUsr_FI_cFRC12sStateIDIf_c = .text:0x802DE6 calcCRC__4sCrcFPCvUl = .text:0x802DE6F0; // type:function size:0x4 fn_802DE700 = .text:0x802DE700; // type:function size:0x8 fn_802DE710 = .text:0x802DE710; // type:function size:0x2C -fn_802DE740 = .text:0x802DE740; // type:function size:0x24 +extrapolate__4sLibFfff = .text:0x802DE740; // type:function size:0x24 addCalc__4sLibFPfffff = .text:0x802DE770; // type:function size:0xC0 -fn_802DE830 = .text:0x802DE830; // type:function size:0x44 -fn_802DE880 = .text:0x802DE880; // type:function size:0x38 -fn_802DE8C0 = .text:0x802DE8C0; // type:function size:0xC +addCalcScaledDiff__4sLibFPffff = .text:0x802DE830; // type:function size:0x44 +addCalcScaled__4sLibFPfff = .text:0x802DE880; // type:function size:0x38 +absDiff__4sLibFss = .text:0x802DE8C0; // type:function size:0xC addCalcAngle__4sLibFPsssss = .text:0x802DE8D0; // type:function size:0x14 addCalcAngleT__4sLibFPsssss_s = .text:0x802DE8F0; // type:function size:0xB4 addCalcAngle__4sLibFPssss = .text:0x802DE9B0; // type:function size:0x10 @@ -17218,8 +17218,8 @@ chase__4sLibFPiii = .text:0x802DEC60; // type:function size:0x4 chaseT__4sLibFPiii_i = .text:0x802DEC70; // type:function size:0x50 chase__4sLibFPfff = .text:0x802DECC0; // type:function size:0x4 chaseT__4sLibFPfff_i = .text:0x802DECD0; // type:function size:0x64 -fn_802DED40 = .text:0x802DED40; // type:function size:0x4 -fn_802DED50 = .text:0x802DED50; // type:function size:0x50 +isInRange__4sLibFfff = .text:0x802DED40; // type:function size:0x4 +isInRangeT__4sLibFfff_i = .text:0x802DED50; // type:function size:0x50 chaseAngle__4sLibFPsss = .text:0x802DEDA0; // type:function size:0x64 fn_802DEE10 = .text:0x802DEE10; // type:function size:0x98 __ct__8sPhase_cFPPFPv_Q28sPhase_c15METHOD_RESULT_ei = .text:0x802DEEB0; // type:function size:0x14 diff --git a/include/s/s_Math.h b/include/s/s_Math.h index 668f5056..bd49c2a3 100644 --- a/include/s/s_Math.h +++ b/include/s/s_Math.h @@ -5,14 +5,22 @@ namespace sLib { +// Names from NSMBW float addCalc(float *value, float target, float ratio, float maxStepSize, float minStepSize); - +short addCalcAngle(short *value, short target, short ratio, short maxStepSize, short minStepSize); BOOL chase(short *value, short target, short stepSize); BOOL chase(int *value, int target, int stepSize); BOOL chase(float *value, float target, float stepSize); - BOOL chaseAngle(short *value, short target, short stepSize); + +// Inofficial names +float extrapolate(float start, float end, float scale); +BOOL isInRange(float val, float min, float max); +void addCalcScaledDiff(float *value, float target, float ratio, float maxStepSize); +void addCalcScaled(float *value, float stepSize, float maxStep); +int absDiff(short a1, short a2); + } // namespace sLib #endif diff --git a/src/s/s_Math.cpp b/src/s/s_Math.cpp index 47855713..064ee233 100644 --- a/src/s/s_Math.cpp +++ b/src/s/s_Math.cpp @@ -1,14 +1,14 @@ -#include #include +#include namespace sLib { -extern "C" float fn_802DE740(float f1, float f2, float f3) { - float diff = f2 - f1; - if (f3 < 1.0f) { - return f2; +float extrapolate(float start, float end, float scale) { + float diff = end - start; + if (scale < 1.0f) { + return end; } - return f1 + diff / f3; + return start + diff / scale; } float addCalc(float *value, float target, float ratio, float maxStepSize, float minStepSize) { @@ -21,7 +21,7 @@ float addCalc(float *value, float target, float ratio, float maxStepSize, float if (step < -maxStepSize) { step = -maxStepSize; } - *value = *value + step; + *value += step; } else if (step > 0.0f) { if (step < minStepSize) { *value = *value + minStepSize; @@ -30,7 +30,7 @@ float addCalc(float *value, float target, float ratio, float maxStepSize, float } } } else if (step > -minStepSize) { - *value = *value + (-minStepSize); + *value += -minStepSize; if (*value < target) { *value = target; } @@ -45,7 +45,7 @@ float addCalc(float *value, float target, float ratio, float maxStepSize, float } } -extern "C" void fn_802DE830(float *value, float target, float ratio, float maxStepSize) { +void addCalcScaledDiff(float *value, float target, float ratio, float maxStepSize) { if (*value == target) { return; } @@ -59,45 +59,53 @@ extern "C" void fn_802DE830(float *value, float target, float ratio, float maxSt *value += step; } -extern "C" void fn_802DE880(float *value, float p2, float p3) { - float step = *value * p2; - if (step > p3) { - step = p3; - } else if (step < -p3) { - step = -p3; +void addCalcScaled(float *value, float stepSize, float maxStep) { + float step = *value * stepSize; + if (step > maxStep) { + step = maxStep; + } else if (step < -maxStep) { + step = -maxStep; } *value -= step; } -extern "C" int fn_802DE8C0(short a1, short a2) { +int absDiff(short a1, short a2) { return abs((short)(a1 - a2)); } template -BOOL chaseT(T *value, T target, T stepSize) { - if (*value == target) { - return 1; - } - - if (stepSize != 0) { - if (*value > target) { - stepSize = -stepSize; - } - - T step = *value + stepSize; - *value = step; - if (stepSize * (step - target) >= 0) { - *value = target; - return 1; +T addCalcAngleT(T *value, T target, T ratio, T maxStepSize, T minStepSize) { + T diff = target - *value; + if (*value != target) { + T step = diff / ratio; + // TODO this is simpler in the original assembly + if (step > minStepSize || step < -minStepSize) { + T actualStep = maxStepSize; + if (maxStepSize > step) { + actualStep = step; + if (step < -maxStepSize) { + actualStep = -maxStepSize; + } + } + *value += actualStep; + } else if (target - *value >= 0) { + T newVal = *value + minStepSize; + *value = newVal; + if ((T)(target - newVal) <= 0) { + *value = target; + } + } else { + T newVal = *value - minStepSize; + *value = newVal; + if ((T)(target - newVal) >= 0) { + *value = target; + } } } - return 0; + return target - *value; } -template -T addCalcAngleT(T *p1, T p2, T p3, T p4, T p5) {} - template void addCalcAngleT(T *value, T target, T ratio, T maxStepSize) { T diff = target - *value; @@ -111,15 +119,55 @@ void addCalcAngleT(T *value, T target, T ratio, T maxStepSize) { } } -short addCalcAngle(short *a, short b, short c, short d, short e) { - return addCalcAngleT(a, b, c, d, e); +short addCalcAngle(short *value, short target, short ratio, short maxStepSize, short minStepSize) { + return addCalcAngleT(value, target, ratio, maxStepSize, minStepSize); } void addCalcAngle(short *value, short target, short ratio, short maxStepSize) { return addCalcAngleT(value, target, ratio, maxStepSize); } -// template BOOL chaseT(char*, char, char); +extern "C" BOOL fn_802DEB80(u8 *value, u8 target, u8 stepSize) { + if (stepSize != 0) { + s16 val = *value; + s16 tgt = target; + s16 szs = stepSize; + if (val > tgt) { + szs = -stepSize; + } + s16 step = val + szs; + if (szs * (step - tgt) >= 0) { + *value = tgt; + return 1; + } + *value = step; + } else if (*value == target) { + return 1; + } + + return 0; +} + +template +BOOL chaseT(T *value, T target, T stepSize) { + if (*value == target) { + return 1; + } + + if (stepSize != 0) { + if (*value > target) { + stepSize = -stepSize; + } + + *value += stepSize; + if (stepSize * (*value - target) >= 0) { + *value = target; + return 1; + } + } + + return 0; +} BOOL chase(short *value, short target, short stepSize) { return chaseT(value, target, stepSize); @@ -130,9 +178,25 @@ BOOL chase(int *value, int target, int stepSize) { } BOOL chase(float *value, float target, float stepSize) { + // TODO the != 0 comparison in the instantiated function has swapped regs for some reason return chaseT(value, target, stepSize); } +template +BOOL isInRangeT(T val, T min, T max) { + BOOL ret; + if (min < max) { + return val >= min && val <= max ? 1 : 0; + } else { + return val >= max && val <= min ? 1 : 0; + } + return ret; +} + +BOOL isInRange(float val, float min, float max) { + return isInRangeT(val, min, max); +} + BOOL chaseAngle(short *value, short target, short stepSize) { if (*value == target) { return 1; @@ -143,9 +207,37 @@ BOOL chaseAngle(short *value, short target, short stepSize) { stepSize = -stepSize; } - short step = *value + stepSize; - *value = step; - if (stepSize * (short)(step - target) >= 0) { + *value += stepSize; + if (stepSize * (short)(*value - target) >= 0) { + *value = target; + return 1; + } + } + + return 0; +} + +// Found in NSMBW (0x801618c0), but no symbol name found yet +extern "C" BOOL fn_802DEE10(short *value, short target, short stepSize) { + if (*value == target) { + return 1; + } + + if (stepSize != 0) { + short szs = stepSize; + if (stepSize < 0) { + szs = 0x7fff; + if (stepSize != 0x8000) { + szs = -stepSize; + } + } + if ((short)(*value - target) > 0) { + szs = -szs; + } + + *value += stepSize; + int b = stepSize * szs; + if (b > 0 && stepSize * (short)(*value - target) >= 0) { *value = target; return 1; } From 37406236795ad7219855b01fd095327484c5d03e Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Tue, 27 Aug 2024 10:48:50 -0400 Subject: [PATCH 3/3] a lot closer + Some updates --- config/SOUE01/symbols.txt | 2 +- configure.py | 47 ++++++--- include/s/s_Math.h | 2 +- src/s/s_Math.cpp | 104 +++++++++++--------- tools/decompctx.py | 5 +- tools/download_tool.py | 16 +++ tools/project.py | 198 +++++++++++++++++++++++++++++++++----- 7 files changed, 287 insertions(+), 87 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 98f90ab3..9f58be2c 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -17211,7 +17211,7 @@ addCalcAngleT__4sLibFPsssss_s = .text:0x802DE8F0; // type:function size:0xB4 addCalcAngle__4sLibFPssss = .text:0x802DE9B0; // type:function size:0x10 addCalcAngleT__4sLibFPssss_v = .text:0x802DE9C0; // type:function size:0x4C fn_802DEA10 = .text:0x802DEA10; // type:function size:0x164 -fn_802DEB80 = .text:0x802DEB80; // type:function size:0x6C +chaseUC__4sLibFPUcUcUc = .text:0x802DEB80; // type:function size:0x6C chase__4sLibFPsss = .text:0x802DEBF0; // type:function size:0xC chaseT__4sLibFPsss_i = .text:0x802DEC00; // type:function size:0x58 chase__4sLibFPiii = .text:0x802DEC60; // type:function size:0x4 diff --git a/configure.py b/configure.py index 6e94cf01..5946d12b 100644 --- a/configure.py +++ b/configure.py @@ -71,11 +71,6 @@ action="store_true", help="generate map file(s)", ) -parser.add_argument( - "--no-asm", - action="store_true", - help="don't incorporate .s files from asm directory", -) parser.add_argument( "--debug", action="store_true", @@ -94,6 +89,12 @@ type=Path, help="path to decomp-toolkit binary or source (optional)", ) +parser.add_argument( + "--objdiff", + metavar="BINARY | DIR", + type=Path, + help="path to objdiff-cli binary or source (optional)", +) parser.add_argument( "--sjiswrap", metavar="EXE", @@ -128,15 +129,16 @@ config.sjiswrap_path = args.sjiswrap if not is_windows(): config.wrapper = args.wrapper -if args.no_asm: +if not config.non_matching: config.asm_dir = None # Tool versions config.binutils_tag = "2.42-1" -config.compilers_tag = "20231018" -config.dtk_tag = "v0.9.0" +config.compilers_tag = "20240706" +config.dtk_tag = "v0.9.4" +config.objdiff_tag = "v2.0.0-beta.3" config.sjiswrap_tag = "v1.1.1" -config.wibo_tag = "0.6.14" +config.wibo_tag = "0.6.11" # Project config.config_path = Path("config") / config.version / "config.yml" @@ -286,9 +288,10 @@ def nw4rLib(lib_name, objects, extra_cflags=[]): Matching = True NonMatching = False +Equivalent = config.non_matching # Object should be linked when configured with --non-matching -config.warn_missing_config = False -config.warn_missing_source = False # TODO +config.warn_missing_config = False +config.warn_missing_source = False config.libs = [ { "lib": "framework", @@ -335,6 +338,17 @@ def nw4rLib(lib_name, objects, extra_cflags=[]): Object(NonMatching, "f/f_base.cpp"), Object(Matching, "f/f_list.cpp"), Object(Matching, "f/f_manager.cpp"), + Object(Matching, "DynamicLink.cpp"), + # framework (f_name) + # d stuff (d_name) + ], + }, + { + "lib": "mlib", + "mw_version": "Wii/1.5", + "cflags": cflags_framework, + "host": False, + "objects": [ Object(Matching, "m/m_allocator.cpp"), Object(Matching, "m/m_angle.cpp"), Object(Matching, "m/m_color_fader.cpp"), @@ -344,15 +358,20 @@ def nw4rLib(lib_name, objects, extra_cflags=[]): Object(Matching, "m/m_heap.cpp"), Object(NonMatching, "m/m_mtx.cpp"), Object(Matching, "m/m_pad.cpp"), + ], + }, + { + "lib": "slib", + "mw_version": "Wii/1.5", + "cflags": cflags_framework, + "host": False, + "objects": [ Object(Matching, "s/s_Crc.cpp"), Object(NonMatching, "s/s_Math.cpp"), Object(Matching, "s/s_StateId.cpp"), Object(Matching, "s/s_StateMethod.cpp"), Object(Matching, "s/s_StateMethodUsr_FI.cpp"), Object(Matching, "s/s_Phase.cpp"), - Object(Matching, "DynamicLink.cpp"), - # framework (f_name) - # d stuff (d_name) ], }, # DolphinLib( diff --git a/include/s/s_Math.h b/include/s/s_Math.h index bd49c2a3..78d7c1d4 100644 --- a/include/s/s_Math.h +++ b/include/s/s_Math.h @@ -13,13 +13,13 @@ BOOL chase(int *value, int target, int stepSize); BOOL chase(float *value, float target, float stepSize); BOOL chaseAngle(short *value, short target, short stepSize); - // Inofficial names float extrapolate(float start, float end, float scale); BOOL isInRange(float val, float min, float max); void addCalcScaledDiff(float *value, float target, float ratio, float maxStepSize); void addCalcScaled(float *value, float stepSize, float maxStep); int absDiff(short a1, short a2); +BOOL chaseUC(u8 *value, u8 target, u8 stepSize); } // namespace sLib diff --git a/src/s/s_Math.cpp b/src/s/s_Math.cpp index 064ee233..ebc8504b 100644 --- a/src/s/s_Math.cpp +++ b/src/s/s_Math.cpp @@ -80,25 +80,25 @@ T addCalcAngleT(T *value, T target, T ratio, T maxStepSize, T minStepSize) { T step = diff / ratio; // TODO this is simpler in the original assembly if (step > minStepSize || step < -minStepSize) { - T actualStep = maxStepSize; - if (maxStepSize > step) { - actualStep = step; - if (step < -maxStepSize) { - actualStep = -maxStepSize; - } - } - *value += actualStep; - } else if (target - *value >= 0) { - T newVal = *value + minStepSize; - *value = newVal; - if ((T)(target - newVal) <= 0) { - *value = target; + if (step > maxStepSize) { + step = maxStepSize; + } else if (step < -maxStepSize) { + step = -maxStepSize; } + *value += step; } else { - T newVal = *value - minStepSize; - *value = newVal; - if ((T)(target - newVal) >= 0) { - *value = target; + if (0 <= diff) { + T newVal = *value + minStepSize; + *value = newVal; + if ((T)(target - *value) <= 0) { + *value = target; + } + } else { + T newVal = *value - minStepSize; + *value = newVal; + if ((T)(target - newVal) >= 0) { + *value = target; + } } } } @@ -127,25 +127,37 @@ void addCalcAngle(short *value, short target, short ratio, short maxStepSize) { return addCalcAngleT(value, target, ratio, maxStepSize); } -extern "C" BOOL fn_802DEB80(u8 *value, u8 target, u8 stepSize) { - if (stepSize != 0) { +extern "C" s16 fn_802DEA10(s16 *pValue, s16 target, s16 scale, s16 maxStep, s16 minStep) { + // NYI +} + +// Is the same as cLib_chaseUC +BOOL chaseUC(u8 *value, u8 target, u8 stepSize) { + if (stepSize) { s16 val = *value; s16 tgt = target; - s16 szs = stepSize; + s16 szs; + if (val > tgt) { szs = -stepSize; + } else { + szs = stepSize; } - s16 step = val + szs; - if (szs * (step - tgt) >= 0) { - *value = tgt; - return 1; + + val += szs; + + if (szs * (val - tgt) >= 0) { + *value = target; + return TRUE; + } else { + *value = val; } - *value = step; - } else if (*value == target) { - return 1; } - return 0; + else if (*value == target) { + return TRUE; + } + return FALSE; } template @@ -154,7 +166,7 @@ BOOL chaseT(T *value, T target, T stepSize) { return 1; } - if (stepSize != 0) { + if (stepSize) { if (*value > target) { stepSize = -stepSize; } @@ -186,9 +198,9 @@ template BOOL isInRangeT(T val, T min, T max) { BOOL ret; if (min < max) { - return val >= min && val <= max ? 1 : 0; + return val >= min && val <= max; } else { - return val >= max && val <= min ? 1 : 0; + return val >= max && val <= min; } return ret; } @@ -220,30 +232,34 @@ BOOL chaseAngle(short *value, short target, short stepSize) { // Found in NSMBW (0x801618c0), but no symbol name found yet extern "C" BOOL fn_802DEE10(short *value, short target, short stepSize) { if (*value == target) { - return 1; + return TRUE; } - if (stepSize != 0) { - short szs = stepSize; + if (stepSize) { + short step = stepSize; + if (stepSize < 0) { - szs = 0x7fff; if (stepSize != 0x8000) { - szs = -stepSize; + stepSize = -stepSize; + } else { + stepSize = 0x7FFF; } } + if ((short)(*value - target) > 0) { - szs = -szs; + stepSize = -stepSize; } - *value += stepSize; - int b = stepSize * szs; - if (b > 0 && stepSize * (short)(*value - target) >= 0) { - *value = target; - return 1; + *value += step; + + if (step * stepSize > 0) { + if (step * (short)(*value - target) >= 0) { + *value = target; + return TRUE; + } } } - - return 0; + return FALSE; } } // namespace sLib diff --git a/tools/decompctx.py b/tools/decompctx.py index dc17d0ee..290946f1 100644 --- a/tools/decompctx.py +++ b/tools/decompctx.py @@ -20,12 +20,11 @@ src_dir = os.path.join(root_dir, "src") include_dirs = [ os.path.join(root_dir, "include"), - os.path.join(root_dir, "include/MSL_C"), # Add additional include directories here ] -include_pattern = re.compile(r'^#include\s*[<"](.+?)[>"]$') -guard_pattern = re.compile(r"^#ifndef\s+(.*)$") +include_pattern = re.compile(r'^#\s*include\s*[<"](.+?)[>"]$') +guard_pattern = re.compile(r"^#\s*ifndef\s+(.*)$") defines = set() diff --git a/tools/download_tool.py b/tools/download_tool.py index 7b386a4b..69ef96a7 100644 --- a/tools/download_tool.py +++ b/tools/download_tool.py @@ -55,6 +55,21 @@ def dtk_url(tag: str) -> str: repo = "https://github.com/encounter/decomp-toolkit" return f"{repo}/releases/download/{tag}/dtk-{system}-{arch}{suffix}" +def objdiff_cli_url(tag: str) -> str: + uname = platform.uname() + suffix = "" + system = uname.system.lower() + if system == "darwin": + system = "macos" + elif system == "windows": + suffix = ".exe" + arch = uname.machine.lower() + if arch == "amd64": + arch = "x86_64" + + repo = "https://github.com/encounter/objdiff" + return f"{repo}/releases/download/{tag}/objdiff-cli-{system}-{arch}{suffix}" + def sjiswrap_url(tag: str) -> str: repo = "https://github.com/encounter/sjiswrap" @@ -70,6 +85,7 @@ def wibo_url(tag: str) -> str: "binutils": binutils_url, "compilers": compilers_url, "dtk": dtk_url, + "objdiff-cli": objdiff_cli_url, "sjiswrap": sjiswrap_url, "wibo": wibo_url, } diff --git a/tools/project.py b/tools/project.py index 15795f1f..373285cf 100644 --- a/tools/project.py +++ b/tools/project.py @@ -69,6 +69,8 @@ def __init__(self) -> None: self.wrapper: Optional[Path] = None # If None, download wibo on Linux self.sjiswrap_tag: Optional[str] = None # Git tag self.sjiswrap_path: Optional[Path] = None # If None, download + self.objdiff_tag: Optional[str] = None # Git tag + self.objdiff_path: Optional[Path] = None # If None, download # Project config self.non_matching: bool = False @@ -85,15 +87,21 @@ def __init__(self) -> None: self.warn_missing_config: bool = False # Warn on missing unit configuration self.warn_missing_source: bool = False # Warn on missing source file self.rel_strip_partial: bool = True # Generate PLFs with -strip_partial - self.rel_empty_file: Optional[ - str - ] = None # Object name for generating empty RELs + self.rel_empty_file: Optional[str] = ( + None # Object name for generating empty RELs + ) self.shift_jis = ( True # Convert source files from UTF-8 to Shift JIS automatically ) self.reconfig_deps: Optional[List[Path]] = ( None # Additional re-configuration dependency files ) + self.custom_build_rules: Optional[List[Dict[str, Any]]] = ( + None # Custom ninja build rules + ) + self.custom_build_steps: Optional[Dict[str, List[Dict[str, Any]]]] = ( + None # Custom build steps, types are ["pre-compile", "post-compile", "post-link", "post-build"] + ) # Progress output and progress.json config self.progress_all: bool = True # Include combined "all" category @@ -231,6 +239,7 @@ def generate_build_ninja( build_path = config.out_path() progress_path = build_path / "progress.json" + report_path = build_path / "report.json" build_tools_path = config.build_dir / "tools" download_tool = config.tools_dir / "download_tool.py" n.rule( @@ -248,17 +257,27 @@ def generate_build_ninja( deps="gcc", ) + cargo_rule_written = False + + def write_cargo_rule(): + nonlocal cargo_rule_written + if not cargo_rule_written: + n.pool("cargo", 1) + n.rule( + name="cargo", + command="cargo build --release --manifest-path $in --bin $bin --target-dir $target", + description="CARGO $bin", + pool="cargo", + depfile=Path("$target") / "release" / "$bin.d", + deps="gcc", + ) + cargo_rule_written = True + if config.dtk_path is not None and config.dtk_path.is_file(): dtk = config.dtk_path elif config.dtk_path is not None: dtk = build_tools_path / "release" / f"dtk{EXE}" - n.rule( - name="cargo", - command="cargo build --release --manifest-path $in --bin $bin --target-dir $target", - description="CARGO $bin", - depfile=Path("$target") / "release" / "$bin.d", - deps="gcc", - ) + write_cargo_rule() n.build( outputs=dtk, rule="cargo", @@ -283,6 +302,35 @@ def generate_build_ninja( else: sys.exit("ProjectConfig.dtk_tag missing") + if config.objdiff_path is not None and config.objdiff_path.is_file(): + objdiff = config.objdiff_path + elif config.objdiff_path is not None: + objdiff = build_tools_path / "release" / f"objdiff-cli{EXE}" + write_cargo_rule() + n.build( + outputs=objdiff, + rule="cargo", + inputs=config.objdiff_path / "Cargo.toml", + implicit=config.objdiff_path / "Cargo.lock", + variables={ + "bin": "objdiff-cli", + "target": build_tools_path, + }, + ) + elif config.objdiff_tag: + objdiff = build_tools_path / f"objdiff-cli{EXE}" + n.build( + outputs=objdiff, + rule="download_tool", + implicit=download_tool, + variables={ + "tool": "objdiff-cli", + "tag": config.objdiff_tag, + }, + ) + else: + sys.exit("ProjectConfig.objdiff_tag missing") + if config.sjiswrap_path: sjiswrap = config.sjiswrap_path elif config.sjiswrap_tag: @@ -361,6 +409,17 @@ def generate_build_ninja( n.newline() + ### + # Helper rule for downloading all tools + ### + n.comment("Download all tools") + n.build( + outputs="tools", + rule="phony", + inputs=[dtk, sjiswrap, wrapper, compilers, binutils, objdiff], + ) + n.newline() + ### # Build rules ### @@ -443,6 +502,49 @@ def generate_build_ninja( ) n.newline() + if len(config.custom_build_rules or {}) > 0: + n.comment("Custom project build rules (pre/post-processing)") + for rule in config.custom_build_rules or {}: + n.rule( + name=rule.get("name"), + command=rule.get("command"), + description=rule.get("description", None), + depfile=rule.get("depfile", None), + generator=rule.get("generator", False), + pool=rule.get("pool", None), + restat=rule.get("restat", False), + rspfile=rule.get("rspfile", None), + rspfile_content=rule.get("rspfile_content", None), + deps=rule.get("deps", None), + ) + n.newline() + + def write_custom_step(step: str) -> List[str]: + implicit = [] + if config.custom_build_steps and step in config.custom_build_steps: + n.comment(f"Custom build steps ({step})") + for custom_step in config.custom_build_steps[step]: + outputs = custom_step.get("outputs") + + if isinstance(outputs, list): + implicit.extend(outputs) + else: + implicit.append(outputs) + + n.build( + outputs=outputs, + rule=custom_step.get("rule"), + inputs=custom_step.get("inputs", None), + implicit=custom_step.get("implicit", None), + order_only=custom_step.get("order_only", None), + variables=custom_step.get("variables", None), + implicit_outputs=custom_step.get("implicit_outputs", None), + pool=custom_step.get("pool", None), + dyndep=custom_step.get("dyndep", None), + ) + n.newline() + return implicit + n.comment("Host build") n.variable("host_cflags", "-I include -Wno-trigraphs") n.variable( @@ -461,6 +563,9 @@ def generate_build_ninja( ) n.newline() + # Add all build steps needed before we compile (e.g. processing assets) + precompile_implicit = write_custom_step("pre-compile") + ### # Source files ### @@ -511,16 +616,15 @@ def write(self, n: ninja_syntax.Writer) -> None: outputs=elf_path, rule="link", inputs=self.inputs, - implicit=[self.ldscript, *mwld_implicit], + implicit=[ + *precompile_implicit, + self.ldscript, + *mwld_implicit, + *postcompile_implicit, + ], implicit_outputs=elf_map, variables={"ldflags": elf_ldflags}, ) - n.build( - outputs=dol_path, - rule="elf2dol", - inputs=elf_path, - implicit=dtk, - ) else: preplf_path = build_path / self.name / f"{self.name}.preplf" plf_path = build_path / self.name / f"{self.name}.plf" @@ -633,7 +737,11 @@ def c_build( return src_obj_path def asm_build( - obj: Object, options: Dict[str, Any], lib_name: str, src_path: Path + obj: Object, + options: Dict[str, Any], + lib_name: str, + src_path: Path, + build_path: Path, ) -> Optional[Path]: asflags = options["asflags"] or config.asflags if asflags is None: @@ -643,7 +751,7 @@ def asm_build( extra_asflags_str = make_flags_str(options["extra_asflags"]) asflags_str += " " + extra_asflags_str - asm_obj_path = build_asm_path / f"{obj.base_name}.o" + asm_obj_path = build_path / f"{obj.base_name}.o" # Avoid creating duplicate build rules if asm_obj_path in source_added: @@ -700,7 +808,9 @@ def add_unit(build_obj, link_step: LinkStep): built_obj_path = c_build(obj, options, lib_name, unit_src_path) elif unit_src_path.suffix == ".s": # Add assembler build rule - built_obj_path = asm_build(obj, options, lib_name, unit_src_path) + built_obj_path = asm_build( + obj, options, lib_name, unit_src_path, build_src_path + ) else: sys.exit(f"Unknown source file type {unit_src_path}") else: @@ -711,7 +821,9 @@ def add_unit(build_obj, link_step: LinkStep): # Assembly overrides if unit_asm_path is not None and unit_asm_path.exists(): link_built_obj = True - built_obj_path = asm_build(obj, options, lib_name, unit_asm_path) + built_obj_path = asm_build( + obj, options, lib_name, unit_asm_path, build_asm_path + ) if link_built_obj and built_obj_path is not None: # Use the source-built object @@ -760,6 +872,9 @@ def add_unit(build_obj, link_step: LinkStep): if config.compilers_path and not os.path.exists(mw_path): sys.exit(f"Linker {mw_path} does not exist") + # Add all build steps needed before we link and after compiling objects + postcompile_implicit = write_custom_step("post-compile") + ### # Link ### @@ -768,6 +883,19 @@ def add_unit(build_obj, link_step: LinkStep): link_outputs.append(step.output()) n.newline() + # Add all build steps needed after linking and before GC/Wii native format generation + postlink_implicit = write_custom_step("post-link") + + ### + # Generate DOL + ### + n.build( + outputs=link_steps[0].output(), + rule="elf2dol", + inputs=link_steps[0].partial_output(), + implicit=[*postlink_implicit, dtk], + ) + ### # Generate RELs ### @@ -830,6 +958,9 @@ def add_unit(build_obj, link_step: LinkStep): ) n.newline() + # Add all build steps needed post-build (re-building archives and such) + postbuild_implicit = write_custom_step("post-build") + ### # Helper rule for building all source files ### @@ -867,7 +998,7 @@ def add_unit(build_obj, link_step: LinkStep): outputs=ok_path, rule="check", inputs=config.check_sha_path, - implicit=[dtk, *link_outputs], + implicit=[dtk, *link_outputs, *postbuild_implicit], ) n.newline() @@ -886,6 +1017,21 @@ def add_unit(build_obj, link_step: LinkStep): implicit=[ok_path, configure_script, python_lib, config.config_path], ) + ### + # Generate progress report + ### + n.comment("Generate progress report") + n.rule( + name="report", + command=f"{objdiff} report generate -o $out", + description="REPORT", + ) + n.build( + outputs=report_path, + rule="report", + implicit=[objdiff, "all_source"], + ) + ### # Helper tools ### @@ -967,7 +1113,7 @@ def add_unit(build_obj, link_step: LinkStep): configure_script, python_lib, python_lib_dir / "ninja_syntax.py", - *(config.reconfig_deps or []) + *(config.reconfig_deps or []), ], ) n.newline() @@ -1116,10 +1262,14 @@ def keep_flag(flag): if compiler_version is None: print(f"Missing scratch compiler mapping for {options['mw_version']}") else: + cflags_str = make_flags_str(cflags) + if options["extra_cflags"] is not None: + extra_cflags_str = make_flags_str(options["extra_cflags"]) + cflags_str += " " + extra_cflags_str unit_config["scratch"] = { "platform": "gc_wii", "compiler": compiler_version, - "c_flags": make_flags_str(cflags), + "c_flags": cflags_str, "ctx_path": src_ctx_path, "build_ctx": True, }