diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index e761d496..e061d7a6 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -1219,8 +1219,8 @@ fn_80032130 = .text:0x80032130; // type:function size:0x48 fn_80032180 = .text:0x80032180; // type:function size:0x2C fn_800321B0 = .text:0x800321B0; // type:function size:0x1CC fn_80032380 = .text:0x80032380; // type:function size:0xC0 -fn_80032440 = .text:0x80032440; // type:function size:0xC -fn_80032450 = .text:0x80032450; // type:function size:0xC +baseID_Wait<10sStateID_c>__Fv_RC10sStateID_c = .text:0x80032440; // type:function size:0xC +baseID_Demo<10sStateID_c>__Fv_RC10sStateID_c = .text:0x80032450; // type:function size:0xC fn_80032460 = .text:0x80032460; // type:function size:0x4 fn_80032470 = .text:0x80032470; // type:function size:0x4 fn_80032480 = .text:0x80032480; // type:function size:0x390 @@ -1636,12 +1636,12 @@ ActorState__callEnter = .text:0x8003EFF0; // type:function size:0x30 fn_8003F020 = .text:0x8003F020; // type:function size:0x40 fn_8003F060 = .text:0x8003F060; // type:function size:0x40 fn_8003F0A0 = .text:0x8003F0A0; // type:function size:0x40 -AcNpc__initStates = .text:0x8003F0E0; // type:function size:0x330 -fn_8003F410 = .text:0x8003F410; // type:function size:0x58 -AcNpc__state_dtor = .text:0x8003F470; // type:function size:0x5C -fn_8003F4D0 = .text:0x8003F4D0; // type:function size:0xDC -fn_8003F5B0 = .text:0x8003F5B0; // type:function size:0xE0 -fn_8003F690 = .text:0x8003F690; // type:function size:0x88 +__sinit_\d_a_npc_cpp = .text:0x8003F0E0; // type:function size:0x330 +__dt__22sFStateID_c<8dAcNpc_c>Fv = .text:0x8003F410; // type:function size:0x58 +__dt__29sFStateVirtualID_c<8dAcNpc_c>Fv = .text:0x8003F470; // type:function size:0x5C +number__29sFStateVirtualID_c<8dAcNpc_c>CFv = .text:0x8003F4D0; // type:function size:0xDC +superID__29sFStateVirtualID_c<8dAcNpc_c>CFv = .text:0x8003F5B0; // type:function size:0xE0 +isSameName__22sFStateID_c<8dAcNpc_c>CFPCc = .text:0x8003F690; // type:function size:0x88 fn_8003F720 = .text:0x8003F720; // type:function size:0x404 fn_8003FB30 = .text:0x8003FB30; // type:function size:0xA0 fn_8003FBD0 = .text:0x8003FBD0; // type:function size:0x4 @@ -1820,13 +1820,13 @@ fn_80045D00 = .text:0x80045D00; // type:function size:0x490 fn_80046190 = .text:0x80046190; // type:function size:0x44 fn_800461E0 = .text:0x800461E0; // type:function size:0xAC fn_80046290 = .text:0x80046290; // type:function size:0x40 -fn_800462D0 = .text:0x800462D0; // type:function size:0xC -fn_800462E0 = .text:0x800462E0; // type:function size:0xC -fn_800462F0 = .text:0x800462F0; // type:function size:0xC -fn_80046300 = .text:0x80046300; // type:function size:0xC -fn_80046310 = .text:0x80046310; // type:function size:0xC -fn_80046320 = .text:0x80046320; // type:function size:0xC -fn_80046330 = .text:0x80046330; // type:function size:0xC +baseID_Pain<10sStateID_c>__Fv_RC10sStateID_c = .text:0x800462D0; // type:function size:0xC +baseID_Surprised<10sStateID_c>__Fv_RC10sStateID_c = .text:0x800462E0; // type:function size:0xC +baseID_Withstand<10sStateID_c>__Fv_RC10sStateID_c = .text:0x800462F0; // type:function size:0xC +baseID_Walk<10sStateID_c>__Fv_RC10sStateID_c = .text:0x80046300; // type:function size:0xC +baseID_LookAwaySt<10sStateID_c>__Fv_RC10sStateID_c = .text:0x80046310; // type:function size:0xC +baseID_LookAway<10sStateID_c>__Fv_RC10sStateID_c = .text:0x80046320; // type:function size:0xC +baseID_Turn<10sStateID_c>__Fv_RC10sStateID_c = .text:0x80046330; // type:function size:0xC AcOrdinaryNpc__PreInit = .text:0x80046340; // type:function size:0x10C fn_80046450 = .text:0x80046450; // type:function size:0x9C fn_800464F0 = .text:0x800464F0; // type:function size:0x13C @@ -1985,16 +1985,16 @@ fn_8004CC60 = .text:0x8004CC60; // type:function size:0x4 fn_8004CC70 = .text:0x8004CC70; // type:function size:0x8 fn_8004CC80 = .text:0x8004CC80; // type:function size:0x8 fn_8004CC90 = .text:0x8004CC90; // type:function size:0x40 -AcOrdinaryNpc__initStates = .text:0x8004CCD0; // type:function size:0x784 -fn_8004D460 = .text:0x8004D460; // type:function size:0x58 -AcOrdinaryNpc__dtor = .text:0x8004D4C0; // type:function size:0x5C -fn_8004D520 = .text:0x8004D520; // type:function size:0xC -fn_8004D530 = .text:0x8004D530; // type:function size:0xDC -fn_8004D610 = .text:0x8004D610; // type:function size:0xE0 -fn_8004D6F0 = .text:0x8004D6F0; // type:function size:0x88 -fn_8004D780 = .text:0x8004D780; // type:function size:0x30 -fn_8004D7B0 = .text:0x8004D7B0; // type:function size:0x30 -fn_8004D7E0 = .text:0x8004D7E0; // type:function size:0x30 +__sinit_\d_a_ordinary_npc_cpp = .text:0x8004CCD0; // type:function size:0x784 +__dt__31sFStateID_c<16dAcOrdinaryNpc_c>Fv = .text:0x8004D460; // type:function size:0x58 +__dt__38sFStateVirtualID_c<16dAcOrdinaryNpc_c>Fv = .text:0x8004D4C0; // type:function size:0x5C +baseID_Wait<8dAcNpc_c>__Fv_RC10sStateID_c = .text:0x8004D520; // type:function size:0xC +number__38sFStateVirtualID_c<16dAcOrdinaryNpc_c>CFv = .text:0x8004D530; // type:function size:0xDC +superID__38sFStateVirtualID_c<16dAcOrdinaryNpc_c>CFv = .text:0x8004D610; // type:function size:0xE0 +isSameName__31sFStateID_c<16dAcOrdinaryNpc_c>CFPCc = .text:0x8004D6F0; // type:function size:0x88 +initializeState__31sFStateID_c<16dAcOrdinaryNpc_c>CFR16dAcOrdinaryNpc_c = .text:0x8004D780; // type:function size:0x30 +executeState__31sFStateID_c<16dAcOrdinaryNpc_c>CFR16dAcOrdinaryNpc_c = .text:0x8004D7B0; // type:function size:0x30 +finalizeState__31sFStateID_c<16dAcOrdinaryNpc_c>CFR16dAcOrdinaryNpc_c = .text:0x8004D7E0; // type:function size:0x30 fn_8004D810 = .text:0x8004D810; // type:function size:0x14 fn_8004D830 = .text:0x8004D830; // type:function size:0x14 fn_8004D850 = .text:0x8004D850; // type:function size:0x14 @@ -29940,11 +29940,11 @@ lbl_80501998 = .data:0x80501998; // type:object size:0xC lbl_805019A4 = .data:0x805019A4; // type:object size:0xC lbl_805019B0 = .data:0x805019B0; // type:object size:0x54 lbl_80501A04 = .data:0x80501A04; // type:object size:0xC -ActorNpcBase__vtable = .data:0x80501A10; // type:object size:0x208 -lbl_80501C18 = .data:0x80501C18; // type:object size:0x30 -lbl_80501C48 = .data:0x80501C48; // type:object size:0x30 -lbl_80501C78 = .data:0x80501C78; // type:object size:0x18 -lbl_80501C90 = .data:0x80501C90; // type:object size:0x18 +__vt__8dAcNpc_c = .data:0x80501A10; // type:object size:0x208 +__vt__46sFStateMgr_c<8dAcNpc_c,20sStateMethodUsr_FI_c> = .data:0x80501C18; // type:object size:0x30 +__vt__76sStateMgr_c<8dAcNpc_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x80501C48; // type:object size:0x30 +__vt__23sFStateFct_c<8dAcNpc_c> = .data:0x80501C78; // type:object size:0x18 +__vt__23sFStateFct_c<8dAcNpc_c> = .data:0x80501C90; // type:object size:0x18 ActorNpcEventFlowManager__vtable = .data:0x80501CA8; // type:object size:0x44 lbl_80501CEC = .data:0x80501CEC; // type:object size:0xC lbl_80501CF8 = .data:0x80501CF8; // type:object size:0x10 @@ -30020,8 +30020,8 @@ AcOrdinaryNpc__vtable = .data:0x80502538; // type:object size:0x360 lbl_80502898 = .data:0x80502898; // type:object size:0x6C lbl_80502904 = .data:0x80502904; // type:object size:0xC lbl_80502910 = .data:0x80502910; // type:object size:0x28C -lbl_80502B9C = .data:0x80502B9C; // type:object size:0x34 -lbl_80502BD0 = .data:0x80502BD0; // type:object size:0x38 +__vt__38sFStateVirtualID_c<16dAcOrdinaryNpc_c> = .data:0x80502B9C; // type:object size:0x34 +__vt__31sFStateID_c<16dAcOrdinaryNpc_c> = .data:0x80502BD0; // type:object size:0x38 lbl_80502C08 = .data:0x80502C08; // type:object size:0xC lbl_80502C14 = .data:0x80502C14; // type:object size:0x10 lbl_80502C24 = .data:0x80502C24; // type:object size:0x10 diff --git a/include/d/a/npc/d_a_npc.h b/include/d/a/npc/d_a_npc.h index ad95da03..86e05ddc 100644 --- a/include/d/a/npc/d_a_npc.h +++ b/include/d/a/npc/d_a_npc.h @@ -2,61 +2,7 @@ #define D_A_NPC_H #include "d/a/obj/d_a_obj_base.h" -#include "s/s_FStateID.hpp" -#include "s/s_FStateMgr.hpp" -#include "s/s_StateID.hpp" -#include "s/s_StateMethodUsr_FI.hpp" - -// Virtual states! -template -class sVFStateID_c : public sFStateID_c { -public: - typedef void (T::*stateFunc)(); - sVFStateID_c(sStateID_c *superState, const char *name, stateFunc initialize, stateFunc execute, stateFunc finalize) - : sFStateID_c(name, initialize, execute, finalize), mpSuperState(superState) {} - - virtual unsigned int number() const { - return getRootState()->numberBase(); - } - - const sVFStateID_c *getRootState() const { - if (!mpSuperState->isNull()) { - return static_cast *>(mpSuperState)->getRootState(); - } - return this; - } - - unsigned int numberBase() const { - return sStateID_c::number(); - } - - -private: - sStateID_c *mpSuperState; -}; - -#define STATE_VIRTUAL_FUNC_DECLARE(class, name) \ - virtual void initializeState_##name(); \ - virtual void executeState_##name(); \ - virtual void finalizeState_##name(); \ - static sVFStateID_c StateID_##name - -#define STATE_VIRTUAL_OVERRIDE_FUNC_DECLARE(class, super_class, name) \ - virtual void initializeState_##name() override; \ - virtual void executeState_##name() override; \ - virtual void finalizeState_##name() override; \ - static sVFStateID_c StateID_##name; \ - -#define STATE_VIRTUAL_DEFINE(class, name) \ - sStateID_c *getDefaultSuperState_##class##name() { \ - return &sStateID::null; \ - } \ - sVFStateID_c class ::StateID_##name( \ - getDefaultSuperState_##class##name(), #class "::StateID_" #name, &class ::initializeState_##name, \ - &class ::executeState_##name, &class ::finalizeState_##name \ - ) - -#define STATE_VIRTUAL_MGR_DECLARE(class_name) sFStateMgr_c mStateMgr; +#include "s/s_State.hpp" // This is the NPC base. Most npcs actually use dAcOrdinaryNpc, but this just is a simpler one? @@ -70,7 +16,7 @@ class dAcNpc_c : public dAcObjBase_c { STATE_VIRTUAL_FUNC_DECLARE(dAcNpc_c, Wait); STATE_VIRTUAL_FUNC_DECLARE(dAcNpc_c, Demo); - STATE_VIRTUAL_MGR_DECLARE(dAcNpc_c); + STATE_MGR_DECLARE(dAcNpc_c); }; #endif diff --git a/include/d/a/npc/d_a_ordinary_npc.h b/include/d/a/npc/d_a_ordinary_npc.h index c826f478..73885421 100644 --- a/include/d/a/npc/d_a_ordinary_npc.h +++ b/include/d/a/npc/d_a_ordinary_npc.h @@ -2,10 +2,19 @@ #define D_A_ORDINARY_NPC_H #include "d/a/npc/d_a_npc.h" +#include "s/s_State.hpp" class dAcOrdinaryNpc_c : public dAcNpc_c { public: + STATE_VIRTUAL_OVERRIDE_FUNC_DECLARE(dAcOrdinaryNpc_c, dAcNpc_c, Wait); STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Pain); + STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Surprised); + STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Withstand); + STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Walk); + STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, LookAwaySt); + STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, LookAway); + STATE_VIRTUAL_FUNC_DECLARE(dAcOrdinaryNpc_c, Turn); + STATE_FUNC_DECLARE(dAcOrdinaryNpc_c, PreWalkTurn); }; #endif diff --git a/include/s/README.txt b/include/s/README.txt index 53c6cb63..22881597 100644 --- a/include/s/README.txt +++ b/include/s/README.txt @@ -22,3 +22,7 @@ the other abstract interface classes and provides this dtor. We're observing a lot of word-to-bool casts in code after these operators are invoked, and while there are ways to force the conversion, this seems the most reasonable. + +## s_FStateVirtualID + +Implemented by SS based on NSMBW symbols. Probably missing some parts, sync with NSMBW if they get around to it. diff --git a/include/s/s_FStateVirtualID.hpp b/include/s/s_FStateVirtualID.hpp new file mode 100644 index 00000000..e48600a2 --- /dev/null +++ b/include/s/s_FStateVirtualID.hpp @@ -0,0 +1,35 @@ +#ifndef S_FSTATE_VIRTUAL_ID_H +#define S_FSTATE_VIRTUAL_ID_H + +#include "s/s_FStateID.hpp" +#include "s/s_StateID.hpp" + +template +class sFStateVirtualID_c : public sFStateID_c { +public: + typedef void (T::*stateFunc)(); + sFStateVirtualID_c( + const sStateID_c *superState, const char *name, stateFunc initialize, stateFunc execute, stateFunc finalize + ) + : sFStateID_c(name, initialize, execute, finalize), mpSuperState(superState) {} + + virtual unsigned int number() const { + return superID()->numberBase(); + } + + const sFStateVirtualID_c *superID() const { + if (!mpSuperState->isNull()) { + return static_cast *>(mpSuperState)->superID(); + } + return this; + } + + unsigned int numberBase() const { + return sStateID_c::number(); + } + +private: + const sStateID_c *mpSuperState; +}; + +#endif diff --git a/include/s/s_State.hpp b/include/s/s_State.hpp index 76339e3a..3a8c4ec5 100644 --- a/include/s/s_State.hpp +++ b/include/s/s_State.hpp @@ -3,6 +3,7 @@ #include "s/s_FStateMgr.hpp" #include "s/s_StateMethodUsr_FI.hpp" +#include "s/s_FStateVirtualID.hpp" // Note: Ported from https://github.com/NSMBW-Community/NSMBW-Decomp/tree/master/include/dol/sLib // See include/s/README.txt for changes made @@ -29,4 +30,37 @@ #define STATE_MGR(class_name) sFStateMgr_c +// TODO this is probably not the whole solution. +// The problems with this approach are: +// * You can't define the same state name for multiple files in the same TU due to baseID_ symbol clash. +// * The use of the templated baseID_ function isn't quite justified (could just use normal functions). + +#define STATE_VIRTUAL_FUNC_DECLARE(class, name) \ + virtual void initializeState_##name(); \ + virtual void executeState_##name(); \ + virtual void finalizeState_##name(); \ + static const sFStateVirtualID_c StateID_##name; \ + typedef sStateID_c StateID_##name##_BaseIDClass + +#define STATE_VIRTUAL_OVERRIDE_FUNC_DECLARE(class, super_class, name) \ + virtual void initializeState_##name() override; \ + virtual void executeState_##name() override; \ + virtual void finalizeState_##name() override; \ + static const sFStateVirtualID_c StateID_##name; \ + typedef super_class StateID_##name##_BaseIDClass + +#define STATE_VIRTUAL_DEFINE(class, name) \ + template \ + static const sStateID_c &baseID_##name() { \ + return T::StateID_##name; \ + } \ + template <> \ + const sStateID_c &baseID_##name() { \ + return sStateID::null; \ + } \ + const sFStateVirtualID_c class ::StateID_##name( \ + &baseID_##name(), #class "::StateID_" #name, \ + &class ::initializeState_##name, &class ::executeState_##name, &class ::finalizeState_##name \ + ) + #endif diff --git a/include/s/s_StateID.hpp b/include/s/s_StateID.hpp index cff3ed9f..d385f354 100644 --- a/include/s/s_StateID.hpp +++ b/include/s/s_StateID.hpp @@ -44,7 +44,7 @@ class sStateID_c : public sStateIDIf_c { namespace sStateID { /// @ingroup state -extern sStateID_c null; ///< A null state instance. +extern const sStateID_c null; ///< A null state instance. } // namespace sStateID #endif diff --git a/src/d/a/npc/d_a_ordinary_npc.cpp b/src/d/a/npc/d_a_ordinary_npc.cpp index 767a9c7e..6e6bb2fd 100644 --- a/src/d/a/npc/d_a_ordinary_npc.cpp +++ b/src/d/a/npc/d_a_ordinary_npc.cpp @@ -2,4 +2,12 @@ #include "d/a/npc/d_a_npc.h" #include "s/s_StateID.hpp" +STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, Wait); STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, Pain); +STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, Surprised); +STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, Withstand); +STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, Walk); +STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, LookAwaySt); +STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, LookAway); +STATE_VIRTUAL_DEFINE(dAcOrdinaryNpc_c, Turn); +STATE_DEFINE(dAcOrdinaryNpc_c, PreWalkTurn); diff --git a/src/s/s_StateID.cpp b/src/s/s_StateID.cpp index be1e8988..bc2bdcaf 100644 --- a/src/s/s_StateID.cpp +++ b/src/s/s_StateID.cpp @@ -11,7 +11,7 @@ // See include/s/README.txt for changes made sStateID_c::NumberMemo_c sStateID_c::sm_numberMemo; -sStateID_c sStateID::null(nullptr); +const sStateID_c sStateID::null(nullptr); sStateID_c::sStateID_c(const char *name) { mpName = name;