diff --git a/config/SOUE01/rels/d_t_timerNP/splits.txt b/config/SOUE01/rels/d_t_timerNP/splits.txt index 94400ef5..1601c0cd 100644 --- a/config/SOUE01/rels/d_t_timerNP/splits.txt +++ b/config/SOUE01/rels/d_t_timerNP/splits.txt @@ -2,7 +2,7 @@ Sections: .text type:code align:16 .ctors type:rodata align:4 .dtors type:rodata align:4 - .rodata type:rodata align:8 + .data type:data align:8 .bss type:bss align:8 REL/executor.c: @@ -10,3 +10,4 @@ REL/executor.c: REL/d/t/d_t_timer.cpp: .text start:0x00000070 end:0x000004CC + .data start:0x00000000 end:0x0000011C diff --git a/config/SOUE01/rels/d_t_timerNP/symbols.txt b/config/SOUE01/rels/d_t_timerNP/symbols.txt index 3a383e26..a6825912 100644 --- a/config/SOUE01/rels/d_t_timerNP/symbols.txt +++ b/config/SOUE01/rels/d_t_timerNP/symbols.txt @@ -1,26 +1,27 @@ _prolog = .text:0x00000000; // type:function size:0x2C scope:global _epilog = .text:0x00000030; // type:function size:0x2C scope:global _unresolved = .text:0x00000060; // type:function size:0x4 scope:global -fn_506_70 = .text:0x00000070; // type:function size:0x4C -fn_506_C0 = .text:0x000000C0; // type:function size:0x58 -fn_506_120 = .text:0x00000120; // type:function size:0x24 -fn_506_150 = .text:0x00000150; // type:function size:0xD4 -fn_506_230 = .text:0x00000230; // type:function size:0xB8 -fn_506_2F0 = .text:0x000002F0; // type:function size:0xC -fn_506_300 = .text:0x00000300; // type:function size:0xC -fn_506_310 = .text:0x00000310; // type:function size:0xC -fn_506_320 = .text:0x00000320; // type:function size:0xC -fn_506_330 = .text:0x00000330; // type:function size:0x8 -fn_506_340 = .text:0x00000340; // type:function size:0x8 -fn_506_350 = .text:0x00000350; // type:function size:0x8 -fn_506_360 = .text:0x00000360; // type:function size:0x28 -fn_506_390 = .text:0x00000390; // type:function size:0x8 -fn_506_3A0 = .text:0x000003A0; // type:function size:0x44 -fn_506_3F0 = .text:0x000003F0; // type:function size:0x58 -fn_506_450 = .text:0x00000450; // type:function size:0x8 -fn_506_460 = .text:0x00000460; // type:function size:0x4 -fn_506_470 = .text:0x00000470; // type:function size:0x5C +dTgTimer_c_classInit__Fv = .text:0x00000070; // type:function size:0x4C +__dt__14dTgTimerBase_cFv = .text:0x000000C0; // type:function size:0x58 +increment__FPUs = .text:0x00000120; // type:function size:0x24 +create__10dTgTimer_cFv = .text:0x00000150; // type:function size:0xD4 +actorExecute__10dTgTimer_cFv = .text:0x00000230; // type:function size:0xB8 +getSubtypeFromParams__10dTgTimer_cFv = .text:0x000002F0; // type:function size:0xC +getTimerFromParams__10dTgTimer_cFv = .text:0x00000300; // type:function size:0xC +getCheckSceneflag__10dTgTimer_cFv = .text:0x00000310; // type:function size:0xC +getSetSceneflag__10dTgTimer_cFv = .text:0x00000320; // type:function size:0xC +getTimer__10dTgTimer_cFv = .text:0x00000330; // type:function size:0x8 +getConstant0x50__10dTgTimer_cFv = .text:0x00000340; // type:function size:0x8 +setTimer__10dTgTimer_cFUs = .text:0x00000350; // type:function size:0x8 +getTargetTime__10dTgTimer_cFv = .text:0x00000360; // type:function size:0x28 +resetTimer__10dTgTimer_cFv = .text:0x00000390; // type:function size:0x8 +incrementTimer__10dTgTimer_cFv = .text:0x000003A0; // type:function size:0x44 +checkShouldTrigger__10dTgTimer_cFv = .text:0x000003F0; // type:function size:0x58 +getStoredTargetTime__10dTgTimer_cFv = .text:0x00000450; // type:function size:0x8 +getConstant0x50_Thunk__10dTgTimer_cFv = .text:0x00000460; // type:function size:0x4 +__dt__10dTgTimer_cFv = .text:0x00000470; // type:function size:0x5C _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global -lbl_506_section4_0 = .rodata:0x00000000; // type:object size:0x34 data:4byte -lbl_506_section4_34 = .rodata:0x00000034; // type:object size:0xE8 +g_profile_TIMER_TAG = .data:0x00000000; // type:object size:0x10 data:4byte +__vt__10dTgTimer_c = .data:0x00000034; // type:object size:0x74 +__vt__14dTgTimerBase_c = .data:0x000000A8; // type:object size:0x74 diff --git a/configure.py b/configure.py index b7a74ac9..257cbaed 100644 --- a/configure.py +++ b/configure.py @@ -1081,7 +1081,7 @@ config.libs = [ Rel(NonMatching, "d_t_sw_area", "REL/d/t/d_t_sw_area.cpp"), Rel(Matching, "d_t_tackle", "REL/d/t/d_t_tackle.cpp"), Rel(NonMatching, "d_t_telop", "REL/d/t/d_t_telop.cpp"), - Rel(NonMatching, "d_t_timer", "REL/d/t/d_t_timer.cpp"), + Rel(Matching, "d_t_timer", "REL/d/t/d_t_timer.cpp"), Rel(NonMatching, "d_t_time_area_check", "REL/d/t/d_t_time_area_check.cpp"), Rel(NonMatching, "d_t_time_door_beam", "REL/d/t/d_t_time_door_beam.cpp"), Rel(NonMatching, "d_t_touch", "REL/d/t/d_t_touch.cpp"), diff --git a/include/d/tg/d_t_timer.h b/include/d/tg/d_t_timer.h new file mode 100644 index 00000000..463bf0b3 --- /dev/null +++ b/include/d/tg/d_t_timer.h @@ -0,0 +1,41 @@ +#ifndef D_T_TIMER_H +#define D_T_TIMER_H + +#include + +class dTgTimerBase_c : public dAcBase_c { +public: + virtual ~dTgTimerBase_c() {} +}; + + +class dTgTimer_c : public dTgTimerBase_c { +public: + dTgTimer_c() {} + virtual ~dTgTimer_c() {} + + virtual int create() override; + virtual int actorExecute() override; + + int getSubtypeFromParams(); + u16 getTimerFromParams(); + + u16 getCheckSceneflag(); + u16 getSetSceneflag(); + u16 getTimer(); + u16 setTimer(u16 val); + u16 getTargetTime(); + bool checkShouldTrigger(); + u16 getStoredTargetTime(); + + u16 getConstant0x50(); + void incrementTimer(); + void resetTimer(); + u16 getConstant0x50_Thunk(); + + u16 (dTgTimer_c::*mGetTargetTimeFunc)(); + u16 mTimer; + u16 mTargetTime; +}; + +#endif diff --git a/include/toBeSorted/sceneflag_manager.h b/include/toBeSorted/sceneflag_manager.h new file mode 100644 index 00000000..bb2106e6 --- /dev/null +++ b/include/toBeSorted/sceneflag_manager.h @@ -0,0 +1,63 @@ +#ifndef SCENEFLAG_MANAGER_H +#define SCENEFLAG_MANAGER_H + +#include +#include +#include + +class SceneflagManager { +public: + FlagSpace mSceneflags; + FlagSpace mTempflags; + FlagSpace mZoneflags; + BitwiseFlagHelper mFlagHelper; + u16 mSceneIdx; + u8 mShouldCommit; + + static u16 sTempFlags[4]; + static u16 sSceneFlags[8]; + static u16 sZoneFlags[0xFC]; + + static SceneflagManager *sInstance; + void doNothing(); + void setShouldCommit(u16 flag); + SceneflagManager(); + s32 isNotTempOrZoneFlag(u16 flag); + s32 isZoneFlag(u32 flag); + void updateFlagindex(u16 flagindex); + void copyFromSave(u32 flagindex); + void unsetAllTempflags(); + void zoneflagsResetAll(); + void zoneflagsResetForRoom(u16 roomId); + void unsetZoneAndTempflags(); + void unsetAllZoneflags(); + void unsetZoneflagsForRoom(u16 roomId); + u16 getZoneflagSlot(u16 roomId, u16 flag); + u16 getSceneflagSlotGlobal(u16 sceneIdx, u16 flag); + u16 getSceneflagSlot(u16 flag); + u16 getTempflagSlot(u16 flag); + bool checkZoneFlag(u16 roomId, u16 flag); + bool checkUncommittedZoneflag(u16 roomId, u16 flag); + u16 checkUncommittedZoneflag2(u16 roomId, u16 flag) { + return checkUncommittedZoneflag(roomId, flag); + } + bool checkUncommittedTempOrSceneflag(u16 flag); + u16 checkUncommittedTempOrSceneflag2(u16 flag) { + return checkUncommittedTempOrSceneflag(flag); + } + u16 checkFlag(u16 roomId, u16 flag); + bool checkSceneflagGlobal(u16 sceneIdx, u16 flag); + bool checkTempOrSceneflag(u16 flag); + bool checkUncommittedFlag(u16 roomId, u16 flag); + void setZoneflag(u16 roomId, u16 flag); + void setFlag(u16 roomId, u16 flag); + void setSceneflagGlobal(u16 sceneIdx, u16 flag); + void setTempOrSceneflag(u16 flag); + void unsetZoneflag(u16 roomId, u16 flag); + void unsetFlag(u16 roomId, u16 flag); + void unsetSceneflagGlobal(u16 sceneIdx, u16 flag); + void unsetTempOrSceneflag(u16 flag); + s32 doCommit(); +}; + +#endif diff --git a/src/REL/d/t/d_t_timer.cpp b/src/REL/d/t/d_t_timer.cpp index e69de29b..2a01f374 100644 --- a/src/REL/d/t/d_t_timer.cpp +++ b/src/REL/d/t/d_t_timer.cpp @@ -0,0 +1,100 @@ +#include +#include + +SPECIAL_ACTOR_PROFILE(TIMER_TAG, dTgTimer_c, fProfile::TAG_TIMER, 0x029F, 0, 0); + +// TODO counter abstraction +bool increment(u16 *t) { + if (*t < 0xFFFF) { + (*t)++; + return true; + } + return false; +} + +int dTgTimer_c::create() { + switch (getSubtypeFromParams()) { + case 0: + mGetTargetTimeFunc = dTgTimer_c::getConstant0x50_Thunk; + break; + case 1: + mTargetTime = getTimerFromParams() * 0x1e; + mGetTargetTimeFunc = getStoredTargetTime; + break; + default: + mTargetTime = getTimerFromParams(); + mGetTargetTimeFunc = getStoredTargetTime; + break; + } + resetTimer(); + return 1; +} + +int dTgTimer_c::actorExecute() { + bool getFlag = SceneflagManager::sInstance->checkFlag(roomid, getCheckSceneflag()); + if (getFlag) { + if (checkShouldTrigger()) { + SceneflagManager::sInstance->setFlag(roomid, getSetSceneflag()); + } else { + incrementTimer(); + } + } else { + resetTimer(); + } + return 1; +} + +int dTgTimer_c::getSubtypeFromParams() { + return params & 0xFF; +} + +u16 dTgTimer_c::getTimerFromParams() { + return params >> 8 & 0xFF; +} + +u16 dTgTimer_c::getCheckSceneflag() { + return params >> 0x10 & 0xFF; +} + +u16 dTgTimer_c::getSetSceneflag() { + return params >> 0x18 & 0xFF; +} + +u16 dTgTimer_c::getTimer() { + return mTimer; +} + +u16 dTgTimer_c::getConstant0x50() { + return 0x50; +} + +u16 dTgTimer_c::setTimer(u16 val) { + mTimer = val; +} + +u16 dTgTimer_c::getTargetTime() { + return (this->*mGetTargetTimeFunc)(); +} + +void dTgTimer_c::resetTimer() { + setTimer(0); +} + +void dTgTimer_c::incrementTimer() { + u16 t = getTimer(); + increment(&t); + setTimer(t); +} + +bool dTgTimer_c::checkShouldTrigger() { + return getTargetTime() <= getTimer(); +} + +u16 dTgTimer_c::getStoredTargetTime() { + return mTargetTime; +} + +// TODO what causes this (likely weak) thunk? +u16 dTgTimer_c::getConstant0x50_Thunk() { + return getConstant0x50(); +} diff --git a/src/toBeSorted/sceneflag_manager.cpp b/src/toBeSorted/sceneflag_manager.cpp index 1cef7560..36ab7087 100644 --- a/src/toBeSorted/sceneflag_manager.cpp +++ b/src/toBeSorted/sceneflag_manager.cpp @@ -1,64 +1,8 @@ #include "libc.h" #include -#include "toBeSorted/bitwise_flag_helper.h" +#include "toBeSorted/sceneflag_manager.h" #include "toBeSorted/file_manager.h" -#include "toBeSorted/flag_space.h" - -class SceneflagManager { -public: - FlagSpace mSceneflags; - FlagSpace mTempflags; - FlagSpace mZoneflags; - BitwiseFlagHelper mFlagHelper; - u16 mSceneIdx; - u8 mShouldCommit; - - static u16 sTempFlags[4]; - static u16 sSceneFlags[8]; - static u16 sZoneFlags[0xFC]; - - static SceneflagManager *sInstance; - void doNothing(); - void setShouldCommit(u16 flag); - SceneflagManager(); - s32 isNotTempOrZoneFlag(u16 flag); - s32 isZoneFlag(u32 flag); - void updateFlagindex(u16 flagindex); - void copyFromSave(u32 flagindex); - void unsetAllTempflags(); - void zoneflagsResetAll(); - void zoneflagsResetForRoom(u16 roomId); - void unsetZoneAndTempflags(); - void unsetAllZoneflags(); - void unsetZoneflagsForRoom(u16 roomId); - u16 getZoneflagSlot(u16 roomId, u16 flag); - u16 getSceneflagSlotGlobal(u16 sceneIdx, u16 flag); - u16 getSceneflagSlot(u16 flag); - u16 getTempflagSlot(u16 flag); - bool checkZoneFlag(u16 roomId, u16 flag); - bool checkUncommittedZoneflag(u16 roomId, u16 flag); - u16 checkUncommittedZoneflag2(u16 roomId, u16 flag) { - return checkUncommittedZoneflag(roomId, flag); - } - bool checkUncommittedTempOrSceneflag(u16 flag); - u16 checkUncommittedTempOrSceneflag2(u16 flag) { - return checkUncommittedTempOrSceneflag(flag); - } - bool checkFlag(u16 roomId, u16 flag); - bool checkSceneflagGlobal(u16 sceneIdx, u16 flag); - bool checkTempOrSceneflag(u16 flag); - bool checkUncommittedFlag(u16 roomId, u16 flag); - void setZoneflag(u16 roomId, u16 flag); - void setFlag(u16 roomId, u16 flag); - void setSceneflagGlobal(u16 sceneIdx, u16 flag); - void setTempOrSceneflag(u16 flag); - void unsetZoneflag(u16 roomId, u16 flag); - void unsetFlag(u16 roomId, u16 flag); - void unsetSceneflagGlobal(u16 sceneIdx, u16 flag); - void unsetTempOrSceneflag(u16 flag); - s32 doCommit(); -}; SceneflagManager *SceneflagManager::sInstance = nullptr; u16 SceneflagManager::sTempFlags[] = {}; @@ -200,7 +144,7 @@ bool SceneflagManager::checkUncommittedTempOrSceneflag(u16 flag) { // mFlagHelper.checkFlag(getSceneflagSlot2(flag), flag % 16, pData, mSceneflags.mCount); } } -bool SceneflagManager::checkFlag(u16 roomId, u16 flag) { +u16 SceneflagManager::checkFlag(u16 roomId, u16 flag) { if (isZoneFlag(flag)) { return checkZoneFlag(roomId, flag); } else {