From 1a33d4cb73c4aa70574b6fa322bc7bb4391f7114 Mon Sep 17 00:00:00 2001 From: JustawayOfTheSamurai <38185583+cclark25@users.noreply.github.com> Date: Thu, 13 Jun 2024 21:58:59 -0400 Subject: [PATCH 1/6] Added initial basic support for intent-based controls. --- include/libultraship/libultra/controller.h | 13 +++ src/Context.cpp | 25 +++++- src/Context.h | 2 +- src/controller/controldeck/ControlDeck.cpp | 6 +- src/controller/controldeck/ControlDeck.h | 2 +- .../controldevice/controller/Controller.cpp | 43 ++++++++-- .../controldevice/controller/Controller.h | 7 +- .../controller/ControllerButton.cpp | 12 +-- .../controller/ControllerButton.h | 8 +- .../mapping/ControllerButtonMapping.cpp | 4 +- .../mapping/ControllerButtonMapping.h | 4 +- .../factories/ButtonMappingFactory.cpp | 84 ++++++++++--------- .../mapping/factories/ButtonMappingFactory.h | 4 +- .../keyboard/KeyboardKeyToButtonMapping.cpp | 6 +- .../keyboard/KeyboardKeyToButtonMapping.h | 2 +- .../sdl/SDLAxisDirectionToButtonMapping.cpp | 4 +- .../sdl/SDLAxisDirectionToButtonMapping.h | 2 +- .../mapping/sdl/SDLButtonToButtonMapping.cpp | 10 ++- .../mapping/sdl/SDLButtonToButtonMapping.h | 2 +- src/public/libultra/os.cpp | 2 + src/window/gui/InputEditorWindow.cpp | 52 +++++++----- src/window/gui/InputEditorWindow.h | 6 +- 22 files changed, 196 insertions(+), 104 deletions(-) diff --git a/include/libultraship/libultra/controller.h b/include/libultraship/libultra/controller.h index 3a985f331..342c43ae4 100644 --- a/include/libultraship/libultra/controller.h +++ b/include/libultraship/libultra/controller.h @@ -120,6 +120,16 @@ typedef struct { /* 0x03 */ uint8_t err_no; } OSContStatus; // size = 0x04 +typedef struct IntentControls IntentControls; +struct IntentControls { + uint8_t (*checkIntentButton)(uint16_t intentId); + void(*registerButtonState)(uint16_t specialButtonId, uint8_t); + void(*updateCurState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); + void(*updatePrevState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); + void(*updatePressState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); + void(*updateRelState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); +}; + typedef struct { /* 0x00 */ CONTROLLERBUTTONS_T button; /* 0x02 */ int8_t stick_x; @@ -129,8 +139,11 @@ typedef struct { /* 0x09 */ float gyro_y; /* 0x1C */ int8_t right_stick_x; /* 0x20 */ int8_t right_stick_y; + IntentControls* intentControls; } OSContPad; // size = 0x24 +#define GET_INTENTS(pad, f, default) (pad->intentControls == NULL ? default : pad->intentControls->f) + typedef struct { /* 0x00 */ void* address; /* 0x04 */ uint8_t databuffer[32]; diff --git a/src/Context.cpp b/src/Context.cpp index db7542329..7ac668478 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -7,6 +7,7 @@ #include "install_config.h" #include "debug/GfxDebugger.h" #include "graphic/Fast3D/Fast3dWindow.h" +#include #ifdef _WIN32 #include @@ -80,7 +81,25 @@ void Context::Init(const std::vector& otrFiles, const std::unordere InitConfiguration(); InitConsoleVariables(); InitResourceManager(otrFiles, validHashes, reservedThreadCount); - InitControlDeck(); + IntentControls* intentControls = new IntentControls; + static std::map* buttonStates = new std::map(); + intentControls->checkIntentButton = +[](uint16_t intentId){ + buttonStates->try_emplace(intentId, 0); + return buttonStates->at(intentId); + }; + intentControls->registerButtonState = [](uint16_t intentId, uint8_t pressed){ + buttonStates->insert_or_assign(intentId, pressed); + }; + intentControls->updateCurState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; + intentControls->updatePrevState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; + intentControls->updatePressState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; + intentControls->updateRelState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; + + InitControlDeck({}, intentControls, { + 1, + 2, + 3 + }); InitCrashHandler(); InitConsole(); InitWindow(); @@ -211,12 +230,12 @@ void Context::InitResourceManager(const std::vector& otrFiles, } } -void Context::InitControlDeck(std::vector additionalBitmasks) { +void Context::InitControlDeck(std::vector additionalBitmasks, IntentControls* intentControls, std::vector specialControls) { if (GetControlDeck() != nullptr) { return; } - mControlDeck = std::make_shared(additionalBitmasks); + mControlDeck = std::make_shared(additionalBitmasks, intentControls, specialControls); } void Context::InitCrashHandler() { diff --git a/src/Context.h b/src/Context.h index d93c34b9e..0c94b2f05 100644 --- a/src/Context.h +++ b/src/Context.h @@ -63,7 +63,7 @@ class Context { void InitConsoleVariables(); void InitResourceManager(const std::vector& otrFiles = {}, const std::unordered_set& validHashes = {}, uint32_t reservedThreadCount = 1); - void InitControlDeck(std::vector additionalBitmasks = {}); + void InitControlDeck(std::vector additionalBitmasks = {}, IntentControls* intentControls = nullptr, std::vector specialControls = {}); void InitCrashHandler(); void InitAudio(); void InitGfxDebugger(); diff --git a/src/controller/controldeck/ControlDeck.cpp b/src/controller/controldeck/ControlDeck.cpp index 2f097be4b..d8336d16b 100644 --- a/src/controller/controldeck/ControlDeck.cpp +++ b/src/controller/controldeck/ControlDeck.cpp @@ -12,16 +12,16 @@ namespace Ship { -ControlDeck::ControlDeck(std::vector additionalBitmasks) +ControlDeck::ControlDeck(std::vector additionalBitmasks, IntentControls* intentControls, std::vector specialButtons) : mPads(nullptr), mSinglePlayerMappingMode(false) { for (int32_t i = 0; i < MAXCONTROLLERS; i++) { - mPorts.push_back(std::make_shared(i, std::make_shared(i, additionalBitmasks))); + mPorts.push_back(std::make_shared(i, std::make_shared(i, additionalBitmasks, intentControls, specialButtons))); } mDeviceIndexMappingManager = std::make_shared(); } -ControlDeck::ControlDeck() : ControlDeck(std::vector()) { +ControlDeck::ControlDeck() : ControlDeck(std::vector(), nullptr, std::vector()) { } ControlDeck::~ControlDeck() { diff --git a/src/controller/controldeck/ControlDeck.h b/src/controller/controldeck/ControlDeck.h index eacf42f5a..cf086fda5 100644 --- a/src/controller/controldeck/ControlDeck.h +++ b/src/controller/controldeck/ControlDeck.h @@ -11,7 +11,7 @@ namespace Ship { class ControlDeck { public: ControlDeck(); - ControlDeck(std::vector additionalBitmasks); + ControlDeck(std::vector additionalBitmasks, IntentControls* intentControls, std::vector intentButtons); ~ControlDeck(); void Init(uint8_t* controllerBits); diff --git a/src/controller/controldevice/controller/Controller.cpp b/src/controller/controldevice/controller/Controller.cpp index acc6961bd..3e4afbb91 100644 --- a/src/controller/controldevice/controller/Controller.cpp +++ b/src/controller/controldevice/controller/Controller.cpp @@ -10,18 +10,28 @@ #include #include "utils/StringHelper.h" +// TODO: move this around better +typedef struct { + bool eventRollEnabled; + bool eventInteractEnabled; +} DefaultStorage; +extern DefaultStorage eventControlStorage; + #define M_TAU 6.2831853071795864769252867665590057 // 2 * pi #define MINIMUM_RADIUS_TO_MAP_NOTCH 0.9 namespace Ship { -Controller::Controller(uint8_t portIndex, std::vector additionalBitmasks) - : ControlDevice(portIndex) { +Controller::Controller(uint8_t portIndex, std::vector additionalBitmasks, IntentControls* intentControls, std::vector specialButtons) + : ControlDevice(portIndex), intentControls(intentControls) { for (auto bitmask : { BUTTON_BITMASKS }) { - mButtons[bitmask] = std::make_shared(portIndex, bitmask); + mButtons[bitmask] = std::make_shared(portIndex, bitmask, nullptr, 0); } for (auto bitmask : additionalBitmasks) { - mButtons[bitmask] = std::make_shared(portIndex, bitmask); + mButtons[bitmask] = std::make_shared(portIndex, bitmask, nullptr, 0); + } + for (auto button : specialButtons) { + mSpecialButtons[button] = std::make_shared(portIndex, 0, intentControls, button); } mLeftStick = std::make_shared(portIndex, LEFT_STICK); mRightStick = std::make_shared(portIndex, RIGHT_STICK); @@ -30,7 +40,7 @@ Controller::Controller(uint8_t portIndex, std::vector addit mLED = std::make_shared(portIndex); } -Controller::Controller(uint8_t portIndex) : Controller(portIndex, {}) { +Controller::Controller(uint8_t portIndex) : Controller(portIndex, {}, nullptr, {}) { } Controller::~Controller() { @@ -40,9 +50,15 @@ Controller::~Controller() { std::unordered_map> Controller::GetAllButtons() { return mButtons; } +std::unordered_map> Controller::GetAllSpecialButtons() { + return mSpecialButtons; +} -std::shared_ptr Controller::GetButton(CONTROLLERBUTTONS_T bitmask) { - return mButtons[bitmask]; +std::shared_ptr Controller::GetButton(CONTROLLERBUTTONS_T bitmask, uint16_t specialButton) { + if(bitmask != 0){ + return mButtons[bitmask]; + } + return mSpecialButtons[specialButton]; } std::shared_ptr Controller::GetLeftStick() { @@ -133,6 +149,18 @@ void Controller::ReadToPad(OSContPad* pad) { for (auto [bitmask, button] : mButtons) { button->UpdatePad(padToBuffer.button); } + + padToBuffer.intentControls = intentControls; + + for (auto [specialButton, button] : mSpecialButtons) { + button->UpdatePad(padToBuffer.button); + uint8_t pressed = 0; + for (auto m : button->GetAllButtonMappings()){ + if(specialButton > 0 && padToBuffer.intentControls != NULL && padToBuffer.intentControls->registerButtonState != NULL){ + padToBuffer.intentControls->registerButtonState(specialButton, m.second->pressed); + } + } + } // Stick Inputs GetLeftStick()->UpdatePad(padToBuffer.stick_x, padToBuffer.stick_y); @@ -147,6 +175,7 @@ void Controller::ReadToPad(OSContPad* pad) { mPadBuffer[std::min(mPadBuffer.size() - 1, (size_t)CVarGetInteger(CVAR_SIMULATED_INPUT_LAG, 0))]; pad->button |= padFromBuffer.button; + pad->intentControls = padToBuffer.intentControls; if (pad->stick_x == 0) { pad->stick_x = padFromBuffer.stick_x; diff --git a/src/controller/controldevice/controller/Controller.h b/src/controller/controldevice/controller/Controller.h index c0cf0ab1f..d5fe0defe 100644 --- a/src/controller/controldevice/controller/Controller.h +++ b/src/controller/controldevice/controller/Controller.h @@ -23,7 +23,7 @@ namespace Ship { class Controller : public ControlDevice { public: Controller(uint8_t portIndex); - Controller(uint8_t portIndex, std::vector additionalBitmasks); + Controller(uint8_t portIndex, std::vector additionalBitmasks, IntentControls* intentControls, std::vector specialButtons); ~Controller(); void ReloadAllMappingsFromConfig(); @@ -36,8 +36,9 @@ class Controller : public ControlDevice { void ClearAllMappingsForDevice(ShipDeviceIndex shipDeviceIndex); void AddDefaultMappings(ShipDeviceIndex shipDeviceIndex); std::unordered_map> GetAllButtons(); + std::unordered_map> GetAllSpecialButtons(); std::shared_ptr GetButtonByBitmask(CONTROLLERBUTTONS_T bitmask); - std::shared_ptr GetButton(CONTROLLERBUTTONS_T bitmask); + std::shared_ptr GetButton(CONTROLLERBUTTONS_T bitmask, uint16_t specialButton); std::shared_ptr GetLeftStick(); std::shared_ptr GetRightStick(); std::shared_ptr GetGyro(); @@ -58,6 +59,8 @@ class Controller : public ControlDevice { void SaveButtonMappingIdsToConfig(); std::unordered_map> mButtons; + std::unordered_map> mSpecialButtons; + IntentControls* intentControls; std::shared_ptr mLeftStick, mRightStick; std::shared_ptr mGyro; std::shared_ptr mRumble; diff --git a/src/controller/controldevice/controller/ControllerButton.cpp b/src/controller/controldevice/controller/ControllerButton.cpp index b5c356a59..0958e108b 100644 --- a/src/controller/controldevice/controller/ControllerButton.cpp +++ b/src/controller/controldevice/controller/ControllerButton.cpp @@ -10,9 +10,9 @@ #include namespace Ship { -ControllerButton::ControllerButton(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask) +ControllerButton::ControllerButton(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, IntentControls* intentControls, uint16_t specialButtonId) : mPortIndex(portIndex), mBitmask(bitmask), mUseKeydownEventToCreateNewMapping(false), - mKeyboardScancodeForNewMapping(LUS_KB_UNKNOWN) { + mKeyboardScancodeForNewMapping(LUS_KB_UNKNOWN), mSpecialButtonId(specialButtonId), intentControls(intentControls) { } ControllerButton::~ControllerButton() { @@ -172,16 +172,16 @@ bool ControllerButton::HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex) { [lusIndex](const auto& mapping) { return mapping.second->GetShipDeviceIndex() == lusIndex; }); } -bool ControllerButton::AddOrEditButtonMappingFromRawPress(CONTROLLERBUTTONS_T bitmask, std::string id) { +bool ControllerButton::AddOrEditButtonMappingFromRawPress(CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, std::string id) { std::shared_ptr mapping = nullptr; mUseKeydownEventToCreateNewMapping = true; if (mKeyboardScancodeForNewMapping != LUS_KB_UNKNOWN) { - mapping = std::make_shared(mPortIndex, bitmask, mKeyboardScancodeForNewMapping); + mapping = std::make_shared(mPortIndex, bitmask, specialButton, mKeyboardScancodeForNewMapping); } if (mapping == nullptr) { - mapping = ButtonMappingFactory::CreateButtonMappingFromSDLInput(mPortIndex, bitmask); + mapping = ButtonMappingFactory::CreateButtonMappingFromSDLInput(mPortIndex, bitmask, specialButton); } if (mapping == nullptr) { @@ -225,7 +225,7 @@ bool ControllerButton::ProcessKeyboardEvent(Ship::KbEventType eventType, Ship::K } void ControllerButton::AddDefaultMappings(ShipDeviceIndex shipDeviceIndex) { - for (auto mapping : ButtonMappingFactory::CreateDefaultSDLButtonMappings(shipDeviceIndex, mPortIndex, mBitmask)) { + for (auto mapping : ButtonMappingFactory::CreateDefaultSDLButtonMappings(shipDeviceIndex, mPortIndex, mBitmask, mSpecialButtonId)) { AddButtonMapping(mapping); } diff --git a/src/controller/controldevice/controller/ControllerButton.h b/src/controller/controldevice/controller/ControllerButton.h index b6ecb535e..754ec9332 100644 --- a/src/controller/controldevice/controller/ControllerButton.h +++ b/src/controller/controldevice/controller/ControllerButton.h @@ -15,7 +15,7 @@ namespace Ship { class ControllerButton { public: - ControllerButton(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask); + ControllerButton(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, IntentControls* intentControls, uint16_t specialButtonId); ~ControllerButton(); std::shared_ptr GetButtonMappingById(std::string id); @@ -32,7 +32,7 @@ class ControllerButton { void ClearAllButtonMappings(); void ClearAllButtonMappingsForDevice(ShipDeviceIndex shipDeviceIndex); - bool AddOrEditButtonMappingFromRawPress(CONTROLLERBUTTONS_T bitmask, std::string id); + bool AddOrEditButtonMappingFromRawPress(CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, std::string id); void UpdatePad(CONTROLLERBUTTONS_T& padButtons); @@ -40,9 +40,11 @@ class ControllerButton { bool HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex); + uint16_t mSpecialButtonId; + CONTROLLERBUTTONS_T mBitmask; + IntentControls* intentControls; private: uint8_t mPortIndex; - CONTROLLERBUTTONS_T mBitmask; std::unordered_map> mButtonMappings; std::string GetConfigNameFromBitmask(CONTROLLERBUTTONS_T bitmask); diff --git a/src/controller/controldevice/controller/mapping/ControllerButtonMapping.cpp b/src/controller/controldevice/controller/mapping/ControllerButtonMapping.cpp index 2362fb6c0..887748f9e 100644 --- a/src/controller/controldevice/controller/mapping/ControllerButtonMapping.cpp +++ b/src/controller/controldevice/controller/mapping/ControllerButtonMapping.cpp @@ -7,8 +7,8 @@ namespace Ship { ControllerButtonMapping::ControllerButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, - CONTROLLERBUTTONS_T bitmask) - : ControllerInputMapping(shipDeviceIndex), mPortIndex(portIndex), mBitmask(bitmask) { + CONTROLLERBUTTONS_T bitmask, uint16_t specialButton) + : ControllerInputMapping(shipDeviceIndex), mPortIndex(portIndex), mBitmask(bitmask), mSpecialButton(specialButton) { } ControllerButtonMapping::~ControllerButtonMapping() { diff --git a/src/controller/controldevice/controller/mapping/ControllerButtonMapping.h b/src/controller/controldevice/controller/mapping/ControllerButtonMapping.h index b4e57b92b..27363d555 100644 --- a/src/controller/controldevice/controller/mapping/ControllerButtonMapping.h +++ b/src/controller/controldevice/controller/mapping/ControllerButtonMapping.h @@ -13,7 +13,7 @@ namespace Ship { class ControllerButtonMapping : virtual public ControllerInputMapping { public: - ControllerButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask); + ControllerButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton); ~ControllerButtonMapping(); virtual std::string GetButtonMappingId() = 0; @@ -26,8 +26,10 @@ class ControllerButtonMapping : virtual public ControllerInputMapping { virtual void SaveToConfig() = 0; virtual void EraseFromConfig() = 0; + uint8_t pressed = 0; protected: uint8_t mPortIndex; + uint16_t mSpecialButton; CONTROLLERBUTTONS_T mBitmask; }; } // namespace Ship diff --git a/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp b/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp index 3386e52e4..97346b5a6 100644 --- a/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp +++ b/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp @@ -16,7 +16,9 @@ std::shared_ptr ButtonMappingFactory::CreateButtonMappi CVarGetString(StringHelper::Sprintf("%s.ButtonMappingClass", mappingCvarKey.c_str()).c_str(), ""); CONTROLLERBUTTONS_T bitmask = CVarGetInteger(StringHelper::Sprintf("%s.Bitmask", mappingCvarKey.c_str()).c_str(), 0); - if (!bitmask) { + CONTROLLERBUTTONS_T specialButton = + CVarGetInteger(StringHelper::Sprintf("%s.SpecialButton", mappingCvarKey.c_str()).c_str(), 0); + if (!bitmask && ! specialButton) { // all button mappings need bitmasks CVarClear(mappingCvarKey.c_str()); CVarSave(); @@ -37,7 +39,7 @@ std::shared_ptr ButtonMappingFactory::CreateButtonMappi } return std::make_shared(static_cast(shipDeviceIndex), portIndex, - bitmask, sdlControllerButton); + bitmask, specialButton, sdlControllerButton); } if (mappingClass == "SDLAxisDirectionToButtonMapping") { @@ -56,14 +58,14 @@ std::shared_ptr ButtonMappingFactory::CreateButtonMappi } return std::make_shared(static_cast(shipDeviceIndex), - portIndex, bitmask, sdlControllerAxis, axisDirection); + portIndex, bitmask, specialButton, sdlControllerAxis, axisDirection); } if (mappingClass == "KeyboardKeyToButtonMapping") { int32_t scancode = CVarGetInteger(StringHelper::Sprintf("%s.KeyboardScancode", mappingCvarKey.c_str()).c_str(), 0); - return std::make_shared(portIndex, bitmask, static_cast(scancode)); + return std::make_shared(portIndex, bitmask, specialButton, static_cast(scancode)); } return nullptr; @@ -75,54 +77,54 @@ ButtonMappingFactory::CreateDefaultKeyboardButtonMappings(uint8_t portIndex, CON switch (bitmask) { case BTN_A: - mappings.push_back(std::make_shared(portIndex, BTN_A, KbScancode::LUS_KB_X)); + mappings.push_back(std::make_shared(portIndex, BTN_A, 0, KbScancode::LUS_KB_X)); break; case BTN_B: - mappings.push_back(std::make_shared(portIndex, BTN_B, KbScancode::LUS_KB_C)); + mappings.push_back(std::make_shared(portIndex, BTN_B, 0, KbScancode::LUS_KB_C)); break; case BTN_L: - mappings.push_back(std::make_shared(portIndex, BTN_L, KbScancode::LUS_KB_E)); + mappings.push_back(std::make_shared(portIndex, BTN_L, 0, KbScancode::LUS_KB_E)); break; case BTN_R: - mappings.push_back(std::make_shared(portIndex, BTN_R, KbScancode::LUS_KB_R)); + mappings.push_back(std::make_shared(portIndex, BTN_R, 0, KbScancode::LUS_KB_R)); break; case BTN_Z: - mappings.push_back(std::make_shared(portIndex, BTN_Z, KbScancode::LUS_KB_Z)); + mappings.push_back(std::make_shared(portIndex, BTN_Z, 0, KbScancode::LUS_KB_Z)); break; case BTN_START: mappings.push_back( - std::make_shared(portIndex, BTN_START, KbScancode::LUS_KB_SPACE)); + std::make_shared(portIndex, BTN_START, 0, KbScancode::LUS_KB_SPACE)); break; case BTN_CUP: mappings.push_back( - std::make_shared(portIndex, BTN_CUP, KbScancode::LUS_KB_ARROWKEY_UP)); + std::make_shared(portIndex, BTN_CUP, 0, KbScancode::LUS_KB_ARROWKEY_UP)); break; case BTN_CDOWN: mappings.push_back( - std::make_shared(portIndex, BTN_CDOWN, KbScancode::LUS_KB_ARROWKEY_DOWN)); + std::make_shared(portIndex, BTN_CDOWN, 0, KbScancode::LUS_KB_ARROWKEY_DOWN)); break; case BTN_CLEFT: mappings.push_back( - std::make_shared(portIndex, BTN_CLEFT, KbScancode::LUS_KB_ARROWKEY_LEFT)); + std::make_shared(portIndex, BTN_CLEFT, 0, KbScancode::LUS_KB_ARROWKEY_LEFT)); break; case BTN_CRIGHT: mappings.push_back( - std::make_shared(portIndex, BTN_CRIGHT, KbScancode::LUS_KB_ARROWKEY_RIGHT)); + std::make_shared(portIndex, BTN_CRIGHT, 0, KbScancode::LUS_KB_ARROWKEY_RIGHT)); break; case BTN_DUP: - mappings.push_back(std::make_shared(portIndex, BTN_DUP, KbScancode::LUS_KB_T)); + mappings.push_back(std::make_shared(portIndex, BTN_DUP, 0, KbScancode::LUS_KB_T)); break; case BTN_DDOWN: mappings.push_back( - std::make_shared(portIndex, BTN_DDOWN, KbScancode::LUS_KB_G)); + std::make_shared(portIndex, BTN_DDOWN, 0, KbScancode::LUS_KB_G)); break; case BTN_DLEFT: mappings.push_back( - std::make_shared(portIndex, BTN_DLEFT, KbScancode::LUS_KB_F)); + std::make_shared(portIndex, BTN_DLEFT, 0, KbScancode::LUS_KB_F)); break; case BTN_DRIGHT: mappings.push_back( - std::make_shared(portIndex, BTN_DRIGHT, KbScancode::LUS_KB_H)); + std::make_shared(portIndex, BTN_DRIGHT, 0, KbScancode::LUS_KB_H)); break; } @@ -131,7 +133,7 @@ ButtonMappingFactory::CreateDefaultKeyboardButtonMappings(uint8_t portIndex, CON std::vector> ButtonMappingFactory::CreateDefaultSDLButtonMappings(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, - CONTROLLERBUTTONS_T bitmask) { + CONTROLLERBUTTONS_T bitmask, uint16_t specialButton) { std::vector> mappings; auto sdlIndexMapping = std::dynamic_pointer_cast( @@ -148,81 +150,85 @@ ButtonMappingFactory::CreateDefaultSDLButtonMappings(ShipDeviceIndex shipDeviceI switch (bitmask) { case BTN_A: mappings.push_back( - std::make_shared(shipDeviceIndex, portIndex, BTN_A, SDL_CONTROLLER_BUTTON_A)); + std::make_shared(shipDeviceIndex, portIndex, BTN_A, 0, SDL_CONTROLLER_BUTTON_A)); break; case BTN_B: mappings.push_back( - std::make_shared(shipDeviceIndex, portIndex, BTN_B, SDL_CONTROLLER_BUTTON_B)); + std::make_shared(shipDeviceIndex, portIndex, BTN_B, 0, SDL_CONTROLLER_BUTTON_B)); break; case BTN_L: if (!isGameCube) { - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_L, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_L, 0, SDL_CONTROLLER_BUTTON_LEFTSHOULDER)); } break; case BTN_R: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_R, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_R, 0, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 1)); break; case BTN_Z: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_Z, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_Z, 0, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 1)); break; case BTN_START: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_START, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_START, 0, SDL_CONTROLLER_BUTTON_START)); break; case BTN_CUP: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CUP, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CUP, 0, SDL_CONTROLLER_AXIS_RIGHTY, -1)); break; case BTN_CDOWN: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CDOWN, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CDOWN, 0, SDL_CONTROLLER_AXIS_RIGHTY, 1)); if (isGameCube) { - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CDOWN, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CDOWN, 0, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)); } break; case BTN_CLEFT: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CLEFT, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CLEFT, 0, SDL_CONTROLLER_AXIS_RIGHTX, -1)); if (isGameCube) { - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CLEFT, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CLEFT, 0, SDL_CONTROLLER_BUTTON_Y)); } break; case BTN_CRIGHT: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CRIGHT, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CRIGHT, 0, SDL_CONTROLLER_AXIS_RIGHTX, 1)); if (isGameCube) { - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CRIGHT, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_CRIGHT, 0, SDL_CONTROLLER_BUTTON_X)); } break; case BTN_DUP: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DUP, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DUP, 0, SDL_CONTROLLER_BUTTON_DPAD_UP)); break; case BTN_DDOWN: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DDOWN, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DDOWN, 0, SDL_CONTROLLER_BUTTON_DPAD_DOWN)); break; case BTN_DLEFT: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DLEFT, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DLEFT, 0, SDL_CONTROLLER_BUTTON_DPAD_LEFT)); break; case BTN_DRIGHT: - mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DRIGHT, + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, BTN_DRIGHT, 0, SDL_CONTROLLER_BUTTON_DPAD_RIGHT)); break; + default: + mappings.push_back(std::make_shared(shipDeviceIndex, portIndex, 0, specialButton, + SDL_CONTROLLER_BUTTON_INVALID)); + break; } return mappings; } std::shared_ptr -ButtonMappingFactory::CreateButtonMappingFromSDLInput(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask) { +ButtonMappingFactory::CreateButtonMappingFromSDLInput(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton) { std::unordered_map sdlControllers; std::shared_ptr mapping = nullptr; for (auto [lusIndex, indexMapping] : @@ -247,7 +253,7 @@ ButtonMappingFactory::CreateButtonMappingFromSDLInput(uint8_t portIndex, CONTROL for (auto [lusIndex, controller] : sdlControllers) { for (int32_t button = SDL_CONTROLLER_BUTTON_A; button < SDL_CONTROLLER_BUTTON_MAX; button++) { if (SDL_GameControllerGetButton(controller, static_cast(button))) { - mapping = std::make_shared(lusIndex, portIndex, bitmask, button); + mapping = std::make_shared(lusIndex, portIndex, bitmask, specialButton, button); break; } } @@ -271,7 +277,7 @@ ButtonMappingFactory::CreateButtonMappingFromSDLInput(uint8_t portIndex, CONTROL } mapping = - std::make_shared(lusIndex, portIndex, bitmask, axis, axisDirection); + std::make_shared(lusIndex, portIndex, bitmask, specialButton, axis, axisDirection); break; } } diff --git a/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.h b/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.h index 1a11b3312..cfc9dfe3c 100644 --- a/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.h +++ b/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.h @@ -14,9 +14,9 @@ class ButtonMappingFactory { CreateDefaultKeyboardButtonMappings(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask); static std::vector> - CreateDefaultSDLButtonMappings(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask); + CreateDefaultSDLButtonMappings(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton); static std::shared_ptr CreateButtonMappingFromSDLInput(uint8_t portIndex, - CONTROLLERBUTTONS_T bitmask); + CONTROLLERBUTTONS_T bitmask, uint16_t specialButton); }; } // namespace Ship diff --git a/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp b/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp index 9487e8580..e1b20770b 100644 --- a/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp +++ b/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp @@ -5,10 +5,10 @@ #include "Context.h" namespace Ship { -KeyboardKeyToButtonMapping::KeyboardKeyToButtonMapping(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, +KeyboardKeyToButtonMapping::KeyboardKeyToButtonMapping(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, KbScancode scancode) : ControllerInputMapping(ShipDeviceIndex::Keyboard), - ControllerButtonMapping(ShipDeviceIndex::Keyboard, portIndex, bitmask), KeyboardKeyToAnyMapping(scancode) { + ControllerButtonMapping(ShipDeviceIndex::Keyboard, portIndex, bitmask, specialButton), KeyboardKeyToAnyMapping(scancode) { } void KeyboardKeyToButtonMapping::UpdatePad(CONTROLLERBUTTONS_T& padButtons) { @@ -16,6 +16,8 @@ void KeyboardKeyToButtonMapping::UpdatePad(CONTROLLERBUTTONS_T& padButtons) { return; } + this->pressed = mKeyPressed; + if (!mKeyPressed) { return; } diff --git a/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.h b/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.h index 81128c75a..2e6124a34 100644 --- a/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.h +++ b/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.h @@ -4,7 +4,7 @@ namespace Ship { class KeyboardKeyToButtonMapping final : public KeyboardKeyToAnyMapping, public ControllerButtonMapping { public: - KeyboardKeyToButtonMapping(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, KbScancode scancode); + KeyboardKeyToButtonMapping(uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, KbScancode scancode); void UpdatePad(CONTROLLERBUTTONS_T& padButtons) override; uint8_t GetMappingType() override; std::string GetButtonMappingId() override; diff --git a/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.cpp b/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.cpp index 2d9219a90..0c04b6807 100644 --- a/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.cpp +++ b/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.cpp @@ -7,9 +7,9 @@ namespace Ship { SDLAxisDirectionToButtonMapping::SDLAxisDirectionToButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, - CONTROLLERBUTTONS_T bitmask, int32_t sdlControllerAxis, + CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, int32_t sdlControllerAxis, int32_t axisDirection) - : ControllerInputMapping(shipDeviceIndex), ControllerButtonMapping(shipDeviceIndex, portIndex, bitmask), + : ControllerInputMapping(shipDeviceIndex), ControllerButtonMapping(shipDeviceIndex, portIndex, bitmask, specialButton), SDLAxisDirectionToAnyMapping(shipDeviceIndex, sdlControllerAxis, axisDirection) { } diff --git a/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h b/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h index 6b4590025..77cce4401 100644 --- a/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h +++ b/src/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h @@ -4,7 +4,7 @@ namespace Ship { class SDLAxisDirectionToButtonMapping final : public ControllerButtonMapping, public SDLAxisDirectionToAnyMapping { public: - SDLAxisDirectionToButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, + SDLAxisDirectionToButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, int32_t sdlControllerAxis, int32_t axisDirection); void UpdatePad(CONTROLLERBUTTONS_T& padButtons) override; uint8_t GetMappingType() override; diff --git a/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp b/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp index d6cc84a6b..eb61d2521 100644 --- a/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp +++ b/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp @@ -4,11 +4,12 @@ #include "window/gui/IconsFontAwesome4.h" #include "public/bridge/consolevariablebridge.h" #include "Context.h" +#include namespace Ship { SDLButtonToButtonMapping::SDLButtonToButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, - CONTROLLERBUTTONS_T bitmask, int32_t sdlControllerButton) - : ControllerInputMapping(shipDeviceIndex), ControllerButtonMapping(shipDeviceIndex, portIndex, bitmask), + CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, int32_t sdlControllerButton) + : ControllerInputMapping(shipDeviceIndex), ControllerButtonMapping(shipDeviceIndex, portIndex, bitmask, specialButton), SDLButtonToAnyMapping(shipDeviceIndex, sdlControllerButton) { } @@ -21,7 +22,8 @@ void SDLButtonToButtonMapping::UpdatePad(CONTROLLERBUTTONS_T& padButtons) { return; } - if (SDL_GameControllerGetButton(mController, mControllerButton)) { + this->pressed = SDL_GameControllerGetButton(mController, mControllerButton); + if (this->pressed) { padButtons |= mBitmask; } } @@ -31,7 +33,7 @@ uint8_t SDLButtonToButtonMapping::GetMappingType() { } std::string SDLButtonToButtonMapping::GetButtonMappingId() { - return StringHelper::Sprintf("P%d-B%d-LUSI%d-SDLB%d", mPortIndex, mBitmask, + return StringHelper::Sprintf("P%d-B%d-S%d-LUSI%d-SDLB%d", mPortIndex, mBitmask, mSpecialButton, ControllerInputMapping::mShipDeviceIndex, mControllerButton); } diff --git a/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.h b/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.h index d31941496..a33a2d641 100644 --- a/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.h +++ b/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.h @@ -4,7 +4,7 @@ namespace Ship { class SDLButtonToButtonMapping final : public SDLButtonToAnyMapping, public ControllerButtonMapping { public: - SDLButtonToButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, + SDLButtonToButtonMapping(ShipDeviceIndex shipDeviceIndex, uint8_t portIndex, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, int32_t sdlControllerButton); void UpdatePad(CONTROLLERBUTTONS_T& padButtons) override; uint8_t GetMappingType() override; diff --git a/src/public/libultra/os.cpp b/src/public/libultra/os.cpp index a71a72825..cbd0438f6 100644 --- a/src/public/libultra/os.cpp +++ b/src/public/libultra/os.cpp @@ -37,7 +37,9 @@ int32_t osContStartReadData(OSMesgQueue* mesg) { } void osContGetReadData(OSContPad* pad) { + IntentControls* intentControls = pad->intentControls; memset(pad, 0, sizeof(OSContPad) * __osMaxControllers); + pad->intentControls = intentControls; Ship::Context::GetInstance()->GetControlDeck()->WriteToPad(pad); } diff --git a/src/window/gui/InputEditorWindow.cpp b/src/window/gui/InputEditorWindow.cpp index 1c1b17527..3a8be3ace 100644 --- a/src/window/gui/InputEditorWindow.cpp +++ b/src/window/gui/InputEditorWindow.cpp @@ -178,10 +178,10 @@ void InputEditorWindow::DrawInputChip(const char* buttonName, ImVec4 color = CHI ImGui::EndDisabled(); } -void InputEditorWindow::DrawButtonLineAddMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask) { +void InputEditorWindow::DrawButtonLineAddMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton) { ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f)); - auto popupId = StringHelper::Sprintf("addButtonMappingPopup##%d-%d", port, bitmask); - if (ImGui::Button(StringHelper::Sprintf("%s###addButtonMappingButton%d-%d", ICON_FA_PLUS, port, bitmask).c_str(), + auto popupId = StringHelper::Sprintf("addButtonMappingPopup##%d-%d-%d", port, bitmask, specialButton); + if (ImGui::Button(StringHelper::Sprintf("%s###addButtonMappingButton%d-%d-%d", ICON_FA_PLUS, port, bitmask, specialButton).c_str(), ImVec2(20.0f, 0.0f))) { ImGui::OpenPopup(popupId.c_str()); }; @@ -198,8 +198,8 @@ void InputEditorWindow::DrawButtonLineAddMappingButton(uint8_t port, CONTROLLERB if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() ->GetControlDeck() ->GetControllerByPort(port) - ->GetButton(bitmask) - ->AddOrEditButtonMappingFromRawPress(bitmask, "")) { + ->GetButton(bitmask, specialButton) + ->AddOrEditButtonMappingFromRawPress(bitmask, specialButton, "")) { mInputEditorPopupOpen = false; ImGui::CloseCurrentPopup(); } @@ -207,11 +207,11 @@ void InputEditorWindow::DrawButtonLineAddMappingButton(uint8_t port, CONTROLLERB } } -void InputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, std::string id) { +void InputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, std::string id) { auto mapping = Ship::Context::GetInstance() ->GetControlDeck() ->GetControllerByPort(port) - ->GetButton(bitmask) + ->GetButton(bitmask, specialButton) ->GetButtonMappingById(id); if (mapping == nullptr) { return; @@ -257,8 +257,8 @@ void InputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, CONTROLLER if (mMappingInputBlockTimer == INT32_MAX && Ship::Context::GetInstance() ->GetControlDeck() ->GetControllerByPort(port) - ->GetButton(bitmask) - ->AddOrEditButtonMappingFromRawPress(bitmask, id)) { + ->GetButton(bitmask, specialButton) + ->AddOrEditButtonMappingFromRawPress(bitmask, specialButton, id)) { mInputEditorPopupOpen = false; ImGui::CloseCurrentPopup(); } @@ -339,7 +339,7 @@ void InputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, CONTROLLER Ship::Context::GetInstance() ->GetControlDeck() ->GetControllerByPort(port) - ->GetButton(bitmask) + ->GetButton(bitmask, specialButton) ->ClearButtonMapping(id); }; ImGui::PopStyleColor(); @@ -348,16 +348,16 @@ void InputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, CONTROLLER ImGui::SameLine(0, 4.0f); } -void InputEditorWindow::DrawButtonLine(const char* buttonName, uint8_t port, CONTROLLERBUTTONS_T bitmask, +void InputEditorWindow::DrawButtonLine(const char* buttonName, uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton = 0, ImVec4 color = CHIP_COLOR_N64_GREY) { ImGui::NewLine(); ImGui::SameLine(32.0f); DrawInputChip(buttonName, color); ImGui::SameLine(86.0f); for (auto id : mBitmaskToMappingIds[port][bitmask]) { - DrawButtonLineEditMappingButton(port, bitmask, id); + DrawButtonLineEditMappingButton(port, bitmask, specialButton, id); } - DrawButtonLineAddMappingButton(port, bitmask); + DrawButtonLineAddMappingButton(port, bitmask, specialButton); } void InputEditorWindow::DrawStickDirectionLineAddMappingButton(uint8_t port, uint8_t stick, Direction direction) { @@ -607,6 +607,16 @@ void InputEditorWindow::UpdateBitmaskToMappingIds(uint8_t port) { } } } + for (auto [specialButton, button] : + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetAllSpecialButtons()) { + + for (auto [id, mapping] : button->GetAllButtonMappings()) { + if (std::find(mBitmaskToMappingIds[port][button->mBitmask].begin(), mBitmaskToMappingIds[port][button->mBitmask].end(), id) == + mBitmaskToMappingIds[port][button->mBitmask].end()) { + mBitmaskToMappingIds[port][button->mBitmask].push_back(id); + } + } + } } void InputEditorWindow::UpdateStickDirectionToMappingIds(uint8_t port) { @@ -1154,19 +1164,21 @@ void InputEditorWindow::DrawPortTab(uint8_t portIndex) { if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); - DrawButtonLine("A", portIndex, BTN_A, CHIP_COLOR_N64_BLUE); - DrawButtonLine("B", portIndex, BTN_B, CHIP_COLOR_N64_GREEN); - DrawButtonLine("Start", portIndex, BTN_START, CHIP_COLOR_N64_RED); + DrawButtonLine("A", portIndex, BTN_A, 0, CHIP_COLOR_N64_BLUE); + DrawButtonLine("B", portIndex, BTN_B, 0, CHIP_COLOR_N64_GREEN); + DrawButtonLine("Start", portIndex, BTN_START, 0, CHIP_COLOR_N64_RED); DrawButtonLine("L", portIndex, BTN_L); DrawButtonLine("R", portIndex, BTN_R); DrawButtonLine("Z", portIndex, BTN_Z); - DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_CUP, + DrawButtonLine("Roll button", portIndex, 0, 1); + DrawButtonLine("Interact button", portIndex, 0, 2); + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_CUP, 0, CHIP_COLOR_N64_YELLOW); - DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_CDOWN, + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_CDOWN, 0, CHIP_COLOR_N64_YELLOW); - DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_CLEFT, + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_CLEFT, 0, CHIP_COLOR_N64_YELLOW); - DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT, + DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT, 0, CHIP_COLOR_N64_YELLOW); } else { DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); diff --git a/src/window/gui/InputEditorWindow.h b/src/window/gui/InputEditorWindow.h index 10c81fd9b..d32220eeb 100644 --- a/src/window/gui/InputEditorWindow.h +++ b/src/window/gui/InputEditorWindow.h @@ -33,9 +33,9 @@ class InputEditorWindow : public GuiWindow { private: void DrawStickDirectionLine(const char* axisDirectionName, uint8_t port, uint8_t stick, Direction direction, ImVec4 color); - void DrawButtonLine(const char* buttonName, uint8_t port, CONTROLLERBUTTONS_T bitmask, ImVec4 color); - void DrawButtonLineEditMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, std::string id); - void DrawButtonLineAddMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask); + void DrawButtonLine(const char* buttonName, uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, ImVec4 color); + void DrawButtonLineEditMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, std::string id); + void DrawButtonLineAddMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton); void DrawStickDirectionLineEditMappingButton(uint8_t port, uint8_t stick, Direction direction, std::string id); void DrawStickDirectionLineAddMappingButton(uint8_t port, uint8_t stick, Direction direction); From 634ce3af9c8179868167aa46896944dbc8588373 Mon Sep 17 00:00:00 2001 From: JustawayOfTheSamurai <38185583+cclark25@users.noreply.github.com> Date: Fri, 14 Jun 2024 22:37:27 -0400 Subject: [PATCH 2/6] Added support for cur, prev, press, and release logic. --- include/libultraship/libultra/controller.h | 20 +++-- src/Context.cpp | 19 +---- src/IntentControlManager.h | 83 +++++++++++++++++++ .../controldevice/controller/Controller.cpp | 2 +- 4 files changed, 101 insertions(+), 23 deletions(-) create mode 100644 src/IntentControlManager.h diff --git a/include/libultraship/libultra/controller.h b/include/libultraship/libultra/controller.h index 342c43ae4..8a6d9a4dc 100644 --- a/include/libultraship/libultra/controller.h +++ b/include/libultraship/libultra/controller.h @@ -121,13 +121,21 @@ typedef struct { } OSContStatus; // size = 0x04 typedef struct IntentControls IntentControls; + +#define BUTTON_STATE_CUR 0 +#define BUTTON_STATE_PREV 1 +#define BUTTON_STATE_PRESS 2 +#define BUTTON_STATE_REL 3 + struct IntentControls { - uint8_t (*checkIntentButton)(uint16_t intentId); - void(*registerButtonState)(uint16_t specialButtonId, uint8_t); - void(*updateCurState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); - void(*updatePrevState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); - void(*updatePressState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); - void(*updateRelState)(IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); + void* userData; + uint8_t (*checkIntentButton)(void* userData, uint16_t intentId, uint8_t buttonStateVersion); + void(*registerButtonState)(void* userData, uint16_t specialButtonId, uint8_t); + void(*updateState)(void* userData); + // void(*updateCurState)(void* userData, IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); + // void(*updatePrevState)(void* userData, IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); + // void(*updatePressState)(void* userData, IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); + // void(*updateRelState)(void* userData, IntentControls* cur, IntentControls* prev, IntentControls* press, IntentControls* rel); }; typedef struct { diff --git a/src/Context.cpp b/src/Context.cpp index 7ac668478..5dd42c05e 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -7,7 +7,7 @@ #include "install_config.h" #include "debug/GfxDebugger.h" #include "graphic/Fast3D/Fast3dWindow.h" -#include +#include "IntentControlManager.h" #ifdef _WIN32 #include @@ -81,21 +81,8 @@ void Context::Init(const std::vector& otrFiles, const std::unordere InitConfiguration(); InitConsoleVariables(); InitResourceManager(otrFiles, validHashes, reservedThreadCount); - IntentControls* intentControls = new IntentControls; - static std::map* buttonStates = new std::map(); - intentControls->checkIntentButton = +[](uint16_t intentId){ - buttonStates->try_emplace(intentId, 0); - return buttonStates->at(intentId); - }; - intentControls->registerButtonState = [](uint16_t intentId, uint8_t pressed){ - buttonStates->insert_or_assign(intentId, pressed); - }; - intentControls->updateCurState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; - intentControls->updatePrevState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; - intentControls->updatePressState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; - intentControls->updateRelState = +[](IntentControls *cur, IntentControls *prev, IntentControls *press, IntentControls *rel){}; - - InitControlDeck({}, intentControls, { + IntentControlManager* intentManager = new IntentControlManager(); + InitControlDeck({}, intentManager->intentControls, { 1, 2, 3 diff --git a/src/IntentControlManager.h b/src/IntentControlManager.h new file mode 100644 index 000000000..752369e63 --- /dev/null +++ b/src/IntentControlManager.h @@ -0,0 +1,83 @@ +#include +#include + +class IntentControlManager { + public: + IntentControls* intentControls = new IntentControls(); + + std::map pendingStates = std::map(); + + std::map curStates = std::map(); + std::map prevStates = std::map(); + std::map pressStates = std::map(); + std::map relStates = std::map(); + + IntentControlManager(){ + intentControls->userData = this; + intentControls->checkIntentButton = +[](void* userData, uint16_t intentId, uint8_t stateVersionId){ + return ((IntentControlManager*) userData)->checkIntentButton(intentId, stateVersionId); + }; + + intentControls->registerButtonState = [](void* userData, uint16_t intentId, uint8_t pressed){ + return ((IntentControlManager*) userData)->registerButtonState(intentId, pressed); + }; + + intentControls->updateState = +[](void* userData){ + ((IntentControlManager*) userData)->updateState(); + }; + } + + uint8_t checkIntentButton(uint16_t intentId, uint8_t stateVersionId){ + std::map* stateVersion = nullptr; + switch (stateVersionId) + { + case BUTTON_STATE_CUR: + stateVersion = &this->curStates; + break; + case BUTTON_STATE_PREV: + stateVersion = &this->prevStates; + break; + case BUTTON_STATE_PRESS: + stateVersion = &this->pressStates; + break; + case BUTTON_STATE_REL: + stateVersion = &this->relStates; + break; + + default: + return 0; + } + + stateVersion->try_emplace(intentId, 0); + return stateVersion->at(intentId); + } + + void registerButtonState(uint16_t intentId, uint8_t pressed){ + pendingStates.insert_or_assign(intentId, pressed); + } + + void updateState(){ + this->prevStates.clear(); + for(auto s : this->curStates){ + prevStates.insert_or_assign(s.first, s.second); + } + + this->curStates.clear(); + for(auto s : this->pendingStates){ + curStates.insert_or_assign(s.first, s.second); + } + + for(auto s : this->prevStates){ + this->curStates.try_emplace(s.first, 0); + uint8_t cur = this->curStates.at(s.first); + uint8_t diff = !cur != !s.second; + + this->pressStates.insert_or_assign(s.first, (diff && cur)); + this->relStates.insert_or_assign(s.first, (diff && s.second)); + } + } + + ~IntentControlManager(){ + + } +}; \ No newline at end of file diff --git a/src/controller/controldevice/controller/Controller.cpp b/src/controller/controldevice/controller/Controller.cpp index 3e4afbb91..5695e2dce 100644 --- a/src/controller/controldevice/controller/Controller.cpp +++ b/src/controller/controldevice/controller/Controller.cpp @@ -157,7 +157,7 @@ void Controller::ReadToPad(OSContPad* pad) { uint8_t pressed = 0; for (auto m : button->GetAllButtonMappings()){ if(specialButton > 0 && padToBuffer.intentControls != NULL && padToBuffer.intentControls->registerButtonState != NULL){ - padToBuffer.intentControls->registerButtonState(specialButton, m.second->pressed); + padToBuffer.intentControls->registerButtonState(padToBuffer.intentControls->userData, specialButton, m.second->pressed); } } } From 7ba3ed48c394171abdb745179cd64c870b71c4a6 Mon Sep 17 00:00:00 2001 From: JustawayOfTheSamurai <38185583+cclark25@users.noreply.github.com> Date: Sun, 16 Jun 2024 17:05:25 -0400 Subject: [PATCH 3/6] Fixed a lot of the mapping saving and loading issues with the new intent controls. Also adjusted the mappings to be defined externally in the apps using the library. --- include/libultraship/libultra/controller.h | 10 +++ src/Context.cpp | 15 +++-- src/Context.h | 2 +- src/IntentControlManager.h | 3 +- src/controller/controldeck/ControlDeck.cpp | 8 ++- src/controller/controldeck/ControlDeck.h | 2 +- .../controldevice/controller/Controller.cpp | 61 +++++++++++++++++-- .../controldevice/controller/Controller.h | 1 + .../controller/ControllerButton.cpp | 25 +++++++- .../controller/ControllerButton.h | 1 + .../factories/ButtonMappingFactory.cpp | 2 +- .../keyboard/KeyboardKeyToButtonMapping.cpp | 2 + .../mapping/sdl/SDLButtonToButtonMapping.cpp | 3 + .../ShipDeviceIndexMappingManager.cpp | 38 ++++++++++++ src/window/gui/InputEditorWindow.cpp | 49 +++++++++++---- src/window/gui/InputEditorWindow.h | 4 +- 16 files changed, 190 insertions(+), 36 deletions(-) diff --git a/include/libultraship/libultra/controller.h b/include/libultraship/libultra/controller.h index 8a6d9a4dc..74dac6381 100644 --- a/include/libultraship/libultra/controller.h +++ b/include/libultraship/libultra/controller.h @@ -150,8 +150,18 @@ typedef struct { IntentControls* intentControls; } OSContPad; // size = 0x24 +typedef struct { + uint16_t id; + char* name; +} IntentControlDefinition; + +extern IntentControlDefinition* intentDefinitions; +extern uint16_t intentDefinitionCount; + #define GET_INTENTS(pad, f, default) (pad->intentControls == NULL ? default : pad->intentControls->f) +#define CHECK_INTENT(intentControls, intent, state, defaultVal) ( intentControls == NULL ? defaultVal : intentControls->checkIntentButton(intentControls->userData, intent, state)) + typedef struct { /* 0x00 */ void* address; /* 0x04 */ uint8_t databuffer[32]; diff --git a/src/Context.cpp b/src/Context.cpp index 5dd42c05e..8a05b380a 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -81,12 +81,11 @@ void Context::Init(const std::vector& otrFiles, const std::unordere InitConfiguration(); InitConsoleVariables(); InitResourceManager(otrFiles, validHashes, reservedThreadCount); - IntentControlManager* intentManager = new IntentControlManager(); - InitControlDeck({}, intentManager->intentControls, { - 1, - 2, - 3 - }); + std::vector specialControls; + for(uint16_t i = 0; i < intentDefinitionCount; i++){ + specialControls.push_back(intentDefinitions[i].id); + } + InitControlDeck({}, specialControls); InitCrashHandler(); InitConsole(); InitWindow(); @@ -217,12 +216,12 @@ void Context::InitResourceManager(const std::vector& otrFiles, } } -void Context::InitControlDeck(std::vector additionalBitmasks, IntentControls* intentControls, std::vector specialControls) { +void Context::InitControlDeck(std::vector additionalBitmasks, std::vector specialControls) { if (GetControlDeck() != nullptr) { return; } - mControlDeck = std::make_shared(additionalBitmasks, intentControls, specialControls); + mControlDeck = std::make_shared(additionalBitmasks, specialControls); } void Context::InitCrashHandler() { diff --git a/src/Context.h b/src/Context.h index 0c94b2f05..c429d1577 100644 --- a/src/Context.h +++ b/src/Context.h @@ -63,7 +63,7 @@ class Context { void InitConsoleVariables(); void InitResourceManager(const std::vector& otrFiles = {}, const std::unordered_set& validHashes = {}, uint32_t reservedThreadCount = 1); - void InitControlDeck(std::vector additionalBitmasks = {}, IntentControls* intentControls = nullptr, std::vector specialControls = {}); + void InitControlDeck(std::vector additionalBitmasks = {}, std::vector specialControls = {}); void InitCrashHandler(); void InitAudio(); void InitGfxDebugger(); diff --git a/src/IntentControlManager.h b/src/IntentControlManager.h index 752369e63..ed7502f9d 100644 --- a/src/IntentControlManager.h +++ b/src/IntentControlManager.h @@ -49,7 +49,8 @@ class IntentControlManager { } stateVersion->try_emplace(intentId, 0); - return stateVersion->at(intentId); + uint8_t result = stateVersion->at(intentId); + return result; } void registerButtonState(uint16_t intentId, uint8_t pressed){ diff --git a/src/controller/controldeck/ControlDeck.cpp b/src/controller/controldeck/ControlDeck.cpp index d8336d16b..83d92af93 100644 --- a/src/controller/controldeck/ControlDeck.cpp +++ b/src/controller/controldeck/ControlDeck.cpp @@ -9,19 +9,21 @@ #endif #include #include "controller/deviceindex/ShipDeviceIndexMappingManager.h" +#include namespace Ship { -ControlDeck::ControlDeck(std::vector additionalBitmasks, IntentControls* intentControls, std::vector specialButtons) +ControlDeck::ControlDeck(std::vector additionalBitmasks, std::vector specialButtons) : mPads(nullptr), mSinglePlayerMappingMode(false) { for (int32_t i = 0; i < MAXCONTROLLERS; i++) { - mPorts.push_back(std::make_shared(i, std::make_shared(i, additionalBitmasks, intentControls, specialButtons))); + IntentControlManager* intentManager = new IntentControlManager(); + mPorts.push_back(std::make_shared(i, std::make_shared(i, additionalBitmasks, intentManager->intentControls, specialButtons))); } mDeviceIndexMappingManager = std::make_shared(); } -ControlDeck::ControlDeck() : ControlDeck(std::vector(), nullptr, std::vector()) { +ControlDeck::ControlDeck() : ControlDeck(std::vector(), std::vector()) { } ControlDeck::~ControlDeck() { diff --git a/src/controller/controldeck/ControlDeck.h b/src/controller/controldeck/ControlDeck.h index cf086fda5..11a240509 100644 --- a/src/controller/controldeck/ControlDeck.h +++ b/src/controller/controldeck/ControlDeck.h @@ -11,7 +11,7 @@ namespace Ship { class ControlDeck { public: ControlDeck(); - ControlDeck(std::vector additionalBitmasks, IntentControls* intentControls, std::vector intentButtons); + ControlDeck(std::vector additionalBitmasks, std::vector intentButtons); ~ControlDeck(); void Init(uint8_t* controllerBits); diff --git a/src/controller/controldevice/controller/Controller.cpp b/src/controller/controldevice/controller/Controller.cpp index 5695e2dce..b8196150b 100644 --- a/src/controller/controldevice/controller/Controller.cpp +++ b/src/controller/controldevice/controller/Controller.cpp @@ -95,6 +95,9 @@ void Controller::ClearAllMappings() { for (auto [bitmask, button] : GetAllButtons()) { button->ClearAllButtonMappings(); } + for (auto [specialButtonId, button] : GetAllSpecialButtons()) { + button->ClearAllButtonMappings(); + } GetLeftStick()->ClearAllMappings(); GetRightStick()->ClearAllMappings(); GetGyro()->ClearGyroMapping(); @@ -106,6 +109,9 @@ void Controller::ClearAllMappingsForDevice(ShipDeviceIndex shipDeviceIndex) { for (auto [bitmask, button] : GetAllButtons()) { button->ClearAllButtonMappingsForDevice(shipDeviceIndex); } + for (auto [specialButtonId, button] : GetAllSpecialButtons()) { + button->ClearAllButtonMappingsForDevice(shipDeviceIndex); + } GetLeftStick()->ClearAllMappingsForDevice(shipDeviceIndex); GetRightStick()->ClearAllMappingsForDevice(shipDeviceIndex); @@ -122,6 +128,9 @@ void Controller::AddDefaultMappings(ShipDeviceIndex shipDeviceIndex) { for (auto [bitmask, button] : GetAllButtons()) { button->AddDefaultMappings(shipDeviceIndex); } + for (auto [specialButtonId, button] : GetAllSpecialButtons()) { + button->AddDefaultMappings(shipDeviceIndex); + } GetLeftStick()->AddDefaultMappings(shipDeviceIndex); GetRumble()->AddDefaultMappings(shipDeviceIndex); @@ -135,6 +144,9 @@ void Controller::ReloadAllMappingsFromConfig() { for (auto [bitmask, button] : GetAllButtons()) { button->ReloadAllMappingsFromConfig(); } + for (auto [specialButton, button] : GetAllSpecialButtons()) { + button->ReloadAllMappingsFromConfig(); + } GetLeftStick()->ReloadAllMappingsFromConfig(); GetRightStick()->ReloadAllMappingsFromConfig(); GetGyro()->ReloadGyroMappingFromConfig(); @@ -152,13 +164,16 @@ void Controller::ReadToPad(OSContPad* pad) { padToBuffer.intentControls = intentControls; - for (auto [specialButton, button] : mSpecialButtons) { - button->UpdatePad(padToBuffer.button); - uint8_t pressed = 0; - for (auto m : button->GetAllButtonMappings()){ - if(specialButton > 0 && padToBuffer.intentControls != NULL && padToBuffer.intentControls->registerButtonState != NULL){ - padToBuffer.intentControls->registerButtonState(padToBuffer.intentControls->userData, specialButton, m.second->pressed); + if(padToBuffer.intentControls != NULL && padToBuffer.intentControls->registerButtonState != NULL){ + for (auto [specialButton, button] : mSpecialButtons) { + button->UpdatePad(padToBuffer.button); + uint8_t pressed = false; + for (auto m : button->GetAllButtonMappings()){ + pressed = pressed || m.second->pressed; } + padToBuffer.intentControls->registerButtonState( + padToBuffer.intentControls->userData, specialButton, pressed + ); } } @@ -209,6 +224,9 @@ bool Controller::ProcessKeyboardEvent(Ship::KbEventType eventType, Ship::KbScanc for (auto [bitmask, button] : GetAllButtons()) { result = button->ProcessKeyboardEvent(eventType, scancode) || result; } + for (auto [specialButtonId, button] : GetAllSpecialButtons()) { + result = button->ProcessKeyboardEvent(eventType, scancode) || result; + } result = GetLeftStick()->ProcessKeyboardEvent(eventType, scancode) || result; result = GetRightStick()->ProcessKeyboardEvent(eventType, scancode) || result; return result; @@ -220,6 +238,12 @@ bool Controller::HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex) { return true; } } + for (auto [specialButtonId, button] : GetAllSpecialButtons()) { + if (button->HasMappingsForShipDeviceIndex(lusIndex)) { + return true; + } + } + if (GetLeftStick()->HasMappingsForShipDeviceIndex(lusIndex)) { return true; } @@ -242,6 +266,9 @@ bool Controller::HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex) { std::shared_ptr Controller::GetButtonByBitmask(CONTROLLERBUTTONS_T bitmask) { return mButtons[bitmask]; } +std::shared_ptr Controller::GetButtonBySpecialId(uint16_t id) { + return mSpecialButtons[id]; +} void Controller::MoveMappingsToDifferentController(std::shared_ptr newController, ShipDeviceIndex lusIndex) { @@ -262,6 +289,23 @@ void Controller::MoveMappingsToDifferentController(std::shared_ptr n button->ClearButtonMappingId(id); } } + for (auto [specialButtonId, button] : GetAllSpecialButtons()) { + std::vector buttonMappingIdsToRemove; + for (auto [id, mapping] : button->GetAllButtonMappings()) { + if (mapping->GetShipDeviceIndex() == lusIndex) { + buttonMappingIdsToRemove.push_back(id); + + mapping->SetPortIndex(newController->GetPortIndex()); + mapping->SaveToConfig(); + + newController->GetButtonBySpecialId(specialButtonId)->AddButtonMapping(mapping); + } + } + newController->GetButtonBySpecialId(specialButtonId)->SaveButtonMappingIdsToConfig(); + for (auto id : buttonMappingIdsToRemove) { + button->ClearButtonMappingId(id); + } + } for (auto stick : { GetLeftStick(), GetRightStick() }) { auto newControllerStick = @@ -340,6 +384,11 @@ std::vector> Controller::GetAllMappings() { allMappings.push_back(mapping); } } + for (auto [specialButtonId, button] : GetAllSpecialButtons()) { + for (auto [id, mapping] : button->GetAllButtonMappings()) { + allMappings.push_back(mapping); + } + } for (auto stick : { GetLeftStick(), GetRightStick() }) { for (auto [direction, mappings] : stick->GetAllAxisDirectionMappings()) { diff --git a/src/controller/controldevice/controller/Controller.h b/src/controller/controldevice/controller/Controller.h index d5fe0defe..2d12d5940 100644 --- a/src/controller/controldevice/controller/Controller.h +++ b/src/controller/controldevice/controller/Controller.h @@ -38,6 +38,7 @@ class Controller : public ControlDevice { std::unordered_map> GetAllButtons(); std::unordered_map> GetAllSpecialButtons(); std::shared_ptr GetButtonByBitmask(CONTROLLERBUTTONS_T bitmask); + std::shared_ptr GetButtonBySpecialId(uint16_t bitmask); std::shared_ptr GetButton(CONTROLLERBUTTONS_T bitmask, uint16_t specialButton); std::shared_ptr GetLeftStick(); std::shared_ptr GetRightStick(); diff --git a/src/controller/controldevice/controller/ControllerButton.cpp b/src/controller/controldevice/controller/ControllerButton.cpp index 0958e108b..08aa47912 100644 --- a/src/controller/controldevice/controller/ControllerButton.cpp +++ b/src/controller/controldevice/controller/ControllerButton.cpp @@ -18,6 +18,14 @@ ControllerButton::ControllerButton(uint8_t portIndex, CONTROLLERBUTTONS_T bitmas ControllerButton::~ControllerButton() { } +std::string ControllerButton::GetConfigNameFromSpecialButtonId(uint16_t id){ + for(uint16_t i = 0; i < intentDefinitionCount; i++){ + if(intentDefinitions[i].id == id){ + return intentDefinitions[i].name; + } + } +} + std::string ControllerButton::GetConfigNameFromBitmask(CONTROLLERBUTTONS_T bitmask) { switch (bitmask) { case BTN_A: @@ -105,9 +113,17 @@ void ControllerButton::SaveButtonMappingIdsToConfig() { buttonMappingIdListString += ","; } + std::string buttonName = ""; + if(mSpecialButtonId > 0){ + buttonName = GetConfigNameFromSpecialButtonId(mSpecialButtonId); + } + else { + buttonName = GetConfigNameFromBitmask(mBitmask); + } + const std::string buttonMappingIdsCvarKey = StringHelper::Sprintf(CVAR_PREFIX_CONTROLLERS ".Port%d.Buttons.%sButtonMappingIds", mPortIndex + 1, - GetConfigNameFromBitmask(mBitmask).c_str()); + buttonName.c_str()); if (buttonMappingIdListString == "") { CVarClear(buttonMappingIdsCvarKey.c_str()); } else { @@ -120,6 +136,11 @@ void ControllerButton::SaveButtonMappingIdsToConfig() { void ControllerButton::ReloadAllMappingsFromConfig() { mButtonMappings.clear(); + std::string configName = GetConfigNameFromBitmask(mBitmask); + if(mSpecialButtonId > 0){ + configName = GetConfigNameFromSpecialButtonId(mSpecialButtonId); + } + // todo: this efficently (when we build out cvar array support?) // i don't expect it to really be a problem with the small number of mappings we have // for each controller (especially compared to include/exclude locations in rando), and @@ -127,7 +148,7 @@ void ControllerButton::ReloadAllMappingsFromConfig() { // hardcoded or provided by an otr file const std::string buttonMappingIdsCvarKey = StringHelper::Sprintf(CVAR_PREFIX_CONTROLLERS ".Port%d.Buttons.%sButtonMappingIds", mPortIndex + 1, - GetConfigNameFromBitmask(mBitmask).c_str()); + configName.c_str()); std::stringstream buttonMappingIdsStringStream(CVarGetString(buttonMappingIdsCvarKey.c_str(), "")); std::string buttonMappingIdString; while (getline(buttonMappingIdsStringStream, buttonMappingIdString, ',')) { diff --git a/src/controller/controldevice/controller/ControllerButton.h b/src/controller/controldevice/controller/ControllerButton.h index 754ec9332..feba07cdf 100644 --- a/src/controller/controldevice/controller/ControllerButton.h +++ b/src/controller/controldevice/controller/ControllerButton.h @@ -47,6 +47,7 @@ class ControllerButton { uint8_t mPortIndex; std::unordered_map> mButtonMappings; std::string GetConfigNameFromBitmask(CONTROLLERBUTTONS_T bitmask); + std::string GetConfigNameFromSpecialButtonId(uint16_t id); bool mUseKeydownEventToCreateNewMapping; KbScancode mKeyboardScancodeForNewMapping; diff --git a/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp b/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp index 97346b5a6..f79186b57 100644 --- a/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp +++ b/src/controller/controldevice/controller/mapping/factories/ButtonMappingFactory.cpp @@ -17,7 +17,7 @@ std::shared_ptr ButtonMappingFactory::CreateButtonMappi CONTROLLERBUTTONS_T bitmask = CVarGetInteger(StringHelper::Sprintf("%s.Bitmask", mappingCvarKey.c_str()).c_str(), 0); CONTROLLERBUTTONS_T specialButton = - CVarGetInteger(StringHelper::Sprintf("%s.SpecialButton", mappingCvarKey.c_str()).c_str(), 0); + CVarGetInteger(StringHelper::Sprintf("%s.SpecialButtonId", mappingCvarKey.c_str()).c_str(), 0); if (!bitmask && ! specialButton) { // all button mappings need bitmasks CVarClear(mappingCvarKey.c_str()); diff --git a/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp b/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp index e1b20770b..30cec474e 100644 --- a/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp +++ b/src/controller/controldevice/controller/mapping/keyboard/KeyboardKeyToButtonMapping.cpp @@ -37,6 +37,8 @@ void KeyboardKeyToButtonMapping::SaveToConfig() { const std::string mappingCvarKey = CVAR_PREFIX_CONTROLLERS ".ButtonMappings." + GetButtonMappingId(); CVarSetString(StringHelper::Sprintf("%s.ButtonMappingClass", mappingCvarKey.c_str()).c_str(), "KeyboardKeyToButtonMapping"); + CVarSetInteger(StringHelper::Sprintf("%s.SpecialButtonId", mappingCvarKey.c_str()).c_str(), + mSpecialButton); CVarSetInteger(StringHelper::Sprintf("%s.Bitmask", mappingCvarKey.c_str()).c_str(), mBitmask); CVarSetInteger(StringHelper::Sprintf("%s.KeyboardScancode", mappingCvarKey.c_str()).c_str(), mKeyboardScancode); CVarSave(); diff --git a/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp b/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp index eb61d2521..6e8c79cc6 100644 --- a/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp +++ b/src/controller/controldevice/controller/mapping/sdl/SDLButtonToButtonMapping.cpp @@ -41,6 +41,8 @@ void SDLButtonToButtonMapping::SaveToConfig() { const std::string mappingCvarKey = CVAR_PREFIX_CONTROLLERS ".ButtonMappings." + GetButtonMappingId(); CVarSetString(StringHelper::Sprintf("%s.ButtonMappingClass", mappingCvarKey.c_str()).c_str(), "SDLButtonToButtonMapping"); + CVarSetInteger(StringHelper::Sprintf("%s.SpecialButtonId", mappingCvarKey.c_str()).c_str(), + mSpecialButton); CVarSetInteger(StringHelper::Sprintf("%s.Bitmask", mappingCvarKey.c_str()).c_str(), mBitmask); CVarSetInteger(StringHelper::Sprintf("%s.ShipDeviceIndex", mappingCvarKey.c_str()).c_str(), ControllerInputMapping::mShipDeviceIndex); @@ -52,6 +54,7 @@ void SDLButtonToButtonMapping::EraseFromConfig() { const std::string mappingCvarKey = CVAR_PREFIX_CONTROLLERS ".ButtonMappings." + GetButtonMappingId(); CVarClear(StringHelper::Sprintf("%s.ButtonMappingClass", mappingCvarKey.c_str()).c_str()); + CVarClear(StringHelper::Sprintf("%s.SpecialButtonId", mappingCvarKey.c_str()).c_str()); CVarClear(StringHelper::Sprintf("%s.Bitmask", mappingCvarKey.c_str()).c_str()); CVarClear(StringHelper::Sprintf("%s.ShipDeviceIndex", mappingCvarKey.c_str()).c_str()); CVarClear(StringHelper::Sprintf("%s.SDLControllerButton", mappingCvarKey.c_str()).c_str()); diff --git a/src/controller/deviceindex/ShipDeviceIndexMappingManager.cpp b/src/controller/deviceindex/ShipDeviceIndexMappingManager.cpp index e8a47cb2e..c52e3abc6 100644 --- a/src/controller/deviceindex/ShipDeviceIndexMappingManager.cpp +++ b/src/controller/deviceindex/ShipDeviceIndexMappingManager.cpp @@ -230,6 +230,21 @@ int32_t ShipDeviceIndexMappingManager::GetNewSDLDeviceIndexFromShipDeviceIndex(S } } + for (auto [specialButtonId, button] : controller->GetAllSpecialButtons()) { + for (auto [id, buttonMapping] : button->GetAllButtonMappings()) { + if (buttonMapping->GetShipDeviceIndex() != lusIndex) { + continue; + } + + auto sdlButtonMapping = std::dynamic_pointer_cast(buttonMapping); + if (sdlButtonMapping == nullptr) { + continue; + } + + return sdlButtonMapping->GetCurrentSDLDeviceIndex(); + } + } + for (auto stick : { controller->GetLeftStick(), controller->GetRightStick() }) { for (auto [direction, axisDirectionMappings] : stick->GetAllAxisDirectionMappings()) { for (auto [id, axisDirectionMapping] : axisDirectionMappings) { @@ -483,6 +498,17 @@ uint8_t ShipDeviceIndexMappingManager::GetPortIndexOfDisconnectedPhysicalDevice( } } } + for (auto [specialButtonId, button] : controller->GetAllSpecialButtons()) { + for (auto [id, buttonMapping] : button->GetAllButtonMappings()) { + auto sdlButtonMapping = std::dynamic_pointer_cast(buttonMapping); + if (sdlButtonMapping == nullptr) { + continue; + } + if (sdlButtonMapping->GetJoystickInstanceId() == sdlJoystickInstanceId) { + return portIndex; + } + } + } for (auto stick : { controller->GetLeftStick(), controller->GetRightStick() }) { for (auto [direction, axisDirectionMappings] : stick->GetAllAxisDirectionMappings()) { @@ -547,6 +573,18 @@ ShipDeviceIndexMappingManager::GetShipDeviceIndexOfDisconnectedPhysicalDevice(in } } } + for (auto [specialButtonId, button] : controller->GetAllSpecialButtons()) { + for (auto [id, buttonMapping] : button->GetAllButtonMappings()) { + auto sdlButtonMapping = std::dynamic_pointer_cast(buttonMapping); + if (sdlButtonMapping == nullptr) { + continue; + } + if (sdlButtonMapping->GetJoystickInstanceId() == sdlJoystickInstanceId) { + shipDeviceIndex = sdlButtonMapping->GetShipDeviceIndex(); + sdlButtonMapping->CloseController(); + } + } + } for (auto stick : { controller->GetLeftStick(), controller->GetRightStick() }) { for (auto [direction, axisDirectionMappings] : stick->GetAllAxisDirectionMappings()) { diff --git a/src/window/gui/InputEditorWindow.cpp b/src/window/gui/InputEditorWindow.cpp index 3a8be3ace..3fe7358df 100644 --- a/src/window/gui/InputEditorWindow.cpp +++ b/src/window/gui/InputEditorWindow.cpp @@ -354,8 +354,15 @@ void InputEditorWindow::DrawButtonLine(const char* buttonName, uint8_t port, CON ImGui::SameLine(32.0f); DrawInputChip(buttonName, color); ImGui::SameLine(86.0f); - for (auto id : mBitmaskToMappingIds[port][bitmask]) { - DrawButtonLineEditMappingButton(port, bitmask, specialButton, id); + if(specialButton == 0){ + for (auto id : mBitmaskToMappingIds[port][bitmask]) { + DrawButtonLineEditMappingButton(port, bitmask, specialButton, id); + } + } + else { + for (auto id : mSpecialIdToMappingIds[port][specialButton]) { + DrawButtonLineEditMappingButton(port, bitmask, specialButton, id); + } } DrawButtonLineAddMappingButton(port, bitmask, specialButton); } @@ -611,9 +618,9 @@ void InputEditorWindow::UpdateBitmaskToMappingIds(uint8_t port) { Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(port)->GetAllSpecialButtons()) { for (auto [id, mapping] : button->GetAllButtonMappings()) { - if (std::find(mBitmaskToMappingIds[port][button->mBitmask].begin(), mBitmaskToMappingIds[port][button->mBitmask].end(), id) == - mBitmaskToMappingIds[port][button->mBitmask].end()) { - mBitmaskToMappingIds[port][button->mBitmask].push_back(id); + if (std::find(mSpecialIdToMappingIds[port][button->mSpecialButtonId].begin(), mSpecialIdToMappingIds[port][button->mSpecialButtonId].end(), id) == + mSpecialIdToMappingIds[port][button->mSpecialButtonId].end()) { + mSpecialIdToMappingIds[port][button->mSpecialButtonId].push_back(id); } } } @@ -928,7 +935,7 @@ void InputEditorWindow::DrawGyroSection(uint8_t port) { } } -void InputEditorWindow::DrawButtonDeviceIcons(uint8_t portIndex, std::set bitmasks) { +void InputEditorWindow::DrawButtonDeviceIcons(uint8_t portIndex, std::set bitmasks, std::set specialButtons) { std::set allLusDeviceIndices; allLusDeviceIndices.insert(ShipDeviceIndex::Keyboard); for (auto [lusIndex, mapping] : Context::GetInstance() @@ -946,6 +953,23 @@ void InputEditorWindow::DrawButtonDeviceIcons(uint8_t portIndex, std::setHasMappingsForShipDeviceIndex(lusIndex)) { + for (auto [id, mapping] : button->GetAllButtonMappings()) { + if (mapping->GetShipDeviceIndex() == lusIndex) { + lusDeviceIndiciesWithMappings.push_back( + std::pair(lusIndex, mapping->PhysicalDeviceIsConnected())); + break; + } + } + break; + } + } + for (auto [specialButtonId, button] : + Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetAllSpecialButtons()) { + if (!specialButtons.contains(specialButtonId)) { + continue; + } + if (button->HasMappingsForShipDeviceIndex(lusIndex)) { for (auto [id, mapping] : button->GetAllButtonMappings()) { if (mapping->GetShipDeviceIndex() == lusIndex) { @@ -1163,15 +1187,16 @@ void InputEditorWindow::DrawPortTab(uint8_t portIndex) { ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { - DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks, mSpecialButtonsIds); DrawButtonLine("A", portIndex, BTN_A, 0, CHIP_COLOR_N64_BLUE); DrawButtonLine("B", portIndex, BTN_B, 0, CHIP_COLOR_N64_GREEN); DrawButtonLine("Start", portIndex, BTN_START, 0, CHIP_COLOR_N64_RED); DrawButtonLine("L", portIndex, BTN_L); DrawButtonLine("R", portIndex, BTN_R); DrawButtonLine("Z", portIndex, BTN_Z); - DrawButtonLine("Roll button", portIndex, 0, 1); - DrawButtonLine("Interact button", portIndex, 0, 2); + for(uint16_t i = 0; i < intentDefinitionCount; i++){ + DrawButtonLine(intentDefinitions[i].name, portIndex, 0, intentDefinitions[i].id); + } DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_CUP, 0, CHIP_COLOR_N64_YELLOW); DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_CDOWN, 0, @@ -1181,17 +1206,17 @@ void InputEditorWindow::DrawPortTab(uint8_t portIndex) { DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT, 0, CHIP_COLOR_N64_YELLOW); } else { - DrawButtonDeviceIcons(portIndex, mButtonsBitmasks); + DrawButtonDeviceIcons(portIndex, mButtonsBitmasks, mSpecialButtonsIds); } if (ImGui::CollapsingHeader("D-Pad", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { - DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + DrawButtonDeviceIcons(portIndex, mDpadBitmasks, {}); DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_DUP); DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_DDOWN); DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_DLEFT); DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_DRIGHT); } else { - DrawButtonDeviceIcons(portIndex, mDpadBitmasks); + DrawButtonDeviceIcons(portIndex, mDpadBitmasks, {}); } if (ImGui::CollapsingHeader("Analog Stick", NULL, ImGuiTreeNodeFlags_DefaultOpen)) { diff --git a/src/window/gui/InputEditorWindow.h b/src/window/gui/InputEditorWindow.h index d32220eeb..bcaaa5d59 100644 --- a/src/window/gui/InputEditorWindow.h +++ b/src/window/gui/InputEditorWindow.h @@ -58,6 +58,7 @@ class InputEditorWindow : public GuiWindow { // mBitmaskToMappingIds[port][bitmask] = { id0, id1, ... } std::unordered_map>> mBitmaskToMappingIds; + std::unordered_map>> mSpecialIdToMappingIds; // mStickDirectionToMappingIds[port][stick][direction] = { id0, id1, ... } std::unordered_map>>> @@ -70,8 +71,9 @@ class InputEditorWindow : public GuiWindow { void DrawPortTab(uint8_t portIndex); void DrawDevicesTab(); std::set mButtonsBitmasks; + std::set mSpecialButtonsIds; std::set mDpadBitmasks; - void DrawButtonDeviceIcons(uint8_t portIndex, std::set bitmasks); + void DrawButtonDeviceIcons(uint8_t portIndex, std::set bitmasks, std::set specialButtons); void DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::Stick stick); void DrawRumbleDeviceIcons(uint8_t portIndex); void DrawGyroDeviceIcons(uint8_t portIndex); From e5dfab3f8ea064ec48e1427eafc0a7417a039eca Mon Sep 17 00:00:00 2001 From: JustawayOfTheSamurai <38185583+cclark25@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:31:31 -0400 Subject: [PATCH 4/6] Made DrawButtonLine function public so it can be called from other windows. --- src/window/gui/InputEditorWindow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/window/gui/InputEditorWindow.h b/src/window/gui/InputEditorWindow.h index bcaaa5d59..d9ad161b6 100644 --- a/src/window/gui/InputEditorWindow.h +++ b/src/window/gui/InputEditorWindow.h @@ -25,6 +25,7 @@ class InputEditorWindow : public GuiWindow { void DrawAnalogPreview(const char* label, ImVec2 stick, float deadzone = 0, bool gyro = false); void DrawControllerSchema(); + void DrawButtonLine(const char* buttonName, uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, ImVec4 color); protected: void InitElement() override; void DrawElement() override; @@ -33,7 +34,6 @@ class InputEditorWindow : public GuiWindow { private: void DrawStickDirectionLine(const char* axisDirectionName, uint8_t port, uint8_t stick, Direction direction, ImVec4 color); - void DrawButtonLine(const char* buttonName, uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, ImVec4 color); void DrawButtonLineEditMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, std::string id); void DrawButtonLineAddMappingButton(uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton); From a9bd6f75d0f534a97473d296a298d428db26f302 Mon Sep 17 00:00:00 2001 From: JustawayOfTheSamurai <38185583+cclark25@users.noreply.github.com> Date: Sat, 3 Aug 2024 14:16:42 -0400 Subject: [PATCH 5/6] Refactored the externs to hopefully fix Windows builds --- include/libultraship/libultra/controller.h | 15 +++++++++++++-- src/Context.cpp | 5 +++-- .../controldevice/controller/Controller.cpp | 10 ++++++++++ .../controldevice/controller/Controller.h | 1 + .../controldevice/controller/ControllerButton.cpp | 7 ++++--- src/window/gui/InputEditorWindow.cpp | 5 +++-- 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/libultraship/libultra/controller.h b/include/libultraship/libultra/controller.h index 74dac6381..f7edd7194 100644 --- a/include/libultraship/libultra/controller.h +++ b/include/libultraship/libultra/controller.h @@ -155,8 +155,19 @@ typedef struct { char* name; } IntentControlDefinition; -extern IntentControlDefinition* intentDefinitions; -extern uint16_t intentDefinitionCount; +typedef struct { + IntentControlDefinition* definitions; + uint16_t count; +} IntentControlDefinitionSet; + +#ifdef __cplusplus +extern "C" { +#endif + extern IntentControlDefinitionSet getIntentControlDefinitions(); + extern void setIntentControlDefinitions(IntentControlDefinitionSet controls); +#ifdef __cplusplus +} +#endif #define GET_INTENTS(pad, f, default) (pad->intentControls == NULL ? default : pad->intentControls->f) diff --git a/src/Context.cpp b/src/Context.cpp index 8a05b380a..2cd177627 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -82,8 +82,9 @@ void Context::Init(const std::vector& otrFiles, const std::unordere InitConsoleVariables(); InitResourceManager(otrFiles, validHashes, reservedThreadCount); std::vector specialControls; - for(uint16_t i = 0; i < intentDefinitionCount; i++){ - specialControls.push_back(intentDefinitions[i].id); + IntentControlDefinitionSet intentDefs = getIntentControlDefinitions(); + for(size_t i = 0; i < intentDefs.count; i++){ + specialControls.push_back(intentDefs.definitions[i].id); } InitControlDeck({}, specialControls); InitCrashHandler(); diff --git a/src/controller/controldevice/controller/Controller.cpp b/src/controller/controldevice/controller/Controller.cpp index b3e582f67..f0d90ca46 100644 --- a/src/controller/controldevice/controller/Controller.cpp +++ b/src/controller/controldevice/controller/Controller.cpp @@ -410,4 +410,14 @@ std::vector> Controller::GetAllMappings() { return allMappings; } + +IntentControlDefinitionSet Controller::intentControlDefinitions = {nullptr, 0}; + } // namespace Ship + +extern "C" IntentControlDefinitionSet getIntentControlDefinitions(){ + return Ship::Controller::intentControlDefinitions; +} +extern "C" void setIntentControlDefinitions(IntentControlDefinitionSet controls){ + Ship::Controller::intentControlDefinitions = controls; +} \ No newline at end of file diff --git a/src/controller/controldevice/controller/Controller.h b/src/controller/controldevice/controller/Controller.h index 160922103..70341bd69 100644 --- a/src/controller/controldevice/controller/Controller.h +++ b/src/controller/controldevice/controller/Controller.h @@ -55,6 +55,7 @@ class Controller : public ControlDevice { bool HasMappingsForShipDeviceIndex(ShipDeviceIndex lusIndex); void MoveMappingsToDifferentController(std::shared_ptr newController, ShipDeviceIndex lusIndex); + static IntentControlDefinitionSet intentControlDefinitions; private: void LoadButtonMappingFromConfig(std::string id); void SaveButtonMappingIdsToConfig(); diff --git a/src/controller/controldevice/controller/ControllerButton.cpp b/src/controller/controldevice/controller/ControllerButton.cpp index d50f17466..b5d91c387 100644 --- a/src/controller/controldevice/controller/ControllerButton.cpp +++ b/src/controller/controldevice/controller/ControllerButton.cpp @@ -19,9 +19,10 @@ ControllerButton::~ControllerButton() { } std::string ControllerButton::GetConfigNameFromSpecialButtonId(uint16_t id){ - for(uint16_t i = 0; i < intentDefinitionCount; i++){ - if(intentDefinitions[i].id == id){ - return intentDefinitions[i].name; + IntentControlDefinitionSet intentDefs = getIntentControlDefinitions(); + for(uint16_t i = 0; i < intentDefs.count; i++){ + if(intentDefs.definitions[i].id == id){ + return intentDefs.definitions[i].name; } } } diff --git a/src/window/gui/InputEditorWindow.cpp b/src/window/gui/InputEditorWindow.cpp index e53ccf4b9..c50d3c1d6 100644 --- a/src/window/gui/InputEditorWindow.cpp +++ b/src/window/gui/InputEditorWindow.cpp @@ -1525,8 +1525,9 @@ void InputEditorWindow::DrawPortTab(uint8_t portIndex) { DrawButtonLine("L", portIndex, BTN_L); DrawButtonLine("R", portIndex, BTN_R); DrawButtonLine("Z", portIndex, BTN_Z); - for(uint16_t i = 0; i < intentDefinitionCount; i++){ - DrawButtonLine(intentDefinitions[i].name, portIndex, 0, intentDefinitions[i].id); + IntentControlDefinitionSet intentDefs = getIntentControlDefinitions(); + for(uint16_t i = 0; i < intentDefs.count; i++){ + DrawButtonLine(intentDefs.definitions[i].name, portIndex, 0, intentDefs.definitions[i].id); } DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_CUP, 0, CHIP_COLOR_N64_YELLOW); From 41366d126498fe09db063da50ec8368e32c7f030 Mon Sep 17 00:00:00 2001 From: JustawayOfTheSamurai <38185583+cclark25@users.noreply.github.com> Date: Sun, 4 Aug 2024 16:39:34 -0400 Subject: [PATCH 6/6] Adjusted some code to improve visibility of control configs outside of the main control mapping window. --- src/window/gui/InputEditorWindow.cpp | 7 ++++--- src/window/gui/InputEditorWindow.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/window/gui/InputEditorWindow.cpp b/src/window/gui/InputEditorWindow.cpp index c50d3c1d6..fb61f96ce 100644 --- a/src/window/gui/InputEditorWindow.cpp +++ b/src/window/gui/InputEditorWindow.cpp @@ -198,7 +198,7 @@ void InputEditorWindow::GetButtonColorsForShipDeviceIndex(ShipDeviceIndex lusInd void InputEditorWindow::DrawInputChip(const char* buttonName, ImVec4 color = CHIP_COLOR_N64_GREY) { ImGui::BeginDisabled(); ImGui::PushStyleColor(ImGuiCol_Button, color); - ImGui::Button(buttonName, ImVec2(SCALE_IMGUI_SIZE(50.0f), 0)); + ImGui::Button(buttonName); ImGui::PopStyleColor(); ImGui::EndDisabled(); } @@ -241,7 +241,8 @@ void InputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, CONTROLLER if (mapping == nullptr) { return; } - if (!mDeviceIndexVisiblity[mapping->GetShipDeviceIndex()]) { + Ship::ShipDeviceIndex deviceIndex = mapping->GetShipDeviceIndex(); + if (!mDeviceIndexVisiblity[deviceIndex]) { return; } @@ -442,7 +443,7 @@ void InputEditorWindow::DrawButtonLine(const char* buttonName, uint8_t port, CON ImGui::NewLine(); ImGui::SameLine(SCALE_IMGUI_SIZE(32.0f)); DrawInputChip(buttonName, color); - ImGui::SameLine(SCALE_IMGUI_SIZE(86.0f)); + ImGui::SameLine(); if(specialButton == 0){ for (auto id : mBitmaskToMappingIds[port][bitmask]) { DrawButtonLineEditMappingButton(port, bitmask, specialButton, id); diff --git a/src/window/gui/InputEditorWindow.h b/src/window/gui/InputEditorWindow.h index 9e9c35290..196d448f4 100644 --- a/src/window/gui/InputEditorWindow.h +++ b/src/window/gui/InputEditorWindow.h @@ -27,6 +27,7 @@ class InputEditorWindow : public GuiWindow { bool TestingRumble(); void DrawButtonLine(const char* buttonName, uint8_t port, CONTROLLERBUTTONS_T bitmask, uint16_t specialButton, ImVec4 color); + void DrawDeviceVisibilityButtons(); protected: void InitElement() override; void DrawElement() override; @@ -85,6 +86,5 @@ class InputEditorWindow : public GuiWindow { void DrawClearAllButton(uint8_t portIndex); std::map mDeviceIndexVisiblity; - void DrawDeviceVisibilityButtons(); }; } // namespace Ship