More CirclePad Pro improvements

This commit is contained in:
wheremyfoodat 2025-07-03 00:52:55 +03:00
parent 935e088ca1
commit 0ab8a6d956
14 changed files with 155 additions and 81 deletions

View file

@ -27,6 +27,12 @@ namespace HID::Keys {
GPIO0Inv = 1 << 12, // Inverted value of GPIO bit 0 GPIO0Inv = 1 << 12, // Inverted value of GPIO bit 0
GPIO14Inv = 1 << 13, // Inverted value of GPIO bit 14 GPIO14Inv = 1 << 13, // Inverted value of GPIO bit 14
// CirclePad Pro buttons. We store them in the HID service for ease, even though they're only used by the IR service
// Whenever the HID service writes to shared memory, we remember to mask them out
ZL = 1 << 14,
ZR = 1 << 15,
CirclePadProButtons = ZL | ZR,
CirclePadRight = 1 << 28, // X >= 41 CirclePadRight = 1 << 28, // X >= 41
CirclePadLeft = 1 << 29, // X <= -41 CirclePadLeft = 1 << 29, // X <= -41
CirclePadUp = 1 << 30, // Y >= 41 CirclePadUp = 1 << 30, // Y >= 41
@ -58,6 +64,9 @@ class HIDService {
s16 roll, pitch, yaw; // Gyroscope state s16 roll, pitch, yaw; // Gyroscope state
s16 accelX, accelY, accelZ; // Accelerometer state s16 accelX, accelY, accelZ; // Accelerometer state
// New 3DS/CirclePad Pro C-stick state
s16 cStickX, cStickY;
bool accelerometerEnabled; bool accelerometerEnabled;
bool eventsInitialized; bool eventsInitialized;
bool gyroEnabled; bool gyroEnabled;
@ -113,7 +122,7 @@ class HIDService {
// Turn bits 28 and 29 off in the new button state, which indicate whether the circlepad is steering left or right // Turn bits 28 and 29 off in the new button state, which indicate whether the circlepad is steering left or right
// Then, set them according to the new value of x // Then, set them according to the new value of x
newButtons &= ~0x3000'0000; newButtons &= ~(HID::Keys::CirclePadLeft | HID::Keys::CirclePadRight);
if (x >= 41) // Pressing right if (x >= 41) // Pressing right
newButtons |= 1 << 28; newButtons |= 1 << 28;
else if (x <= -41) // Pressing left else if (x <= -41) // Pressing left
@ -125,13 +134,19 @@ class HIDService {
// Turn bits 30 and 31 off in the new button state, which indicate whether the circlepad is steering up or down // Turn bits 30 and 31 off in the new button state, which indicate whether the circlepad is steering up or down
// Then, set them according to the new value of y // Then, set them according to the new value of y
newButtons &= ~0xC000'0000; newButtons &= ~(HID::Keys::CirclePadUp | HID::Keys::CirclePadDown);
if (y >= 41) // Pressing up if (y >= 41) // Pressing up
newButtons |= 1 << 30; newButtons |= 1 << 30;
else if (y <= -41) // Pressing down else if (y <= -41) // Pressing down
newButtons |= 1 << 31; newButtons |= 1 << 31;
} }
void setCStickX(s16 x) { cStickX = x; }
void setCStickY(s16 y) { cStickY = y; }
s16 getCStickX() { return cStickX; }
s16 getCStickY() { return cStickY; }
void setRoll(s16 value) { roll = value; } void setRoll(s16 value) { roll = value; }
void setPitch(s16 value) { pitch = value; } void setPitch(s16 value) { pitch = value; }
void setYaw(s16 value) { yaw = value; } void setYaw(s16 value) { yaw = value; }
@ -157,9 +172,6 @@ class HIDService {
touchScreenPressed = true; touchScreenPressed = true;
} }
void releaseTouchScreen() { void releaseTouchScreen() { touchScreenPressed = false; }
touchScreenPressed = false;
}
bool isTouchScreenPressed() { return touchScreenPressed; } bool isTouchScreenPressed() { return touchScreenPressed; }
}; };

View file

@ -8,7 +8,6 @@ namespace IR {
public: public:
struct ButtonState { struct ButtonState {
static constexpr int C_STICK_CENTER = 0x800; static constexpr int C_STICK_CENTER = 0x800;
static constexpr int C_STICK_RADIUS = 0x7FF;
union { union {
BitField<0, 8, u32> header; BitField<0, 8, u32> header;

View file

@ -8,6 +8,7 @@
#include "logger.hpp" #include "logger.hpp"
#include "memory.hpp" #include "memory.hpp"
#include "result/result.hpp" #include "result/result.hpp"
#include "services/hid.hpp"
#include "services/ir/circlepad_pro.hpp" #include "services/ir/circlepad_pro.hpp"
// Circular dependencies in this project? Never // Circular dependencies in this project? Never
@ -23,6 +24,8 @@ class IRUserService {
Handle handle = KernelHandles::IR_USER; Handle handle = KernelHandles::IR_USER;
Memory& mem; Memory& mem;
Kernel& kernel; Kernel& kernel;
// The IR service has a reference to the HID service as that's where the frontends store CirclePad Pro button state in
HIDService& hid;
const EmulatorConfig& config; const EmulatorConfig& config;
MAKE_LOG_FUNCTION(log, irUserLogger) MAKE_LOG_FUNCTION(log, irUserLogger)
@ -76,11 +79,9 @@ class IRUserService {
void sendPayload(std::span<const u8> payload); void sendPayload(std::span<const u8> payload);
public: public:
IRUserService(Memory& mem, const EmulatorConfig& config, Kernel& kernel) IRUserService(Memory& mem, HIDService& hid, const EmulatorConfig& config, Kernel& kernel)
: mem(mem), config(config), kernel(kernel), cpp([&](IR::Device::Payload payload) { sendPayload(payload); }) {} : mem(mem), hid(hid), config(config), kernel(kernel), cpp([&](IR::Device::Payload payload) { sendPayload(payload); }) {}
void setZRPressed(bool pressed) { cpp.state.buttons.zrNotPressed = pressed ? 0 : 1; }
void setZLPressed(bool pressed) { cpp.state.buttons.zrNotPressed = pressed ? 0 : 1; }
void setCStickX(s16 value) { cpp.state.cStick.x = value; } void setCStickX(s16 value) { cpp.state.cStick.x = value; }
void setCStickY(s16 value) { cpp.state.cStick.y = value; } void setCStickY(s16 value) { cpp.state.cStick.y = value; }

View file

@ -1,7 +1,9 @@
#include "services/hid.hpp" #include "services/hid.hpp"
#include <bit>
#include "ipc.hpp" #include "ipc.hpp"
#include "kernel.hpp" #include "kernel.hpp"
#include <bit>
namespace HIDCommands { namespace HIDCommands {
enum : u32 { enum : u32 {
@ -36,6 +38,8 @@ void HIDService::reset() {
touchScreenX = touchScreenY = 0; touchScreenX = touchScreenY = 0;
roll = pitch = yaw = 0; roll = pitch = yaw = 0;
accelX = accelY = accelZ = 0; accelX = accelY = accelZ = 0;
cStickX = cStickY = 0;
} }
void HIDService::handleSyncRequest(u32 messagePointer) { void HIDService::handleSyncRequest(u32 messagePointer) {
@ -153,19 +157,23 @@ void HIDService::updateInputs(u64 currentTick) {
writeSharedMem<u64>(0x0, currentTick); // Write new tick count writeSharedMem<u64>(0x0, currentTick); // Write new tick count
} }
// Mask out the CirclePadPro buttons when writing to HID shared memory, since the actual OS doesn't store anything in those bits
const u32 currentButtons = newButtons & ~HID::Keys::CirclePadProButtons;
const u32 previousButtons = oldButtons & ~HID::Keys::CirclePadProButtons;
oldButtons = newButtons;
writeSharedMem<u32>(0x10, nextPadIndex); // Index last updated by the HID module writeSharedMem<u32>(0x10, nextPadIndex); // Index last updated by the HID module
writeSharedMem<u32>(0x1C, newButtons); // Current PAD state writeSharedMem<u32>(0x1C, currentButtons); // Current PAD state
writeSharedMem<s16>(0x20, circlePadX); // Current circle pad state writeSharedMem<s16>(0x20, circlePadX); // Current circle pad state
writeSharedMem<s16>(0x22, circlePadY); writeSharedMem<s16>(0x22, circlePadY);
const size_t padEntryOffset = 0x28 + (nextPadIndex * 0x10); // Offset in the array of 8 pad entries const size_t padEntryOffset = 0x28 + (nextPadIndex * 0x10); // Offset in the array of 8 pad entries
nextPadIndex = (nextPadIndex + 1) % 8; // Move to next entry nextPadIndex = (nextPadIndex + 1) % 8; // Move to next entry
const u32 pressed = (newButtons ^ oldButtons) & newButtons; // Pressed buttons const u32 pressed = (currentButtons ^ previousButtons) & currentButtons; // Pressed buttons
const u32 released = (newButtons ^ oldButtons) & oldButtons; // Released buttons const u32 released = (currentButtons ^ previousButtons) & previousButtons; // Released buttons
oldButtons = newButtons;
writeSharedMem<u32>(padEntryOffset, newButtons); writeSharedMem<u32>(padEntryOffset, currentButtons);
writeSharedMem<u32>(padEntryOffset + 4, pressed); writeSharedMem<u32>(padEntryOffset + 4, pressed);
writeSharedMem<u32>(padEntryOffset + 8, released); writeSharedMem<u32>(padEntryOffset + 8, released);
writeSharedMem<s16>(padEntryOffset + 12, circlePadX); writeSharedMem<s16>(padEntryOffset + 12, circlePadX);

View file

@ -333,7 +333,17 @@ void IRUserService::updateCirclePadPro() {
return; return;
} }
std::vector<u8> response(sizeof(cpp.state)); // The button state for the CirclePad Pro is stored in the HID service to make the frontend logic simpler
std::memcpy(response.data(), &cpp.state, sizeof(cpp.state)); // We take the button state, format it nicely into the CirclePad Pro struct, and return it
auto& cppState = cpp.state;
u32 buttons = hid.getOldButtons();
cppState.buttons.zlNotPressed = (buttons & HID::Keys::ZL) ? 0 : 1;
cppState.buttons.zrNotPressed = (buttons & HID::Keys::ZR) ? 0 : 1;
cppState.cStick.x = hid.getCStickX();
cppState.cStick.y = hid.getCStickY();
std::vector<u8> response(sizeof(cppState));
std::memcpy(response.data(), &cppState, sizeof(cppState));
sendPayload(response); sendPayload(response);
} }

View file

@ -7,7 +7,7 @@
ServiceManager::ServiceManager(std::span<u32, 16> regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel, const EmulatorConfig& config) ServiceManager::ServiceManager(std::span<u32, 16> regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel, const EmulatorConfig& config)
: regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem, kernel), cecd(mem, kernel), : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem, kernel), cecd(mem, kernel),
cfg(mem, config), csnd(mem, kernel), dlp_srvr(mem), dsp(mem, kernel, config), hid(mem, kernel), http(mem), ir_user(mem, config, kernel), cfg(mem, config), csnd(mem, kernel), dlp_srvr(mem), dsp(mem, kernel, config), hid(mem, kernel), http(mem), ir_user(mem, hid, config, kernel),
frd(mem), fs(mem, kernel, config), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem, kernel), mcu_hwc(mem, config), frd(mem), fs(mem, kernel, config), gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem, kernel), mcu_hwc(mem, config),
mic(mem, kernel), nfc(mem, kernel), nim(mem), ndm(mem), news_u(mem), ns(mem), nwm_uds(mem, kernel), ptm(mem, config), soc(mem), ssl(mem), mic(mem, kernel), nfc(mem, kernel), nim(mem), ndm(mem), news_u(mem), ns(mem), nwm_uds(mem, kernel), ptm(mem, config), soc(mem), ssl(mem),
y2r(mem, kernel) {} y2r(mem, kernel) {}

View file

@ -93,8 +93,10 @@ HttpServer::HttpServer(Emulator* emulator)
{"Left", {HID::Keys::Left}}, {"Left", {HID::Keys::Left}},
{"Up", {HID::Keys::Up}}, {"Up", {HID::Keys::Up}},
{"Down", {HID::Keys::Down}}, {"Down", {HID::Keys::Down}},
{"R", {HID::Keys::R}},
{"L", {HID::Keys::L}}, {"L", {HID::Keys::L}},
{"R", {HID::Keys::R}},
{"ZL", {HID::Keys::ZL}},
{"ZR", {HID::Keys::ZR}},
{"X", {HID::Keys::X}}, {"X", {HID::Keys::X}},
{"Y", {HID::Keys::Y}}, {"Y", {HID::Keys::Y}},
}) { }) {

View file

@ -82,6 +82,7 @@ void HydraCore::runFrame() {
hid.setKey(HID::Keys::Down, checkButtonCallback(0, hydra::ButtonType::Keypad1Down)); hid.setKey(HID::Keys::Down, checkButtonCallback(0, hydra::ButtonType::Keypad1Down));
hid.setKey(HID::Keys::Left, checkButtonCallback(0, hydra::ButtonType::Keypad1Left)); hid.setKey(HID::Keys::Left, checkButtonCallback(0, hydra::ButtonType::Keypad1Left));
hid.setKey(HID::Keys::Right, checkButtonCallback(0, hydra::ButtonType::Keypad1Right)); hid.setKey(HID::Keys::Right, checkButtonCallback(0, hydra::ButtonType::Keypad1Right));
// TODO: N3DS buttons
int x = !!checkButtonCallback(0, hydra::ButtonType::Analog1Right) - !!checkButtonCallback(0, hydra::ButtonType::Analog1Left); int x = !!checkButtonCallback(0, hydra::ButtonType::Analog1Right) - !!checkButtonCallback(0, hydra::ButtonType::Analog1Left);
int y = !!checkButtonCallback(0, hydra::ButtonType::Analog1Up) - !!checkButtonCallback(0, hydra::ButtonType::Analog1Down); int y = !!checkButtonCallback(0, hydra::ButtonType::Analog1Up) - !!checkButtonCallback(0, hydra::ButtonType::Analog1Down);

View file

@ -351,6 +351,7 @@ void retro_run() {
hid.setKey(HID::Keys::Down, getButtonState(RETRO_DEVICE_ID_JOYPAD_DOWN)); hid.setKey(HID::Keys::Down, getButtonState(RETRO_DEVICE_ID_JOYPAD_DOWN));
hid.setKey(HID::Keys::Left, getButtonState(RETRO_DEVICE_ID_JOYPAD_LEFT)); hid.setKey(HID::Keys::Left, getButtonState(RETRO_DEVICE_ID_JOYPAD_LEFT));
hid.setKey(HID::Keys::Right, getButtonState(RETRO_DEVICE_ID_JOYPAD_RIGHT)); hid.setKey(HID::Keys::Right, getButtonState(RETRO_DEVICE_ID_JOYPAD_RIGHT));
// TODO: N3DS buttons
// Get analog values for the left analog stick (Right analog stick is N3DS-only and unimplemented) // Get analog values for the left analog stick (Right analog stick is N3DS-only and unimplemented)
float xLeft = getAxisState(RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X); float xLeft = getAxisState(RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);

View file

@ -367,6 +367,8 @@ void LuaManager::initializeThunks() {
addIntConstant(HID::Keys::Right, "__ButtonRight"); addIntConstant(HID::Keys::Right, "__ButtonRight");
addIntConstant(HID::Keys::L, "__ButtonL"); addIntConstant(HID::Keys::L, "__ButtonL");
addIntConstant(HID::Keys::R, "__ButtonR"); addIntConstant(HID::Keys::R, "__ButtonR");
addIntConstant(HID::Keys::ZL, "__ButtonZL");
addIntConstant(HID::Keys::ZR, "__ButtonZR");
// Call our Lua runtime initialization before any Lua script runs // Call our Lua runtime initialization before any Lua script runs
luaL_loadstring(L, runtimeInit); luaL_loadstring(L, runtimeInit);

View file

@ -592,14 +592,18 @@ void MainWindow::initControllers() {
} }
void MainWindow::pollControllers() { void MainWindow::pollControllers() {
// Update circlepad if a controller is plugged in // Update circlepad/c-stick/ZL/ZR if a controller is plugged in
if (gameController != nullptr) { if (gameController != nullptr) {
HIDService& hid = emu->getServiceManager().getHID(); HIDService& hid = emu->getServiceManager().getHID();
const s16 stickX = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX); const s16 stickX = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX);
const s16 stickY = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY); const s16 stickY = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY);
constexpr s16 deadzone = 3276; constexpr s16 deadzone = 3276;
constexpr s16 maxValue = 0x9C; constexpr s16 triggerThreshold = SDL_JOYSTICK_AXIS_MAX / 2;
constexpr s16 div = 0x8000 / maxValue;
{
// Update circlepad
constexpr s16 circlepadMax = 0x9C;
constexpr s16 div = 0x8000 / circlepadMax;
// Avoid overriding the keyboard's circlepad input // Avoid overriding the keyboard's circlepad input
if (std::abs(stickX) < deadzone && !keyboardAnalogX) { if (std::abs(stickX) < deadzone && !keyboardAnalogX) {
@ -613,26 +617,28 @@ void MainWindow::pollControllers() {
} else { } else {
hid.setCirclepadY(-(stickY / div)); hid.setCirclepadY(-(stickY / div));
} }
}
auto& ir = emu->getServiceManager().getIRUser();
const s16 l2 = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERLEFT); const s16 l2 = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
const s16 r2 = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); const s16 r2 = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
const s16 cstickX = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTX); const s16 cstickX = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTX);
const s16 cstickY = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTY); const s16 cstickY = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTY);
ir.setZLPressed(l2 > 16000); hid.setKey(HID::Keys::ZL, l2 > triggerThreshold);
ir.setZRPressed(r2 > 16000); hid.setKey(HID::Keys::ZR, r2 > triggerThreshold);
// Update C-Stick
// To convert from SDL coordinates, ie [-32768, 32767] to [-2048, 2047] we just divide by 8
if (std::abs(cstickX) < deadzone) { if (std::abs(cstickX) < deadzone) {
ir.setCStickX(IR::CirclePadPro::ButtonState::C_STICK_CENTER); hid.setCStickX(IR::CirclePadPro::ButtonState::C_STICK_CENTER);
} else { } else {
ir.setCStickX(cstickX / 8); hid.setCStickX(cstickX / 8);
} }
if (std::abs(cstickY) < deadzone) { if (std::abs(cstickY) < deadzone) {
ir.setCStickY(IR::CirclePadPro::ButtonState::C_STICK_CENTER); hid.setCStickY(IR::CirclePadPro::ButtonState::C_STICK_CENTER);
} else { } else {
ir.setCStickY(-(cstickY / 8)); hid.setCStickY(-(cstickY / 8));
} }
} }

View file

@ -10,6 +10,8 @@ InputMappings InputMappings::defaultKeyboardMappings() {
mappings.setMapping(Qt::Key_I, HID::Keys::Y); mappings.setMapping(Qt::Key_I, HID::Keys::Y);
mappings.setMapping(Qt::Key_Q, HID::Keys::L); mappings.setMapping(Qt::Key_Q, HID::Keys::L);
mappings.setMapping(Qt::Key_P, HID::Keys::R); mappings.setMapping(Qt::Key_P, HID::Keys::R);
mappings.setMapping(Qt::Key_1, HID::Keys::ZL);
mappings.setMapping(Qt::Key_0, HID::Keys::ZR);
mappings.setMapping(Qt::Key_Up, HID::Keys::Up); mappings.setMapping(Qt::Key_Up, HID::Keys::Up);
mappings.setMapping(Qt::Key_Down, HID::Keys::Down); mappings.setMapping(Qt::Key_Down, HID::Keys::Down);
mappings.setMapping(Qt::Key_Right, HID::Keys::Right); mappings.setMapping(Qt::Key_Right, HID::Keys::Right);

View file

@ -401,27 +401,55 @@ void FrontendSDL::run() {
// Update controller analog sticks and HID service // Update controller analog sticks and HID service
if (emu.romType != ROMType::None) { if (emu.romType != ROMType::None) {
// Update circlepad/c-stick/ZL/ZR if a controller is plugged in
if (gameController != nullptr) { if (gameController != nullptr) {
const s16 stickX = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX); const s16 stickX = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX);
const s16 stickY = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY); const s16 stickY = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY);
constexpr s16 deadzone = 3276; constexpr s16 deadzone = 3276;
constexpr s16 maxValue = 0x9C; constexpr s16 triggerThreshold = SDL_JOYSTICK_AXIS_MAX / 2;
constexpr s16 div = 0x8000 / maxValue;
{
// Update circlepad
constexpr s16 circlepadMax = 0x9C;
constexpr s16 div = 0x8000 / circlepadMax;
// Avoid overriding the keyboard's circlepad input // Avoid overriding the keyboard's circlepad input
if (abs(stickX) < deadzone && !keyboardAnalogX) { if (std::abs(stickX) < deadzone && !keyboardAnalogX) {
hid.setCirclepadX(0); hid.setCirclepadX(0);
} else { } else {
hid.setCirclepadX(stickX / div); hid.setCirclepadX(stickX / div);
} }
if (abs(stickY) < deadzone && !keyboardAnalogY) { if (std::abs(stickY) < deadzone && !keyboardAnalogY) {
hid.setCirclepadY(0); hid.setCirclepadY(0);
} else { } else {
hid.setCirclepadY(-(stickY / div)); hid.setCirclepadY(-(stickY / div));
} }
} }
const s16 l2 = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
const s16 r2 = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
const s16 cstickX = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTX);
const s16 cstickY = SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTY);
hid.setKey(HID::Keys::ZL, l2 > triggerThreshold);
hid.setKey(HID::Keys::ZR, r2 > triggerThreshold);
// Update C-Stick
// To convert from SDL coordinates, ie [-32768, 32767] to [-2048, 2047] we just divide by 8
if (std::abs(cstickX) < deadzone) {
hid.setCStickX(IR::CirclePadPro::ButtonState::C_STICK_CENTER);
} else {
hid.setCStickX(cstickX / 8);
}
if (std::abs(cstickY) < deadzone) {
hid.setCStickY(IR::CirclePadPro::ButtonState::C_STICK_CENTER);
} else {
hid.setCStickY(-(cstickY / 8));
}
}
hid.updateInputs(emu.getTicks()); hid.updateInputs(emu.getTicks());
} }
// TODO: Should this be uncommented? // TODO: Should this be uncommented?

View file

@ -10,6 +10,8 @@ InputMappings InputMappings::defaultKeyboardMappings() {
mappings.setMapping(SDLK_i, HID::Keys::Y); mappings.setMapping(SDLK_i, HID::Keys::Y);
mappings.setMapping(SDLK_q, HID::Keys::L); mappings.setMapping(SDLK_q, HID::Keys::L);
mappings.setMapping(SDLK_p, HID::Keys::R); mappings.setMapping(SDLK_p, HID::Keys::R);
mappings.setMapping(SDLK_1, HID::Keys::ZL);
mappings.setMapping(SDLK_0, HID::Keys::ZR);
mappings.setMapping(SDLK_UP, HID::Keys::Up); mappings.setMapping(SDLK_UP, HID::Keys::Up);
mappings.setMapping(SDLK_DOWN, HID::Keys::Down); mappings.setMapping(SDLK_DOWN, HID::Keys::Down);
mappings.setMapping(SDLK_RIGHT, HID::Keys::Right); mappings.setMapping(SDLK_RIGHT, HID::Keys::Right);