summaryrefslogtreecommitdiff
path: root/src/d/d_wood.cpp
diff options
context:
space:
mode:
authorMike Lester <themikelester@gmail.com>2024-10-31 14:58:37 -0600
committerGitHub <noreply@github.com>2024-10-31 16:58:37 -0400
commit64cc277d055439456e926e294fc131d91685b6ff (patch)
tree671460304df96dc9240deb02d8d55e9e5c0bd562 /src/d/d_wood.cpp
parent6f27d32ab148f8e075986b65df8ccdf6bf0801fa (diff)
d_wood (bushes) matching (#682)
* d_wood (bushes) 73% matching * d_wood::Unit_c::set_ground 100% match Jasper pointed me to the fact that the complicated inv_sqrt function I wrote was indeed just std::sqrtf(), which unlocked the rest of the match * Replace some bitshifts with multiplies based on PR feedback * Remove all instances of "this->" from d_wood * Add missing struct offset comment for mTevStr * Cleaned up d_tree externs * Use MTXIdentity instead of PSMTXIdentity * Remove incorrect TODO rearding cCcD_ObjAtType enum * Use the mDoAud_seStart inline function * Remove unnecessary parenthesis * Fix incorrect branching logic in d_wood::cc_hit_before_cut() * d_wood data sections fixup * Re-add "Nonmatching" comments to all nonmatching functions * Formatting: reformat from 2 to 4 space indentation This was a local system problem which slipped by me in a previous commit * 100% match for d_wood::Anm_c::mode_norm() Thanks Chippy! https://discord.com/channels/727908905392275526/873250400483024976/1298360716964790294 * Use cLib_*Bit() functions for flag checking and setting Based on the inline functions from the .map * d_wood: Use AnmID_e according to the .map file * d_wood: add a couple AnmID_e related inlines from the .map * d_wood: Name remaining unknowns related to animation * d_wood: Match cc_hit_before_cut() * d_wood: Match calc_cc() by using the dComIfGp_roomControl_getStayNo() inline * d_wood: Match string table and search_anm() by using a constant in assert string * d_wood: Match mode_to_norm() Switching normAnim to a const* did most of the work * d_wood: 100% match for L_attr and the .rodata section * d_wood: Fill in .data section. Still some extra data from vtables * d_wood: Match .sbss section * d_wood: Match .sdata section * d_wood: 98% match for Packet_c::draw() The only error is that g_dTree_shadowTexCoord is still using a 32-bit load instead of 16. the only way I know of to fix that is to define the data in this compilation unit. But that can't be right * d_wood: Various small formatting changes - No one line function implementations - Replaced instances of (SomeType*)0x0 (copy/pasted from Ghidra) with NULL - Replaced a few instances of 0.0 with 0.0f - Replaced one instance where a number was used instead of an enum value * d_wood: More formatting fixes - Removed unused variables from functions - Removed unnecessary iVar1 loop variables (leftover Ghidra detritus) - Fixed dtk function comments being wrapped by autoformatter. They now always appear on one line * d_tree: 100% match of data which is used by d_wood This moves g_dTree_shadowTexCoord into .sdata which allows d_wood::Packet_c::draw() to load its address with a single instruction. This makes a 100% match for draw() * d_wood: Removed unnecessary comment now that draw() matches g_dTree_shadowTexCoord now lives in the d_tree .sdata section, so its instruction can be loaded with a single instruction. This makes a 100% match with draw(). * d_wood: 100% match for mode_cut() * d_wood: Match mode_push_into() Also renamed mWindDir to mForceDir as it represents both wind and an actor pushing from a vector * d_wood: Match mode_push_back * d_wood: Match __sinit_d_wood_cpp The l_matDL display list is dynamically patched to reference the l_Txa_swood_bTEX texture at static initialization time. Is there a better way to represent this? * d_wood: Fix incorrect constant in set_ground() * d_wood: Simplify dummy data at the top of .data section * d_wood: Mark as matching in configure.py Had to move Packet_c destructor to get the functions in the right order. See discussion: https://discord.com/channels/727908905392275526/873250400483024976/1300680009458913280 * d_wood: Add `d/d_cc_d.h` include as some enums have moved * d_wood: Clean up some types at the top * Mark d_wood as non-matching for the Japanese version
Diffstat (limited to 'src/d/d_wood.cpp')
-rw-r--r--src/d/d_wood.cpp959
1 files changed, 885 insertions, 74 deletions
diff --git a/src/d/d_wood.cpp b/src/d/d_wood.cpp
index e5fca806..a7732220 100644
--- a/src/d/d_wood.cpp
+++ b/src/d/d_wood.cpp
@@ -4,184 +4,995 @@
//
#include "d/d_wood.h"
+#include "JAZelAudio/JAIZelBasic.h"
+#include "JSystem/J3DGraphBase/J3DShape.h"
+#include "JSystem/J3DU/J3DUClipper.h"
+#include "JSystem/JMath/JMath.h"
+#include "JSystem/JUtility/JUTAssert.h"
+#include "SSystem/SComponent/c_bg_s_gnd_chk.h"
+#include "SSystem/SComponent/c_lib.h"
+#include "d/d_bg_s_gnd_chk.h"
+#include "d/d_bg_s_spl_grp_chk.h"
+#include "d/d_com_inf_game.h"
+#include "d/d_drawlist.h"
+#include "d/d_kankyo_wether.h"
+#include "d/d_procname.h"
+#include "d/d_tree.h"
+#include "d/d_cc_d.h"
+#include "dolphin/gf/GFGeometry.h"
+#include "dolphin/gf/GFTev.h"
+#include "dolphin/gf/GFTransform.h"
+#include "dolphin/gx/GXAttr.h"
+#include "dolphin/gx/GXDisplayList.h"
#include "dolphin/types.h"
+#include "m_Do/m_Do_lib.h"
+#include "m_Do/m_Do_mtx.h"
+
+//-----------------------------------------
+// Types
+//-----------------------------------------
+enum AttrSway_e {
+ SWAY_LIGHT,
+ SWAY_MEDIUM,
+ SWAY_STRONG,
+ SWAY_PUSH,
+};
+
+struct AttrSway_c {
+ /* 0x0 */ s16 phaseVelY;
+ /* 0x2 */ s16 ampY;
+ /* 0x4 */ s16 phaseVelX;
+ /* 0x6 */ s16 ampX;
+ /* 0x8 */ float phaseBiasX;
+};
+struct Attr_c {
+ /* 0x0 */ AttrSway_c kSways[4][2];
+ /* 0x60 */ u8 kCutCooldown; // = 20
+ /* 0x61 */ u8 kCutFadeStart; // = 20 (Countdown time at which bush starts to fade out)
+ /* 0x62 */ u8 kCutAlphaFadeSpeed; // = 14
+ /* 0x64 */ float kCutInitVelY; // = 18.0f
+ /* 0x68 */ float kCutYAccel; // = -3.0f (Units per frame per frame)
+ /* 0x6C */ float kCutZVel; // = 2.5f (Units per frame)
+ /* 0x70 */ s16 kCutPitchVel; // = 200 (shortRad per frame)
+ /* 0x74 */ float kUncutShadowScale; // = 1.5f
+ /* 0x78 */ float kCutShadowScale; // = 0.3f
+ /* 0x7c */ float kCollisionRad; // = 80.0f;
+ /* 0x80 */ float kCollisionRadCut; // = 15.0f;
+ /* 0x84 */ float kCollisionHeight; // = 80.0f;
+ /* 0x88 */ float kCollisionHeightCut; // = 15.0f;
+ /* 0x8c */ float kClipRadius; // = 100.0f;
+ /* 0x90 */ float kClipCenterYOffset; // = 40.0f;
+ /* 0x94 */ u8 kPushBackCountdown; // = 23
+ /* 0x95 */ const u8 L_Alpha_Cutoff; // = 0x80;
+};
+
+typedef void (dWood::Anm_c::*modeProcFunc)(dWood::Packet_c *);
+
+//-----------------------------------------
+// Data
+//-----------------------------------------
+static Vec dummy1 = { 1.0f, 1.0f, 1.0f };
+static Vec dummy2 = { 1.0f, 1.0f, 1.0f };
+
+namespace dWood {
+namespace {
+// .data
+u8 l_Txa_swood_bTEX[0x800] ALIGN_DECL(32) = { 0x34, 0x66, 0x3c, 0xe7, 0xff, 0xff, 0x55, 0x80, 0x3c, 0x86, 0x3c, 0xe7, 0xff, 0xff, 0x5b, 0x95, 0x2c, 0x05, 0x2b, 0xc4, 0x2d, 0xa0, 0xa0, 0x00, 0x3c, 0xc7, 0x2c, 0x05, 0x78, 0x57, 0x55, 0x55, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0x7f, 0x3c, 0xa7, 0x3d, 0x07, 0xff, 0xff, 0xfa, 0x81, 0x2c, 0x25, 0x3c, 0xc7, 0x5d, 0x55, 0x95, 0x24, 0x3c, 0xe7, 0x2b, 0xe5, 0x0a, 0x37, 0xd5, 0x75, 0x3c, 0xc7, 0x3c, 0xe7, 0xff, 0xff, 0x3f, 0x4f, 0x00, 0x00, 0x3c, 0xc7, 0xff, 0xff, 0xff, 0xfd, 0x3c, 0xa7, 0x3c, 0xe7, 0xaf, 0x5d, 0x55, 0x14, 0x3c, 0xc7, 0x2c, 0x05, 0x00, 0x00, 0x0b, 0xd5, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0x57, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x34, 0x46, 0x3c, 0xe7, 0x57, 0x57, 0x17, 0x17, 0x3c, 0xc7, 0x3c, 0xc7, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xc7, 0x3c, 0xc7, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xfd, 0xf5, 0xf5, 0x3c, 0xc7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0x95, 0x34, 0x25, 0x3c, 0xe7, 0xf5, 0xd5, 0xd6, 0xd4, 0x3c, 0xc7, 0x3c, 0xe7, 0xff, 0x7f, 0x87, 0x55, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xc7, 0x2b, 0xe5, 0xe0, 0x5c, 0x56, 0x5f, 0x3c, 0xa7, 0x3c, 0xe7, 0x7f, 0x7f, 0x5d, 0x95, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x25, 0x3c, 0xc7, 0xf5, 0x55, 0x56, 0x40, 0x3c, 0xc7, 0x2b, 0xc5, 0x00, 0x00, 0xff, 0x5d, 0x2c, 0x25, 0x2b, 0xe5, 0xae, 0x38, 0x03, 0x3e, 0x2c, 0x25, 0x2b, 0xc5, 0x80, 0xa0, 0x72, 0xae, 0x2c, 0x25, 0x2b, 0xc5, 0x2a, 0xe2, 0xe0, 0x62, 0x2c, 0x05, 0x23, 0x84, 0x05, 0xa5, 0x25, 0x85, 0x2c, 0x25, 0x2b, 0xe5, 0xe1, 0x9a, 0xfc, 0x3a, 0x2c, 0x05, 0x2b, 0xe5, 0x82, 0xc3, 0x00, 0xc2, 0x2c, 0x05, 0x23, 0x84, 0x80, 0x60, 0x58, 0x56, 0x2c, 0x05, 0x2b, 0xc5, 0x80, 0x03, 0xf0, 0x0e, 0x3c, 0xe7, 0x2c, 0x05, 0x81, 0x85, 0xf7, 0x55, 0x34, 0x46, 0x2b, 0xe5, 0xfb, 0xe9, 0xfa, 0xb4, 0x2c, 0x05, 0x23, 0x84, 0x00, 0x28, 0xd0, 0x58, 0x3c, 0xe7, 0x2b, 0xe5, 0x54, 0x5c, 0x77, 0x5d, 0x34, 0x86, 0x3c, 0xe7, 0x17, 0x17, 0x9f, 0x5f, 0x3c, 0xe7, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x05, 0x3c, 0xc7, 0x5f, 0x55, 0x95, 0x01, 0x00, 0x00, 0x3c, 0xe7, 0xfd, 0x5d, 0x5f, 0x5f, 0x3c, 0xc7, 0x3c, 0xe7, 0xff, 0xff, 0xf9, 0x55, 0x3c, 0xc7, 0x3c, 0xe7, 0xfd, 0xfd, 0x59, 0x41, 0x3c, 0xe7, 0x2b, 0xc5, 0x00, 0x0f, 0x0d, 0x01, 0x3c, 0xa7, 0x23, 0x84, 0x00, 0xfa, 0xef, 0xf7, 0x3c, 0xe7, 0x2c, 0x05, 0x00, 0x26, 0x25, 0x25, 0x3c, 0xe7, 0x2c, 0x05, 0x01, 0x0d, 0xf5, 0x55, 0x3d, 0x07, 0x2c, 0x05, 0x25, 0xf5, 0x55, 0x55, 0x2c, 0x05, 0x23, 0x84, 0x00, 0x20, 0x00, 0x60, 0x2c, 0x05, 0x2b, 0xc5, 0x08, 0x00, 0x60, 0x82, 0x3c, 0xc7, 0x2b, 0xe5, 0xc2, 0x6d, 0x55, 0xf5, 0x2c, 0x05, 0x2b, 0xc5, 0x30, 0x02, 0x02, 0x00, 0x2c, 0x05, 0x23, 0x84, 0x0a, 0x0d, 0x0d, 0x15, 0x2c, 0x25, 0x2b, 0xe5, 0x98, 0x5b, 0xa3, 0x89, 0x2c, 0x05, 0x2b, 0xc5, 0x20, 0x00, 0x02, 0x0c, 0x2c, 0x05, 0x23, 0x64, 0xa8, 0x78, 0x58, 0xfc, 0x2c, 0x05, 0x2b, 0xe5, 0x20, 0x90, 0x09, 0x02, 0x2c, 0x25, 0x2b, 0xc5, 0xa2, 0xb8, 0x98, 0x02, 0x2c, 0x25, 0x23, 0x84, 0x85, 0x2d, 0x3d, 0x89, 0x2c, 0x25, 0x2b, 0xe5, 0x26, 0x76, 0x7a, 0x82, 0x2c, 0x05, 0x2b, 0xa4, 0x01, 0x02, 0x02, 0x02, 0x2b, 0x84, 0x23, 0x64, 0x08, 0x00, 0x20, 0x00, 0x2c, 0x05, 0x23, 0x84, 0x03, 0x81, 0x49, 0x6d, 0x23, 0x84, 0x23, 0x64, 0x00, 0x00, 0x02, 0x22, 0x23, 0x84, 0x23, 0x64, 0x02, 0x00, 0x00, 0x00, 0x2c, 0x25, 0x23, 0x84, 0x58, 0x7a, 0x7a, 0x70, 0x2c, 0x05, 0x2b, 0xe5, 0xa0, 0x80, 0x00, 0x23, 0x2c, 0x25, 0x23, 0x84, 0x78, 0x68, 0x60, 0xef, 0x2c, 0x05, 0x2b, 0xc5, 0x02, 0x98, 0x20, 0x55, 0x3c, 0xc7, 0x2c, 0x05, 0x5c, 0x50, 0x70, 0x40, 0x3c, 0xc7, 0x3c, 0xe7, 0x7f, 0xbf, 0xff, 0x5f, 0x3c, 0xc7, 0x2c, 0x05, 0x78, 0x55, 0x55, 0x55, 0x3c, 0xe7, 0x2b, 0xc5, 0x00, 0xe0, 0x58, 0xe0, 0x34, 0x46, 0x3c, 0xe7, 0xd4, 0xf5, 0xfd, 0xfd, 0x3c, 0xe7, 0x2c, 0x05, 0x55, 0xd5, 0x0b, 0x03, 0x2b, 0xe5, 0x3c, 0xe7, 0xd5, 0x58, 0x58, 0x56, 0x34, 0x46, 0x2b, 0xe5, 0x03, 0x5f, 0x7d, 0x7d, 0x2c, 0x05, 0x2b, 0xc5, 0x03, 0x08, 0x00, 0x82, 0x2c, 0x05, 0x23, 0x84, 0x5c, 0x56, 0xd5, 0xd5, 0x2c, 0x05, 0x2b, 0xe5, 0x02, 0x08, 0x88, 0x00, 0x2c, 0x25, 0x23, 0x84, 0x95, 0x35, 0x25, 0x2d, 0x2c, 0x05, 0x23, 0x84, 0x08, 0x02, 0x03, 0x4d, 0x2b, 0xc5, 0x23, 0x84, 0x17, 0xff, 0xff, 0x75, 0x2b, 0xc5, 0x23, 0x64, 0x8b, 0xff, 0xff, 0xad, 0x23, 0x84, 0x23, 0x64, 0x00, 0x00, 0x08, 0x08, 0x2c, 0x05, 0x23, 0x84, 0x5c, 0x5c, 0x58, 0x70, 0x2c, 0x05, 0x2b, 0xc5, 0xe0, 0x08, 0x00, 0x08, 0x2c, 0x05, 0x23, 0x84, 0x60, 0xc2, 0xc0, 0x80, 0x2c, 0x25, 0x2b, 0xc5, 0x0a, 0x0a, 0xca, 0x88, 0x2c, 0x05, 0x2b, 0xc5, 0x02, 0xa0, 0x00, 0x62, 0x2c, 0x05, 0x2b, 0xe5, 0x02, 0x00, 0xf0, 0x51, 0x2c, 0x25, 0x2b, 0xc5, 0x60, 0x0b, 0x28, 0xf0, 0x2c, 0x25, 0x2b, 0xc5, 0x8b, 0x7e, 0xaa, 0x82, 0x2c, 0x05, 0x23, 0x84, 0xd5, 0x35, 0x25, 0x09, 0x23, 0x84, 0x23, 0x64, 0x80, 0x00, 0x00, 0x00, 0x2c, 0x05, 0x23, 0x84, 0x01, 0x02, 0x00, 0x03, 0x2b, 0xe5, 0x23, 0x84, 0x55, 0x57, 0xd5, 0x15, 0x23, 0x84, 0x23, 0x64, 0x02, 0x00, 0x00, 0x80, 0x2c, 0x05, 0x23, 0x84, 0x55, 0x56, 0x50, 0x80, 0x2c, 0x05, 0x23, 0x84, 0x78, 0x70, 0x50, 0x58, 0x2c, 0x05, 0x2b, 0xc5, 0x0e, 0x00, 0x00, 0x02, 0x34, 0x86, 0x2b, 0xe5, 0x5e, 0xdc, 0x7d, 0x5f, 0x2c, 0x25, 0x3d, 0x07, 0x97, 0x7f, 0x9f, 0x27, 0x34, 0x46, 0x2b, 0xc5, 0xa7, 0xfa, 0xdb, 0xe2, 0x3c, 0xe7, 0x2c, 0x05, 0x70, 0x58, 0x5c, 0x5c, 0x3c, 0xc7, 0x3c, 0xe7, 0xd5, 0xfd, 0xff, 0xff, 0x2c, 0x05, 0x3c, 0xe7, 0x80, 0x58, 0xd4, 0x50, 0x3c, 0xc7, 0x3c, 0xe7, 0xff, 0x7e, 0x7d, 0x3d, 0x3c, 0xe7, 0x2c, 0x05, 0x25, 0x25, 0x3d, 0x00, 0x2c, 0x05, 0x23, 0x84, 0x00, 0x00, 0x0b, 0x35, 0x2c, 0x05, 0x23, 0x84, 0x09, 0xb5, 0x55, 0x55, 0x3c, 0x86, 0x23, 0x84, 0x95, 0xef, 0xee, 0x00, 0x2c, 0x05, 0x23, 0x84, 0x75, 0x05, 0x0d, 0x05, 0x23, 0x84, 0x23, 0x64, 0x00, 0x80, 0x80, 0x02, 0x2b, 0xe5, 0x23, 0x84, 0x57, 0x54, 0xdc, 0x50, 0x23, 0x84, 0x23, 0x64, 0x02, 0x00, 0x80, 0x02, 0x2c, 0x05, 0x23, 0x64, 0xf0, 0x60, 0x40, 0xc0, 0x2c, 0x25, 0x2b, 0xe5, 0x0a, 0xba, 0xab, 0xb8, 0x8b, 0x28, 0x2c, 0x05, 0x55, 0x57, 0x58, 0xe0, 0x83, 0x28, 0x2c, 0x05, 0x57, 0x5c, 0x60, 0x80, 0x8b, 0x28, 0x83, 0x48, 0x4f, 0xbf, 0xff, 0xff, 0x2c, 0x25, 0x2b, 0xa4, 0xe0, 0x2a, 0xaa, 0xa2, 0x2c, 0x25, 0x2b, 0xe5, 0x3c, 0x3e, 0x16, 0x3b, 0x2c, 0x05, 0x2b, 0xa4, 0x08, 0x24, 0x08, 0x00, 0x2c, 0x05, 0x2b, 0xc5, 0x03, 0x00, 0x00, 0x28, 0x2c, 0x05, 0x2b, 0xc5, 0x07, 0x00, 0x00, 0x02, 0x2c, 0x05, 0x23, 0x84, 0x35, 0x25, 0x0d, 0x09, 0x2c, 0x25, 0x2b, 0xe5, 0x82, 0x82, 0xeb, 0xa2, 0x2c, 0x05, 0x23, 0x84, 0x81, 0x02, 0x08, 0x00, 0x2c, 0x25, 0x23, 0x84, 0x5c, 0x5c, 0x54, 0x56, 0x2c, 0x05, 0x2b, 0xc5, 0x32, 0x02, 0x0e, 0x80, 0x2b, 0xe5, 0x23, 0x84, 0x57, 0x54, 0x94, 0x3c, 0x3c, 0xa7, 0x2b, 0xe5, 0x75, 0xd6, 0x58, 0xe0, 0x2c, 0x05, 0x3c, 0xe7, 0x25, 0x25, 0x17, 0x17, 0x3c, 0xc7, 0x3c, 0xe7, 0x85, 0x55, 0xff, 0xff, 0x3c, 0xc7, 0x3c, 0xe7, 0x1f, 0x5f, 0xbf, 0x5f, 0x3c, 0xe7, 0x3d, 0x07, 0xff, 0xff, 0xfc, 0xfd, 0x3c, 0xc7, 0x3c, 0xe7, 0x3f, 0x7f, 0xff, 0xff, 0x3c, 0xc7, 0x3c, 0xe7, 0x55, 0xff, 0xff, 0xff, 0x2b, 0xe5, 0x3c, 0xc7, 0xff, 0x57, 0x55, 0x49, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0x7f, 0x3c, 0xa7, 0x3c, 0xe7, 0x5d, 0xfe, 0xf4, 0xf6, 0x2c, 0x25, 0x23, 0x84, 0x25, 0x25, 0x25, 0x25, 0x3c, 0x86, 0x3c, 0xe7, 0xf4, 0xf6, 0xfe, 0x55, 0x3c, 0xc7, 0x23, 0x84, 0xf5, 0xfd, 0xbd, 0x2f, 0x2c, 0x05, 0x23, 0x84, 0x55, 0x56, 0x5c, 0x58, 0x8b, 0x28, 0x33, 0xe5, 0x56, 0x58, 0x60, 0x80, 0x83, 0x28, 0x2b, 0xa4, 0x56, 0x58, 0x60, 0xc0, 0xa4, 0x2c, 0x83, 0x28, 0x55, 0x55, 0x55, 0x54, 0x8b, 0x49, 0x83, 0x08, 0x80, 0x00, 0x02, 0x0c, 0xa4, 0x2c, 0x83, 0x28, 0x55, 0x55, 0x55, 0x25, 0xee, 0x73, 0x83, 0x28, 0x56, 0x70, 0xc0, 0x00, 0xee, 0x73, 0x8b, 0x48, 0x0d, 0x01, 0x01, 0x01, 0x2c, 0x05, 0x2b, 0xc5, 0x07, 0x28, 0x80, 0x00, 0x2c, 0x25, 0x2b, 0xe5, 0x28, 0x28, 0xd6, 0x6a, 0x2c, 0x25, 0x2b, 0xe5, 0x8a, 0xea, 0xe8, 0xe0, 0x2c, 0x05, 0x2b, 0xe5, 0x00, 0x80, 0xa2, 0xb0, 0x2c, 0x05, 0x2b, 0xe5, 0x02, 0x20, 0x08, 0x01, 0x2c, 0x25, 0x2b, 0xc5, 0x2a, 0xa5, 0x8a, 0x68, 0x2c, 0x05, 0x2b, 0xe5, 0x20, 0x02, 0x03, 0x20, 0x2c, 0x05, 0x2b, 0xc5, 0x08, 0x02, 0x20, 0xe0, 0x2c, 0x05, 0x2b, 0xc5, 0x00, 0x00, 0x09, 0x02, 0x34, 0x25, 0x2b, 0xe5, 0x00, 0x28, 0xe4, 0x8f, 0x2c, 0x05, 0x2b, 0xe5, 0x0a, 0xc1, 0x88, 0x20, 0x2c, 0x05, 0x2b, 0xa5, 0x02, 0xc0, 0x0a, 0x0d, 0x3c, 0xe7, 0x2c, 0x05, 0x80, 0x70, 0x56, 0x75, 0x2c, 0x05, 0x3c, 0xe7, 0xf5, 0x76, 0x54, 0x58, 0x2c, 0x05, 0x2b, 0xe5, 0x82, 0x22, 0x00, 0x00, 0x3c, 0xa7, 0x2c, 0x05, 0x85, 0x55, 0x5d, 0x55, 0x34, 0x86, 0x2b, 0xe5, 0xf4, 0x5c, 0xde, 0xdf, 0x34, 0x46, 0x3c, 0xe7, 0x7d, 0x55, 0x55, 0x54, 0x2c, 0x05, 0x2b, 0xe5, 0x0a, 0xe0, 0x0e, 0x08, 0x45, 0x07, 0x2c, 0x05, 0x8d, 0xe5, 0x55, 0x55, 0x3c, 0xe7, 0x2c, 0x05, 0x02, 0x2d, 0xd7, 0x55, 0x83, 0x28, 0x2c, 0x25, 0x57, 0x5c, 0x70, 0x40, 0x8b, 0x28, 0x2b, 0xe5, 0x55, 0x56, 0x5c, 0x58, 0x83, 0x28, 0x6b, 0x67, 0x40, 0x00, 0x00, 0x00, 0x93, 0x89, 0x83, 0x07, 0xff, 0xff, 0xfd, 0xfc, 0xee, 0x73, 0x83, 0x08, 0x5c, 0x70, 0xc0, 0x00, 0xbc, 0xce, 0x83, 0x28, 0x54, 0x54, 0x57, 0x55, 0xee, 0x74, 0x83, 0x28, 0x00, 0x00, 0x80, 0x5f, 0xee, 0x94, 0xe6, 0x52, 0x1e, 0x60, 0x80, 0x02, 0xee, 0x93, 0x83, 0x08, 0x09, 0x09, 0x09, 0x09, 0xee, 0x74, 0xac, 0x8d, 0x00, 0x00, 0x00, 0x55, 0xee, 0x74, 0x83, 0x08, 0x0d, 0x0d, 0x25, 0xd5, 0x2c, 0x25, 0x2b, 0xc5, 0x0b, 0xab, 0x98, 0x08, 0x2c, 0x25, 0x2b, 0xe5, 0xaf, 0xa8, 0x22, 0xac, 0x2c, 0x25, 0x2b, 0xe5, 0xee, 0x7b, 0xda, 0xac, 0x2c, 0x05, 0x2b, 0xc5, 0x1c, 0x22, 0x0c, 0x0a, 0x2c, 0x05, 0x2b, 0xe5, 0x01, 0x50, 0xe2, 0x80, 0x2c, 0x05, 0x2b, 0xe5, 0x80, 0x20, 0xe2, 0x8b, 0x2c, 0x25, 0x2b, 0xe5, 0x6e, 0xa6, 0xb8, 0x8a, 0x2c, 0x25, 0x2b, 0xc5, 0x3a, 0x3e, 0x0a, 0x00, 0x2c, 0x05, 0x2b, 0xa4, 0x20, 0x00, 0x20, 0x24, 0x2c, 0x05, 0x23, 0x84, 0x01, 0x23, 0x03, 0x08, 0x2c, 0x25, 0x2b, 0xe5, 0x96, 0xf0, 0xa0, 0x8f, 0x2c, 0x05, 0x2b, 0xc5, 0x40, 0x80, 0x02, 0x02, 0x2b, 0xe5, 0x23, 0x84, 0xc0, 0x70, 0x5c, 0xf6, 0x2c, 0x25, 0x2b, 0xe5, 0x28, 0xbe, 0xb8, 0xad, 0x2b, 0xe5, 0x23, 0x84, 0x9d, 0x35, 0x25, 0x07, 0x2c, 0x05, 0x23, 0x84, 0x80, 0x40, 0x70, 0x70, 0x2c, 0x05, 0x2b, 0xc5, 0x00, 0x92, 0x30, 0x00, 0x2c, 0x05, 0x23, 0x64, 0x02, 0x8b, 0x2d, 0xd5, 0x2c, 0x05, 0x2b, 0x84, 0x00, 0x03, 0x09, 0x0d, 0x2c, 0x25, 0x23, 0x84, 0x57, 0x57, 0x56, 0x5c, 0x5b, 0x87, 0x2b, 0xe5, 0x5c, 0xd5, 0x55, 0x55, 0x8b, 0x48, 0x2c, 0x05, 0x80, 0x58, 0x5c, 0x5c, 0x2c, 0x05, 0x2b, 0xc5, 0x00, 0x87, 0x00, 0x20, 0xa3, 0xa8, 0x2c, 0x05, 0x58, 0x55, 0x55, 0x5c, 0xa3, 0xc8, 0x83, 0x28, 0x55, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x83, 0x28, 0x55, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x83, 0x28, 0x55, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x83, 0x28, 0x55, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0xa3, 0xa8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0x2c, 0x25, 0x2b, 0xe5, 0xaa, 0x51, 0xa1, 0xe1, 0x2c, 0x25, 0x2b, 0xe5, 0x52, 0xa0, 0xc2, 0x40, 0x2c, 0x25, 0x2b, 0x84, 0x82, 0x02, 0xa0, 0x70, 0x2c, 0x25, 0x2b, 0xe5, 0x82, 0xe3, 0xaa, 0x08, 0x2c, 0x25, 0x2b, 0xc5, 0x2b, 0xbe, 0xaa, 0x08, 0x2c, 0x05, 0x2b, 0xc5, 0x0a, 0xc3, 0x88, 0x08, 0x2c, 0x05, 0x2b, 0xe5, 0x80, 0x4f, 0x8a, 0x01, 0x2c, 0x25, 0x2b, 0xe5, 0x06, 0x0a, 0xcf, 0xcd, 0x2c, 0x25, 0x2b, 0xe5, 0xa6, 0xca, 0x82, 0x2a, 0x2c, 0x05, 0x2b, 0xc5, 0x20, 0x00, 0x0a, 0x04, 0x2c, 0x25, 0x2b, 0xe5, 0xba, 0xb0, 0x8a, 0x8f, 0x2c, 0x05, 0x2b, 0xe5, 0x00, 0x38, 0x14, 0x02, 0x2c, 0x25, 0x23, 0x84, 0x05, 0x8d, 0x89, 0x01, 0x2c, 0x05, 0x23, 0x84, 0x5c, 0x54, 0xd6, 0x55, 0x2c, 0x05, 0x2b, 0xe5, 0x21, 0x00, 0x80, 0x42, 0x2c, 0x05, 0x23, 0x84, 0x55, 0x95, 0x35, 0x25, 0x2b, 0xe5, 0x23, 0x84, 0x05, 0x35, 0x1d, 0xd5, 0x2c, 0x25, 0x23, 0x84, 0x58, 0x70, 0x60, 0xc0, 0x2c, 0x05, 0x23, 0x84, 0x57, 0x5c, 0x58, 0x70, 0x2c, 0x25, 0x2b, 0xe5, 0xeb, 0x26, 0x0a, 0x01, 0x2c, 0x25, 0x2b, 0xc5, 0xba, 0x22, 0x2a, 0xa8, 0xab, 0xa8, 0x2c, 0x05, 0x5c, 0x55, 0x55, 0x5c, 0x2c, 0x05, 0x2b, 0xc5, 0x88, 0x08, 0x38, 0x2c, 0xa3, 0xa8, 0x2c, 0x05, 0x58, 0x55, 0x55, 0x55, 0xa3, 0xc8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0x93, 0x47, 0x73, 0x07, 0x00, 0x7f, 0xaa, 0xaa, 0x93, 0x47, 0x7a, 0xe7, 0x00, 0x55, 0xaa, 0xaa, 0xa3, 0xc8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0xa3, 0xc8, 0x7a, 0xe7, 0xaa, 0x55, 0xff, 0x00, 0x93, 0x47, 0x7a, 0xe7, 0x00, 0x55, 0xaa, 0xaa, 0x93, 0x47, 0x7a, 0xe7, 0x00, 0x55, 0xaa, 0xaa };
+u8 l_pos[0x2e8] = { 0x37, 0xb8, 0x8c, 0xa4, 0x41, 0x6e, 0xc3, 0xf7, 0xc2, 0xb3, 0xf6, 0xf9, 0xc2, 0x9b, 0xda, 0xa2, 0x41, 0x6e, 0xc3, 0xf7, 0xc2, 0x33, 0xf6, 0xfe, 0xc2, 0x9b, 0xda, 0xa3, 0x41, 0x6e, 0xc3, 0xf7, 0x42, 0x33, 0xf6, 0xf6, 0xb7, 0x06, 0x37, 0xbd, 0x41, 0x6e, 0xc3, 0xf7, 0x42, 0xb3, 0xf6, 0xf7, 0x42, 0x9b, 0xda, 0xa1, 0x41, 0x6e, 0xc3, 0xf7, 0x42, 0x33, 0xf6, 0xf8, 0x42, 0x9b, 0xda, 0xa1, 0x41, 0x6e, 0xc3, 0xf7, 0xc2, 0x33, 0xf6, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x42, 0xac, 0x37, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x42, 0x40, 0x4b, 0x91, 0x42, 0x03, 0x2c, 0x64, 0xc2, 0xa6, 0x88, 0x4d, 0xc2, 0x40, 0x4b, 0x86, 0x42, 0x03, 0x2c, 0x64, 0xc2, 0xa6, 0x88, 0x4f, 0xc2, 0xc0, 0x4b, 0x8a, 0x42, 0x03, 0x2c, 0x64, 0xb7, 0x7b, 0xa8, 0x82, 0xc2, 0x40, 0x4b, 0x8b, 0x42, 0x03, 0x2c, 0x64, 0x42, 0xa6, 0x88, 0x4d, 0x42, 0x40, 0x4b, 0x87, 0x42, 0x03, 0x2c, 0x64, 0x42, 0xa6, 0x88, 0x4d, 0x42, 0xc0, 0x4b, 0x89, 0x42, 0x03, 0x2c, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbd, 0x95, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x42, 0x3b, 0x22, 0xd7, 0x42, 0x87, 0x96, 0x71, 0xc2, 0xa2, 0x10, 0x84, 0xc2, 0x3b, 0x22, 0xcc, 0x42, 0x87, 0x96, 0x71, 0xc2, 0xa2, 0x10, 0x86, 0xc2, 0xbb, 0x22, 0xd1, 0x42, 0x87, 0x96, 0x71, 0xb7, 0x7b, 0xa8, 0x82, 0xc2, 0x3b, 0x22, 0xd2, 0x42, 0x87, 0x96, 0x71, 0x42, 0xa2, 0x10, 0x84, 0x42, 0x3b, 0x22, 0xcf, 0x42, 0x87, 0x96, 0x71, 0x42, 0xa2, 0x10, 0x84, 0x42, 0xbb, 0x22, 0xd0, 0x42, 0x87, 0x96, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xd2, 0xc8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe7, 0x0f, 0x01, 0x42, 0xc5, 0x3b, 0x61, 0xc2, 0x48, 0x1a, 0x3c, 0xc1, 0xe7, 0x0e, 0xf5, 0x42, 0xc5, 0x3b, 0x61, 0xc2, 0x48, 0x1a, 0x42, 0xc2, 0x67, 0x0e, 0xf9, 0x42, 0xc5, 0x3b, 0x61, 0xb7, 0x16, 0xfe, 0xb5, 0xc1, 0xe7, 0x0e, 0xfb, 0x42, 0xc5, 0x3b, 0x61, 0x42, 0x48, 0x1a, 0x3c, 0x41, 0xe7, 0x0e, 0xf6, 0x42, 0xc5, 0x3b, 0x61, 0x42, 0x48, 0x1a, 0x3c, 0x42, 0x67, 0x0e, 0xf7, 0x42, 0xc5, 0x3b, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xda, 0x1f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x42, 0x24, 0xf5, 0x0b, 0x3f, 0x96, 0x3e, 0xc9, 0xc2, 0x8e, 0xdb, 0x67, 0xc2, 0x24, 0xf5, 0x01, 0x3f, 0x96, 0x3e, 0xc9, 0xc2, 0x8e, 0xdb, 0x69, 0xc2, 0xa4, 0xf5, 0x05, 0x3f, 0x96, 0x3e, 0xc9, 0xb7, 0x5a, 0x1a, 0x93, 0xc2, 0x24, 0xf5, 0x06, 0x3f, 0x96, 0x3e, 0xc9, 0x42, 0x8e, 0xdb, 0x67, 0x42, 0x24, 0xf5, 0x02, 0x3f, 0x96, 0x3e, 0xc9, 0x42, 0x8e, 0xdb, 0x67, 0x42, 0xa4, 0xf5, 0x03, 0x3f, 0x96, 0x3e, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x8c, 0x89, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x37, 0xd1, 0xb7, 0x17, 0x42, 0x4b, 0x3d, 0xf5, 0xc2, 0xc3, 0x63, 0xe0, 0xc2, 0xa9, 0x36, 0x7a, 0x42, 0x4b, 0x3d, 0xf5, 0xc2, 0x43, 0x63, 0xe4, 0xc2, 0xa9, 0x36, 0x7d, 0x42, 0x4b, 0x3d, 0xf5, 0x42, 0x43, 0x63, 0xdc, 0xb7, 0x27, 0xc5, 0xac, 0x42, 0x4b, 0x3d, 0xf5, 0x42, 0xc3, 0x63, 0xde, 0x42, 0xa9, 0x36, 0x7a, 0x42, 0x4b, 0x3d, 0xf5, 0x42, 0x43, 0x63, 0xdf, 0x42, 0xa9, 0x36, 0x7a, 0x42, 0x4b, 0x3d, 0xf5, 0xc2, 0x43, 0x63, 0xde, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcc, 0x24, 0x67, 0x00, 0x00, 0x00, 0x00, 0x37, 0xb0, 0x29, 0x28, 0x42, 0xa4, 0x8f, 0x40, 0xc2, 0xa0, 0x12, 0x3e, 0xc2, 0x8a, 0xa0, 0x33, 0x42, 0xa4, 0x8f, 0x40, 0xc2, 0x20, 0x12, 0x43, 0xc2, 0x8a, 0xa0, 0x35, 0x42, 0xa4, 0x8f, 0x40, 0x42, 0x20, 0x12, 0x3d, 0xb7, 0x06, 0x37, 0xbd, 0x42, 0xa4, 0x8f, 0x40, 0x42, 0xa0, 0x12, 0x3f, 0x42, 0x8a, 0xa0, 0x33, 0x42, 0xa4, 0x8f, 0x40, 0x42, 0x20, 0x12, 0x3f, 0x42, 0x8a, 0xa0, 0x33, 0x42, 0xa4, 0x8f, 0x40, 0xc2, 0x20, 0x12, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x42, 0xda, 0x0b, 0x81, 0x00, 0x00, 0x00, 0x00, 0x40, 0x50, 0x61, 0xdd, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xbd, 0x7d, 0x44, 0x40, 0x50, 0x61, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x40, 0xbd, 0x7d, 0x44, 0xc0, 0xa5, 0x2c, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xea, 0x44, 0xc8, 0x41, 0x3c, 0x67, 0x6f, 0xbe, 0x7f, 0x13, 0x8c, 0xbf, 0x5c, 0xeb, 0xbc, 0x41, 0x9e, 0x08, 0x97, 0x41, 0x09, 0x94, 0x81, 0xc1, 0x15, 0xb8, 0x96, 0x41, 0x9c, 0xac, 0xef, 0x41, 0x34, 0x4a, 0xd4, 0xc1, 0x01, 0x4e, 0x1d, 0x41, 0x9e, 0x11, 0x4d, 0x40, 0x44, 0x75, 0x2e, 0xc0, 0x0e, 0x33, 0x37, 0x41, 0x98, 0x13, 0x05, 0xc1, 0x01, 0x2a, 0x2c, 0xc1, 0x18, 0x08, 0xee, 0x41, 0x98, 0x13, 0x05, 0xc0, 0x80, 0xc7, 0x39, 0xc1, 0x06, 0xa2, 0x25, 0x41, 0x98, 0x13, 0x05, 0xc1, 0x40, 0x57, 0xb5, 0x41, 0x57, 0x63, 0xee, 0x41, 0xb0, 0x33, 0x7c, 0x3f, 0xc9, 0xad, 0xb0, 0x40, 0xb1, 0xf3, 0x9f, 0x41, 0xb0, 0x33, 0x7c, 0x40, 0x87, 0x54, 0x2a, 0x40, 0xb5, 0x00, 0x0f, 0x41, 0xb0, 0x33, 0x7c, 0xc0, 0x6f, 0xf7, 0xe4 };
+u8 l_color[0x50] = { 0x7f, 0x7f, 0x7f, 0xff, 0x98, 0x98, 0x99, 0xff, 0x99, 0x99, 0x99, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x66, 0x66, 0x66, 0xff, 0xb2, 0xb2, 0xb2, 0xff, 0xe5, 0xe5, 0xe5, 0xff, 0xf4, 0xf4, 0xf4, 0xff, 0xab, 0xab, 0xab, 0xff, 0xfc, 0xfc, 0xfc, 0xff, 0xf7, 0xf7, 0xf7, 0xff, 0xf8, 0xf8, 0xf8, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xa1, 0xa1, 0xa1, 0xff, 0xf5, 0xf5, 0xf5, 0xff, 0xfb, 0xfb, 0xfb, 0xff, 0x73, 0x73, 0x73, 0xff, 0x43, 0x43, 0x43, 0xff, 0x9a, 0x9a, 0x9a, 0xff };
+u8 l_texCoord[0x50] = { 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x3e, 0xe9, 0x5d, 0xb3, 0x3f, 0x80, 0x00, 0x00, 0x3f, 0x40, 0x00, 0x00, 0x3f, 0x34, 0xae, 0xda, 0x3f, 0x40, 0x00, 0x00, 0x3f, 0x75, 0x5e, 0x6c, 0x3f, 0x80, 0x00, 0x00, 0x3f, 0x4a, 0xf9, 0x55, 0x3f, 0x40, 0x00, 0x00, 0x3f, 0x75, 0x5e, 0x6c, 0x3f, 0x40, 0x00, 0x00, 0x3f, 0x4a, 0xf9, 0x55, 0x3f, 0x80, 0x00, 0x00 };
+u8 l_Oba_swood_bDL[0x11c] ALIGN_DECL(32) = { 0x98, 0x00, 0x05, 0x2a, 0x07, 0x02, 0x2f, 0x07, 0x01, 0x30, 0x07, 0x00, 0x2e, 0x07, 0x02, 0x2d, 0x07, 0x01, 0x98, 0x00, 0x05, 0x2d, 0x07, 0x01, 0x2c, 0x07, 0x02, 0x30, 0x07, 0x00, 0x2b, 0x07, 0x01, 0x2a, 0x07, 0x02, 0x98, 0x00, 0x05, 0x23, 0x06, 0x02, 0x28, 0x06, 0x01, 0x29, 0x06, 0x00, 0x27, 0x06, 0x02, 0x26, 0x06, 0x01, 0x98, 0x00, 0x05, 0x26, 0x06, 0x01, 0x25, 0x06, 0x02, 0x29, 0x06, 0x00, 0x24, 0x06, 0x01, 0x23, 0x06, 0x02, 0x98, 0x00, 0x05, 0x1c, 0x05, 0x02, 0x21, 0x05, 0x01, 0x22, 0x05, 0x00, 0x20, 0x05, 0x02, 0x1f, 0x05, 0x01, 0x98, 0x00, 0x05, 0x1f, 0x05, 0x01, 0x1e, 0x05, 0x02, 0x22, 0x05, 0x00, 0x1d, 0x05, 0x01, 0x1c, 0x05, 0x02, 0x98, 0x00, 0x05, 0x15, 0x04, 0x02, 0x1a, 0x04, 0x01, 0x1b, 0x04, 0x00, 0x19, 0x04, 0x02, 0x18, 0x04, 0x01, 0x98, 0x00, 0x05, 0x18, 0x04, 0x01, 0x17, 0x04, 0x02, 0x1b, 0x04, 0x00, 0x16, 0x04, 0x01, 0x15, 0x04, 0x02, 0x98, 0x00, 0x05, 0x0e, 0x03, 0x02, 0x13, 0x03, 0x01, 0x14, 0x03, 0x00, 0x12, 0x03, 0x02, 0x11, 0x03, 0x01, 0x98, 0x00, 0x05, 0x11, 0x03, 0x01, 0x10, 0x03, 0x02, 0x14, 0x03, 0x00, 0x0f, 0x03, 0x01, 0x0e, 0x03, 0x02, 0x98, 0x00, 0x05, 0x07, 0x02, 0x02, 0x0c, 0x02, 0x01, 0x0d, 0x01, 0x00, 0x0b, 0x02, 0x02, 0x0a, 0x02, 0x01, 0x98, 0x00, 0x05, 0x0a, 0x02, 0x01, 0x09, 0x02, 0x02, 0x0d, 0x01, 0x00, 0x08, 0x02, 0x01, 0x07, 0x02, 0x02, 0x98, 0x00, 0x05, 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, 0x06, 0x00, 0x00, 0x04, 0x00, 0x02, 0x03, 0x00, 0x01, 0x98, 0x00, 0x05, 0x03, 0x00, 0x01, 0x02, 0x00, 0x02, 0x06, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+u8 l_Oba_swood_b_cutDL[0xcb] ALIGN_DECL(32) = { 0x98, 0x00, 0x04, 0x31, 0x13, 0x06, 0x32, 0x11, 0x09, 0x3b, 0x0d, 0x08, 0x3c, 0x0b, 0x07, 0x98, 0x00, 0x04, 0x3b, 0x0d, 0x07, 0x3d, 0x0c, 0x08, 0x31, 0x13, 0x09, 0x34, 0x00, 0x06, 0x98, 0x00, 0x04, 0x31, 0x13, 0x06, 0x34, 0x00, 0x09, 0x38, 0x0a, 0x08, 0x39, 0x08, 0x07, 0x98, 0x00, 0x04, 0x33, 0x12, 0x06, 0x31, 0x13, 0x09, 0x3a, 0x09, 0x08, 0x38, 0x0a, 0x07, 0x98, 0x00, 0x04, 0x3a, 0x09, 0x07, 0x39, 0x08, 0x08, 0x33, 0x12, 0x09, 0x34, 0x00, 0x06, 0x98, 0x00, 0x04, 0x36, 0x0e, 0x08, 0x33, 0x12, 0x06, 0x37, 0x0f, 0x07, 0x34, 0x00, 0x09, 0x98, 0x00, 0x04, 0x33, 0x12, 0x09, 0x36, 0x0e, 0x07, 0x32, 0x11, 0x06, 0x35, 0x10, 0x08, 0x98, 0x00, 0x04, 0x32, 0x11, 0x06, 0x34, 0x00, 0x09, 0x3c, 0x0b, 0x08, 0x3d, 0x0c, 0x07, 0x98, 0x00, 0x04, 0x32, 0x11, 0x09, 0x35, 0x10, 0x07, 0x34, 0x00, 0x06, 0x37, 0x0f, 0x08, 0x98, 0x00, 0x03, 0x36, 0x0e, 0x03, 0x37, 0x0f, 0x04, 0x35, 0x10, 0x05, 0x98, 0x00, 0x03, 0x3c, 0x0b, 0x03, 0x3d, 0x0c, 0x04, 0x3b, 0x0d, 0x05, 0x98, 0x00, 0x03, 0x39, 0x08, 0x03, 0x3a, 0x09, 0x04, 0x38, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+u8 l_matDL[0xa3] ALIGN_DECL(32) = { 0x61, 0x80, 0x00, 0x01, 0x3a, 0x61, 0x84, 0x00, 0x00, 0x00, 0x61, 0x88, 0xe0, 0xfc, 0x3f, 0x61, 0x94, ((int)l_Txa_swood_bTEX >> 21) & 0xFF, ((int)l_Txa_swood_bTEX >> 13) & 0xFF, ((int)l_Txa_swood_bTEX >> 5) & 0xFF, 0x61, 0x30, 0x00, 0x00, 0x40, 0x61, 0x31, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x10, 0x40, 0xff, 0xff, 0x42, 0x80, 0x08, 0x30, 0x3c, 0xf3, 0xcf, 0x00, 0x10, 0x00, 0x00, 0x10, 0x18, 0x3c, 0xf3, 0xcf, 0x00, 0x10, 0x00, 0x00, 0x10, 0x0e, 0x00, 0x00, 0x05, 0x43, 0x61, 0x28, 0x3c, 0x00, 0x00, 0x61, 0xc0, 0x08, 0x24, 0xaf, 0x61, 0xc1, 0x08, 0xff, 0xf0, 0x61, 0x28, 0x3c, 0x00, 0x00, 0x61, 0xc2, 0x08, 0xf0, 0x8f, 0x61, 0xc3, 0x08, 0xee, 0x70, 0x61, 0x40, 0x00, 0x00, 0x17, 0x61, 0xf3, 0x64, 0x00, 0x00, 0x61, 0xf3, 0x64, 0xfe, 0xfe, 0x10, 0x00, 0x00, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+// .rodata
+const Attr_c L_attr = {
+ {{{
+ 0x00C8,
+ 0x50,
+ 0x5DC,
+ 0x32,
+ 0.6
+ }, {
+ 0x00B4,
+ 0x1E,
+ 0xC80,
+ 0xA,
+ 0.2,
+ }}, {{
+ 0x01f4,
+ 0x96,
+ 0x4B0,
+ 0x96,
+ 0.6,
+ }, {
+ 0x02BC,
+ 0x32,
+ 0x898,
+ 0x1E,
+ 0.2,
+ }}, {{
+ 0x0258,
+ 0xC8,
+ 0x898,
+ 0x12C,
+ 0.6,
+ }, {
+ 0x01BC,
+ 0x1E,
+ 0xFA0,
+ 0x32,
+ 0.2,
+ }}, {{
+ 0x0258,
+ 0xC8,
+ 0x1838,
+ 0x1F4,
+ 0.6,
+ }, {
+ 0x01BC,
+ 0x1E,
+ 0x3E8,
+ 0x32,
+ 0.2,
+ }}
+ }, 0x14, 0x14, 0x0e, 18.0f, -3.0f, 2.5f, 200, 1.5f, 0.3f, 80.0f, 15.0f, 80.0f, 15.0f, 100.0f, 40.0f, 0x23, 0x80
+};
+} // namespace
+} // namespace dWood
+
+//-----------------------------------------
+// Constants
+//-----------------------------------------
+const s32 L_Room_Max = 64;
+const float l_Ground_check_y_offset = 100.0f;
+const double l_Ground_check_unk1 = 0.5;
+const double l_Ground_check_unk2 = 3.0;
+const float kGroundHeightBias = 1.0f;
+
+const u32 l_Oba_swood_bDL_SIZE = 0x100;
+const u32 l_Oba_swood_b_cutDL_SIZE = 0xc0;
+
+s32 dWood::Anm_c::M_init_num = 0;
+
+//-----------------------------------------
+// Helpers
+//-----------------------------------------
+namespace {
+inline const Attr_c &attr() { return dWood::L_attr; }
+
+inline const AttrSway_c &attr_sway(AttrSway_e swayID, int idx) {
+ return attr().kSways[swayID][idx];
+}
+} // namespace
+
+//-----------------------------------------
+// Classes
+//-----------------------------------------
/* 800BD678-800BD710 .text __ct__Q25dWood5Anm_cFv */
dWood::Anm_c::Anm_c() {
- /* Nonmatching */
+ MTXIdentity(mModelMtx);
+ MTXIdentity(mTrunkModelMtx);
+ mMode = Mode_Max;
+ mCountdown = 0;
+ mForceDir = 0;
+ mWindPow = 0.0f;
+ mPosOffsetY = 0.0f;
+ mPosOffsetZ = 0.0f;
+ mVelY = 0.0f;
+
+ for (u32 i = 0; i < 2; i++) {
+ mPhaseY[i] = 0;
+ mPhaseX[i] = 0;
+ mAmpY[i] = 0;
+ mAmpX[i] = 0;
+ }
+
+ mNormAnimIdx = AnmID_Norm0;
+ mAlphaScale = 0xff;
+ return;
}
/* 800BD710-800BD800 .text play__Q25dWood5Anm_cFPQ25dWood8Packet_c */
-void dWood::Anm_c::play(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Anm_c::play(dWood::Packet_c *i_packet) {
+ if (mMode != Mode_Max) {
+ static modeProcFunc mode_proc[] = {
+ &dWood::Anm_c::mode_cut, &dWood::Anm_c::mode_push_into,
+ &dWood::Anm_c::mode_push_back, &dWood::Anm_c::mode_fan,
+ &dWood::Anm_c::mode_norm, &dWood::Anm_c::mode_to_norm,
+ };
+ (this->*mode_proc[mMode])(i_packet);
+ }
+ return;
}
/* 800BD800-800BD848 .text copy_angamp__Q25dWood5Anm_cFPCQ25dWood5Anm_c */
-void dWood::Anm_c::copy_angamp(const dWood::Anm_c*) {
- /* Nonmatching */
-}
-
-/* 800BD848-800BD8BC .text mode_cut_init__Q25dWood5Anm_cFPCQ25dWood5Anm_cs */
-void dWood::Anm_c::mode_cut_init(const dWood::Anm_c*, short) {
- /* Nonmatching */
+void dWood::Anm_c::copy_angamp(const dWood::Anm_c *other) {
+ if (this == other) {
+ return;
+ }
+
+ for (u32 i = 0; i < 2; i++) {
+ mPhaseY[i] = other->mPhaseY[i];
+ mPhaseX[i] = other->mPhaseX[i];
+ mAmpY[i] = other->mAmpY[i];
+ mAmpX[i] = other->mAmpX[i];
+ }
+}
+
+/* 800BD848-800BD8BC .text mode_cut_init__Q25dWood5Anm_cFPCQ25dWood5Anm_cs
+ */
+void dWood::Anm_c::mode_cut_init(const dWood::Anm_c *, short targetAngle) {
+ for (u32 i = 0; i < 2; i++) {
+ mPhaseY[i] = 0;
+ mPhaseX[i] = 0;
+ mAmpY[i] = 0;
+ mAmpX[i] = 0;
+ }
+
+ mForceDir = targetAngle;
+ mVelY = L_attr.kCutInitVelY;
+ mPosOffsetY = 0.0f;
+ mPosOffsetZ = 0.0f;
+ mAlphaScale = 0xff;
+ mCountdown = L_attr.kCutCooldown;
+ mMode = Anm_c::Mode_Cut;
}
/* 800BD8BC-800BD9E4 .text mode_cut__Q25dWood5Anm_cFPQ25dWood8Packet_c */
-void dWood::Anm_c::mode_cut(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Anm_c::mode_cut(dWood::Packet_c *) {
+ mVelY = mVelY + L_attr.kCutYAccel;
+ if (mVelY < -40.0f) {
+ mVelY = -40.0f;
+ }
+
+ mPosOffsetY = mPosOffsetY + mVelY;
+ mPosOffsetZ = mPosOffsetZ + L_attr.kCutZVel;
+ mPhaseX[0] = mPhaseX[0] - L_attr.kCutPitchVel;
+
+ mDoMtx_YrotS(mDoMtx_stack_c::now, (int)mForceDir);
+ mDoMtx_stack_c::transM(0.0f, mPosOffsetY, mPosOffsetZ);
+ mDoMtx_XrotM(mDoMtx_stack_c::now, mPhaseX[0]);
+ mDoMtx_YrotM(mDoMtx_stack_c::now, -mForceDir);
+ mDoMtx_copy(mDoMtx_stack_c::now, mModelMtx);
+
+ // Fade out the bush as it falls
+ if (mCountdown < attr().kCutFadeStart) {
+ int alphaScale = mAlphaScale;
+ alphaScale -= attr().kCutAlphaFadeSpeed;
+ if (alphaScale < 0) {
+ alphaScale = 0;
+ }
+ mAlphaScale = (u8)alphaScale;
+ }
+
+ if ((s32)mCountdown > 0) {
+ mCountdown = mCountdown + -1;
+ }
}
/* 800BD9E4-800BDA38 .text mode_push_into_init__Q25dWood5Anm_cFPCQ25dWood5Anm_cs */
-void dWood::Anm_c::mode_push_into_init(const dWood::Anm_c*, short) {
- /* Nonmatching */
+void dWood::Anm_c::mode_push_into_init(const dWood::Anm_c *anm,
+ short targetAngle) {
+ copy_angamp(anm);
+ mForceDir = targetAngle;
+ mAlphaScale = 0xff;
+ mCountdown = 2;
+ mMode = Mode_PushInto;
}
/* 800BDA38-800BDC24 .text mode_push_into__Q25dWood5Anm_cFPQ25dWood8Packet_c */
-void dWood::Anm_c::mode_push_into(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Anm_c::mode_push_into(dWood::Packet_c *packet) {
+ if (--mCountdown <= 0) {
+ mode_push_back_init();
+ }
+ else {
+ float rotY = 0.0f;
+ float rotX = rotY;
+ for (s32 i = 0; i < 2; i++) {
+ const AttrSway_c* sway = &attr().kSways[SWAY_PUSH][i];
+ s32 phaseVelX = sway->phaseVelX;
+ s32 ampY = sway->ampY;
+ s32 ampX = sway->ampX;
+ float phaseBiasX = sway->phaseBiasX;
+
+ mPhaseY[i] += sway->phaseVelY;
+ cLib_chaseAngleS(&mPhaseX[i], 0, phaseVelX);
+ cLib_chaseS(&mAmpY[i], ampY/4, 0x14);
+ cLib_addCalcAngleS(&mAmpX[i], ampX, 8, 0x14, 5);
+
+ rotY += mAmpY[i] * JMASCos(mPhaseY[i]);
+ rotX += mAmpX[i] * (phaseBiasX + JMASCos(mPhaseX[i]));
+ }
+
+ mDoMtx_YrotS(mModelMtx, (s16)rotY + mForceDir);
+ mDoMtx_XrotM(mModelMtx, (s32)rotX);
+ mDoMtx_YrotM(mModelMtx, -mForceDir);
+ }
}
/* 800BDC24-800BDC48 .text mode_push_back_init__Q25dWood5Anm_cFv */
void dWood::Anm_c::mode_push_back_init() {
- /* Nonmatching */
+ mCountdown = L_attr.kPushBackCountdown;
+ mAlphaScale = 0xff;
+ mMode = Mode_PushBack;
}
/* 800BDC48-800BDECC .text mode_push_back__Q25dWood5Anm_cFPQ25dWood8Packet_c */
-void dWood::Anm_c::mode_push_back(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Anm_c::mode_push_back(dWood::Packet_c *packet) {
+ if (--mCountdown <= 0) {
+ AnmID_e animIdx = packet->search_anm(Anm_c::Mode_Norm);
+ mode_to_norm_init(animIdx);
+ }
+ else {
+ float t = mCountdown * (1.0f / L_attr.kPushBackCountdown);
+
+ float rotY = 0.0;
+ float rotX = rotY;
+ for (s32 i = 0; i < 2; i++) {
+ const AttrSway_c* sway = &attr().kSways[SWAY_PUSH][i];
+ s32 phaseVelX = sway->phaseVelX;
+ s16 ampY = t * sway->ampY;
+ s16 ampX = t * sway->ampX;
+ float phaseBiasX = sway->phaseBiasX;
+
+ mPhaseY[i] += sway->phaseVelY;
+ mPhaseX[i] += phaseVelX;
+ cLib_chaseS(&mAmpY[i], (s32)ampY, 0x14);
+ cLib_chaseS(&mAmpX[i], (s32)ampX, 0x14);
+
+ rotY += mAmpY[i] * JMASCos(mPhaseY[i]);
+ rotX += mAmpX[i] * (phaseBiasX + JMASCos(mPhaseX[i]));
+ }
+
+ mDoMtx_YrotS(mModelMtx, (s16)rotY + mForceDir);
+ mDoMtx_XrotM(mModelMtx, (s32)rotX);
+ mDoMtx_YrotM(mModelMtx, -mForceDir);
+ }
}
/* 800BDECC-800BDED0 .text mode_fan__Q25dWood5Anm_cFPQ25dWood8Packet_c */
-void dWood::Anm_c::mode_fan(dWood::Packet_c*) {
- /* Nonmatching */
-}
+void dWood::Anm_c::mode_fan(dWood::Packet_c *) {}
/* 800BDED0-800BDF5C .text mode_norm_init__Q25dWood5Anm_cFv */
void dWood::Anm_c::mode_norm_init() {
- /* Nonmatching */
+ mMode = Mode_Norm;
+
+ for (u32 i = 0; i < 2; i++) {
+ mPhaseY[i] = M_init_num * 0x2000;
+ mPhaseX[i] = M_init_num * 0x2000;
+ mAmpY[i] = attr_sway(SWAY_LIGHT, i).ampY;
+ mAmpX[i] = attr_sway(SWAY_LIGHT, i).ampX;
+ }
+
+ mAlphaScale = 0xff;
+
+ M_init_num++;
+ M_init_num = M_init_num % 8;
}
/* 800BDF5C-800BE148 .text mode_norm__Q25dWood5Anm_cFPQ25dWood8Packet_c */
-void dWood::Anm_c::mode_norm(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Anm_c::mode_norm(dWood::Packet_c *packet) {
+ AttrSway_e swayID;
+ if (mWindPow < 0.33f) {
+ swayID = SWAY_LIGHT;
+ } else {
+ if (mWindPow < 0.66f) {
+ swayID = SWAY_MEDIUM;
+ } else {
+ swayID = SWAY_STRONG;
+ }
+ }
+
+ float rotY = 0.0f;
+ float rotX = rotY;
+ for (s32 i = 0; i < 2; i++) {
+ const AttrSway_c *sway = &attr_sway(swayID, i);
+ s32 phaseVelX = sway->phaseVelX;
+ s16 ampY = sway->ampY;
+ s16 ampX = sway->ampX;
+ float phaseBiasX = sway->phaseBiasX;
+
+ mPhaseY[i] += sway->phaseVelY;
+ mPhaseX[i] += phaseVelX;
+ cLib_chaseS(&mAmpY[i], ampY, 2);
+ cLib_chaseS(&mAmpX[i], ampX, 2);
+
+ rotY += mAmpY[i] * JMASCos(mPhaseY[i]);
+ rotX += mAmpX[i] * (phaseBiasX + JMASCos(mPhaseX[i]));
+ }
+
+ mDoMtx_YrotS(mModelMtx, (s16)rotY + mForceDir); // Y Rotation (Yaw)
+ mDoMtx_XrotM(mModelMtx, rotX); // X Rotation
+ mDoMtx_YrotM(mModelMtx, -mForceDir); // Y Rotation
}
/* 800BE148-800BE154 .text mode_norm_set_wind__Q25dWood5Anm_cFfs */
-void dWood::Anm_c::mode_norm_set_wind(float, short) {
- /* Nonmatching */
+void dWood::Anm_c::mode_norm_set_wind(float windPow, short windDir) {
+ mWindPow = windPow;
+ mForceDir = windDir;
}
-
/* 800BE154-800BE1F0 .text mode_to_norm_init__Q25dWood5Anm_cFQ25dWood7AnmID_e */
-void dWood::Anm_c::mode_to_norm_init(dWood::AnmID_e) {
- /* Nonmatching */
+void dWood::Anm_c::mode_to_norm_init(dWood::AnmID_e anm_id_norm) {
+ JUT_ASSERT(0x4d7, (anm_id_norm >= 0) && (anm_id_norm < AnmID_Norm_Max));
+
+ mode_to_norm_set_AnmID(anm_id_norm);
+ mAlphaScale = 0xff;
+ mCountdown = 0x14;
+ mMode = Anm_c::Mode_ToNorm;
}
/* 800BE1F0-800BE428 .text mode_to_norm__Q25dWood5Anm_cFPQ25dWood8Packet_c */
-void dWood::Anm_c::mode_to_norm(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Anm_c::mode_to_norm(dWood::Packet_c *packet) {
+ const Anm_c *normAnim = packet->get_anm_p(mode_to_norm_get_AnmID());
+
+ AttrSway_e swayID;
+ if (normAnim->mWindPow < 0.33f) {
+ swayID = SWAY_LIGHT;
+ } else {
+ if (normAnim->mWindPow < 0.66f) {
+ swayID = SWAY_MEDIUM;
+ } else {
+ swayID = SWAY_STRONG;
+ }
+ }
+
+ cLib_chaseAngleS(&mForceDir, normAnim->mForceDir, 3000);
+
+ float rotY = 0.0f;
+ float rotX = rotY;
+ for (s32 i = 0; i < 2; i++) {
+ const AttrSway_c *sway = &attr_sway(swayID, i);
+ float phaseBiasX = sway->phaseBiasX;
+ s32 phaseVelX = sway->phaseVelX;
+ s16 rotXStep = phaseVelX + 3000;
+
+ cLib_chaseS(&mPhaseY[i], normAnim->mPhaseY[i], sway->phaseVelY + 3000);
+ cLib_chaseS(&mPhaseX[i], normAnim->mPhaseX[i], rotXStep);
+ cLib_chaseS(&mAmpY[i], normAnim->mAmpY[i], 0xf);
+ cLib_chaseS(&mAmpX[i], normAnim->mAmpX[i], 0xf);
+
+ rotY += mAmpY[i] * JMASCos(mPhaseY[i]);
+ rotX += mAmpX[i] * (phaseBiasX + JMASCos(mPhaseX[i]));
+ }
+
+ mDoMtx_YrotS(mModelMtx, (s16)rotY + mForceDir);
+ mDoMtx_XrotM(mModelMtx, rotX);
+ mDoMtx_YrotM(mModelMtx, -mForceDir);
+
+ if (mCountdown > 0) {
+ mCountdown -= 1;
+ }
}
/* 800BE428-800BE4DC .text __ct__Q25dWood6Unit_cFv */
dWood::Unit_c::Unit_c() {
- /* Nonmatching */
+ clear();
}
/* 800BE4DC-800BE93C .text set_ground__Q25dWood6Unit_cFv */
-void dWood::Unit_c::set_ground() {
- /* Nonmatching */
+bool dWood::Unit_c::set_ground() {
+ cXyz pos(mPos.x, mPos.y + l_Ground_check_y_offset, mPos.z);
+
+ // Cast the current position to the ground
+ dBgS_ObjGndChk gndChk;
+ gndChk.SetPos(&pos);
+ f32 gndHeight = dComIfG_Bgsp()->GroundCross(&gndChk);
+
+ if (gndHeight > -1000000000.0f) {
+ mPos.y = gndHeight;
+ cM3dGPla *triPla = dComIfG_Bgsp()->GetTriPla(gndChk);
+
+ cXyz gndNorm = *triPla->GetNP();
+ float unkFloat = std::sqrtf(1.0f - gndNorm.x * gndNorm.x);
+
+ float scaledNormY;
+ float scaledNormZ;
+ if (unkFloat != 0.0f) {
+ scaledNormY = gndNorm.y * unkFloat;
+ scaledNormZ = -gndNorm.z * unkFloat;
+ } else {
+ scaledNormY = 0.0f;
+ scaledNormZ = 0.0f;
+ }
+
+ MtxP mtx = mDoMtx_stack_c::get();
+
+ mtx[0][0] = unkFloat;
+ mtx[0][1] = gndNorm.x;
+ mtx[0][2] = 0.0f;
+ mtx[0][3] = mPos.x;
+
+ mtx[1][0] = -gndNorm.x * scaledNormY;
+ mtx[1][1] = gndNorm.y;
+ mtx[1][2] = scaledNormZ;
+ mtx[1][3] = kGroundHeightBias + gndHeight;
+
+ mtx[2][0] = gndNorm.x * scaledNormZ;
+ mtx[2][1] = gndNorm.z;
+ mtx[2][2] = scaledNormY;
+ mtx[2][3] = mPos.z;
+ mDoMtx_stack_c::scaleM(L_attr.kUncutShadowScale, kGroundHeightBias,
+ L_attr.kUncutShadowScale);
+ mDoMtx_copy(mDoMtx_stack_c::now, mShadowModelMtx);
+ return true;
+ } else {
+ return false;
+ }
}
/* 800BE93C-800BEA28 .text set_mtx__Q25dWood6Unit_cFPQ25dWood5Anm_c */
-void dWood::Unit_c::set_mtx(dWood::Anm_c*) {
- /* Nonmatching */
+void dWood::Unit_c::set_mtx(dWood::Anm_c *anim) {
+ int anmIdx = mAnmIdx;
+
+ mDoMtx_copy(anim[anmIdx].mModelMtx, mDoMtx_stack_c::get());
+ mDoMtx_stack_c::now[0][3] = mDoMtx_stack_c::now[0][3] + mPos.x;
+ mDoMtx_stack_c::now[1][3] = mDoMtx_stack_c::now[1][3] + mPos.y;
+ mDoMtx_stack_c::now[2][3] = mDoMtx_stack_c::now[2][3] + mPos.z;
+ mDoMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::now, mModelViewMtx);
+
+ mDoMtx_copy(anim[anmIdx].mTrunkModelMtx, mDoMtx_stack_c::get());
+ mDoMtx_stack_c::now[0][3] = mPos.x;
+ mDoMtx_stack_c::now[1][3] = mPos.y;
+ mDoMtx_stack_c::now[2][3] = mPos.z;
+ mDoMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::get(),
+ mTrunkModelViewMtx);
+
+ mDoMtx_concat(j3dSys.getViewMtx(), mShadowModelMtx, mShadowModelViewMtx);
}
/* 800BEA28-800BEA50 .text clear__Q25dWood6Unit_cFv */
-void dWood::Unit_c::clear() {
- /* Nonmatching */
+void dWood::Unit_c::clear() {
+ cLib_memSet(this, 0, 0x18c);
}
/* 800BEA50-800BEE9C .text cc_hit_before_cut__Q25dWood6Unit_cFPQ25dWood8Packet_c */
-void dWood::Unit_c::cc_hit_before_cut(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Unit_c::cc_hit_before_cut(dWood::Packet_c *packet) {
+ AnmID_e animIdx;
+ AnmID_e oldAnimIdx;
+ s16 targetAngle;
+
+ dCcMassS_HitInf inf;
+ fopAc_ac_c *actor;
+ u32 ret = dComIfG_Ccsp()->ChkMass(&mPos, &actor, &inf);
+
+ if (mAnimCooldown > 0) {
+ mAnimCooldown -= 1;
+ }
+
+ // Evaluate for attacks that will not cut us down
+ if (cLib_checkBit(ret, 0x01UL)) {
+ cCcD_Obj *atHitObj = inf.GetAtHitObj();
+ if (atHitObj != NULL && (atHitObj->ChkAtType(AT_TYPE_WIND) ||
+ atHitObj->ChkAtType(AT_TYPE_BOMB) ||
+ atHitObj->ChkAtType(AT_TYPE_FIRE) ||
+ atHitObj->ChkAtType(AT_TYPE_NORMAL_ARROW) ||
+ atHitObj->ChkAtType(AT_TYPE_FIRE_ARROW) ||
+ atHitObj->ChkAtType(AT_TYPE_ICE_ARROW) ||
+ atHitObj->ChkAtType(AT_TYPE_LIGHT_ARROW) ||
+ atHitObj->ChkAtType(AT_TYPE_HOOKSHOT))) {
+
+ // Clear the hit bit so that we don't get cut down
+ ret &= ~0x01;
+
+ if (actor != NULL && mAnimCooldown == 0) {
+ animIdx = packet->search_anm(Anm_c::Mode_PushInto);
+ mAnimCooldown = 20;
+
+ // Play the cut sound
+ mDoAud_seStart(JA_SE_OBJ_TREE_SWING, &mPos, 0, 0);
+
+ // If we are currently performing a basic animation, assign a
+ // new animation
+ oldAnimIdx = mAnmIdx;
+ if ((oldAnimIdx < 8) && (animIdx != AnmID_Norm_Invalid)) {
+ mAnmIdx = animIdx;
+ }
+
+ // If we were able to allocate an animation (or we already have
+ // one), start the "PushInto" (shrinking) animation
+ if ((mAnmIdx >= 8) && packet->get_anm_p(mAnmIdx)->get_mode() >=
+ Anm_c::Mode_PushInto) {
+ targetAngle = cLib_targetAngleY(&actor->current.pos, &mPos);
+ packet->get_anm_p(mAnmIdx)->mode_push_into_init(
+ packet->mAnm + oldAnimIdx, (s32)targetAngle);
+ }
+ }
+ }
+ }
+
+ // Check for collisions that are not attacks
+ if (cLib_checkBit(ret, 0x02UL) && actor && inf.GetCoHitObj() &&
+ inf.GetCoHitObj()->GetStts()) {
+ animIdx = packet->search_anm(Anm_c::Mode_PushInto);
+
+ if (fopAcM_GetProfName(actor) == PROC_PLAYER &&
+ inf.GetCoHitLen() >= 2.0f && mAnimCooldown == 0) {
+
+ mAnimCooldown = 20;
+ mDoAud_seStart(JA_SE_OBJ_TREE_SWING, &mPos, 0, 0);
+
+ // If we are currently performing a basic animation, assign a new
+ // animation
+ oldAnimIdx = mAnmIdx;
+ if ((oldAnimIdx < 8) && (animIdx != AnmID_Norm_Invalid)) {
+ mAnmIdx = animIdx;
+ }
+
+ // If we were able to allocate an animation (or we already have
+ // one), start the "PushInto" (shrinking) animation
+ if ((mAnmIdx >= 8) && (packet->get_anm_p(mAnmIdx)->get_mode() >=
+ Anm_c::Mode_PushInto)) {
+ targetAngle = cLib_targetAngleY(&actor->current.pos, &mPos);
+ packet->get_anm_p(mAnmIdx)->mode_push_into_init(
+ packet->mAnm + oldAnimIdx, (s32)targetAngle);
+ }
+ }
+ }
+
+ // Check for attacks that WILL cut us down
+ if (cLib_checkBit(ret, 0x01UL)) {
+ AnmID_e oldAnimIdx = mAnmIdx;
+
+ if ((mAnmIdx < 8)) {
+ animIdx = packet->search_anm(Anm_c::Mode_Cut);
+ if (animIdx != AnmID_Norm_Invalid) {
+ mAnmIdx = animIdx;
+ }
+ }
+
+ if ((mAnmIdx >= 8)) {
+ if (packet->get_anm_p(mAnmIdx)->get_mode() > Anm_c::Mode_Cut) {
+ targetAngle = cLib_targetAngleY(&actor->current.pos, &mPos);
+ packet->get_anm_p(mAnmIdx)->mode_cut_init(
+ packet->get_anm_p(oldAnimIdx), (s32)targetAngle);
+
+ // Compute the color settings for particels
+ g_env_light.settingTevStruct(TEV_TYPE_BG0, &mPos, &mTevStr);
+
+ // Spawn cut down particles (a bunch of leaves)
+ dComIfGp_particle_set(dPa_name::ID_CUT_L_TREE_DOWN, &mPos, NULL,
+ NULL, 0xff, NULL, -1, &mTevStr.mColorK0,
+ NULL, NULL);
+
+ mDoAud_seStart(JA_SE_OBJ_CUT_L_TREE_DOWN, &mPos, 0, 0);
+
+ float newShadowScale =
+ L_attr.kCutShadowScale / L_attr.kUncutShadowScale;
+
+ mDoMtx_copy(mShadowModelMtx, mDoMtx_stack_c::get());
+ mDoMtx_stack_c::scaleM(newShadowScale, 1.0f, newShadowScale);
+ mDoMtx_copy(mDoMtx_stack_c::get(), mShadowModelMtx);
+ }
+ }
+ }
}
/* 800BEE9C-800BEEA0 .text cc_hit_after_cut__Q25dWood6Unit_cFPQ25dWood8Packet_c */
-void dWood::Unit_c::cc_hit_after_cut(dWood::Packet_c*) {
- /* Nonmatching */
-}
+void dWood::Unit_c::cc_hit_after_cut(dWood::Packet_c *) {}
/* 800BEEA0-800BEF78 .text proc__Q25dWood6Unit_cFPQ25dWood8Packet_c */
-void dWood::Unit_c::proc(dWood::Packet_c*) {
- /* Nonmatching */
+void dWood::Unit_c::proc(dWood::Packet_c *packet) {
+ // If this unit is active, and performing a non-normal animation...
+ if (cLib_checkBit(mFlags, STATE_ACTIVE)) {
+ AnmID_e animIdx = mAnmIdx;
+
+ if (animIdx >= 8) {
+ Anm_c *anim = packet->get_anm_p(animIdx);
+ Anm_c::Mode_e mode = anim->mMode;
+ if (mode == Anm_c::Mode_ToNorm) {
+ if (anim->mCountdown <= 0) {
+ mAnmIdx = anim->mode_to_norm_get_AnmID();
+ anim->mMode = Anm_c::Mode_Max;
+ }
+ } else if (mode == Anm_c::Mode_Cut) {
+ if (anim->mCountdown <= 0) {
+ AnmID_e newAnimIdx = packet->search_anm(Anm_c::Mode_Norm);
+ mAnmIdx = newAnimIdx;
+ anim->mMode = Anm_c::Mode_Max;
+ cLib_onBit(mFlags, STATE_CUT);
+ }
+ } else if (mode == Anm_c::Mode_Max) {
+ animIdx = packet->search_anm(Anm_c::Mode_Norm);
+ mAnmIdx = animIdx;
+ }
+ }
+ }
}
/* 800BEF78-800BEF84 .text __ct__Q25dWood6Room_cFv */
-dWood::Room_c::Room_c() {
- /* Nonmatching */
+dWood::Room_c::Room_c() {
+ mpUnit = NULL;
}
-/* 800BEF84-800BEF94 .text entry_unit__Q25dWood6Room_cFPQ25dWood6Unit_c */
-void dWood::Room_c::entry_unit(dWood::Unit_c*) {
- /* Nonmatching */
+/* 800BEF84-800BEF94 .text entry_unit__Q25dWood6Room_cFPQ25dWood6Unit_c
+ */
+void dWood::Room_c::entry_unit(dWood::Unit_c *unit) {
+ unit->mpNext = mpUnit;
+ mpUnit = unit;
+ return;
}
/* 800BEF94-800BEFF0 .text delete_all_unit__Q25dWood6Room_cFv */
void dWood::Room_c::delete_all_unit() {
- /* Nonmatching */
+ Unit_c *unit;
+ while (unit = mpUnit, unit != NULL) {
+ mpUnit = unit->mpNext;
+ mDoAud_zelAudio_c::getInterface()->seDeleteObject((Vec *)unit);
+ unit->clear();
+ }
}
/* 800BEFF0-800BF0D4 .text __ct__Q25dWood8Packet_cFv */
dWood::Packet_c::Packet_c() {
- /* Nonmatching */
+ for (s32 i = 0; i < 8; i++) {
+ mAnm[i].mode_norm_init();
+ }
}
-/* 800BF0D4-800BF110 .text __dt__Q25dWood6Unit_cFv */
-dWood::Unit_c::~Unit_c() {
- /* Nonmatching */
-}
-
-/* 800BF110-800BF194 .text __dt__Q25dWood8Packet_cFv */
-dWood::Packet_c::~Packet_c() {
- /* Nonmatching */
-}
+dWood::Packet_c::~Packet_c() {};
/* 800BF194-800BF1C8 .text delete_room__Q25dWood8Packet_cFi */
-void dWood::Packet_c::delete_room(int) {
- /* Nonmatching */
+void dWood::Packet_c::delete_room(int room_no) {
+ mRoom[room_no].delete_all_unit();
}
/* 800BF1C8-800BF2D4 .text put_unit__Q25dWood8Packet_cFRC4cXyzi */
-void dWood::Packet_c::put_unit(const cXyz&, int) {
- /* Nonmatching */
+s32 dWood::Packet_c::put_unit(const cXyz &pos, int room_no) {
+ JUT_ASSERT(0x6e0, (room_no >= 0) && (room_no < L_Room_Max));
+
+ const s32 unitCount = ARRAY_SIZE(mUnit);
+ s32 unitIdx = search_empty_UnitID();
+ if (unitIdx != unitCount) {
+ Unit_c *unit = &mUnit[unitIdx];
+ cLib_setBit(unit->mFlags, Unit_c::STATE_ACTIVE);
+ unit->mPos.x = pos.x;
+ unit->mPos.y = pos.y;
+ unit->mPos.z = pos.z;
+ unit->mAnmIdx = search_anm(Anm_c::Mode_Norm);
+ s8 valid = unit->set_ground();
+ if (valid & 0xff) {
+ mRoom[room_no].entry_unit(unit);
+ } else {
+ unit->clear();
+ }
+ }
+ return unitIdx;
}
/* 800BF2D4-800BF404 .text calc_cc__Q25dWood8Packet_cFv */
+// Collision Calculations
void dWood::Packet_c::calc_cc() {
- /* Nonmatching */
+ int roomIdx = dComIfGp_roomControl_getStayNo();
+
+ if ((roomIdx >= 0) && (roomIdx < (s32)ARRAY_SIZE(mRoom))) {
+ dComIfG_Ccsp()->SetMassAttr(L_attr.kCollisionRad,
+ L_attr.kCollisionHeight, (u8)0x13, 1);
+
+ Room_c *room = &mRoom[roomIdx];
+ for (Unit_c *unit = room->mpUnit; unit != NULL; unit = unit->mpNext) {
+ if (!cLib_checkBit(unit->mFlags, Unit_c::STATE_CUT)) {
+ unit->cc_hit_before_cut(this);
+ }
+ }
+
+ dComIfG_Ccsp()->SetMassAttr(L_attr.kCollisionRadCut,
+ L_attr.kCollisionHeightCut, (u8)0x12, 1);
+ for (Unit_c *unit = room->mpUnit; unit != NULL; unit = unit->mpNext) {
+ if (cLib_checkBit(unit->mFlags, Unit_c::STATE_CUT)) {
+ unit->cc_hit_after_cut(this);
+ }
+ }
+ }
}
/* 800BF404-800BF4EC .text calc__Q25dWood8Packet_cFv */
void dWood::Packet_c::calc() {
- /* Nonmatching */
+ calc_cc();
+
+ cXyz *windDir = dKyw_get_wind_vec();
+ float windVel = dKyw_get_wind_pow();
+ s16 windAngle = cM_atan2s(windDir->x, windDir->z);
+
+ for (s32 i = 0; i < (s32)8; i++) {
+ mAnm[i].mode_norm_set_wind(windVel, (s32)windAngle);
+ }
+
+ for (s32 i = 0; i < (s32)ARRAY_SIZE(mAnm); i++) {
+ mAnm[i].play(this);
+ }
+
+ for (s32 i = 0; i < (s32)ARRAY_SIZE(mUnit); i++) {
+ mUnit[i].proc(this);
+ }
}
/* 800BF4EC-800BF614 .text update__Q25dWood8Packet_cFv */
void dWood::Packet_c::update() {
- /* Nonmatching */
+ s32 i = 0;
+ for (Unit_c *unit = mUnit; i < (s32)ARRAY_SIZE(mUnit); i++, unit++) {
+ if (cLib_checkBit(unit->mFlags, Unit_c::STATE_ACTIVE)) {
+ cXyz clipPos(unit->mPos.x, unit->mPos.y + L_attr.kClipCenterYOffset,
+ unit->mPos.z);
+ s32 res = mDoLib_clipper::clip(j3dSys.getViewMtx(), clipPos,
+ L_attr.kClipRadius);
+
+ if (res != 0) {
+ cLib_onBit(unit->mFlags, Unit_c::STATE_FRUSTUM_CULLED);
+ } else {
+ cLib_offBit(unit->mFlags, Unit_c::STATE_FRUSTUM_CULLED);
+ unit->set_mtx(mAnm);
+ }
+ }
+ }
+
+ dComIfGd_setXluListBG();
+ j3dSys.getDrawBuffer(0)->entryImm(this, 0);
+ dComIfGd_setXluList();
}
/* 800BF614-800BF900 .text draw__Q25dWood8Packet_cFv */
void dWood::Packet_c::draw() {
- /* Nonmatching */
+ u8 bVar1;
+ int iVar2;
+ int iVar3;
+ uint uVar4;
+ int iVar6;
+ int iVar7;
+ GXColor local_48;
+ GXColor local_44;
+ GXColor local_40;
+ GXColor local_38;
+ GXColorS10 local_30;
+
+ static GXVtxDescList l_shadowVtxDescList[] = {
+ {GX_VA_POS, GX_INDEX8},
+ {GX_VA_TEX0, GX_INDEX8},
+ {GX_VA_NULL, GX_NONE},
+ };
+ static GXVtxAttrFmtList l_shadowVtxAttrFmtList[] = {
+ {GX_VA_POS, GX_CLR_RGBA, GX_RGB8},
+ {GX_VA_TEX0, GX_CLR_RGBA, GX_RGB8},
+ {GX_VA_NULL, GX_CLR_RGBA, GX_RGB8},
+ };
+ static GXVtxDescList l_vtxDescList[] = {
+ {GX_VA_POS, GX_INDEX8},
+ {GX_VA_CLR0, GX_INDEX8},
+ {GX_VA_TEX0, GX_INDEX8},
+ {GX_VA_NULL, GX_NONE},
+ };
+ static GXVtxAttrFmtList l_vtxAttrFmtList[] = {
+ {GX_VA_POS, GX_CLR_RGBA, GX_F32},
+ {GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8},
+ {GX_VA_TEX0, GX_CLR_RGBA, GX_F32},
+ {GX_VA_NULL, GX_CLR_RGBA, GX_RGB8},
+ };
+ static GXColor l_shadowColor = {0x00, 0x00, 0x00, 0x64};
+
+ // Assign the shadow material and draw state
+ GFSetVtxDescv(l_shadowVtxDescList);
+ GFSetVtxAttrFmtv(GX_VTXFMT0, l_shadowVtxAttrFmtList);
+ GFSetArray(GX_VA_POS, g_dTree_shadowPos, 3);
+ GFSetArray(GX_VA_TEX0, g_dTree_shadowTexCoord, 2);
+ dKy_GxFog_set();
+ GXCallDisplayList(g_dTree_shadowMatDL, g_dTree_shadowMatDL_SIZE & ~0b11111);
+ GFSetTevColor(GX_TEVREG0, l_shadowColor);
+
+ // Draw the drop shadows for each active unit
+ Room_c* room;
+ int i;
+
+ for (i = 0, room = mRoom; i < (s32)ARRAY_SIZE(mRoom); room++, i++) {
+ for (Unit_c *data = room->mpUnit; data != NULL; data = data->mpNext) {
+ if (!cLib_checkBit(data->mFlags, Unit_c::STATE_FRUSTUM_CULLED)) {
+ GFLoadPosMtxImm(data->mShadowModelViewMtx, 0);
+ GXCallDisplayList(g_dTree_Oba_kage_32DL, g_dTree_Oba_kage_32DL_SIZE & ~0b11111); // This is probably an inline
+ }
+ }
+ }
+
+ // Assign the body and trunk material and draw state
+ GXColor alphaColor = {0xff, 0xff, 0xff, 0xff};
+ GFSetVtxDescv(l_vtxDescList);
+ GFSetVtxAttrFmtv(GX_VTXFMT0, l_vtxAttrFmtList);
+ GFSetArray(GX_VA_POS, l_pos, 0xc);
+ GFSetArray(GX_VA_CLR0, l_color, 4);
+ GFSetArray(GX_VA_TEX0, l_texCoord, 8);
+ GXCallDisplayList(l_matDL, 0xa0);
+ GFSetAlphaCompare(GX_GREATER, L_attr.L_Alpha_Cutoff, GX_AOP_OR, GX_GREATER,
+ L_attr.L_Alpha_Cutoff);
+ GFSetTevColor(GX_TEVREG2, alphaColor);
+
+ // Draw the trunk and body for each active unit
+ for (i = 0, room = mRoom; i < (s32)ARRAY_SIZE(mRoom); i++, room++) {
+ dKy_tevstr_c *tevStr = dComIfGp_roomControl_getTevStr(i);
+ GFSetTevColorS10(GX_TEVREG0, tevStr->mColorC0);
+ GFSetTevColor(GX_TEVREG1, tevStr->mColorK0);
+
+ dKy_GfFog_tevstr_set(tevStr);
+
+ for (Unit_c *data = room->mpUnit; data != NULL; data = data->mpNext) {
+ if (!cLib_checkBit(data->mFlags, Unit_c::STATE_FRUSTUM_CULLED)) {
+ if (!cLib_checkBit(data->mFlags, Unit_c::STATE_CUT)) {
+ u32 alphaScale = mAnm[data->mAnmIdx].mAlphaScale;
+ alphaColor.a = alphaScale;
+ bool fading = alphaColor.a != 0xff;
+
+ if (fading) {
+ GFSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER,
+ 0); // Disable Alpha Test
+ }
+ GFSetTevColor(GX_TEVREG2, alphaColor);
+ GFLoadPosMtxImm(data->mModelViewMtx, 0);
+ GXCallDisplayList(l_Oba_swood_bDL, l_Oba_swood_bDL_SIZE);
+
+ if (fading) {
+ GFSetAlphaCompare(
+ GX_GREATER, L_attr.L_Alpha_Cutoff, GX_AOP_OR,
+ GX_GREATER,
+ L_attr.L_Alpha_Cutoff); // Alpha Test < 50%
+ }
+ alphaColor.a = 0xff;
+ GFSetTevColor(GX_TEVREG2, alphaColor);
+ }
+ GFLoadPosMtxImm(data->mTrunkModelViewMtx, 0);
+ GXCallDisplayList(l_Oba_swood_b_cutDL, l_Oba_swood_b_cutDL_SIZE);
+ }
+ }
+ }
+ J3DShape::sOldVcdVatCmd = 0;
}
/* 800BF900-800BF938 .text search_empty_UnitID__Q25dWood8Packet_cCFv */
-void dWood::Packet_c::search_empty_UnitID() const {
- /* Nonmatching */
+s32 dWood::Packet_c::search_empty_UnitID() const {
+ const Unit_c *unit;
+ int idx = 0;
+ unit = mUnit;
+
+ for (s32 i = 0; i < ARRAY_SIZE(mUnit); i++) {
+ if ((s32)unit->mFlags == 0) {
+ return idx;
+ }
+ idx += 1;
+ unit = unit + 1;
+ }
+
+ return ARRAY_SIZE(mUnit);
}
/* 800BF938-800BFA70 .text search_anm__Q25dWood8Packet_cFQ35dWood5Anm_c6Mode_e */
-void dWood::Packet_c::search_anm(dWood::Anm_c::Mode_e) {
- /* Nonmatching */
+dWood::AnmID_e dWood::Packet_c::search_anm(dWood::Anm_c::Mode_e i_mode) {
+ u32 animIdx;
+
+ JUT_ASSERT(0x80d, (i_mode >= 0) && (i_mode < Anm_c::Mode_Max));
+
+ if (i_mode == Anm_c::Mode_Norm) {
+ static s32 anm_norm_num = 0;
+ animIdx = anm_norm_num++;
+ anm_norm_num = anm_norm_num % 8;
+ } else {
+ // Return the first anim slot which has an unset mode
+ animIdx = 8;
+ for (s32 i = 0; i < 64; i++) {
+ if (mAnm[animIdx].mMode == Anm_c::Mode_Max) {
+ return (AnmID_e)animIdx;
+ }
+ animIdx++;
+ }
+
+ // If none are available, return the first one which has a higher mode
+ animIdx = 8;
+ for (s32 i = 0; i < 64; i++) {
+ if (i_mode < mAnm[animIdx].mMode) {
+ return (AnmID_e)animIdx;
+ }
+ animIdx++;
+ }
+
+ // If no available anim slot is found, return -1
+ animIdx = AnmID_Norm_Invalid;
+ }
+
+ return (AnmID_e)animIdx;
}