From 228319e2a55d1e007a9da7de0301e3aeb49f210a Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sun, 11 Sep 2022 11:45:19 -0700 Subject: [PATCH] Link DolphinIController.cpp, start matching CSmallAllocPool --- asm/Kyoto/Input/CDolphinController.s | 41 +++---- asm/Kyoto/Input/DolphinIController.s | 32 +++-- include/Kyoto/Alloc/CSmallAllocPool.hpp | 22 ++++ include/Kyoto/Input/CControllerAxis.hpp | 16 +++ include/Kyoto/Input/CControllerButton.hpp | 20 +++ .../Kyoto/Input/CControllerGamepadData.hpp | 28 +++++ include/Kyoto/Input/CDolphinController.hpp | 26 ++++ include/Kyoto/Input/IController.hpp | 29 +++++ include/Kyoto/Input/InputTypes.hpp | 48 ++++++++ obj_files.mk | 2 +- src/Kyoto/Alloc/CSmallAllocPool.cpp | 116 ++++++++++++++++++ src/Kyoto/Input/DolphinIController.cpp | 18 +++ 12 files changed, 362 insertions(+), 36 deletions(-) create mode 100644 include/Kyoto/Alloc/CSmallAllocPool.hpp create mode 100644 include/Kyoto/Input/CControllerAxis.hpp create mode 100644 include/Kyoto/Input/CControllerButton.hpp create mode 100644 include/Kyoto/Input/CControllerGamepadData.hpp create mode 100644 include/Kyoto/Input/CDolphinController.hpp create mode 100644 include/Kyoto/Input/IController.hpp create mode 100644 include/Kyoto/Input/InputTypes.hpp create mode 100644 src/Kyoto/Alloc/CSmallAllocPool.cpp create mode 100644 src/Kyoto/Input/DolphinIController.cpp diff --git a/asm/Kyoto/Input/CDolphinController.s b/asm/Kyoto/Input/CDolphinController.s index d6e6ed30..41f54fb0 100644 --- a/asm/Kyoto/Input/CDolphinController.s +++ b/asm/Kyoto/Input/CDolphinController.s @@ -25,6 +25,16 @@ lbl_803EF6B8: .4byte GetControllerType__18CDolphinControllerFi .4byte SetMotorState__18CDolphinControllerF7EIOPort11EMotorState +.section .sbss, "wa" +.balign 8 + +.global lbl_805A95C8 +lbl_805A95C8: + .skip 0x1 +.global lbl_805A95C9 +lbl_805A95C9: + .skip 0x7 + .section .text, "ax" .global GetAnalogStickMaxValue__18CDolphinControllerCF8EJoyAxis @@ -86,14 +96,14 @@ GetDeviceCount__18CDolphinControllerCFv: .global ProcessAnalogButton__18CDolphinControllerFfR15CControllerAxis ProcessAnalogButton__18CDolphinControllerFfR15CControllerAxis: /* 8034F0F4 0034C054 C0 02 CC 7C */ lfs f0, lbl_805AE99C@sda21(r2) -/* 8034F0F8 0034C058 C0 42 CC 54 */ lfs f2, lbl_805AE974@sda21(r2) +/* 8034F0F8 0034C058 C0 42 CC 54 */ lfs f2, kAbsoluteMaximum__11IController@sda21(r2) /* 8034F0FC 0034C05C EC 61 00 32 */ fmuls f3, f1, f0 /* 8034F100 0034C060 FC 03 10 40 */ fcmpo cr0, f3, f2 /* 8034F104 0034C064 40 81 00 08 */ ble lbl_8034F10C /* 8034F108 0034C068 FC 60 10 90 */ fmr f3, f2 lbl_8034F10C: /* 8034F10C 0034C06C C0 04 00 04 */ lfs f0, 4(r4) -/* 8034F110 0034C070 C0 22 CC 5C */ lfs f1, lbl_805AE97C@sda21(r2) +/* 8034F110 0034C070 C0 22 CC 5C */ lfs f1, kRelativeMaximum__11IController@sda21(r2) /* 8034F114 0034C074 EC 03 00 28 */ fsubs f0, f3, f0 /* 8034F118 0034C078 FC 00 08 40 */ fcmpo cr0, f0, f1 /* 8034F11C 0034C07C 40 81 00 08 */ ble lbl_8034F124 @@ -274,26 +284,26 @@ lbl_8034F370: /* 8034F398 0034C2F8 EC 60 08 28 */ fsubs f3, f0, f1 lbl_8034F39C: /* 8034F39C 0034C2FC EC 43 00 B2 */ fmuls f2, f3, f2 -/* 8034F3A0 0034C300 C0 02 CC 50 */ lfs f0, lbl_805AE970@sda21(r2) +/* 8034F3A0 0034C300 C0 02 CC 50 */ lfs f0, kAbsoluteMinimum__11IController@sda21(r2) /* 8034F3A4 0034C304 FC 02 00 40 */ fcmpo cr0, f2, f0 /* 8034F3A8 0034C308 40 80 00 0C */ bge lbl_8034F3B4 /* 8034F3AC 0034C30C FC 40 00 90 */ fmr f2, f0 /* 8034F3B0 0034C310 48 00 00 14 */ b lbl_8034F3C4 lbl_8034F3B4: -/* 8034F3B4 0034C314 C0 02 CC 54 */ lfs f0, lbl_805AE974@sda21(r2) +/* 8034F3B4 0034C314 C0 02 CC 54 */ lfs f0, kAbsoluteMaximum__11IController@sda21(r2) /* 8034F3B8 0034C318 FC 02 00 40 */ fcmpo cr0, f2, f0 /* 8034F3BC 0034C31C 40 81 00 08 */ ble lbl_8034F3C4 /* 8034F3C0 0034C320 FC 40 00 90 */ fmr f2, f0 lbl_8034F3C4: /* 8034F3C4 0034C324 C0 04 00 04 */ lfs f0, 4(r4) -/* 8034F3C8 0034C328 C0 22 CC 58 */ lfs f1, lbl_805AE978@sda21(r2) +/* 8034F3C8 0034C328 C0 22 CC 58 */ lfs f1, kRelativeMinimum__11IController@sda21(r2) /* 8034F3CC 0034C32C EC 62 00 28 */ fsubs f3, f2, f0 /* 8034F3D0 0034C330 FC 03 08 40 */ fcmpo cr0, f3, f1 /* 8034F3D4 0034C334 40 80 00 0C */ bge lbl_8034F3E0 /* 8034F3D8 0034C338 FC 60 08 90 */ fmr f3, f1 /* 8034F3DC 0034C33C 48 00 00 14 */ b lbl_8034F3F0 lbl_8034F3E0: -/* 8034F3E0 0034C340 C0 02 CC 5C */ lfs f0, lbl_805AE97C@sda21(r2) +/* 8034F3E0 0034C340 C0 02 CC 5C */ lfs f0, kRelativeMaximum__11IController@sda21(r2) /* 8034F3E4 0034C344 FC 03 00 40 */ fcmpo cr0, f3, f0 /* 8034F3E8 0034C348 40 81 00 08 */ ble lbl_8034F3F0 /* 8034F3EC 0034C34C FC 60 00 90 */ fmr f3, f0 @@ -656,25 +666,6 @@ __ct__15CControllerAxisFv: .section .sdata2, "a" .balign 8 -.global lbl_805AE970 -lbl_805AE970: - # ROM: 0x3FB210 - .float -1.0 - -.global lbl_805AE974 -lbl_805AE974: - # ROM: 0x3FB214 - .float 1.0 - -.global lbl_805AE978 -lbl_805AE978: - # ROM: 0x3FB218 - .float -1.0 - -.global lbl_805AE97C -lbl_805AE97C: - # ROM: 0x3FB21C - .float 1.0 .global lbl_805AE980 lbl_805AE980: diff --git a/asm/Kyoto/Input/DolphinIController.s b/asm/Kyoto/Input/DolphinIController.s index cb8122ce..ed0ce706 100644 --- a/asm/Kyoto/Input/DolphinIController.s +++ b/asm/Kyoto/Input/DolphinIController.s @@ -15,16 +15,6 @@ lbl_803EF680: .4byte 0 .4byte 0 -.section .sbss, "wa" -.balign 8 - -.global lbl_805A95C8 -lbl_805A95C8: - .skip 0x1 -.global lbl_805A95C9 -lbl_805A95C9: - .skip 0x7 - .section .text, "ax" .global Create__11IControllerFRC10COsContext @@ -89,3 +79,25 @@ lbl_803D8228: .asciz "??(??)" .balign 4 +.section .sdata2, "a" +.balign 8 + +.global kAbsoluteMinimum__11IController +kAbsoluteMinimum__11IController: + # ROM: 0x3FB210 + .float -1.0 + +.global kAbsoluteMaximum__11IController +kAbsoluteMaximum__11IController: + # ROM: 0x3FB214 + .float 1.0 + +.global kRelativeMinimum__11IController +kRelativeMinimum__11IController: + # ROM: 0x3FB218 + .float -1.0 + +.global kRelativeMaximum__11IController +kRelativeMaximum__11IController: + # ROM: 0x3FB21C + .float 1.0 diff --git a/include/Kyoto/Alloc/CSmallAllocPool.hpp b/include/Kyoto/Alloc/CSmallAllocPool.hpp new file mode 100644 index 00000000..b46d7539 --- /dev/null +++ b/include/Kyoto/Alloc/CSmallAllocPool.hpp @@ -0,0 +1,22 @@ +#ifndef __CSMALLALLOCPOOL_HPP__ +#define __CSMALLALLOCPOOL_HPP__ + +#include + +class CSmallAllocPool { +public: + CSmallAllocPool(uint len, void* mainData, void* bookKeeping); + void* FindFree(int len); + void* Alloc(uint size); + bool Free(const void* ptr); +private: + void* x0_mainData; + void* x4_bookKeeping; + int x8_numBlocks; + void* xc_cachedBookKeepingOffset; + int x10_; + int x14_; + uint x18_numBlocksAvailable; + uint x1c_numAllocs; +}; +#endif // __CSMALLALLOCPOOL_HPP__ diff --git a/include/Kyoto/Input/CControllerAxis.hpp b/include/Kyoto/Input/CControllerAxis.hpp new file mode 100644 index 00000000..390656e2 --- /dev/null +++ b/include/Kyoto/Input/CControllerAxis.hpp @@ -0,0 +1,16 @@ +#ifndef __CCONTROLLERAXIS_HPP__ +#define __CCONTROLLERAXIS_HPP__ + +class CControllerAxis { +public: + CControllerAxis() : x0_relative(0.f), x4_absolute(0.f) {} + void SetRelativeValue(float val) { x0_relative = val; } + float GetRelativeValue() const { return x0_relative; } + void SetAbsoluteValue(float val) { x4_absolute = val; } + float GetAbsoluteValue() const { return x4_absolute; } +public: + float x0_relative; + float x4_absolute; +}; + +#endif // __CCONTROLLERAXIS_HPP__ diff --git a/include/Kyoto/Input/CControllerButton.hpp b/include/Kyoto/Input/CControllerButton.hpp new file mode 100644 index 00000000..d21e9890 --- /dev/null +++ b/include/Kyoto/Input/CControllerButton.hpp @@ -0,0 +1,20 @@ +#ifndef __CCONTROLLERBUTTON_HPP__ +#define __CCONTROLLERBUTTON_HPP__ + +class CControllerButton { +public: + CControllerButton() : x0_pressed(false), x1_pressEvent(false), x2_releaseEvent(false) {} + void SetIsPressed(bool pressed) { x0_pressed = pressed; } + bool GetIsPressed() const { return x0_pressed; } + void SetPressEvent(bool press) { x1_pressEvent = press; } + bool GetPressEvent() const { return x1_pressEvent; } + void SetReleaseEvent(bool release) { x2_releaseEvent = release; }; + bool GetReleaseEvent() const { return x2_releaseEvent; } + +private: + bool x0_pressed; + bool x1_pressEvent; + bool x2_releaseEvent; +}; + +#endif // __CCONTROLLERBUTTON_HPP__ diff --git a/include/Kyoto/Input/CControllerGamepadData.hpp b/include/Kyoto/Input/CControllerGamepadData.hpp new file mode 100644 index 00000000..ad56a120 --- /dev/null +++ b/include/Kyoto/Input/CControllerGamepadData.hpp @@ -0,0 +1,28 @@ +#ifndef __CCONTROLLERGAMEPADDATA_HPP__ +#define __CCONTROLLERGAMEPADDATA_HPP__ + +#include "Kyoto/Input/CControllerAxis.hpp" +#include "Kyoto/Input/CControllerButton.hpp" + +class CControllerGamepadData { +public: + void SetDeviceIsPresent(bool present) { x0_present = present; } + bool DeviceIsPresent() const { return x0_present; } + + const CControllerAxis& GetAxis(EJoyAxis axis) const { return x4_axes[axis]; } + CControllerAxis& GetAxis(EJoyAxis axis) { return x4_axes[axis]; } + + const CControllerButton& GetButton(EButton button) const { return x34_buttons[button]; } + CControllerButton& GetButton(EButton button) { return x34_buttons[button]; } + + const CControllerAxis& GetAnalogButton(EAnalogButton button) const { return x24_triggers[button]; } + CControllerAxis& GetAnalogButton(EAnalogButton button) { return x24_triggers[button]; } + +private: + bool x0_present; + CControllerAxis x4_axes[4]; + CControllerAxis x24_triggers[2]; + CControllerButton x34_buttons[12]; +}; + +#endif // __CCONTROLLERGAMEPADDATA_HPP__ diff --git a/include/Kyoto/Input/CDolphinController.hpp b/include/Kyoto/Input/CDolphinController.hpp new file mode 100644 index 00000000..07927a50 --- /dev/null +++ b/include/Kyoto/Input/CDolphinController.hpp @@ -0,0 +1,26 @@ +#ifndef __CDOLPHINCONTROLLER_HPP__ +#define __CDOLPHINCONTROLLER_HPP__ + +#include "Kyoto/Input/IController.hpp" + +class CDolphinController : public IController { +public: + CDolphinController(); + void Poll(); + uint GetDeviceCount() const; + CControllerGamepadData& GetGamepadData(int controller); + u32 GetControllerType(int) const; + void SetMotorState(EIOPort port, EMotorState state); + bool Initialize(); +private: + PADStatus x4_status[4]; + CControllerGamepadData x34_gamepadStates[4]; + EMotorState x194_motorStates[4]; + u32 x1a4_controllerTypes[4]; + u32 x1b4_controllerTypePollTime[4]; + u32 x1c4_; + u32 x1c8_invalidControllers; + u32 x1cc_; +}; + +#endif // __CDOLPHINCONTROLLER_HPP__ diff --git a/include/Kyoto/Input/IController.hpp b/include/Kyoto/Input/IController.hpp new file mode 100644 index 00000000..ecafb45d --- /dev/null +++ b/include/Kyoto/Input/IController.hpp @@ -0,0 +1,29 @@ +#ifndef __ICONTROLLER_HPP__ +#define __ICONTROLLER_HPP__ + +#include + +#include "Kyoto/Input/InputTypes.hpp" +#include "Kyoto/Input/CControllerGamepadData.hpp" + + +class COsContext; +class IController { + static const float kAbsoluteMinimum; + static const float kAbsoluteMaximum; + static const float kRelativeMinimum; + static const float kRelativeMaximum; + +public: + IController(); + virtual ~IController(); + virtual void Poll()=0; + virtual uint GetDeviceCount() const = 0; + virtual CControllerGamepadData& GetGamepadData(int controller) = 0; + virtual u32 GetControllerType(int) const = 0; + virtual void SetMotorState(EIOPort port, EMotorState state) = 0; + + static IController* Create(const COsContext& ctx); +}; + +#endif // __ICONTROLLER_HPP__ diff --git a/include/Kyoto/Input/InputTypes.hpp b/include/Kyoto/Input/InputTypes.hpp new file mode 100644 index 00000000..cac9775f --- /dev/null +++ b/include/Kyoto/Input/InputTypes.hpp @@ -0,0 +1,48 @@ +#ifndef __INPUTTYPES_HPP__ +#define __INPUTTYPES_HPP__ + +#include + +enum EIOPort { + kIOP_Player1 = PAD_CHAN0, + kIOP_Player2 = PAD_CHAN1, + kIOP_Player3 = PAD_CHAN2, + kIOP_Player4 = PAD_CHAN3, +}; + +enum EMotorState { + kMS_Stop = PAD_MOTOR_STOP, + kMS_Rumble = PAD_MOTOR_RUMBLE, + kMS_StopHard = PAD_MOTOR_STOP_HARD, +}; + +enum EJoyAxis { + kJA_LeftX, + kJA_LeftY, + kJA_RightX, + kJA_RightY, + kJA_MAX +}; + +enum EButton { + kBU_A, + kBU_B, + kBU_X, + kBU_Y, + kBU_Start, + kBU_Z, + kBU_Up, + kBU_Right, + kBU_Down, + kBU_Left, + kBU_L, + kBU_R, + kBU_MAX, +}; + +enum EAnalogButton { + kBA_Left, + kBA_Right, +}; + +#endif // __INPUTTYPES_HPP__ diff --git a/obj_files.mk b/obj_files.mk index ce91ea1b..a6b7c148 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -583,7 +583,7 @@ KYOTO_2 :=\ $(BUILD_DIR)/asm/Kyoto/Audio/DolphinCAudioGroupSet.o\ $(BUILD_DIR)/asm/Kyoto/Audio/DolphinCAudioSys.o\ $(BUILD_DIR)/asm/Kyoto/DolphinCMemoryCardSys.o\ - $(BUILD_DIR)/asm/Kyoto/Input/DolphinIController.o\ + $(BUILD_DIR)/src/Kyoto/Input/DolphinIController.o\ $(BUILD_DIR)/asm/Kyoto/Input/CDolphinController.o\ $(BUILD_DIR)/asm/Kyoto/DolphinCDvdFile.o\ $(BUILD_DIR)/asm/Kyoto/Alloc/CMediumAllocPool.o\ diff --git a/src/Kyoto/Alloc/CSmallAllocPool.cpp b/src/Kyoto/Alloc/CSmallAllocPool.cpp new file mode 100644 index 00000000..168c5a14 --- /dev/null +++ b/src/Kyoto/Alloc/CSmallAllocPool.cpp @@ -0,0 +1,116 @@ +#include "Kyoto/Alloc/CSmallAllocPool.hpp" +#include + +CSmallAllocPool::CSmallAllocPool(uint len, void* mainData, void* bookKeeping) +: x0_mainData(mainData) +, x4_bookKeeping(bookKeeping) +, x8_numBlocks(len) +, xc_cachedBookKeepingOffset(NULL) +, x10_(-1) +, x14_(-1) +, x18_numBlocksAvailable(len) +, x1c_numAllocs(0) { + memset(bookKeeping, 0, len / 2); +} + +void* CSmallAllocPool::FindFree(int len) { + if (xc_cachedBookKeepingOffset == nullptr) { + xc_cachedBookKeepingOffset = x4_bookKeeping; + } + + u8* curKeepingOffset = static_cast(xc_cachedBookKeepingOffset); + u8* bookKeepingPtr = static_cast(x4_bookKeeping); + u8* bookKeepingEndPtr = bookKeepingPtr + (x8_numBlocks >> 1); + u8* curKeepingIter = curKeepingOffset; + do { + u8* tmpIter = nullptr; + if (static_cast(curKeepingIter)[0] != 0 || curKeepingIter == bookKeepingEndPtr){ + tmpIter = bookKeepingPtr; + if (curKeepingIter != bookKeepingEndPtr) { + u32 tmp = static_cast(curKeepingIter)[0]; + tmpIter = curKeepingIter + (tmp >> 5); + } + } else { + tmpIter = curKeepingIter; + while (static_cast(tmpIter)[0] == 0) { + ++tmpIter; + if (tmpIter == curKeepingOffset || tmpIter == bookKeepingEndPtr || tmpIter == curKeepingIter + (len / 2)) { + break; + } + } + + if (tmpIter == curKeepingIter + (len / 2)) { + if (tmpIter == bookKeepingEndPtr) { + xc_cachedBookKeepingOffset = bookKeepingPtr; + } else { + xc_cachedBookKeepingOffset = curKeepingIter; + } + return curKeepingIter; + } + + if (tmpIter == curKeepingOffset) { + return nullptr; + } + if (tmpIter == bookKeepingEndPtr) { + tmpIter = bookKeepingPtr; + } + } + curKeepingIter = tmpIter; + if (tmpIter == curKeepingOffset) { + return nullptr; + } + } while (true); +} + +void* CSmallAllocPool::Alloc(uint size) { + uint len = size >= 4 ? len = (size + 3) / 4 : 1; + + if ((len & 1) != 0) { + len += 1; + } + + u8* freePtr = static_cast(FindFree(len)); + if (freePtr == nullptr) { + return nullptr; + } + + uint blockCount = (len - 2) / 2; + u8* bookKeepingStart = static_cast(x4_bookKeeping); + u8* bufPtr = static_cast(x0_mainData); + + *static_cast(freePtr) = (len << 4) | 0xf; + u8* freePtrIter = freePtr + 1; + if (blockCount != 0) { + for (int i = 0; i < blockCount; i++, freePtrIter++) { + freePtr[i] = 0xff; + } + } + + x18_numBlocksAvailable = x18_numBlocksAvailable - len; + ++x1c_numAllocs; + + return bufPtr + ((freePtr - bookKeepingStart) * 8); +} + + +bool CSmallAllocPool::Free(const void* ptr) { + s32 temp_r4 = (u8*)ptr - x0_mainData; + s32 temp_r8 = temp_r4 / 4; + s32 temp_r9 = temp_r4 / 8; + s32 temp_r4_2 = ((s32) *((u8*)x4_bookKeeping + temp_r9)) >> (4 & ~-(temp_r8 & 1)) & 0xF; + x18_numBlocksAvailable += temp_r4_2; + s32 var_r5 = temp_r4_2; + x1c_numAllocs -= 1; + x14_ = temp_r8; + if ((u32) temp_r8 == (u32) x10_) { + x10_ = -1; + } + + u8* var_r3 = ((u8*)x4_bookKeeping) + temp_r9; + while (var_r5 != 0) { + *var_r3 = 0; + var_r5 -= 2; + ++var_r3; + } + return true; +} diff --git a/src/Kyoto/Input/DolphinIController.cpp b/src/Kyoto/Input/DolphinIController.cpp new file mode 100644 index 00000000..ed29e2d6 --- /dev/null +++ b/src/Kyoto/Input/DolphinIController.cpp @@ -0,0 +1,18 @@ +#include "Kyoto/Input/IController.hpp" +#include "Kyoto/Input/CDolphinController.hpp" +#include "Kyoto/Basics/COsContext.hpp" +#include "Kyoto/Alloc/CMemory.hpp" + +const float IController::kAbsoluteMinimum = -1.f; +const float IController::kAbsoluteMaximum = 1.f; +const float IController::kRelativeMinimum = -1.f; +const float IController::kRelativeMaximum = 1.f; + +IController::IController() {} +IController::~IController() {} + +IController* IController::Create(const COsContext& ctx) { + CDolphinController* cont = new CDolphinController(); + cont->Initialize(); + return cont; +}