diff --git a/Source/Core/Core/API/Controller.cpp b/Source/Core/Core/API/Controller.cpp index 0b9447805d78..89eb6403aa83 100644 --- a/Source/Core/Core/API/Controller.cpp +++ b/Source/Core/Core/API/Controller.cpp @@ -5,143 +5,259 @@ #include "Controller.h" #include "Core/Config/MainSettings.h" +#include "Core/HW/GBAPadEmu.h" #include "Core/HW/GCPad.h" #include "Core/HW/SI/SI_Device.h" +#include "Core/HW/GBAPad.h" +#include "Core/HW/GCPadEmu.h" #include "Core/HW/Wiimote.h" -#include "Core/HW/WiimoteEmu/Camera.h" -#include "InputCommon/GCAdapter.h" +#include "Core/HW/WiimoteEmu/WiimoteEmu.h" +#include "Core/HW/WiimoteEmu/Extension/Classic.h" +#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" +#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h" +#include "InputCommon/InputConfig.h" namespace API { -GCPadStatus GCManip::Get(int controller_id) +BaseManip::BaseManip(API::EventHub& event_hub, + const std::vector controllers) + : m_event_hub(event_hub), m_controllers(controllers) { - auto iter = m_overrides.find(controller_id); - if (iter != m_overrides.end()) - return iter->second.pad_status; - if (Config::Get(Config::GetInfoForSIDevice(controller_id)) == SerialInterface::SIDEVICE_WIIU_ADAPTER) - return GCAdapter::Input(controller_id); - else - return Pad::GetStatus(controller_id); + m_frame_advanced_listener = m_event_hub.ListenEvent( + [&](const API::Events::FrameAdvance&) { NotifyFrameAdvanced(); }); + for (auto i = 0; i < m_controllers.size(); i++) + { + // TODO felk: find a more robust way to set the input override functions. + // This way scripting breaks once the TAS input window is opened, + // and vice versa, the TAS window breaks once scripting starts. + m_controllers[i]->SetInputOverrideFunction([=](const std::string_view group_name, + const std::string_view control_name, + ControlState orig_state) { + const InputKey input_key = {group_name, control_name}; + std::optional manip = this->PerformInputManip(i, input_key, orig_state); + m_last_seen_input[{i, input_key}] = manip.value_or(orig_state); + return manip; + }); + } +} + +BaseManip::~BaseManip() +{ + m_event_hub.UnlistenEvent(m_frame_advanced_listener); + // TODO felk: find a proper place to hook up unregistering + /*for (const auto controller : m_controllers) + { + controller->ClearInputOverrideFunction(); + }*/ } -void GCManip::Set(GCPadStatus pad_status, int controller_id, ClearOn clear_on) +void BaseManip::NotifyFrameAdvanced() { - m_overrides[controller_id] = {pad_status, clear_on, /* used: */ false}; + std::erase_if(m_overrides, [](const auto& kvp) { + return kvp.second.clear_on == ClearOn::NextFrame && kvp.second.used; + }); } -void GCManip::PerformInputManip(GCPadStatus* pad_status, int controller_id) +std::optional +BaseManip::PerformInputManip(int controller_id, const InputKey& input_key, ControlState orig_state) { - auto iter = m_overrides.find(controller_id); + auto iter = m_overrides.find({controller_id, input_key}); if (iter == m_overrides.end()) { - return; + return std::nullopt; } - GCInputOverride& input_override = iter->second; - *pad_status = input_override.pad_status; + InputOverride& input_override = iter->second; + input_override.used = true; if (input_override.clear_on == ClearOn::NextPoll) { - m_overrides.erase(controller_id); - return; + m_overrides.erase({controller_id, input_key}); } - input_override.used = true; -} -WiimoteCommon::ButtonData WiiButtonsManip::Get(int controller_id) -{ - auto iter = m_overrides.find(controller_id); - if (iter != m_overrides.end()) - return iter->second.button_data; - return Wiimote::GetButtonData(controller_id); + return std::make_optional(input_override.state); } -void WiiButtonsManip::Set(WiimoteCommon::ButtonData button_data, int controller_id, - ClearOn clear_on) +void BaseManip::Set(int controller_id, InputKey input_key, ControlState state, ClearOn clear_on) { - m_overrides[controller_id] = {button_data, clear_on, /* used: */ false}; + m_overrides[{controller_id, input_key}] = {state, clear_on, /* used: */ false}; } -void WiiButtonsManip::PerformInputManip(WiimoteCommon::DataReportBuilder& rpt, int controller_id) +ControlState BaseManip::Get(const int controller_id, const InputKey& input_key) { - if (!rpt.HasCore()) + auto iter = m_last_seen_input.find({controller_id, input_key}); + if (iter == m_last_seen_input.end()) { - return; + return 0; // TODO felk: more sensible default? } - auto iter = m_overrides.find(controller_id); - if (iter == m_overrides.end()) - { - return; - } - WiiInputButtonsOverride& input_override = iter->second; + return iter->second; +} - WiimoteCommon::DataReportBuilder::CoreData core; - rpt.GetCoreData(&core); - core.hex = input_override.button_data.hex; - rpt.SetCoreData(core); - if (input_override.clear_on == ClearOn::NextPoll) +BaseManip& GetGCManip() +{ + const InputConfig* controller_config = Pad::GetConfig(); + const int num_controllers = controller_config->GetControllerCount(); + std::vector controllers; + for (int i = 0; i < num_controllers; i++) { - m_overrides.erase(controller_id); - return; + controllers.push_back(controller_config->GetController(i)); } - input_override.used = true; -} -void WiiIRManip::Set(IRCameraTransform ircamera_transform, int controller_id, ClearOn clear_on) -{ - m_overrides[controller_id] = {ircamera_transform, clear_on, /* used: */ false}; + static BaseManip manip(GetEventHub(), std::move(controllers)); + return manip; } -void WiiIRManip::PerformInputManip(WiimoteCommon::DataReportBuilder& rpt, int controller_id) +BaseManip& GetWiiManip() { - if (!rpt.HasIR()) + const InputConfig* controller_config = Wiimote::GetConfig(); + const int num_controllers = controller_config->GetControllerCount(); + std::vector controllers; + for (int i = 0; i < num_controllers; i++) { - return; + controllers.push_back(controller_config->GetController(i)); } - const auto iter = m_overrides.find(controller_id); - if (iter == m_overrides.end()) - { - return; - } - const WiiInputIROverride& input_override = iter->second; - -// u8* const ir_data = rpt.GetIRDataPtr(); - - using WiimoteEmu::CameraLogic; - u8 mode = CameraLogic::IR_MODE_BASIC; - if (rpt.GetIRDataSize() == sizeof(WiimoteEmu::IRExtended) * 4) - mode = CameraLogic::IR_MODE_EXTENDED; - else if (rpt.GetIRDataSize() == sizeof(WiimoteEmu::IRFull) * 2) - mode = CameraLogic::IR_MODE_FULL; - - using namespace Common; - const auto face_forward = Matrix33::RotateX(static_cast(MathUtil::TAU) / -4); - const auto ir_transform = input_override.ircamera_transform; - const auto transform = - Matrix44::FromMatrix33(face_forward) * - Matrix44::FromQuaternion(Quaternion::RotateXYZ(ir_transform.pitch_yaw_roll)) * - Matrix44::Translate(ir_transform.position); - const Vec2 fov = {CameraLogic::CAMERA_FOV_X, CameraLogic::CAMERA_FOV_Y}; - // TODO figure out how to hook this up again -// auto cam_points = CameraLogic::GetCameraPoints(transform, fov); -// m_camera_logic->Update(cam_points); + + static BaseManip manip(GetEventHub(), std::move(controllers)); + return manip; } -GCManip& GetGCManip() +BaseManip& GetWiiClassicManip() { - static GCManip manip(GetEventHub()); + const InputConfig* controller_config = Wiimote::GetConfig(); + const int num_controllers = controller_config->GetControllerCount(); + std::vector controllers; + for (int i = 0; i < num_controllers; i++) + { + const auto* wiimote = static_cast(controller_config->GetController(i)); + const auto* attachments_group = static_cast( + wiimote->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::Attachments)); + const auto& attachments = attachments_group->GetAttachmentList(); + ControllerEmu::EmulatedController* classic_controller = + attachments[WiimoteEmu::ExtensionNumber::CLASSIC].get(); + controllers.push_back(classic_controller); + } + + static BaseManip manip(GetEventHub(), std::move(controllers)); return manip; } -WiiButtonsManip& GetWiiButtonsManip() +BaseManip& GetWiiNunchukManip() { - static WiiButtonsManip manip(GetEventHub()); + const InputConfig* controller_config = Wiimote::GetConfig(); + const int num_controllers = controller_config->GetControllerCount(); + std::vector controllers; + for (int i = 0; i < num_controllers; i++) + { + const auto* wiimote = static_cast(controller_config->GetController(i)); + const auto* attachments_group = static_cast( + wiimote->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::Attachments)); + const auto& attachments = attachments_group->GetAttachmentList(); + ControllerEmu::EmulatedController* nunchuk_controller = + attachments[WiimoteEmu::ExtensionNumber::NUNCHUK].get(); + controllers.push_back(nunchuk_controller); + } + + static BaseManip manip(GetEventHub(), std::move(controllers)); return manip; } -WiiIRManip& GetWiiIRManip() +BaseManip& GetGBAManip() { - static WiiIRManip manip(GetEventHub()); + const InputConfig* controller_config = Pad::GetGBAConfig(); + const int num_controllers = controller_config->GetControllerCount(); + std::vector controllers; + for (int i = 0; i < num_controllers; i++) + { + controllers.push_back(controller_config->GetController(i)); + } + + static BaseManip manip(GetEventHub(), std::move(controllers)); return manip; } +using XYInput = ControllerEmu::ReshapableInput; +using Wii = WiimoteEmu::Wiimote; +using WiiClassic = WiimoteEmu::Classic; +using WiiNunchuk = WiimoteEmu::Nunchuk; +using GBA = GBAPad; + +const InputKey InputKey::GC_A = {GCPad::BUTTONS_GROUP, GCPad::A_BUTTON}; +const InputKey InputKey::GC_B = {GCPad::BUTTONS_GROUP, GCPad::B_BUTTON}; +const InputKey InputKey::GC_X = {GCPad::BUTTONS_GROUP, GCPad::X_BUTTON}; +const InputKey InputKey::GC_Y = {GCPad::BUTTONS_GROUP, GCPad::Y_BUTTON}; +const InputKey InputKey::GC_Z = {GCPad::BUTTONS_GROUP, GCPad::Z_BUTTON}; +const InputKey InputKey::GC_START = {GCPad::BUTTONS_GROUP, GCPad::START_BUTTON}; +const InputKey InputKey::GC_UP = {GCPad::DPAD_GROUP, DIRECTION_UP}; +const InputKey InputKey::GC_DOWN = {GCPad::DPAD_GROUP, DIRECTION_DOWN}; +const InputKey InputKey::GC_LEFT = {GCPad::DPAD_GROUP, DIRECTION_LEFT}; +const InputKey InputKey::GC_RIGHT = {GCPad::DPAD_GROUP, DIRECTION_RIGHT}; +const InputKey InputKey::GC_L = {GCPad::TRIGGERS_GROUP, GCPad::L_DIGITAL}; +const InputKey InputKey::GC_R = {GCPad::TRIGGERS_GROUP, GCPad::R_DIGITAL}; +const InputKey InputKey::GC_L_ANALOG = {GCPad::TRIGGERS_GROUP, GCPad::L_ANALOG}; +const InputKey InputKey::GC_R_ANALOG = {GCPad::TRIGGERS_GROUP, GCPad::R_ANALOG}; +const InputKey InputKey::GC_STICK_X = {GCPad::MAIN_STICK_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::GC_STICK_Y = {GCPad::MAIN_STICK_GROUP, XYInput::Y_INPUT_OVERRIDE}; +const InputKey InputKey::GC_C_STICK_X = {GCPad::C_STICK_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::GC_C_STICK_Y = {GCPad::C_STICK_GROUP, XYInput::Y_INPUT_OVERRIDE}; + +const InputKey InputKey::WII_A = {Wii::BUTTONS_GROUP, Wii::A_BUTTON}; +const InputKey InputKey::WII_B = {Wii::BUTTONS_GROUP, Wii::B_BUTTON}; +const InputKey InputKey::WII_ONE = {Wii::BUTTONS_GROUP, Wii::ONE_BUTTON}; +const InputKey InputKey::WII_TWO = {Wii::BUTTONS_GROUP, Wii::TWO_BUTTON}; +const InputKey InputKey::WII_PLUS = {Wii::BUTTONS_GROUP, Wii::PLUS_BUTTON}; +const InputKey InputKey::WII_MINUS = {Wii::BUTTONS_GROUP, Wii::MINUS_BUTTON}; +const InputKey InputKey::WII_HOME = {Wii::BUTTONS_GROUP, Wii::HOME_BUTTON}; +const InputKey InputKey::WII_UP = {Wii::DPAD_GROUP, DIRECTION_UP}; +const InputKey InputKey::WII_DOWN = {Wii::DPAD_GROUP, DIRECTION_DOWN}; +const InputKey InputKey::WII_LEFT = {Wii::DPAD_GROUP, DIRECTION_LEFT}; +const InputKey InputKey::WII_RIGHT = {Wii::DPAD_GROUP, DIRECTION_RIGHT}; +const InputKey InputKey::WII_IR_X = {Wii::IR_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::WII_IR_Y = {Wii::IR_GROUP, XYInput::Y_INPUT_OVERRIDE}; +const InputKey InputKey::WII_ACCELERATION_X = {Wii::ACCELEROMETER_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::WII_ACCELERATION_Y = {Wii::ACCELEROMETER_GROUP, XYInput::Y_INPUT_OVERRIDE}; +const InputKey InputKey::WII_ACCELERATION_Z = {Wii::ACCELEROMETER_GROUP, XYInput::Z_INPUT_OVERRIDE}; +const InputKey InputKey::WII_ANGULAR_VELOCITY_X = {Wii::GYROSCOPE_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::WII_ANGULAR_VELOCITY_Y = {Wii::GYROSCOPE_GROUP, XYInput::Y_INPUT_OVERRIDE}; +const InputKey InputKey::WII_ANGULAR_VELOCITY_Z = {Wii::GYROSCOPE_GROUP, XYInput::Z_INPUT_OVERRIDE}; + +const InputKey InputKey::WII_CLASSIC_A = {WiiClassic::BUTTONS_GROUP, WiiClassic::A_BUTTON}; +const InputKey InputKey::WII_CLASSIC_B = {WiiClassic::BUTTONS_GROUP, WiiClassic::B_BUTTON}; +const InputKey InputKey::WII_CLASSIC_X = {WiiClassic::BUTTONS_GROUP, WiiClassic::X_BUTTON}; +const InputKey InputKey::WII_CLASSIC_Y = {WiiClassic::BUTTONS_GROUP, WiiClassic::Y_BUTTON}; +const InputKey InputKey::WII_CLASSIC_ZL = {WiiClassic::BUTTONS_GROUP, WiiClassic::ZL_BUTTON}; +const InputKey InputKey::WII_CLASSIC_ZR = {WiiClassic::BUTTONS_GROUP, WiiClassic::ZR_BUTTON}; +const InputKey InputKey::WII_CLASSIC_PLUS = {WiiClassic::BUTTONS_GROUP, WiiClassic::PLUS_BUTTON}; +const InputKey InputKey::WII_CLASSIC_MINUS = {WiiClassic::BUTTONS_GROUP, WiiClassic::MINUS_BUTTON}; +const InputKey InputKey::WII_CLASSIC_HOME = {WiiClassic::BUTTONS_GROUP, WiiClassic::HOME_BUTTON}; +const InputKey InputKey::WII_CLASSIC_UP = {WiiClassic::DPAD_GROUP, DIRECTION_UP}; +const InputKey InputKey::WII_CLASSIC_DOWN = {WiiClassic::DPAD_GROUP, DIRECTION_DOWN}; +const InputKey InputKey::WII_CLASSIC_LEFT = {WiiClassic::DPAD_GROUP, DIRECTION_LEFT}; +const InputKey InputKey::WII_CLASSIC_RIGHT = {WiiClassic::DPAD_GROUP, DIRECTION_RIGHT}; +const InputKey InputKey::WII_CLASSIC_L = {WiiClassic::TRIGGERS_GROUP, WiiClassic::L_DIGITAL}; +const InputKey InputKey::WII_CLASSIC_R = {WiiClassic::TRIGGERS_GROUP, WiiClassic::R_DIGITAL}; +const InputKey InputKey::WII_CLASSIC_L_ANALOG = {WiiClassic::TRIGGERS_GROUP, WiiClassic::L_ANALOG}; +const InputKey InputKey::WII_CLASSIC_R_ANALOG = {WiiClassic::TRIGGERS_GROUP, WiiClassic::R_ANALOG}; +const InputKey InputKey::WII_CLASSIC_LEFT_STICK_X = {WiiClassic::LEFT_STICK_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::WII_CLASSIC_LEFT_STICK_Y = {WiiClassic::LEFT_STICK_GROUP, XYInput::Y_INPUT_OVERRIDE}; +const InputKey InputKey::WII_CLASSIC_RIGHT_STICK_X = {WiiClassic::RIGHT_STICK_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::WII_CLASSIC_RIGHT_STICK_Y = {WiiClassic::RIGHT_STICK_GROUP, XYInput::Y_INPUT_OVERRIDE}; + +const InputKey InputKey::WII_NUNCHUK_C = {WiiNunchuk::BUTTONS_GROUP, WiiNunchuk::C_BUTTON}; +const InputKey InputKey::WII_NUNCHUK_Z = {WiiNunchuk::BUTTONS_GROUP, WiiNunchuk::Z_BUTTON}; +const InputKey InputKey::WII_NUNCHUK_STICK_X = {WiiNunchuk::STICK_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::WII_NUNCHUK_STICK_Y = {WiiNunchuk::STICK_GROUP, XYInput::Y_INPUT_OVERRIDE}; +const InputKey InputKey::WII_NUNCHUCK_ACCELERATION_X = {WiiNunchuk::ACCELEROMETER_GROUP, XYInput::X_INPUT_OVERRIDE}; +const InputKey InputKey::WII_NUNCHUCK_ACCELERATION_Y = {WiiNunchuk::ACCELEROMETER_GROUP, XYInput::Y_INPUT_OVERRIDE}; +const InputKey InputKey::WII_NUNCHUCK_ACCELERATION_Z = {WiiNunchuk::ACCELEROMETER_GROUP, XYInput::Z_INPUT_OVERRIDE}; + +const InputKey InputKey::GBA_A = {GBA::BUTTONS_GROUP, GBA::A_BUTTON}; +const InputKey InputKey::GBA_B = {GBA::BUTTONS_GROUP, GBA::B_BUTTON}; +const InputKey InputKey::GBA_L = {GBA::BUTTONS_GROUP, GBA::L_BUTTON}; +const InputKey InputKey::GBA_R = {GBA::BUTTONS_GROUP, GBA::R_BUTTON}; +const InputKey InputKey::GBA_START = {GBA::BUTTONS_GROUP, GBA::START_BUTTON}; +const InputKey InputKey::GBA_SELECT = {GBA::BUTTONS_GROUP, GBA::SELECT_BUTTON}; +const InputKey InputKey::GBA_UP = {GBA::DPAD_GROUP, DIRECTION_UP}; +const InputKey InputKey::GBA_DOWN = {GBA::DPAD_GROUP, DIRECTION_DOWN}; +const InputKey InputKey::GBA_LEFT = {GBA::DPAD_GROUP, DIRECTION_LEFT}; +const InputKey InputKey::GBA_RIGHT = {GBA::DPAD_GROUP, DIRECTION_RIGHT}; + } // namespace API diff --git a/Source/Core/Core/API/Controller.h b/Source/Core/Core/API/Controller.h index f4e4241f1302..debb905277f8 100644 --- a/Source/Core/Core/API/Controller.h +++ b/Source/Core/Core/API/Controller.h @@ -4,13 +4,14 @@ #pragma once -#include "Common/CommonTypes.h" #include "Core/API/Events.h" #include "Core/HW/WiimoteCommon/DataReport.h" -#include "InputCommon/GCPadStatus.h" +#include "Core/HW/WiimoteEmu/WiimoteEmu.h" +#include "InputCommon/InputConfig.h" namespace API { + enum class ClearOn { NextPoll = 0, @@ -18,94 +19,136 @@ enum class ClearOn NextOverride = 2, }; -template -class BaseManip +struct InputKey { -public: - BaseManip(API::EventHub& event_hub) : m_event_hub(event_hub) - { - m_frame_advanced_listener = m_event_hub.ListenEvent( - [&](const API::Events::FrameAdvance&) { NotifyFrameAdvanced(); }); - } - ~BaseManip() { m_event_hub.UnlistenEvent(m_frame_advanced_listener); } - void Clear() { m_overrides.clear(); } - void NotifyFrameAdvanced() - { - // std::erase_if back-ported to C++17 - for (auto i = m_overrides.begin(), last = m_overrides.end(); i != last; ) - { - auto kvp = *i; - if (kvp.second.clear_on == ClearOn::NextFrame && kvp.second.used) - i = m_overrides.erase(i); - else - ++i; - } - } + static const InputKey GC_A; + static const InputKey GC_B; + static const InputKey GC_X; + static const InputKey GC_Y; + static const InputKey GC_Z; + static const InputKey GC_START; + static const InputKey GC_UP; + static const InputKey GC_DOWN; + static const InputKey GC_LEFT; + static const InputKey GC_RIGHT; + static const InputKey GC_L; + static const InputKey GC_R; + static const InputKey GC_L_ANALOG; + static const InputKey GC_R_ANALOG; + static const InputKey GC_STICK_X; + static const InputKey GC_STICK_Y; + static const InputKey GC_C_STICK_X; + static const InputKey GC_C_STICK_Y; -protected: - std::map m_overrides; + static const InputKey WII_A; + static const InputKey WII_B; + static const InputKey WII_ONE; + static const InputKey WII_TWO; + static const InputKey WII_PLUS; + static const InputKey WII_MINUS; + static const InputKey WII_HOME; + static const InputKey WII_UP; + static const InputKey WII_DOWN; + static const InputKey WII_LEFT; + static const InputKey WII_RIGHT; + static const InputKey WII_IR_X; + static const InputKey WII_IR_Y; + static const InputKey WII_ACCELERATION_X; + static const InputKey WII_ACCELERATION_Y; + static const InputKey WII_ACCELERATION_Z; + static const InputKey WII_ANGULAR_VELOCITY_X; + static const InputKey WII_ANGULAR_VELOCITY_Y; + static const InputKey WII_ANGULAR_VELOCITY_Z; -private: - API::EventHub& m_event_hub; - API::ListenerID m_frame_advanced_listener; -}; + static const InputKey WII_CLASSIC_A; + static const InputKey WII_CLASSIC_B; + static const InputKey WII_CLASSIC_X; + static const InputKey WII_CLASSIC_Y; + static const InputKey WII_CLASSIC_ZL; + static const InputKey WII_CLASSIC_ZR; + static const InputKey WII_CLASSIC_PLUS; + static const InputKey WII_CLASSIC_MINUS; + static const InputKey WII_CLASSIC_HOME; + static const InputKey WII_CLASSIC_UP; + static const InputKey WII_CLASSIC_DOWN; + static const InputKey WII_CLASSIC_LEFT; + static const InputKey WII_CLASSIC_RIGHT; + static const InputKey WII_CLASSIC_L; + static const InputKey WII_CLASSIC_R; + static const InputKey WII_CLASSIC_L_ANALOG; + static const InputKey WII_CLASSIC_R_ANALOG; + static const InputKey WII_CLASSIC_LEFT_STICK_X; + static const InputKey WII_CLASSIC_LEFT_STICK_Y; + static const InputKey WII_CLASSIC_RIGHT_STICK_X; + static const InputKey WII_CLASSIC_RIGHT_STICK_Y; -struct WiiInputButtonsOverride -{ - WiimoteCommon::ButtonData button_data; - ClearOn clear_on; - bool used; -}; + static const InputKey WII_NUNCHUK_C; + static const InputKey WII_NUNCHUK_Z; + static const InputKey WII_NUNCHUK_STICK_X; + static const InputKey WII_NUNCHUK_STICK_Y; + static const InputKey WII_NUNCHUCK_ACCELERATION_X; + static const InputKey WII_NUNCHUCK_ACCELERATION_Y; + static const InputKey WII_NUNCHUCK_ACCELERATION_Z; -struct IRCameraTransform -{ - Common::Vec3 position; - Common::Vec3 pitch_yaw_roll; -}; + static const InputKey GBA_A; + static const InputKey GBA_B; + static const InputKey GBA_L; + static const InputKey GBA_R; + static const InputKey GBA_START; + static const InputKey GBA_SELECT; + static const InputKey GBA_UP; + static const InputKey GBA_DOWN; + static const InputKey GBA_LEFT; + static const InputKey GBA_RIGHT; -struct WiiInputIROverride -{ - IRCameraTransform ircamera_transform; - ClearOn clear_on; - bool used; -}; + std::string_view group_name; + std::string_view control_name; -class WiiButtonsManip : public BaseManip -{ -public: - using BaseManip::BaseManip; - WiimoteCommon::ButtonData Get(int controller_id); - void Set(WiimoteCommon::ButtonData button_data, int controller_id, ClearOn clear_on); - void PerformInputManip(WiimoteCommon::DataReportBuilder& rpt, int controller_id); -}; + bool operator==(const InputKey& o) const + { + return group_name == o.group_name && control_name == o.control_name; + } -class WiiIRManip : public BaseManip -{ -public: - using BaseManip::BaseManip; - void Set(IRCameraTransform ircamera_transform, int controller_id, ClearOn clear_on); - void PerformInputManip(WiimoteCommon::DataReportBuilder& rpt, int controller_id); + bool operator<(const InputKey& o) const + { + return group_name < o.group_name || + (group_name == o.group_name && control_name < o.control_name); + } }; -struct GCInputOverride +struct InputOverride { - GCPadStatus pad_status; + ControlState state; ClearOn clear_on; bool used; }; -class GCManip : public BaseManip +class BaseManip { public: - using BaseManip::BaseManip; - GCPadStatus Get(int controller_id); - void Set(GCPadStatus pad_status, int controller_id, ClearOn clear_on); - void PerformInputManip(GCPadStatus* pad_status, int controller_id); + BaseManip(API::EventHub& event_hub, + const std::vector controllers); + ~BaseManip(); + ControlState Get(int controller_id, const InputKey& input_key); + void Set(int controller_id, InputKey input_key, ControlState state, ClearOn clear_on); + void Clear() { m_overrides.clear(); } + void NotifyFrameAdvanced(); + std::optional PerformInputManip(int controller_id, const InputKey& input_key, + ControlState orig_state); + +private: + std::map, InputOverride> m_overrides; + std::map, ControlState> m_last_seen_input; + EventHub& m_event_hub; + ListenerID m_frame_advanced_listener; + std::vector m_controllers; }; // global instances -GCManip& GetGCManip(); -WiiButtonsManip& GetWiiButtonsManip(); -WiiIRManip& GetWiiIRManip(); +BaseManip& GetGCManip(); +BaseManip& GetWiiManip(); +BaseManip& GetWiiClassicManip(); +BaseManip& GetWiiNunchukManip(); +BaseManip& GetGBAManip(); } // namespace API diff --git a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp index 1495b1dbfeaf..9f0941bd1629 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp @@ -10,7 +10,6 @@ #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Common/Swap.h" -#include "Core/API/Controller.h" #include "Core/Config/MainSettings.h" #include "Core/CoreTiming.h" #include "Core/HW/GCPad.h" @@ -129,8 +128,6 @@ int CSIDevice_GCController::RunBuffer(u8* buffer, int request_length) void CSIDevice_GCController::HandleMoviePadStatus(int device_number, GCPadStatus* pad_status) { - API::GetGCManip().PerformInputManip(pad_status, device_number); - Movie::SetPolledDevice(); if (NetPlay_GetInput(device_number, pad_status)) { diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 8a334ad20bbf..b44961c5f9f5 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -19,7 +19,6 @@ #include "Common/MathUtil.h" #include "Common/MsgHandler.h" -#include "Core/API/Controller.h" #include "Core/Config/MainSettings.h" #include "Core/Config/SYSCONFSettings.h" #include "Core/ConfigManager.h" @@ -631,9 +630,6 @@ void Wiimote::SendDataReport(const DesiredWiimoteState& target_state) std::fill_n(ext_data, ext_size, u8(0xff)); } } - - API::GetWiiButtonsManip().PerformInputManip(rpt_builder, m_index); - API::GetWiiIRManip().PerformInputManip(rpt_builder, m_index); } Movie::CheckWiimoteStatus(m_bt_device_index, rpt_builder, m_active_extension, diff --git a/Source/Core/Scripting/Python/Modules/controllermodule.cpp b/Source/Core/Scripting/Python/Modules/controllermodule.cpp index dfbfd2871522..0f3299b99c21 100644 --- a/Source/Core/Scripting/Python/Modules/controllermodule.cpp +++ b/Source/Core/Scripting/Python/Modules/controllermodule.cpp @@ -5,7 +5,7 @@ #include "Scripting/Python/Modules/controllermodule.h" #include "Core/API/Controller.h" -#include "Common/Logging/Log.h" +#include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Scripting/Python/PyScriptingBackend.h" #include "Scripting/Python/Utils/module.h" @@ -13,218 +13,536 @@ namespace PyScripting { struct ControllerModuleState { - API::GCManip* gc_manip; - API::WiiButtonsManip* wii_buttons_manip; - API::WiiIRManip* wii_ir_manip; + API::BaseManip* gc_manip; + API::BaseManip* wii_manip; + API::BaseManip* wii_classic_manip; + API::BaseManip* wii_nunchuk_manip; + API::BaseManip* gba_manip; }; -static PyObject* GCPadStatusToPyDict(GCPadStatus status) { +static PyObject* get_gc_buttons(PyObject* module, PyObject* args) +{ + const auto controller_id_opt = Py::ParseTuple(args); + if (!controller_id_opt.has_value()) + return nullptr; + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + const auto get_bool = [&](const API::InputKey& input_key) { + return state->gc_manip->Get(controller_id, input_key) != 0 ? Py_True : Py_False; + }; + const auto get_analog = [&](const API::InputKey& input_key) { + return state->gc_manip->Get(controller_id, input_key); + }; return Py_BuildValue("{s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O," - "s:B,s:B,s:B,s:B,s:B,s:B,s:B,s:B,s:O}", - "Left", status.button & PAD_BUTTON_LEFT ? Py_True : Py_False, - "Right", status.button & PAD_BUTTON_RIGHT ? Py_True : Py_False, - "Down", status.button & PAD_BUTTON_DOWN ? Py_True : Py_False, - "Up", status.button & PAD_BUTTON_UP ? Py_True : Py_False, - "Z", status.button & PAD_TRIGGER_Z ? Py_True : Py_False, - "R", status.button & PAD_TRIGGER_R ? Py_True : Py_False, - "L", status.button & PAD_TRIGGER_L ? Py_True : Py_False, - "A", status.button & PAD_BUTTON_A ? Py_True : Py_False, - "B", status.button & PAD_BUTTON_B ? Py_True : Py_False, - "X", status.button & PAD_BUTTON_X ? Py_True : Py_False, - "Y", status.button & PAD_BUTTON_Y ? Py_True : Py_False, - "Start", status.button & PAD_BUTTON_START ? Py_True : Py_False, - - "StickX", status.stickX, - "StickY", status.stickY, - "CStickX", status.substickX, - "CStickY", status.substickY, - "TriggerLeft", status.triggerLeft, - "TriggerRight", status.triggerRight, - "AnalogA", status.analogA, - "AnalogB", status.analogB, - - "Connected", status.isConnected ? Py_True : Py_False + "s:d,s:d,s:d,s:d,s:d,s:d}", + "A", get_bool(API::InputKey::GC_A), + "B", get_bool(API::InputKey::GC_B), + "X", get_bool(API::InputKey::GC_X), + "Y", get_bool(API::InputKey::GC_Y), + "Z", get_bool(API::InputKey::GC_Z), + "Start", get_bool(API::InputKey::GC_START), + "Up", get_bool(API::InputKey::GC_UP), + "Down", get_bool(API::InputKey::GC_DOWN), + "Left", get_bool(API::InputKey::GC_LEFT), + "Right", get_bool(API::InputKey::GC_RIGHT), + "L", get_bool(API::InputKey::GC_L), + "R", get_bool(API::InputKey::GC_R), + + "StickX", get_analog(API::InputKey::GC_STICK_X), + "StickY", get_analog(API::InputKey::GC_STICK_Y), + "CStickX", get_analog(API::InputKey::GC_C_STICK_X), + "CStickY", get_analog(API::InputKey::GC_C_STICK_Y), + "TriggerLeft", get_analog(API::InputKey::GC_L_ANALOG), + "TriggerRight", get_analog(API::InputKey::GC_R_ANALOG) ); } -static GCPadStatus GCPadStatusFromPyDict(PyObject* dict) { - PyObject* py_button_left = PyDict_GetItemString(dict, "Left"); - PyObject* py_button_right = PyDict_GetItemString(dict, "Right"); - PyObject* py_button_down = PyDict_GetItemString(dict, "Down"); - PyObject* py_button_up = PyDict_GetItemString(dict, "Up"); - PyObject* py_trigger_z = PyDict_GetItemString(dict, "Z"); - PyObject* py_trigger_r = PyDict_GetItemString(dict, "R"); - PyObject* py_trigger_l = PyDict_GetItemString(dict, "L"); +static PyObject* set_gc_buttons(PyObject* module, PyObject* args) +{ + int controller_id; + PyObject* dict; + if (!PyArg_ParseTuple(args, "iO!", &controller_id, &PyDict_Type, &dict)) + return nullptr; + const ControllerModuleState* state = Py::GetState(module); + + constexpr auto clear_on = API::ClearOn::NextFrame; + const auto set_bool = [&](const API::InputKey& input_key, PyObject* py_object) { + state->gc_manip->Set(controller_id, input_key, PyObject_IsTrue(py_object) ? 1 : 0, clear_on); + }; + const auto set_analog = [&](const API::InputKey& input_key, PyObject* py_object) { + state->gc_manip->Set(controller_id, input_key, PyFloat_AsDouble(py_object), clear_on); + }; + PyObject* py_button_a = PyDict_GetItemString(dict, "A"); PyObject* py_button_b = PyDict_GetItemString(dict, "B"); PyObject* py_button_x = PyDict_GetItemString(dict, "X"); PyObject* py_button_y = PyDict_GetItemString(dict, "Y"); + PyObject* py_button_z = PyDict_GetItemString(dict, "Z"); PyObject* py_button_start = PyDict_GetItemString(dict, "Start"); - bool button_left = py_button_left != nullptr && PyObject_IsTrue(py_button_left); - bool button_right = py_button_right != nullptr && PyObject_IsTrue(py_button_right); - bool button_down = py_button_down != nullptr && PyObject_IsTrue(py_button_down); - bool button_up = py_button_up != nullptr && PyObject_IsTrue(py_button_up); - bool trigger_z = py_trigger_z != nullptr && PyObject_IsTrue(py_trigger_z); - bool trigger_r = py_trigger_r != nullptr && PyObject_IsTrue(py_trigger_r); - bool trigger_l = py_trigger_l != nullptr && PyObject_IsTrue(py_trigger_l); - bool button_a = py_button_a != nullptr && PyObject_IsTrue(py_button_a); - bool button_b = py_button_b != nullptr && PyObject_IsTrue(py_button_b); - bool button_x = py_button_x != nullptr && PyObject_IsTrue(py_button_x); - bool button_y = py_button_y != nullptr && PyObject_IsTrue(py_button_y); - bool button_start = py_button_start != nullptr && PyObject_IsTrue(py_button_start); + PyObject* py_button_up = PyDict_GetItemString(dict, "Up"); + PyObject* py_button_down = PyDict_GetItemString(dict, "Down"); + PyObject* py_button_left = PyDict_GetItemString(dict, "Left"); + PyObject* py_button_right = PyDict_GetItemString(dict, "Right"); + PyObject* py_button_l = PyDict_GetItemString(dict, "L"); + PyObject* py_button_r = PyDict_GetItemString(dict, "R"); + if (py_button_a != nullptr) set_bool(API::InputKey::GC_A, py_button_a); + if (py_button_b != nullptr) set_bool(API::InputKey::GC_B, py_button_b); + if (py_button_x != nullptr) set_bool(API::InputKey::GC_X, py_button_x); + if (py_button_y != nullptr) set_bool(API::InputKey::GC_Y, py_button_y); + if (py_button_z != nullptr) set_bool(API::InputKey::GC_Z, py_button_z); + if (py_button_start != nullptr) set_bool(API::InputKey::GC_START, py_button_start); + if (py_button_up != nullptr) set_bool(API::InputKey::GC_UP, py_button_up); + if (py_button_down != nullptr) set_bool(API::InputKey::GC_DOWN, py_button_down); + if (py_button_left != nullptr) set_bool(API::InputKey::GC_LEFT, py_button_left); + if (py_button_right != nullptr) set_bool(API::InputKey::GC_RIGHT, py_button_right); + if (py_button_l != nullptr) set_bool(API::InputKey::GC_L, py_button_l); + if (py_button_r != nullptr) set_bool(API::InputKey::GC_R, py_button_r); PyObject* py_stick_x = PyDict_GetItemString(dict, "StickX"); PyObject* py_stick_y = PyDict_GetItemString(dict, "StickY"); - PyObject* py_substick_x = PyDict_GetItemString(dict, "CStickX"); - PyObject* py_substick_y = PyDict_GetItemString(dict, "CStickY"); + PyObject* py_c_stick_x = PyDict_GetItemString(dict, "CStickX"); + PyObject* py_c_stick_y = PyDict_GetItemString(dict, "CStickY"); PyObject* py_trigger_left = PyDict_GetItemString(dict, "TriggerLeft"); PyObject* py_trigger_right = PyDict_GetItemString(dict, "TriggerRight"); - PyObject* py_analog_a = PyDict_GetItemString(dict, "AnalogA"); - PyObject* py_analog_b = PyDict_GetItemString(dict, "AnalogB"); - u8 stick_x = py_stick_x == nullptr ? 128 : PyLong_AsUnsignedLong(py_stick_x); - u8 stick_y = py_stick_y == nullptr ? 128 : PyLong_AsUnsignedLong(py_stick_y); - u8 substick_x = py_substick_x == nullptr ? 128 : PyLong_AsUnsignedLong(py_substick_x); - u8 substick_y = py_substick_y == nullptr ? 128 : PyLong_AsUnsignedLong(py_substick_y); - u8 trigger_left = py_trigger_left == nullptr ? 0 : PyLong_AsUnsignedLong(py_trigger_left); - u8 trigger_right = py_trigger_right == nullptr ? 0 : PyLong_AsUnsignedLong(py_trigger_right); - u8 analog_a = py_analog_a == nullptr ? 0 : PyLong_AsUnsignedLong(py_analog_a); - u8 analog_b = py_analog_b == nullptr ? 0 : PyLong_AsUnsignedLong(py_analog_b); - - PyObject* py_connected = PyDict_GetItemString(dict, "Connected"); - bool connected = py_connected != nullptr && PyObject_IsTrue(py_connected); - - GCPadStatus status; - status.button = (button_left ? PAD_BUTTON_LEFT : 0) | (button_right ? PAD_BUTTON_RIGHT : 0) | - (button_down ? PAD_BUTTON_DOWN : 0) | (button_up ? PAD_BUTTON_UP : 0) | - (trigger_z ? PAD_TRIGGER_Z : 0) | (trigger_r ? PAD_TRIGGER_R : 0) | - (trigger_l ? PAD_TRIGGER_L : 0) | (button_a ? PAD_BUTTON_A : 0) | - (button_b ? PAD_BUTTON_B : 0) | (button_x ? PAD_BUTTON_X : 0) | - (button_y ? PAD_BUTTON_Y : 0) | (button_start ? PAD_BUTTON_START : 0); - status.stickX = stick_x; - status.stickY = stick_y; - status.substickX = substick_x; - status.substickY = substick_y; - status.triggerLeft = trigger_left; - status.triggerRight = trigger_right; - status.analogA = analog_a; - status.analogB = analog_b; - status.isConnected = connected; - return status; -} - -static PyObject* WiiButtonDataToPyDict(WiimoteCommon::ButtonData status) { + if (py_stick_x != nullptr) set_analog(API::InputKey::GC_STICK_X, py_stick_x); + if (py_stick_y != nullptr) set_analog(API::InputKey::GC_STICK_Y, py_stick_y); + if (py_c_stick_x != nullptr) set_analog(API::InputKey::GC_C_STICK_X, py_c_stick_x); + if (py_c_stick_y != nullptr) set_analog(API::InputKey::GC_C_STICK_Y, py_c_stick_y); + if (py_trigger_left != nullptr) set_analog(API::InputKey::GC_L_ANALOG, py_trigger_left); + if (py_trigger_right != nullptr) set_analog(API::InputKey::GC_R_ANALOG, py_trigger_right); + + Py_RETURN_NONE; +} + +static PyObject* get_wii_buttons(PyObject* module, PyObject* args) +{ + const auto controller_id_opt = Py::ParseTuple(args); + if (!controller_id_opt.has_value()) + return nullptr; + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + const auto get_bool = [&](const API::InputKey& input_key) { + return state->wii_manip->Get(controller_id, input_key) != 0 ? Py_True : Py_False; + }; return Py_BuildValue("{s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O}", - "Left", status.left ? Py_True : Py_False, - "Right", status.right ? Py_True : Py_False, - "Down", status.down ? Py_True : Py_False, - "Up", status.up ? Py_True : Py_False, - "Plus", status.plus ? Py_True : Py_False, - "Two", status.two ? Py_True : Py_False, - "One", status.one ? Py_True : Py_False, - "B", status.b ? Py_True : Py_False, - "A", status.a ? Py_True : Py_False, - "Minus", status.minus ? Py_True : Py_False, - "Home", status.home ? Py_True : Py_False + "A", get_bool(API::InputKey::WII_A), + "B", get_bool(API::InputKey::WII_B), + "One", get_bool(API::InputKey::WII_ONE), + "Two", get_bool(API::InputKey::WII_TWO), + "Plus", get_bool(API::InputKey::WII_PLUS), + "Minus", get_bool(API::InputKey::WII_MINUS), + "Home", get_bool(API::InputKey::WII_HOME), + "Up", get_bool(API::InputKey::WII_UP), + "Down", get_bool(API::InputKey::WII_DOWN), + "Left", get_bool(API::InputKey::WII_LEFT), + "Right", get_bool(API::InputKey::WII_RIGHT) ); } -static WiimoteCommon::ButtonData WiiButtonDataFromPyDict(PyObject* dict) { - WiimoteCommon::ButtonData status; - status.hex = 0; - PyObject* py_left = PyDict_GetItemString(dict, "Left"); - PyObject* py_right = PyDict_GetItemString(dict, "Right"); - PyObject* py_down = PyDict_GetItemString(dict, "Down"); - PyObject* py_up = PyDict_GetItemString(dict, "Up"); - PyObject* py_plus = PyDict_GetItemString(dict, "Plus"); - PyObject* py_two = PyDict_GetItemString(dict, "Two"); - PyObject* py_one = PyDict_GetItemString(dict, "One"); - PyObject* py_b = PyDict_GetItemString(dict, "B"); +static PyObject* set_wii_buttons(PyObject* module, PyObject* args) +{ + int controller_id; + PyObject* dict; + if (!PyArg_ParseTuple(args, "iO!", &controller_id, &PyDict_Type, &dict)) + return nullptr; + + const ControllerModuleState* state = Py::GetState(module); + + const auto set_bool = [&](const API::InputKey& input_key, PyObject* py_object) { + state->wii_manip->Set(controller_id, input_key, PyObject_IsTrue(py_object) ? 1 : 0, + API::ClearOn::NextFrame); + }; + PyObject* py_a = PyDict_GetItemString(dict, "A"); + PyObject* py_b = PyDict_GetItemString(dict, "B"); + PyObject* py_one = PyDict_GetItemString(dict, "One"); + PyObject* py_two = PyDict_GetItemString(dict, "Two"); + PyObject* py_plus = PyDict_GetItemString(dict, "Plus"); PyObject* py_minus = PyDict_GetItemString(dict, "Minus"); PyObject* py_home = PyDict_GetItemString(dict, "Home"); - status.left = py_left != nullptr && PyObject_IsTrue(py_left); - status.right = py_right != nullptr && PyObject_IsTrue(py_right); - status.down = py_down != nullptr && PyObject_IsTrue(py_down); - status.up = py_up != nullptr && PyObject_IsTrue(py_up); - status.plus = py_plus != nullptr && PyObject_IsTrue(py_plus); - status.two = py_two != nullptr && PyObject_IsTrue(py_two); - status.one = py_one != nullptr && PyObject_IsTrue(py_one); - status.b = py_b != nullptr && PyObject_IsTrue(py_b); - status.a = py_a != nullptr && PyObject_IsTrue(py_a); - status.minus = py_minus != nullptr && PyObject_IsTrue(py_minus); - status.home = py_home != nullptr && PyObject_IsTrue(py_home); - return status; + PyObject* py_up = PyDict_GetItemString(dict, "Up"); + PyObject* py_down = PyDict_GetItemString(dict, "Down"); + PyObject* py_left = PyDict_GetItemString(dict, "Left"); + PyObject* py_right = PyDict_GetItemString(dict, "Right"); + if (py_a != nullptr) set_bool(API::InputKey::WII_A, py_a); + if (py_b != nullptr) set_bool(API::InputKey::WII_B, py_b); + if (py_one != nullptr) set_bool(API::InputKey::WII_ONE, py_one); + if (py_two != nullptr) set_bool(API::InputKey::WII_TWO, py_two); + if (py_plus != nullptr) set_bool(API::InputKey::WII_PLUS, py_plus); + if (py_minus != nullptr) set_bool(API::InputKey::WII_MINUS, py_minus); + if (py_home != nullptr) set_bool(API::InputKey::WII_HOME, py_home); + if (py_up != nullptr) set_bool(API::InputKey::WII_UP, py_up); + if (py_down != nullptr) set_bool(API::InputKey::WII_DOWN, py_down); + if (py_left != nullptr) set_bool(API::InputKey::WII_LEFT, py_left); + if (py_right != nullptr) set_bool(API::InputKey::WII_RIGHT, py_right); + + Py_RETURN_NONE; } -static PyObject* get_gc_buttons(PyObject* module, PyObject* args) +static PyObject* get_wii_pointer(PyObject* module, PyObject* args) { - auto controller_id_opt = Py::ParseTuple(args); + const auto controller_id_opt = Py::ParseTuple(args); if (!controller_id_opt.has_value()) return nullptr; - int controller_id = std::get<0>(controller_id_opt.value()); - ControllerModuleState* state = Py::GetState(module); - GCPadStatus pad_status = state->gc_manip->Get(controller_id); - return GCPadStatusToPyDict(pad_status); + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + return Py_BuildValue("(dd)", state->wii_manip->Get(controller_id, API::InputKey::WII_IR_X), + state->wii_manip->Get(controller_id, API::InputKey::WII_IR_Y)); } -static PyObject* set_gc_buttons(PyObject* module, PyObject* args) +static PyObject* set_wii_pointer(PyObject* module, PyObject* args) +{ + int controller_id; + float x, y; + if (!PyArg_ParseTuple(args, "iff", &controller_id, &x, &y)) + return nullptr; + const ControllerModuleState* state = Py::GetState(module); + state->wii_manip->Set(controller_id, API::InputKey::WII_IR_X, x, API::ClearOn::NextFrame); + state->wii_manip->Set(controller_id, API::InputKey::WII_IR_Y, y, API::ClearOn::NextFrame); + Py_RETURN_NONE; +} + +static PyObject* get_wii_acceleration(PyObject* module, PyObject* args) +{ + const auto controller_id_opt = Py::ParseTuple(args); + if (!controller_id_opt.has_value()) + return nullptr; + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + return Py_BuildValue("(ddd)", state->wii_manip->Get(controller_id, API::InputKey::WII_ACCELERATION_X), + state->wii_manip->Get(controller_id, API::InputKey::WII_ACCELERATION_Y), + state->wii_manip->Get(controller_id, API::InputKey::WII_ACCELERATION_Z)); +} + +static PyObject* set_wii_acceleration(PyObject* module, PyObject* args) +{ + int controller_id; + float x, y, z; + if (!PyArg_ParseTuple(args, "ifff", &controller_id, &x, &y, &z)) + return nullptr; + const ControllerModuleState* state = Py::GetState(module); + state->wii_manip->Set(controller_id, API::InputKey::WII_ACCELERATION_X, x, API::ClearOn::NextFrame); + state->wii_manip->Set(controller_id, API::InputKey::WII_ACCELERATION_Y, y, API::ClearOn::NextFrame); + state->wii_manip->Set(controller_id, API::InputKey::WII_ACCELERATION_Z, z, API::ClearOn::NextFrame); + Py_RETURN_NONE; +} + +static PyObject* get_wii_angular_velocity(PyObject* module, PyObject* args) +{ + const auto controller_id_opt = Py::ParseTuple(args); + if (!controller_id_opt.has_value()) + return nullptr; + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + return Py_BuildValue("(ddd)", + state->wii_manip->Get(controller_id, API::InputKey::WII_ANGULAR_VELOCITY_X), + state->wii_manip->Get(controller_id, API::InputKey::WII_ANGULAR_VELOCITY_Y), + state->wii_manip->Get(controller_id, API::InputKey::WII_ANGULAR_VELOCITY_Z)); +} + +static PyObject* set_wii_angular_velocity(PyObject* module, PyObject* args) +{ + int controller_id; + float x, y, z; + if (!PyArg_ParseTuple(args, "ifff", &controller_id, &x, &y, &z)) + return nullptr; + const ControllerModuleState* state = Py::GetState(module); + state->wii_manip->Set(controller_id, API::InputKey::WII_ANGULAR_VELOCITY_X, x, API::ClearOn::NextFrame); + state->wii_manip->Set(controller_id, API::InputKey::WII_ANGULAR_VELOCITY_Y, y, API::ClearOn::NextFrame); + state->wii_manip->Set(controller_id, API::InputKey::WII_ANGULAR_VELOCITY_Z, z, API::ClearOn::NextFrame); + Py_RETURN_NONE; +} + +static PyObject* get_wii_classic_buttons(PyObject* module, PyObject* args) +{ + const auto controller_id_opt = Py::ParseTuple(args); + if (!controller_id_opt.has_value()) + return nullptr; + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + const auto get_bool = [&](const API::InputKey& input_key) { + return state->wii_classic_manip->Get(controller_id, input_key) != 0 ? Py_True : Py_False; + }; + const auto get_analog = [&](const API::InputKey& input_key) { + return state->wii_classic_manip->Get(controller_id, input_key); + }; + + return Py_BuildValue("{s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O," + "s:d,s:d,s:d,s:d,s:d,s:d}", + "A", get_bool(API::InputKey::WII_CLASSIC_A), + "B", get_bool(API::InputKey::WII_CLASSIC_B), + "X", get_bool(API::InputKey::WII_CLASSIC_X), + "Y", get_bool(API::InputKey::WII_CLASSIC_Y), + "ZL", get_bool(API::InputKey::WII_CLASSIC_ZL), + "ZR", get_bool(API::InputKey::WII_CLASSIC_ZR), + "Plus", get_bool(API::InputKey::WII_CLASSIC_PLUS), + "Minus", get_bool(API::InputKey::WII_CLASSIC_MINUS), + "Home", get_bool(API::InputKey::WII_CLASSIC_HOME), + "Up", get_bool(API::InputKey::WII_CLASSIC_UP), + "Down", get_bool(API::InputKey::WII_CLASSIC_DOWN), + "Left", get_bool(API::InputKey::WII_CLASSIC_LEFT), + "Right", get_bool(API::InputKey::WII_CLASSIC_RIGHT), + "L", get_bool(API::InputKey::WII_CLASSIC_L), + "R", get_bool(API::InputKey::WII_CLASSIC_R), + "TriggerLeft", get_analog(API::InputKey::WII_CLASSIC_L_ANALOG), + "TriggerRight", get_analog(API::InputKey::WII_CLASSIC_R_ANALOG), + "LeftStickX", get_analog(API::InputKey::WII_CLASSIC_LEFT_STICK_X), + "LeftStickY", get_analog(API::InputKey::WII_CLASSIC_LEFT_STICK_Y), + "RightStickX", get_analog(API::InputKey::WII_CLASSIC_RIGHT_STICK_X), + "RightStickY", get_analog(API::InputKey::WII_CLASSIC_RIGHT_STICK_Y) + ); +} + +static PyObject* set_wii_classic_buttons(PyObject* module, PyObject* args) { int controller_id; PyObject* dict; if (!PyArg_ParseTuple(args, "iO!", &controller_id, &PyDict_Type, &dict)) return nullptr; - GCPadStatus status = GCPadStatusFromPyDict(dict); - ControllerModuleState* state = Py::GetState(module); - state->gc_manip->Set(status, controller_id, API::ClearOn::NextFrame); + + const ControllerModuleState* state = Py::GetState(module); + + const auto set_bool = [&](const API::InputKey& input_key, PyObject* py_object) { + state->wii_classic_manip->Set(controller_id, input_key, PyObject_IsTrue(py_object) ? 1 : 0, + API::ClearOn::NextFrame); + }; + const auto set_analog = [&](const API::InputKey& input_key, PyObject* py_object) { + state->wii_classic_manip->Set(controller_id, input_key, PyFloat_AsDouble(py_object), + API::ClearOn::NextFrame); + }; + + PyObject* py_a = PyDict_GetItemString(dict, "A"); + PyObject* py_b = PyDict_GetItemString(dict, "B"); + PyObject* py_x = PyDict_GetItemString(dict, "X"); + PyObject* py_y = PyDict_GetItemString(dict, "Y"); + PyObject* py_zl = PyDict_GetItemString(dict, "ZL"); + PyObject* py_zr = PyDict_GetItemString(dict, "ZR"); + PyObject* py_plus = PyDict_GetItemString(dict, "Plus"); + PyObject* py_minus = PyDict_GetItemString(dict, "Minus"); + PyObject* py_home = PyDict_GetItemString(dict, "Home"); + PyObject* py_up = PyDict_GetItemString(dict, "Up"); + PyObject* py_down = PyDict_GetItemString(dict, "Down"); + PyObject* py_left = PyDict_GetItemString(dict, "Left"); + PyObject* py_right = PyDict_GetItemString(dict, "Right"); + PyObject* py_l = PyDict_GetItemString(dict, "L"); + PyObject* py_r = PyDict_GetItemString(dict, "R"); + PyObject* py_trigger_l = PyDict_GetItemString(dict, "TriggerLeft"); + PyObject* py_trigger_r = PyDict_GetItemString(dict, "TriggerRight"); + PyObject* py_left_stick_x = PyDict_GetItemString(dict, "LeftStickX"); + PyObject* py_left_stick_y = PyDict_GetItemString(dict, "LeftStickY"); + PyObject* py_right_stick_x = PyDict_GetItemString(dict, "RightStickX"); + PyObject* py_right_stick_y = PyDict_GetItemString(dict, "RightStickY"); + if (py_a != nullptr) + set_bool(API::InputKey::WII_CLASSIC_A, py_a); + if (py_b != nullptr) + set_bool(API::InputKey::WII_CLASSIC_B, py_b); + if (py_x != nullptr) + set_bool(API::InputKey::WII_CLASSIC_X, py_x); + if (py_y != nullptr) + set_bool(API::InputKey::WII_CLASSIC_Y, py_y); + if (py_zl != nullptr) + set_bool(API::InputKey::WII_CLASSIC_ZL, py_zl); + if (py_zr != nullptr) + set_bool(API::InputKey::WII_CLASSIC_ZR, py_zr); + if (py_plus != nullptr) + set_bool(API::InputKey::WII_CLASSIC_PLUS, py_plus); + if (py_minus != nullptr) + set_bool(API::InputKey::WII_CLASSIC_MINUS, py_minus); + if (py_home != nullptr) + set_bool(API::InputKey::WII_CLASSIC_HOME, py_home); + if (py_up != nullptr) + set_bool(API::InputKey::WII_CLASSIC_UP, py_up); + if (py_down != nullptr) + set_bool(API::InputKey::WII_CLASSIC_DOWN, py_down); + if (py_left != nullptr) + set_bool(API::InputKey::WII_CLASSIC_LEFT, py_left); + if (py_right != nullptr) + set_bool(API::InputKey::WII_CLASSIC_RIGHT, py_right); + if (py_l != nullptr) + set_bool(API::InputKey::WII_CLASSIC_L, py_l); + if (py_r != nullptr) + set_bool(API::InputKey::WII_CLASSIC_R, py_r); + if (py_trigger_l != nullptr) + set_analog(API::InputKey::WII_CLASSIC_L_ANALOG, py_trigger_l); + if (py_trigger_r != nullptr) + set_analog(API::InputKey::WII_CLASSIC_R_ANALOG, py_trigger_r); + if (py_left_stick_x != nullptr) + set_analog(API::InputKey::WII_CLASSIC_LEFT_STICK_X, py_left_stick_x); + if (py_left_stick_y != nullptr) + set_analog(API::InputKey::WII_CLASSIC_LEFT_STICK_Y, py_left_stick_y); + if (py_right_stick_x != nullptr) + set_analog(API::InputKey::WII_CLASSIC_RIGHT_STICK_X, py_right_stick_x); + if (py_right_stick_y != nullptr) + set_analog(API::InputKey::WII_CLASSIC_RIGHT_STICK_Y, py_right_stick_y); + Py_RETURN_NONE; } -static PyObject* get_wii_buttons(PyObject* module, PyObject* args) +static PyObject* get_wii_nunchuk_buttons(PyObject* module, PyObject* args) { - auto controller_id_opt = Py::ParseTuple(args); + const auto controller_id_opt = Py::ParseTuple(args); if (!controller_id_opt.has_value()) return nullptr; - int controller_id = std::get<0>(controller_id_opt.value()); - ControllerModuleState* state = Py::GetState(module); - WiimoteCommon::ButtonData status = state->wii_buttons_manip->Get(controller_id); - return WiiButtonDataToPyDict(status); + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + const auto get_bool = [&](const API::InputKey& input_key) { + return state->wii_nunchuk_manip->Get(controller_id, input_key) != 0 ? Py_True : Py_False; + }; + const auto get_analog = [&](const API::InputKey& input_key) { + return state->wii_nunchuk_manip->Get(controller_id, input_key); + }; + + return Py_BuildValue("{s:O,s:O,s:d,s:d}", + "C", get_bool(API::InputKey::WII_NUNCHUK_C), + "Z", get_bool(API::InputKey::WII_NUNCHUK_Z), + "StickX", get_analog(API::InputKey::WII_NUNCHUK_STICK_X), + "StickY", get_analog(API::InputKey::WII_NUNCHUK_STICK_Y) + ); } -static PyObject* set_wii_buttons(PyObject* module, PyObject* args) +static PyObject* set_wii_nunchuk_buttons(PyObject* module, PyObject* args) { int controller_id; PyObject* dict; if (!PyArg_ParseTuple(args, "iO!", &controller_id, &PyDict_Type, &dict)) return nullptr; - WiimoteCommon::ButtonData status = WiiButtonDataFromPyDict(dict); - ControllerModuleState* state = Py::GetState(module); - state->wii_buttons_manip->Set(status, controller_id, API::ClearOn::NextFrame); + + const ControllerModuleState* state = Py::GetState(module); + + const auto set_bool = [&](const API::InputKey& input_key, PyObject* py_object) { + state->wii_nunchuk_manip->Set(controller_id, input_key, PyObject_IsTrue(py_object) ? 1 : 0, + API::ClearOn::NextFrame); + }; + + PyObject* py_c = PyDict_GetItemString(dict, "C"); + PyObject* py_z = PyDict_GetItemString(dict, "Z"); + PyObject* py_stick_x = PyDict_GetItemString(dict, "StickX"); + PyObject* py_stick_y = PyDict_GetItemString(dict, "StickY"); + if (py_c != nullptr) + set_bool(API::InputKey::WII_NUNCHUK_C, py_c); + if (py_z != nullptr) + set_bool(API::InputKey::WII_NUNCHUK_Z, py_z); + if (py_stick_x != nullptr) + set_bool(API::InputKey::WII_NUNCHUK_STICK_X, py_stick_x); + if (py_stick_y != nullptr) + set_bool(API::InputKey::WII_NUNCHUK_STICK_Y, py_stick_y); + Py_RETURN_NONE; } -static PyObject* set_wii_ircamera_transform(PyObject* module, PyObject* args) +static PyObject* get_wii_nunchuk_acceleration(PyObject* module, PyObject* args) +{ + const auto controller_id_opt = Py::ParseTuple(args); + if (!controller_id_opt.has_value()) + return nullptr; + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + return Py_BuildValue( + "(ddd)", + state->wii_nunchuk_manip->Get(controller_id, API::InputKey::WII_NUNCHUCK_ACCELERATION_X), + state->wii_nunchuk_manip->Get(controller_id, API::InputKey::WII_NUNCHUCK_ACCELERATION_Y), + state->wii_nunchuk_manip->Get(controller_id, API::InputKey::WII_NUNCHUCK_ACCELERATION_Z)); +} + +static PyObject* set_wii_nunchuk_acceleration(PyObject* module, PyObject* args) { int controller_id; - float x, y; - float z = -2; // 2 meters away from sensor bar by default - float pitch, yaw, roll; - if (!PyArg_ParseTuple(args, "ifff|fff", &controller_id, &x, &y, &z, &pitch, &yaw, &roll)) + float x, y, z; + if (!PyArg_ParseTuple(args, "ifff", &controller_id, &x, &y, &z)) + return nullptr; + const ControllerModuleState* state = Py::GetState(module); + state->wii_nunchuk_manip->Set(controller_id, API::InputKey::WII_NUNCHUCK_ACCELERATION_X, x, + API::ClearOn::NextFrame); + state->wii_nunchuk_manip->Set(controller_id, API::InputKey::WII_NUNCHUCK_ACCELERATION_Y, y, + API::ClearOn::NextFrame); + state->wii_nunchuk_manip->Set(controller_id, API::InputKey::WII_NUNCHUCK_ACCELERATION_Z, z, + API::ClearOn::NextFrame); + Py_RETURN_NONE; +} + +static PyObject* get_gba_buttons(PyObject* module, PyObject* args) +{ + const auto controller_id_opt = Py::ParseTuple(args); + if (!controller_id_opt.has_value()) + return nullptr; + const int controller_id = std::get<0>(controller_id_opt.value()); + const ControllerModuleState* state = Py::GetState(module); + const auto get_bool = [&](const API::InputKey& input_key) { + return state->gba_manip->Get(controller_id, input_key) != 0 ? Py_True : Py_False; + }; + return Py_BuildValue("{s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O,s:O}", + "A", get_bool(API::InputKey::GBA_A), + "B", get_bool(API::InputKey::GBA_B), + "L", get_bool(API::InputKey::GBA_L), + "R", get_bool(API::InputKey::GBA_R), + "Start", get_bool(API::InputKey::GBA_START), + "Select", get_bool(API::InputKey::GBA_SELECT), + "Up", get_bool(API::InputKey::GBA_UP), + "Down", get_bool(API::InputKey::GBA_DOWN), + "Left", get_bool(API::InputKey::GBA_LEFT), + "Right", get_bool(API::InputKey::GBA_RIGHT)); +} + +static PyObject* set_gba_buttons(PyObject* module, PyObject* args) +{ + int controller_id; + PyObject* dict; + if (!PyArg_ParseTuple(args, "iO!", &controller_id, &PyDict_Type, &dict)) return nullptr; const ControllerModuleState* state = Py::GetState(module); - state->wii_ir_manip->Set({{x, y, z}, {pitch, yaw, roll}}, controller_id, API::ClearOn::NextFrame); + constexpr auto clear_on = API::ClearOn::NextFrame; + const auto set_bool = [&](const API::InputKey& input_key, PyObject* py_object) { + state->gba_manip->Set(controller_id, input_key, PyObject_IsTrue(py_object) ? 1 : 0, clear_on); + }; + + PyObject* py_button_a = PyDict_GetItemString(dict, "A"); + PyObject* py_button_b = PyDict_GetItemString(dict, "B"); + PyObject* py_button_l = PyDict_GetItemString(dict, "L"); + PyObject* py_button_r = PyDict_GetItemString(dict, "R"); + PyObject* py_button_start = PyDict_GetItemString(dict, "Start"); + PyObject* py_button_select = PyDict_GetItemString(dict, "Select"); + PyObject* py_button_up = PyDict_GetItemString(dict, "Up"); + PyObject* py_button_down = PyDict_GetItemString(dict, "Down"); + PyObject* py_button_left = PyDict_GetItemString(dict, "Left"); + PyObject* py_button_right = PyDict_GetItemString(dict, "Right"); + if (py_button_a != nullptr) + set_bool(API::InputKey::GBA_A, py_button_a); + if (py_button_b != nullptr) + set_bool(API::InputKey::GBA_B, py_button_b); + if (py_button_l != nullptr) + set_bool(API::InputKey::GBA_L, py_button_l); + if (py_button_r != nullptr) + set_bool(API::InputKey::GBA_R, py_button_r); + if (py_button_start != nullptr) + set_bool(API::InputKey::GBA_START, py_button_start); + if (py_button_select != nullptr) + set_bool(API::InputKey::GBA_START, py_button_select); + if (py_button_up != nullptr) + set_bool(API::InputKey::GBA_UP, py_button_up); + if (py_button_down != nullptr) + set_bool(API::InputKey::GBA_DOWN, py_button_down); + if (py_button_left != nullptr) + set_bool(API::InputKey::GBA_LEFT, py_button_left); + if (py_button_right != nullptr) + set_bool(API::InputKey::GBA_RIGHT, py_button_right); + Py_RETURN_NONE; } static void setup_controller_module(PyObject* module, ControllerModuleState* state) { state->gc_manip = PyScriptingBackend::GetCurrent()->GetGCManip(); - state->wii_buttons_manip = PyScriptingBackend::GetCurrent()->GetWiiButtonsManip(); - state->wii_ir_manip = PyScriptingBackend::GetCurrent()->GetWiiIRManip(); + state->wii_manip = PyScriptingBackend::GetCurrent()->GetWiiManip(); + state->wii_classic_manip = PyScriptingBackend::GetCurrent()->GetWiiClassicManip(); + state->wii_nunchuk_manip = PyScriptingBackend::GetCurrent()->GetWiiNunchukManip(); + state->gba_manip = PyScriptingBackend::GetCurrent()->GetGBAManip(); PyScriptingBackend::GetCurrent()->AddCleanupFunc([state] { state->gc_manip->Clear(); - state->wii_buttons_manip->Clear(); - state->wii_ir_manip->Clear(); + state->wii_manip->Clear(); + state->wii_classic_manip->Clear(); + state->wii_nunchuk_manip->Clear(); + state->gba_manip->Clear(); }); } @@ -235,7 +553,20 @@ PyMODINIT_FUNC PyInit_controller() {"set_gc_buttons", set_gc_buttons, METH_VARARGS, ""}, {"get_wii_buttons", get_wii_buttons, METH_VARARGS, ""}, {"set_wii_buttons", set_wii_buttons, METH_VARARGS, ""}, - {"set_wii_ircamera_transform", set_wii_ircamera_transform, METH_VARARGS, ""}, + {"get_wii_pointer", get_wii_pointer, METH_VARARGS, ""}, + {"set_wii_pointer", set_wii_pointer, METH_VARARGS, ""}, + {"get_wii_acceleration", get_wii_acceleration, METH_VARARGS, ""}, + {"set_wii_acceleration", set_wii_acceleration, METH_VARARGS, ""}, + {"get_wii_angular_velocity", get_wii_angular_velocity, METH_VARARGS, ""}, + {"set_wii_angular_velocity", set_wii_angular_velocity, METH_VARARGS, ""}, + {"get_wii_classic_buttons", get_wii_classic_buttons, METH_VARARGS, ""}, + {"set_wii_classic_buttons", set_wii_classic_buttons, METH_VARARGS, ""}, + {"get_wii_nunchuk_buttons", get_wii_nunchuk_buttons, METH_VARARGS, ""}, + {"set_wii_nunchuk_buttons", set_wii_nunchuk_buttons, METH_VARARGS, ""}, + {"get_wii_nunchuk_acceleration", get_wii_nunchuk_acceleration, METH_VARARGS, ""}, + {"set_wii_nunchuk_acceleration", set_wii_nunchuk_acceleration, METH_VARARGS, ""}, + {"get_gba_buttons", get_gba_buttons, METH_VARARGS, ""}, + {"set_gba_buttons", set_gba_buttons, METH_VARARGS, ""}, {nullptr, nullptr, 0, nullptr} // Sentinel }; static PyModuleDef module_def = diff --git a/Source/Core/Scripting/Python/PyScriptingBackend.cpp b/Source/Core/Scripting/Python/PyScriptingBackend.cpp index fdeaaa4cfdb1..c362ee8f4175 100644 --- a/Source/Core/Scripting/Python/PyScriptingBackend.cpp +++ b/Source/Core/Scripting/Python/PyScriptingBackend.cpp @@ -111,10 +111,11 @@ static void ShutdownMainPythonInterpreter() PyScriptingBackend::PyScriptingBackend(std::filesystem::path script_filepath, API::EventHub& event_hub, API::Gui& gui, - API::GCManip& gc_manip, API::WiiButtonsManip& wii_buttons_manip, - API::WiiIRManip& wii_ir_manip) - : m_event_hub(event_hub), m_gui(gui), m_gc_manip(gc_manip), m_wii_buttons_manip(wii_buttons_manip), - m_wii_ir_manip(wii_ir_manip) + API::BaseManip& gc_manip, API::BaseManip& wii_manip, + API::BaseManip& wii_classic_manip, API::BaseManip& wii_nunchuk_manip, + API::BaseManip& gba_manip) + : m_event_hub(event_hub), m_gui(gui), m_gc_manip(gc_manip), m_wii_manip(wii_manip), + m_wii_classic_manip(wii_classic_manip), m_wii_nunchuk_manip(wii_nunchuk_manip), m_gba_manip(gba_manip) { std::lock_guard lock{s_bookkeeping_lock}; if (s_instances.empty()) @@ -250,19 +251,29 @@ API::Gui* PyScriptingBackend::GetGui() return &m_gui; } -API::GCManip* PyScriptingBackend::GetGCManip() +API::BaseManip* PyScriptingBackend::GetGCManip() { return &m_gc_manip; } -API::WiiButtonsManip* PyScriptingBackend::GetWiiButtonsManip() +API::BaseManip* PyScriptingBackend::GetWiiManip() { - return &m_wii_buttons_manip; + return &m_wii_manip; } -API::WiiIRManip* PyScriptingBackend::GetWiiIRManip() +API::BaseManip* PyScriptingBackend::GetWiiClassicManip() { - return &m_wii_ir_manip; + return &m_wii_classic_manip; +} + +API::BaseManip* PyScriptingBackend::GetWiiNunchukManip() +{ + return &m_wii_nunchuk_manip; +} + +API::BaseManip* PyScriptingBackend::GetGBAManip() +{ + return &m_gba_manip; } void PyScriptingBackend::AddCleanupFunc(std::function cleanup_func) diff --git a/Source/Core/Scripting/Python/PyScriptingBackend.h b/Source/Core/Scripting/Python/PyScriptingBackend.h index e5833a95f73b..e2aecbf5ebf3 100644 --- a/Source/Core/Scripting/Python/PyScriptingBackend.h +++ b/Source/Core/Scripting/Python/PyScriptingBackend.h @@ -20,14 +20,17 @@ class PyScriptingBackend { public: PyScriptingBackend(std::filesystem::path script_filepath, API::EventHub& event_hub, API::Gui& gui, - API::GCManip& gc_manip, API::WiiButtonsManip& wii_buttons_manip, API::WiiIRManip& wii_ir_manip); + API::BaseManip& gc_manip, API::BaseManip& wii_manip, API::BaseManip& wii_classic_manip, + API::BaseManip& wii_nunchuk_manip, API::BaseManip& gba_manip); ~PyScriptingBackend(); static PyScriptingBackend* GetCurrent(); API::EventHub* GetEventHub(); API::Gui* GetGui(); - API::GCManip* GetGCManip(); - API::WiiButtonsManip* GetWiiButtonsManip(); - API::WiiIRManip* GetWiiIRManip(); + API::BaseManip* GetGCManip(); + API::BaseManip* GetWiiManip(); + API::BaseManip* GetWiiClassicManip(); + API::BaseManip* GetWiiNunchukManip(); + API::BaseManip* GetGBAManip(); void AddCleanupFunc(std::function cleanup_func); // this class somewhat is a wrapper around a python interpreter state, @@ -47,9 +50,11 @@ class PyScriptingBackend PyThreadState* m_interp_threadstate; API::EventHub& m_event_hub; API::Gui& m_gui; - API::GCManip& m_gc_manip; - API::WiiButtonsManip& m_wii_buttons_manip; - API::WiiIRManip& m_wii_ir_manip; + API::BaseManip& m_gc_manip; + API::BaseManip& m_wii_manip; + API::BaseManip& m_wii_classic_manip; + API::BaseManip& m_wii_nunchuk_manip; + API::BaseManip& m_gba_manip; std::vector> m_cleanups; }; diff --git a/Source/Core/Scripting/ScriptingEngine.cpp b/Source/Core/Scripting/ScriptingEngine.cpp index 76fd831720a5..348014078208 100644 --- a/Source/Core/Scripting/ScriptingEngine.cpp +++ b/Source/Core/Scripting/ScriptingEngine.cpp @@ -19,7 +19,8 @@ ScriptingBackend::ScriptingBackend(std::filesystem::path script_filepath) // If there was support for multiple backend, a fitting one could be // detected based on the script file's extension for example. m_state = new PyScripting::PyScriptingBackend(script_filepath, API::GetEventHub(), API::GetGui(), - API::GetGCManip(), API::GetWiiButtonsManip(), API::GetWiiIRManip()); + API::GetGCManip(), API::GetWiiManip(), API::GetWiiClassicManip(), + API::GetWiiNunchukManip(), API::GetGBAManip()); } ScriptingBackend::~ScriptingBackend() {