Link CDolphinController.cpp

This commit is contained in:
Phillip Stephens 2022-09-13 22:24:41 -07:00
parent 52b5ab45d3
commit 0450f7b1f1
8 changed files with 211 additions and 57 deletions

View File

@ -3,6 +3,7 @@
#include <types.h>
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<u8*>(x0_mainData) + (idx << 3); }
void* x0_mainData;
void* x4_bookKeeping;
int x8_numBlocks;

View File

@ -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__

View File

@ -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 <dolphin/os/OSContext.h>
#include <dolphin/os/OSFont.h>
#include <dolphin/os/OSReset.h>
#include <dolphin/os/OSSerial.h>
#include <dolphin/os/OSThread.h>
#endif

View File

@ -0,0 +1,68 @@
#ifndef __OSSERIAL_H__
#define __OSSERIAL_H__
#include <types.h>
#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

View File

@ -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;

View File

@ -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\

View File

@ -22,7 +22,7 @@ void* CSmallAllocPool::FindFree(int len) {
u8* bookKeepingPtr = static_cast<u8*>(x4_bookKeeping);
u8* bookKeepingEndPtr = bookKeepingPtr + (x8_numBlocks >> 1);
u8* curKeepingIter = curKeepingOffset;
do {
while (true) {
u8* tmpIter = nullptr;
if (static_cast<u8*>(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<u8*>(FindFree(len));
if (freePtr == nullptr) {
return nullptr;
}
uint blockCount = (len - 2) / 2;
u8* bookKeepingStart = static_cast<u8*>(x4_bookKeeping);
u8* bufPtr = static_cast<u8*>(x0_mainData);
*static_cast<u8*>(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<u8*>(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<u8*>(x4_bookKeeping);
blockSize >>= 1;
u8* bufPtr = GetPtrFromIndex(freePtr - bookKeepingStart);
*static_cast<u8*>(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;
}

View File

@ -3,6 +3,8 @@
#include "Kyoto/Math/CMath.hpp"
#include <dolphin/gba.h>
#include <dolphin/os/OSSerial.h>
#include <string.h>
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; }