diff --git a/include/Kyoto/Alloc/CSmallAllocPool.hpp b/include/Kyoto/Alloc/CSmallAllocPool.hpp index b46d7539..af07fadf 100644 --- a/include/Kyoto/Alloc/CSmallAllocPool.hpp +++ b/include/Kyoto/Alloc/CSmallAllocPool.hpp @@ -3,6 +3,7 @@ #include +static const int kPointerSize = sizeof(void*); class CSmallAllocPool { public: CSmallAllocPool(uint len, void* mainData, void* bookKeeping); @@ -10,6 +11,9 @@ public: void* Alloc(uint size); bool Free(const void* ptr); private: + uint GetIndexFromPtr(const void* ptr) const { return ((const u8*)ptr - x0_mainData) / kPointerSize; } + long GetEntryValue(uint idx) const { return (long)*((u8*)x4_bookKeeping + idx); } + u8* GetPtrFromIndex(unsigned int idx) const { return static_cast(x0_mainData) + (idx << 3); } void* x0_mainData; void* x4_bookKeeping; int x8_numBlocks; diff --git a/include/Kyoto/Input/CControllerButton.hpp b/include/Kyoto/Input/CControllerButton.hpp index d21e9890..1ce8541b 100644 --- a/include/Kyoto/Input/CControllerButton.hpp +++ b/include/Kyoto/Input/CControllerButton.hpp @@ -5,16 +5,16 @@ 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; } + uint 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; + uchar x0_pressed; + uchar x1_pressEvent; + uchar x2_releaseEvent; }; #endif // __CCONTROLLERBUTTON_HPP__ diff --git a/include/dolphin/os.h b/include/dolphin/os.h index 5d7c2799..16c381e2 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -31,12 +31,12 @@ u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h #define OS_CORE_CLOCK __OSCoreClock #define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) -#define OSPhysicalToCached(paddr) ((void*) ((u32)(paddr) + OS_BASE_CACHED)) -#define OSPhysicalToUncached(paddr) ((void*) ((u32)(paddr) + OS_BASE_UNCACHED)) -#define OSCachedToPhysical(caddr) ((u32) ((u8*)(caddr) - OS_BASE_CACHED)) -#define OSUncachedToPhysical(ucaddr) ((u32) ((u8*)(ucaddr)- OS_BASE_UNCACHED)) -#define OSCachedToUncached(caddr) ((void*) ((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED))) -#define OSUncachedToCached(ucaddr) ((void*) ((u8*)(ucaddr)- (OS_BASE_UNCACHED - OS_BASE_CACHED))) +#define OSPhysicalToCached(paddr) ((void*)((u32)(paddr) + OS_BASE_CACHED)) +#define OSPhysicalToUncached(paddr) ((void*)((u32)(paddr) + OS_BASE_UNCACHED)) +#define OSCachedToPhysical(caddr) ((u32)((u8*)(caddr)-OS_BASE_CACHED)) +#define OSUncachedToPhysical(ucaddr) ((u32)((u8*)(ucaddr)-OS_BASE_UNCACHED)) +#define OSCachedToUncached(caddr) ((void*)((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED))) +#define OSUncachedToCached(ucaddr) ((void*)((u8*)(ucaddr) - (OS_BASE_UNCACHED - OS_BASE_CACHED))) #define OSTicksToCycles(ticks) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2) #define OSTicksToSeconds(ticks) ((ticks) / OS_TIMER_CLOCK) @@ -64,5 +64,6 @@ void OSReport(const char* msg, ...); #include #include #include +#include #include #endif diff --git a/include/dolphin/os/OSSerial.h b/include/dolphin/os/OSSerial.h new file mode 100644 index 00000000..34f43a55 --- /dev/null +++ b/include/dolphin/os/OSSerial.h @@ -0,0 +1,68 @@ +#ifndef __OSSERIAL_H__ +#define __OSSERIAL_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SI_MAX_CHAN 4 +#define SI_MAX_COMCSR_INLNGTH 128 +#define SI_MAX_COMCSR_OUTLNGTH 128 +#define SI_ERROR_UNDER_RUN 0x0001 +#define SI_ERROR_OVER_RUN 0x0002 +#define SI_ERROR_COLLISION 0x0004 +#define SI_ERROR_NO_RESPONSE 0x0008 +#define SI_ERROR_WRST 0x0010 +#define SI_ERROR_RDST 0x0020 +#define SI_ERROR_UNKNOWN 0x0040 +#define SI_ERROR_BUSY 0x0080 +#define SI_CHAN0 0 +#define SI_CHAN1 1 +#define SI_CHAN2 2 +#define SI_CHAN3 3 +#define SI_CHAN0_BIT 0x80000000 +#define SI_CHAN1_BIT 0x40000000 +#define SI_CHAN2_BIT 0x20000000 +#define SI_CHAN3_BIT 0x10000000 +#define SI_CHAN_BIT(chan) (SI_CHAN0_BIT >> (chan)) +#define SI_TYPE_MASK 0x18000000u +#define SI_TYPE_N64 0x00000000u +#define SI_TYPE_DOLPHIN 0x08000000u +#define SI_TYPE_GC SI_TYPE_DOLPHIN +#define SI_GC_WIRELESS 0x80000000 +#define SI_GC_NOMOTOR 0x20000000 +#define SI_GC_STANDARD 0x01000000 +#define SI_WIRELESS_RECEIVED 0x40000000 +#define SI_WIRELESS_IR 0x04000000 +#define SI_WIRELESS_STATE 0x02000000 +#define SI_WIRELESS_ORIGIN 0x00200000 +#define SI_WIRELESS_FIX_ID 0x00100000 +#define SI_WIRELESS_TYPE 0x000f0000 +#define SI_WIRELESS_LITE_MASK 0x000c0000 +#define SI_WIRELESS_LITE 0x00040000 +#define SI_WIRELESS_CONT_MASK 0x00080000 +#define SI_WIRELESS_CONT 0x00000000 +#define SI_WIRELESS_ID 0x00c0ff00 +#define SI_WIRELESS_TYPE_ID (SI_WIRELESS_TYPE | SI_WIRELESS_ID) +#define SI_N64_CONTROLLER (SI_TYPE_N64 | 0x05000000) +#define SI_N64_MIC (SI_TYPE_N64 | 0x00010000) +#define SI_N64_KEYBOARD (SI_TYPE_N64 | 0x00020000) +#define SI_N64_MOUSE (SI_TYPE_N64 | 0x02000000) +#define SI_GBA (SI_TYPE_N64 | 0x00040000) +#define SI_GC_CONTROLLER (SI_TYPE_GC | SI_GC_STANDARD) +#define SI_GC_RECEIVER (SI_TYPE_GC | SI_GC_WIRELESS) +#define SI_GC_WAVEBIRD (SI_TYPE_GC | SI_GC_WIRELESS | SI_GC_STANDARD | SI_WIRELESS_STATE | SI_WIRELESS_FIX_ID) +#define SI_GC_KEYBOARD (SI_TYPE_GC | 0x00200000) +#define SI_GC_STEERING (SI_TYPE_GC | 0x00000000) + +u32 SIProbe(s32 chan); +char* SIGetTypeString(u32 type); +void SIRefreshSamplingRate(void); +void SISetSamplingRate(u32 msec); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/types.h b/include/types.h index d264cc0b..442a9ab8 100644 --- a/include/types.h +++ b/include/types.h @@ -11,6 +11,7 @@ extern "C" { // Dolphin u32 is unsigned long typedef unsigned int uint; +typedef unsigned char uchar; // Pointer to unknown, to be determined at a later date. typedef void* unkptr; diff --git a/obj_files.mk b/obj_files.mk index 5446646f..70a89bfb 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -584,7 +584,7 @@ KYOTO_2 :=\ $(BUILD_DIR)/asm/Kyoto/Audio/DolphinCAudioSys.o\ $(BUILD_DIR)/asm/Kyoto/DolphinCMemoryCardSys.o\ $(BUILD_DIR)/src/Kyoto/Input/DolphinIController.o\ - $(BUILD_DIR)/asm/Kyoto/Input/CDolphinController.o\ + $(BUILD_DIR)/src/Kyoto/Input/CDolphinController.o\ $(BUILD_DIR)/asm/Kyoto/DolphinCDvdFile.o\ $(BUILD_DIR)/asm/Kyoto/Alloc/CMediumAllocPool.o\ $(BUILD_DIR)/asm/Kyoto/Alloc/CSmallAllocPool.o\ diff --git a/src/Kyoto/Alloc/CSmallAllocPool.cpp b/src/Kyoto/Alloc/CSmallAllocPool.cpp index 168c5a14..7f2cbb7f 100644 --- a/src/Kyoto/Alloc/CSmallAllocPool.cpp +++ b/src/Kyoto/Alloc/CSmallAllocPool.cpp @@ -22,7 +22,7 @@ void* CSmallAllocPool::FindFree(int len) { u8* bookKeepingPtr = static_cast(x4_bookKeeping); u8* bookKeepingEndPtr = bookKeepingPtr + (x8_numBlocks >> 1); u8* curKeepingIter = curKeepingOffset; - do { + while (true) { u8* tmpIter = nullptr; if (static_cast(curKeepingIter)[0] != 0 || curKeepingIter == bookKeepingEndPtr){ tmpIter = bookKeepingPtr; @@ -59,45 +59,47 @@ void* CSmallAllocPool::FindFree(int len) { if (tmpIter == curKeepingOffset) { return nullptr; } - } while (true); + } } void* CSmallAllocPool::Alloc(uint size) { - uint len = size >= 4 ? len = (size + 3) / 4 : 1; + u32 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; + if ((len & 1) != 0) { + len += 1; } - } - x18_numBlocksAvailable = x18_numBlocksAvailable - len; - ++x1c_numAllocs; + u8* freePtr = static_cast(FindFree(len)); + if (freePtr == NULL) { + return NULL; + } - return bufPtr + ((freePtr - bookKeepingStart) * 8); + s32 sub = len - 2; + s32 blockSize = (sub >> 31) & 1; + blockSize = blockSize + sub; + u8* bookKeepingStart = static_cast(x4_bookKeeping); + blockSize >>= 1; + u8* bufPtr = GetPtrFromIndex(freePtr - bookKeepingStart); + *static_cast(freePtr) = (len << 4) | 0xf; + u8* freePtrIter = freePtr + 1; + while(blockSize--) { + *freePtrIter = 0xff; + ++freePtrIter; + } + + x18_numBlocksAvailable -= len; + ++x1c_numAllocs; + + return bufPtr; } -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; +bool CSmallAllocPool::Free(const void* arg0) { + s32 temp_r8 = GetIndexFromPtr(arg0); + s32 mask = (temp_r8 & 1) ? 0 : 4; + u32 temp_r9 = (u32)temp_r8 / 2; + s32 temp_r4_2 = GetEntryValue(temp_r9); + temp_r4_2 = (temp_r4_2 >> mask) & 0xF; x18_numBlocksAvailable += temp_r4_2; s32 var_r5 = temp_r4_2; x1c_numAllocs -= 1; @@ -112,5 +114,5 @@ bool CSmallAllocPool::Free(const void* ptr) { var_r5 -= 2; ++var_r3; } - return true; + return 1; } diff --git a/src/Kyoto/Input/CDolphinController.cpp b/src/Kyoto/Input/CDolphinController.cpp index 49ac201b..c07afb50 100644 --- a/src/Kyoto/Input/CDolphinController.cpp +++ b/src/Kyoto/Input/CDolphinController.cpp @@ -3,6 +3,8 @@ #include "Kyoto/Math/CMath.hpp" #include +#include + #include CDolphinController::CDolphinController() : x1c4_(0xf0000000), x1c8_invalidControllers(0), x1cc_(0) { @@ -36,7 +38,54 @@ void CDolphinController::Poll() { ProcessInputData(); } -void CDolphinController::ReadDevices() {} +void CDolphinController::ReadDevices() { + PADStatus status[4]; + PADRead(status); + if (status[0].err == PAD_ERR_NONE) { + PADClamp(status); + memcpy(x4_status, status, sizeof(PADStatus) * 4); + } else { + for (int i = 0; i < 4; ++i) { + x4_status[i].err = status[i].err; + } + } + + for (int i = 0; i < 4; ++i) { + uint controller = (PAD_CHAN0_BIT >> i); + if (x4_status[i].err != PAD_ERR_NOT_READY) { + if (x4_status[i].err == PAD_ERR_NONE) { + x34_gamepadStates[i].SetDeviceIsPresent(true); + } else if (x4_status[i].err == PAD_ERR_NO_CONTROLLER) { + x1c8_invalidControllers |= controller; + x34_gamepadStates[i].SetDeviceIsPresent(false); + } + } + + if (x1b4_controllerTypePollTime[i] != 0) { + --x1b4_controllerTypePollTime[i]; + } else { + const u32 type = SIProbe(i); + if ((type & (SI_ERROR_NO_RESPONSE | SI_ERROR_UNKNOWN | SI_ERROR_BUSY)) != 0) { + if (x1b4_controllerTypePollTime[i] == 0) { + x1a4_controllerTypes[i] = skTypeUnknown; + } + } else { + x1b4_controllerTypePollTime[i] = 60; + if (type == SI_GC_WAVEBIRD) { + x1a4_controllerTypes[i] = skTypeWavebird; + } else if (type == SI_GBA) { + x1a4_controllerTypes[i] = skTypeGBA; + } else if (type == SI_GC_CONTROLLER) { + x1a4_controllerTypes[i] = skTypeStandard; + } + } + } + } + + if (x1c8_invalidControllers != 0 && PADReset(x1c8_invalidControllers)) { + x1c8_invalidControllers = 0; + } +} void CDolphinController::ProcessInputData() { for (int i = 0; i < 4; ++i) { @@ -56,17 +105,35 @@ void CDolphinController::ProcessAxis(int controller, EJoyAxis axis) { float axisValue = 0.f; switch (axis) { - case kJA_LeftX: axisValue = x4_status[controller].stickX; break; - case kJA_LeftY: axisValue = x4_status[controller].stickY; break; - case kJA_RightX: axisValue = x4_status[controller].substickX; break; - case kJA_RightY: axisValue = x4_status[controller].substickY; break; + case kJA_LeftX: + axisValue = x4_status[controller].stickX; + break; + case kJA_LeftY: + axisValue = x4_status[controller].stickY; + break; + case kJA_RightX: + axisValue = x4_status[controller].substickX; + break; + case kJA_RightY: + axisValue = x4_status[controller].substickY; + break; + } + + float absolute = axisValue * maxAxisValue; + if (absolute < kAbsoluteMinimum) { + absolute = kAbsoluteMinimum; + } else if (absolute > kAbsoluteMaximum) { + absolute = kAbsoluteMaximum; + } + + float relativeValue = absolute - data.GetAbsoluteValue(); + if (relativeValue < kRelativeMinimum) { + relativeValue = kRelativeMinimum; + } else if (relativeValue > kRelativeMaximum) { + relativeValue = kRelativeMaximum; } -#if 0 - float absolute = CMath::Clamp(kAbsoluteMinimum, axisValue * maxAxisValue, kAbsoluteMaximum); - float relativeValue = CMath::Clamp(kRelativeMinimum, absolute - data.GetAbsoluteValue(), kRelativeMaximum); data.SetRelativeValue(relativeValue); data.SetAbsoluteValue(absolute); -#endif } static u16 mButtonMapping[size_t(kBU_MAX)] = { @@ -75,14 +142,12 @@ static u16 mButtonMapping[size_t(kBU_MAX)] = { }; void CDolphinController::ProcessButtons(int controller) { - for (s32 i = 0; i < s32(kBU_MAX); ++i) { + for (s32 i = 0; i < s32(kBU_MAX); ++i) { ProcessDigitalButton(controller, x34_gamepadStates[controller].GetButton(EButton(i)), mButtonMapping[i]); } - ProcessAnalogButton(x4_status[controller].triggerL, - x34_gamepadStates[controller].GetAnalogButton(kBA_Left)); - ProcessAnalogButton(x4_status[controller].triggerR, - x34_gamepadStates[controller].GetAnalogButton(kBA_Right)); + ProcessAnalogButton(x4_status[controller].triggerL, x34_gamepadStates[controller].GetAnalogButton(kBA_Left)); + ProcessAnalogButton(x4_status[controller].triggerR, x34_gamepadStates[controller].GetAnalogButton(kBA_Right)); } void CDolphinController::ProcessDigitalButton(int controller, CControllerButton& button, u16 mapping) { @@ -92,7 +157,20 @@ void CDolphinController::ProcessDigitalButton(int controller, CControllerButton& button.SetIsPressed(btnPressed); } -void CDolphinController::ProcessAnalogButton(float value, CControllerAxis& axis) {} +void CDolphinController::ProcessAnalogButton(float value, CControllerAxis& axis) { + value *= 1.f / 150.f; + if (value > kAbsoluteMaximum) { + value = kAbsoluteMaximum; + } + + float relative = value - axis.GetAbsoluteValue(); + if (relative > kRelativeMaximum) { + relative = kRelativeMaximum; + } + + axis.SetRelativeValue(relative); + axis.SetAbsoluteValue(value); +} uint CDolphinController::GetDeviceCount() const { return 4; }