diff --git a/Source/Core/Core/HW/GCPadEmu.h b/Source/Core/Core/HW/GCPadEmu.h index 66a1aee4e4..a03eaebcd3 100644 --- a/Source/Core/Core/HW/GCPadEmu.h +++ b/Source/Core/Core/HW/GCPadEmu.h @@ -65,6 +65,7 @@ public: static constexpr const char* X_BUTTON = "X"; static constexpr const char* Y_BUTTON = "Y"; static constexpr const char* Z_BUTTON = "Z"; + static constexpr const char* HOTKEY_BUTTON = "Hotkey"; static constexpr const char* START_BUTTON = "Start"; // i18n: The left trigger button (labeled L on real controllers) diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp index 470d2b8c2f..97818b5b67 100644 --- a/Source/Core/Core/HW/GCPadEmu.cpp +++ b/Source/Core/Core/HW/GCPadEmu.cpp @@ -25,6 +25,7 @@ static const u16 button_bitmasks[] = { PAD_BUTTON_Y, PAD_TRIGGER_Z, PAD_BUTTON_START, + PAD_BUTTON_HOTKEY, 0 // MIC HAX }; @@ -47,6 +48,9 @@ GCPad::GCPad(const unsigned int index) : m_index(index) // i18n: The START/PAUSE button on GameCube controllers m_buttons->AddInput(ControllerEmu::Translate, START_BUTTON, _trans("START")); + // Hotkey Button + m_buttons->AddInput(ControllerEmu::Translate, HOTKEY_BUTTON, _trans("HOTKEY")); + // sticks groups.emplace_back(m_main_stick = new ControllerEmu::OctagonAnalogStick( MAIN_STICK_GROUP, _trans("Control Stick"), MAIN_STICK_GATE_RADIUS)); diff --git a/Source/Core/DolphinNoGUI/PlatformX11.cpp b/Source/Core/DolphinNoGUI/PlatformX11.cpp index 8dcd93bf52..5d7386da38 100644 --- a/Source/Core/DolphinNoGUI/PlatformX11.cpp +++ b/Source/Core/DolphinNoGUI/PlatformX11.cpp @@ -16,6 +16,12 @@ static constexpr auto X_None = None; #include "Core/Core.h" #include "Core/State.h" +#include "Core/HW/GCPad.h" +#include "InputCommon/GCPadStatus.h" +#include +#include "Core/Config/GraphicsSettings.h" +#include "VideoCommon/VideoConfig.h" + #include #include #include @@ -149,11 +155,78 @@ void PlatformX11::MainLoop() { while (IsRunning()) { + static int hotkey = 0; + static int slot = 0; + static int fps = 0; + static int aspect = 0; + UpdateRunningFlag(); Core::HostDispatchJobs(); ProcessEvents(); UpdateWindowPosition(); + if(Pad::IsInitialized()) { + GCPadStatus x = Pad::GetStatus(0); + + if( (x.button & PAD_BUTTON_HOTKEY) == PAD_BUTTON_HOTKEY) { // hotkey pressed + if(hotkey == 1) { + hotkey = 2; + } + } else { + hotkey = 1; // assure hotkey is released between actions + } + + if(hotkey == 2) { // hotkey pressed + if( (x.button & PAD_BUTTON_START) == PAD_BUTTON_START) { + RequestShutdown(); + hotkey = 0; + } + + if( (x.button & PAD_TRIGGER_L) == PAD_TRIGGER_L) { + State::Load(slot); + hotkey = 0; + } + if( (x.button & PAD_TRIGGER_R) == PAD_TRIGGER_R) { + State::Save(slot); + hotkey = 0; + } + if( (x.button & PAD_BUTTON_DOWN) == PAD_BUTTON_DOWN) { + if(slot > 0) slot--; + Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); + hotkey = 0; + } + if( (x.button & PAD_BUTTON_UP) == PAD_BUTTON_UP) { + if(slot < 10) slot++; + Core::DisplayMessage(fmt::format("Slot {} selected", slot), 4000); + hotkey = 0; + } + if( (x.button & PAD_BUTTON_A) == PAD_BUTTON_A) { + Core::SaveScreenShot(); + hotkey = 0; + } + if( (x.button & PAD_BUTTON_Y) == PAD_BUTTON_Y) { + if(fps == 0) { + Config::SetCurrent(Config::GFX_SHOW_FPS, True); + fps = 1; + } else { + Config::SetCurrent(Config::GFX_SHOW_FPS, False); + fps = 0; + } + hotkey = 0; + } + if( (x.button & PAD_BUTTON_X) == PAD_BUTTON_X) { + if(aspect == 0) { + Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Stretch); + aspect = 1; + } else { + Config::SetCurrent(Config::GFX_ASPECT_RATIO, AspectMode::Auto); + aspect = 0; + } + hotkey = 0; + } + } + } + // TODO: Is this sleep appropriate? std::this_thread::sleep_for(std::chrono::milliseconds(1)); } diff --git a/Source/Core/InputCommon/GCPadStatus.h b/Source/Core/InputCommon/GCPadStatus.h index 7da1bbd..57d294d 100644 --- a/Source/Core/InputCommon/GCPadStatus.h +++ b/Source/Core/InputCommon/GCPadStatus.h @@ -27,6 +27,7 @@ enum PadButton PAD_BUTTON_X = 0x0400, PAD_BUTTON_Y = 0x0800, PAD_BUTTON_START = 0x1000, + PAD_BUTTON_HOTKEY = 0x2000, }; struct GCPadStatus