mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2025-12-16 12:08:49 +00:00
Add Toggle Turbo Mode to controller input settings
- Add ability to bind a controller button to Toggle Turbo Mode to turbo using the controller. Behaves exactly the same as the keyboard Toggle Turbo Mode shortcut. - Respects the Turbo Speed Limit To test, bind a controller button to the Toggle Turbo Mode input in the Controls -> Input -> Misc area.
This commit is contained in:
parent
e0b8e8440a
commit
4d31469062
@ -803,6 +803,7 @@ object NativeLibrary {
|
||||
const val DPAD = 780
|
||||
const val BUTTON_DEBUG = 781
|
||||
const val BUTTON_GPIO14 = 782
|
||||
const val BUTTON_TURBO = 783
|
||||
const val BUTTON_SWAP = 800
|
||||
const val BUTTON_TURBO = 801
|
||||
}
|
||||
|
||||
@ -66,8 +66,9 @@ static const std::array<int, Settings::NativeButton::NumButtons> default_buttons
|
||||
InputManager::N3DS_TRIGGER_L, InputManager::N3DS_TRIGGER_R,
|
||||
InputManager::N3DS_BUTTON_START, InputManager::N3DS_BUTTON_SELECT,
|
||||
InputManager::N3DS_BUTTON_DEBUG, InputManager::N3DS_BUTTON_GPIO14,
|
||||
InputManager::N3DS_BUTTON_ZL, InputManager::N3DS_BUTTON_ZR,
|
||||
InputManager::N3DS_BUTTON_HOME,
|
||||
InputManager::N3DS_BUTTON_TURBO, InputManager::N3DS_BUTTON_ZL,
|
||||
InputManager::N3DS_BUTTON_ZR, InputManager::N3DS_BUTTON_HOME,
|
||||
InputManager::N3DS_BUTTON_POWER,
|
||||
};
|
||||
|
||||
static const std::array<int, Settings::NativeAnalog::NumAnalogs> default_analogs{{
|
||||
|
||||
@ -40,6 +40,7 @@ button_start=
|
||||
button_select=
|
||||
button_debug=
|
||||
button_gpio14=
|
||||
button_turbo=
|
||||
button_zl=
|
||||
button_zr=
|
||||
button_home=
|
||||
|
||||
@ -40,6 +40,7 @@ enum ButtonType {
|
||||
N3DS_TRIGGER_R = 774,
|
||||
N3DS_BUTTON_DEBUG = 781,
|
||||
N3DS_BUTTON_GPIO14 = 782
|
||||
N3DS_BUTTON_TURBO = 783
|
||||
};
|
||||
|
||||
class ButtonList;
|
||||
|
||||
@ -494,6 +494,9 @@ void GMainWindow::InitializeWidgets() {
|
||||
});
|
||||
|
||||
InputCommon::Init();
|
||||
turbo_poll_timer.setInterval(10);
|
||||
connect(&turbo_poll_timer, &QTimer::timeout, this, &GMainWindow::PollTurboButton);
|
||||
UpdateTurboButtonBinding(true);
|
||||
multiplayer_state = new MultiplayerState(system, this, game_list->GetModel(),
|
||||
ui->action_Leave_Room, ui->action_Show_Room);
|
||||
multiplayer_state->setVisible(false);
|
||||
@ -878,6 +881,8 @@ void GMainWindow::InitializeHotkeys() {
|
||||
const auto fullscreen_hotkey = hotkey_registry.GetKeySequence(main_window, fullscreen);
|
||||
add_secondary_window_hotkey(action_secondary_fullscreen, fullscreen_hotkey,
|
||||
SLOT(ToggleSecondaryFullscreen()));
|
||||
|
||||
UpdateTurboButtonBinding(true);
|
||||
}
|
||||
|
||||
void GMainWindow::SetDefaultUIGeometry() {
|
||||
@ -1565,6 +1570,7 @@ void GMainWindow::ShutdownGame() {
|
||||
UpdateSaveStates();
|
||||
|
||||
emulation_running = false;
|
||||
RefreshTurboPollingState();
|
||||
|
||||
game_title.clear();
|
||||
UpdateWindowTitle();
|
||||
@ -2460,6 +2466,7 @@ void GMainWindow::OnStartGame() {
|
||||
|
||||
UpdateSaveStates();
|
||||
UpdateStatusButtons();
|
||||
UpdateTurboButtonBinding();
|
||||
}
|
||||
|
||||
void GMainWindow::OnRestartGame() {
|
||||
@ -2668,6 +2675,54 @@ void GMainWindow::ReloadTurbo() {
|
||||
UpdateStatusBar();
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateTurboButtonBinding(bool force) {
|
||||
const auto& binding =
|
||||
Settings::values.current_input_profile.buttons[Settings::NativeButton::Turbo];
|
||||
|
||||
if (!force && binding == turbo_button_binding) {
|
||||
RefreshTurboPollingState();
|
||||
return;
|
||||
}
|
||||
|
||||
turbo_button_binding = binding;
|
||||
if (!turbo_button_binding.empty()) {
|
||||
turbo_button_device = Input::CreateDevice<Input::ButtonDevice>(turbo_button_binding);
|
||||
if (!turbo_button_device) {
|
||||
LOG_WARNING(Frontend, "Failed to create turbo controller device for binding {}",
|
||||
turbo_button_binding);
|
||||
}
|
||||
} else {
|
||||
turbo_button_device.reset();
|
||||
}
|
||||
|
||||
RefreshTurboPollingState();
|
||||
}
|
||||
|
||||
void GMainWindow::RefreshTurboPollingState() {
|
||||
if (emulation_running && turbo_button_device) {
|
||||
turbo_button_was_pressed = turbo_button_device->GetStatus();
|
||||
if (!turbo_poll_timer.isActive()) {
|
||||
turbo_poll_timer.start();
|
||||
}
|
||||
} else {
|
||||
turbo_poll_timer.stop();
|
||||
turbo_button_was_pressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::PollTurboButton() {
|
||||
if (!emulation_running || !turbo_button_device) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool pressed = turbo_button_device->GetStatus();
|
||||
if (pressed && !turbo_button_was_pressed) {
|
||||
SetTurboEnabled(!IsTurboEnabled());
|
||||
}
|
||||
|
||||
turbo_button_was_pressed = pressed;
|
||||
}
|
||||
|
||||
// TODO: This should probably take in something more descriptive than a bool. -OS
|
||||
void GMainWindow::AdjustSpeedLimit(bool increase) {
|
||||
const int SPEED_LIMIT_STEP = 5;
|
||||
@ -2818,6 +2873,8 @@ void GMainWindow::OnConfigure() {
|
||||
Settings::values.touch_from_button_maps = old_touch_from_button_maps;
|
||||
Settings::LoadProfile(old_input_profile_index);
|
||||
}
|
||||
|
||||
UpdateTurboButtonBinding(true);
|
||||
}
|
||||
|
||||
void GMainWindow::OnLoadAmiibo() {
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#ifdef __unix__
|
||||
#include <QDBusObjectPath>
|
||||
@ -23,6 +24,7 @@
|
||||
#include "citra_qt/hotkeys.h"
|
||||
#include "citra_qt/user_data_migration.h"
|
||||
#include "core/core.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/savestate.h"
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
|
||||
@ -266,6 +268,9 @@ private slots:
|
||||
bool IsTurboEnabled();
|
||||
void SetTurboEnabled(bool);
|
||||
void ReloadTurbo();
|
||||
void UpdateTurboButtonBinding(bool force = false);
|
||||
void RefreshTurboPollingState();
|
||||
void PollTurboButton();
|
||||
void AdjustSpeedLimit(bool increase);
|
||||
void UpdateSecondaryWindowVisibility();
|
||||
void ToggleScreenLayout();
|
||||
@ -377,6 +382,10 @@ private:
|
||||
bool auto_paused = false;
|
||||
bool auto_muted = false;
|
||||
QTimer mouse_hide_timer;
|
||||
QTimer turbo_poll_timer;
|
||||
std::unique_ptr<Input::ButtonDevice> turbo_button_device;
|
||||
std::string turbo_button_binding;
|
||||
bool turbo_button_was_pressed = false;
|
||||
|
||||
// Movie
|
||||
bool movie_record_on_start = false;
|
||||
|
||||
@ -29,7 +29,7 @@ QtConfig::~QtConfig() {
|
||||
const std::array<int, Settings::NativeButton::NumButtons> QtConfig::default_buttons = {
|
||||
Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_T, Qt::Key_G,
|
||||
Qt::Key_F, Qt::Key_H, Qt::Key_Q, Qt::Key_W, Qt::Key_M, Qt::Key_N,
|
||||
Qt::Key_O, Qt::Key_P, Qt::Key_1, Qt::Key_2, Qt::Key_B, Qt::Key_V,
|
||||
Qt::Key_O, Qt::Key_P, Qt::Key_unknown, Qt::Key_1, Qt::Key_2, Qt::Key_B, Qt::Key_V,
|
||||
};
|
||||
|
||||
const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> QtConfig::default_analogs{{
|
||||
|
||||
@ -170,8 +170,8 @@ ConfigureInput::ConfigureInput(Core::System& _system, QWidget* parent)
|
||||
ui->buttonA, ui->buttonB, ui->buttonX, ui->buttonY,
|
||||
ui->buttonDpadUp, ui->buttonDpadDown, ui->buttonDpadLeft, ui->buttonDpadRight,
|
||||
ui->buttonL, ui->buttonR, ui->buttonStart, ui->buttonSelect,
|
||||
ui->buttonDebug, ui->buttonGpio14, ui->buttonZL, ui->buttonZR,
|
||||
ui->buttonHome, ui->buttonPower,
|
||||
ui->buttonDebug, ui->buttonGpio14, ui->buttonTurbo, ui->buttonZL,
|
||||
ui->buttonZR, ui->buttonHome, ui->buttonPower,
|
||||
};
|
||||
|
||||
analog_map_buttons = {{
|
||||
|
||||
@ -470,6 +470,24 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_32">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_40">
|
||||
<property name="text">
|
||||
<string>Toggle Turbo Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonTurbo">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -1093,6 +1111,7 @@
|
||||
<tabstop>buttonHome</tabstop>
|
||||
<tabstop>buttonCircleMod</tabstop>
|
||||
<tabstop>buttonDebug</tabstop>
|
||||
<tabstop>buttonTurbo</tabstop>
|
||||
<tabstop>buttonGpio14</tabstop>
|
||||
<tabstop>buttonMotionTouch</tabstop>
|
||||
<tabstop>buttonAutoMap</tabstop>
|
||||
|
||||
@ -48,9 +48,11 @@ bool SdlConfig::LoadINI(const std::string& default_contents, bool retry) {
|
||||
}
|
||||
|
||||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons = {
|
||||
SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T, SDL_SCANCODE_G,
|
||||
SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_M, SDL_SCANCODE_N,
|
||||
SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B,
|
||||
SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X,
|
||||
SDL_SCANCODE_T, SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H,
|
||||
SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_M, SDL_SCANCODE_N,
|
||||
SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_1,
|
||||
SDL_SCANCODE_2, SDL_SCANCODE_B, SDL_SCANCODE_V,
|
||||
};
|
||||
|
||||
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs{{
|
||||
|
||||
@ -40,6 +40,7 @@ button_start=
|
||||
button_select=
|
||||
button_debug=
|
||||
button_gpio14=
|
||||
button_turbo=
|
||||
button_zl=
|
||||
button_zr=
|
||||
button_home=
|
||||
|
||||
@ -133,6 +133,7 @@ enum Values {
|
||||
Select,
|
||||
Debug,
|
||||
Gpio14,
|
||||
Turbo,
|
||||
|
||||
ZL,
|
||||
ZR,
|
||||
@ -170,6 +171,7 @@ static const std::array<const char*, NumButtons> mapping = {{
|
||||
"button_select",
|
||||
"button_debug",
|
||||
"button_gpio14",
|
||||
"button_turbo",
|
||||
"button_zl",
|
||||
"button_zr",
|
||||
"button_home",
|
||||
|
||||
@ -208,6 +208,7 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||
state.select.Assign(buttons[Select - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.debug.Assign(buttons[Debug - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.gpio14.Assign(buttons[Gpio14 - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.turbo.Assign(buttons[Turbo - BUTTON_HID_BEGIN]->GetStatus());
|
||||
|
||||
// Get current circle pad position and update circle pad direction
|
||||
float circle_pad_x_f, circle_pad_y_f;
|
||||
|
||||
@ -52,6 +52,7 @@ struct PadState {
|
||||
BitField<11, 1, u32> y;
|
||||
BitField<12, 1, u32> debug;
|
||||
BitField<13, 1, u32> gpio14;
|
||||
BitField<14, 1, u32> turbo;
|
||||
|
||||
BitField<28, 1, u32> circle_right;
|
||||
BitField<29, 1, u32> circle_left;
|
||||
|
||||
@ -59,7 +59,8 @@ struct ControllerState {
|
||||
BitField<11, 1, u16> y;
|
||||
BitField<12, 1, u16> debug;
|
||||
BitField<13, 1, u16> gpio14;
|
||||
// Bits 14-15 are currently unused
|
||||
BitField<14, 1, u16> turbo;
|
||||
// Bit 15 is currently unused
|
||||
};
|
||||
s16_le circle_pad_x;
|
||||
s16_le circle_pad_y;
|
||||
@ -261,6 +262,7 @@ void Movie::Play(Service::HID::PadState& pad_state, s16& circle_pad_x, s16& circ
|
||||
pad_state.y.Assign(s.pad_and_circle.y);
|
||||
pad_state.debug.Assign(s.pad_and_circle.debug);
|
||||
pad_state.gpio14.Assign(s.pad_and_circle.gpio14);
|
||||
pad_state.turbo.Assign(s.pad_and_circle.turbo);
|
||||
|
||||
circle_pad_x = s.pad_and_circle.circle_pad_x;
|
||||
circle_pad_y = s.pad_and_circle.circle_pad_y;
|
||||
@ -385,6 +387,7 @@ void Movie::Record(const Service::HID::PadState& pad_state, const s16& circle_pa
|
||||
s.pad_and_circle.y.Assign(static_cast<u16>(pad_state.y));
|
||||
s.pad_and_circle.debug.Assign(static_cast<u16>(pad_state.debug));
|
||||
s.pad_and_circle.gpio14.Assign(static_cast<u16>(pad_state.gpio14));
|
||||
s.pad_and_circle.turbo.Assign(static_cast<u16>(pad_state.turbo));
|
||||
|
||||
s.pad_and_circle.circle_pad_x = circle_pad_x;
|
||||
s.pad_and_circle.circle_pad_y = circle_pad_y;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user