From 3e545729b7ba3e0e4f427873ca498a6ec46e8e1e Mon Sep 17 00:00:00 2001 From: alvaroms97 Date: Thu, 10 Sep 2026 15:39:56 +0200 Subject: [PATCH 1/3] Decompile `cLib::memSet`, `cLib::targetAngleY` and `cLib::targetAngleX` --- include/game/cLib/c_lib.hpp | 3 +++ slices/wiimj2d.json | 12 ++++++++++++ source/dol/cLib/c_lib.cpp | 15 +++++++++++++++ source/dol/cLib/c_memset.cpp | 10 ++++++++++ 4 files changed, 40 insertions(+) create mode 100644 source/dol/cLib/c_lib.cpp create mode 100644 source/dol/cLib/c_memset.cpp diff --git a/include/game/cLib/c_lib.hpp b/include/game/cLib/c_lib.hpp index db2b0dc28..d60cce39b 100644 --- a/include/game/cLib/c_lib.hpp +++ b/include/game/cLib/c_lib.hpp @@ -7,6 +7,9 @@ /// @ingroup clib namespace cLib { + void memSet(void *dst, int val, ulong size); + s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2); + s16 targetAngleX(const mVec3_c &vec1, const mVec3_c &vec2); } // namespace cLib diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index aa394c969..68bacacfd 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -721,6 +721,18 @@ ".sbss": "0x7b0-0x7d0" } }, + { + "source": "dol/cLib/c_memset.cpp", + "memoryRanges": { + ".text": "0x15a490-0x15a4a0" + } + }, + { + "source": "dol/cLib/c_lib.cpp", + "memoryRanges": { + ".text": "0x15a840-0x15a8d0" + } + }, { "source": "dol/cLib/c_line.cpp", "memoryRanges": { diff --git a/source/dol/cLib/c_lib.cpp b/source/dol/cLib/c_lib.cpp new file mode 100644 index 000000000..c2126ef54 --- /dev/null +++ b/source/dol/cLib/c_lib.cpp @@ -0,0 +1,15 @@ +#include +#include + +namespace cLib { + +s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2) { + return cM::atan2s(vec2.x - vec1.x, vec2.z - vec1.z); +} + +s16 targetAngleX(const mVec3_c &vec1, const mVec3_c &vec2) { + mVec3_c diff = vec2 - vec1; + return cM::atan2s(diff.y, EGG::Mathf::sqrt(diff.x * diff.x + diff.z * diff.z)); +} + +} // namespace cLib diff --git a/source/dol/cLib/c_memset.cpp b/source/dol/cLib/c_memset.cpp new file mode 100644 index 000000000..4099c74f0 --- /dev/null +++ b/source/dol/cLib/c_memset.cpp @@ -0,0 +1,10 @@ +#include +#include + +namespace cLib { + +void memSet(void *dst, int val, ulong size) { + std::memset(dst, val, size); +} + +} // namespace cLib From 2028ca31c8a7bc5d8f344f0438cd77b995ed0ed4 Mon Sep 17 00:00:00 2001 From: alvaroms97 Date: Thu, 10 Sep 2026 18:04:20 +0200 Subject: [PATCH 2/3] Decompile `cLib::addCalcPos` and `cLib::chasePos` --- include/game/cLib/c_lib.hpp | 3 +++ slices/wiimj2d.json | 3 ++- source/dol/cLib/c_lib.cpp | 54 +++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/include/game/cLib/c_lib.hpp b/include/game/cLib/c_lib.hpp index d60cce39b..427d54ebe 100644 --- a/include/game/cLib/c_lib.hpp +++ b/include/game/cLib/c_lib.hpp @@ -12,4 +12,7 @@ namespace cLib { s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2); s16 targetAngleX(const mVec3_c &vec1, const mVec3_c &vec2); + float addCalcPos(mVec3_c *pos, const mVec3_c &target, float ratio, float maxSpeed, float minSpeed); + bool chasePos(mVec3_c *pos, const mVec3_c &target, float speed); + } // namespace cLib diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index 68bacacfd..6b6dd9993 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -730,7 +730,8 @@ { "source": "dol/cLib/c_lib.cpp", "memoryRanges": { - ".text": "0x15a840-0x15a8d0" + ".text": "0x15a4a0-0x15a8d0", + ".sdata2": "0x2b80-0x2b88" } }, { diff --git a/source/dol/cLib/c_lib.cpp b/source/dol/cLib/c_lib.cpp index c2126ef54..cfaae9fd8 100644 --- a/source/dol/cLib/c_lib.cpp +++ b/source/dol/cLib/c_lib.cpp @@ -1,8 +1,62 @@ #include #include +#include +#include + +inline bool isZero(float val) { + return (std::fabs(val) < FLT_EPSILON); +} + +inline float calcDistance(const mVec3_c &a, const mVec3_c &b) { + float dx = a.x - b.x; + float dy = a.y - b.y; + float dz = a.z - b.z; + return EGG::Mathf::sqrt(dx * dx + dy * dy + dz * dz); +} namespace cLib { +float addCalcPos(mVec3_c *pos, const mVec3_c &target, float ratio, float maxSpeed, float minSpeed) { + if (*pos != target) { + mVec3_c diff; + diff = *pos - target; + float mag = PSVECMag(diff); + if (mag < minSpeed) { + *pos = target; + } else { + diff *= ratio; + float stepMag = mag * ratio; + if (!isZero(stepMag)) { + if (stepMag > maxSpeed) { + diff *= maxSpeed / stepMag; + } else if (stepMag < minSpeed) { + diff *= minSpeed / stepMag; + } + *pos -= diff; + } else { + *pos = target; + } + } + } + + return calcDistance(*pos, target); +} + +bool chasePos(mVec3_c *pos, const mVec3_c &target, float speed) { + if (speed) { + mVec3_c diff = *pos - target; + float mag = PSVECMag(diff); + if (isZero(mag) || mag <= speed) { + *pos = target; + return true; + } + *pos -= (speed / mag) * diff; + } else if (*pos == target) { + return true; + } + return false; +} + s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2) { return cM::atan2s(vec2.x - vec1.x, vec2.z - vec1.z); } From e73ade9163c9d2195816f976bce88a61175495d8 Mon Sep 17 00:00:00 2001 From: CLF78 <29682335+CLF78@users.noreply.github.com> Date: Sun, 13 Sep 2026 13:49:47 +0200 Subject: [PATCH 3/3] Apply code review --- include/game/cLib/c_lib.hpp | 40 ++++++++++++++++++++--- slices/wiimj2d.json | 8 +---- source/dol/cLib/c_lib.cpp | 62 ++++++++++++++++++------------------ source/dol/cLib/c_math.cpp | 9 ++---- source/dol/cLib/c_memset.cpp | 10 ------ 5 files changed, 71 insertions(+), 58 deletions(-) delete mode 100644 source/dol/cLib/c_memset.cpp diff --git a/include/game/cLib/c_lib.hpp b/include/game/cLib/c_lib.hpp index 427d54ebe..5832c4f0a 100644 --- a/include/game/cLib/c_lib.hpp +++ b/include/game/cLib/c_lib.hpp @@ -1,18 +1,50 @@ #pragma once #include #include -/// @file /// @brief Provides common utilities. /// @ingroup clib namespace cLib { + void memSet(void *dst, int val, ulong size); ///< See memset. - void memSet(void *dst, int val, ulong size); + /// @brief Checks if a floating-point value is effectively zero within epsilon tolerance. + /// @param val The float value to evaluate. + /// @return @p true if the absolute value is less than FLT_EPSILON, @p false otherwise. + inline bool isZero(float val) { + return (std::fabs(val) < FLT_EPSILON); + } + /// @brief Calculates the yaw (Y-axis) orientation angle from an origin position to a target position. + /// @param vec1 The origin position vector. + /// @param vec2 The target position vector. + /// @return The calculated yaw value. s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2); + + /// @brief Calculates the pitch (X-axis) orientation angle from an origin position to a target position. + /// @param vec1 The origin position vector. + /// @param vec2 The target position vector. + /// @return The calculated pitch value. s16 targetAngleX(const mVec3_c &vec1, const mVec3_c &vec2); - float addCalcPos(mVec3_c *pos, const mVec3_c &target, float ratio, float maxSpeed, float minSpeed); - bool chasePos(mVec3_c *pos, const mVec3_c &target, float speed); + /** + * @brief Smoothly moves @p currentPos towards @p targetPos using proportional scaling. + * @details If the applied step overshoots the target, the position is snapped exactly to the target. + * @param currentPos The position to be updated. + * @param targetPos The target position. + * @param ratio The smoothing ratio (between @p 0.0f and @p 1.0f). Higher value means snappier movement. + * @param maxStep The maximum step for a single update. + * @param minStep The minimum step to prevent jittering. + * @return The absolute remaining distance to the target position. + */ + float addCalcPos(mVec3_c *currentPos, const mVec3_c &targetPos, float ratio, float maxStep, float minStep); + + /** @brief Moves @p currentPos towards @p targetPos by a fixed @p step amount. + * @details If the applied step overshoots the target, the position is snapped exactly to the target. + * @param currentPos The position to be updated. + * @param targetPos The target position. + * @param step The step value. + * @return @p true if the position reached the target, @p false otherwise. + */ + bool chasePos(mVec3_c *currentPos, const mVec3_c &targetPos, float step); } // namespace cLib diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index 6b6dd9993..d1560d23d 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -721,16 +721,10 @@ ".sbss": "0x7b0-0x7d0" } }, - { - "source": "dol/cLib/c_memset.cpp", - "memoryRanges": { - ".text": "0x15a490-0x15a4a0" - } - }, { "source": "dol/cLib/c_lib.cpp", "memoryRanges": { - ".text": "0x15a4a0-0x15a8d0", + ".text": "0x15a490-0x15a8d0", ".sdata2": "0x2b80-0x2b88" } }, diff --git a/source/dol/cLib/c_lib.cpp b/source/dol/cLib/c_lib.cpp index cfaae9fd8..73b8e8016 100644 --- a/source/dol/cLib/c_lib.cpp +++ b/source/dol/cLib/c_lib.cpp @@ -1,11 +1,7 @@ #include #include #include -#include - -inline bool isZero(float val) { - return (std::fabs(val) < FLT_EPSILON); -} +#include inline float calcDistance(const mVec3_c &a, const mVec3_c &b) { float dx = a.x - b.x; @@ -16,42 +12,46 @@ inline float calcDistance(const mVec3_c &a, const mVec3_c &b) { namespace cLib { -float addCalcPos(mVec3_c *pos, const mVec3_c &target, float ratio, float maxSpeed, float minSpeed) { - if (*pos != target) { - mVec3_c diff; - diff = *pos - target; - float mag = PSVECMag(diff); - if (mag < minSpeed) { - *pos = target; +void memSet(void *dst, int val, ulong size) { + memset(dst, val, size); +} + +float addCalcPos(mVec3_c *currPos, const mVec3_c &targetPos, float ratio, float maxStep, float minStep) { + if (*currPos != targetPos) { + mVec3_c stepVector; + stepVector = *currPos - targetPos; + float distance = PSVECMag(stepVector); + if (distance < minStep) { + *currPos = targetPos; } else { - diff *= ratio; - float stepMag = mag * ratio; - if (!isZero(stepMag)) { - if (stepMag > maxSpeed) { - diff *= maxSpeed / stepMag; - } else if (stepMag < minSpeed) { - diff *= minSpeed / stepMag; + stepVector *= ratio; + float step = distance * ratio; + if (!isZero(step)) { + if (step > maxStep) { + stepVector *= maxStep / step; + } else if (step < minStep) { + stepVector *= minStep / step; } - *pos -= diff; + *currPos -= stepVector; } else { - *pos = target; + *currPos = targetPos; } } } - return calcDistance(*pos, target); + return calcDistance(*currPos, targetPos); } -bool chasePos(mVec3_c *pos, const mVec3_c &target, float speed) { - if (speed) { - mVec3_c diff = *pos - target; - float mag = PSVECMag(diff); - if (isZero(mag) || mag <= speed) { - *pos = target; +bool chasePos(mVec3_c *currentPos, const mVec3_c &targetPos, float step) { + if (step) { + mVec3_c offset = *currentPos - targetPos; + float distance = PSVECMag(offset); + if (isZero(distance) || distance <= step) { + *currentPos = targetPos; return true; } - *pos -= (speed / mag) * diff; - } else if (*pos == target) { + *currentPos -= (step / distance) * offset; + } else if (*currentPos == targetPos) { return true; } return false; @@ -63,7 +63,7 @@ s16 targetAngleY(const mVec3_c &vec1, const mVec3_c &vec2) { s16 targetAngleX(const mVec3_c &vec1, const mVec3_c &vec2) { mVec3_c diff = vec2 - vec1; - return cM::atan2s(diff.y, EGG::Mathf::sqrt(diff.x * diff.x + diff.z * diff.z)); + return cM::atan2s(diff.y, diff.xzLen()); } } // namespace cLib diff --git a/source/dol/cLib/c_math.cpp b/source/dol/cLib/c_math.cpp index 5aea4f0fb..2046eb77b 100644 --- a/source/dol/cLib/c_math.cpp +++ b/source/dol/cLib/c_math.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include /// @file @@ -96,10 +97,6 @@ inline float getCircleUnit() { return 65536 / (2 * M_PI); } -inline bool isZero(float val) { - return (std::fabs(val) < FLT_EPSILON); -} - s16 rad2s(float rad) { // Clamp the value between -65535 and 65535 int mod = (float)fmod(rad, 2 * M_PI) * getCircleUnit(); @@ -125,11 +122,11 @@ namespace cM { inline u32 atan2i(float sin,float cos) { // 0° or 180° - if (isZero(sin)) { + if (cLib::isZero(sin)) { return (cos >= 0.0f) ? 0 : 0x8000; // 90° or 270° - } else if (isZero(cos)) { + } else if (cLib::isZero(cos)) { return (sin >= 0.0f) ? 0x4000 : 0xC000; } else if (sin >= 0.0f) { diff --git a/source/dol/cLib/c_memset.cpp b/source/dol/cLib/c_memset.cpp deleted file mode 100644 index 4099c74f0..000000000 --- a/source/dol/cLib/c_memset.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -namespace cLib { - -void memSet(void *dst, int val, ulong size) { - std::memset(dst, val, size); -} - -} // namespace cLib