From 9f9afeb63e912dd71e3e58338c7b4f3c03b3d6bc Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 26 Nov 2017 12:33:48 -0600 Subject: [PATCH 01/15] Wiimote Emulation: Be able to trigger swings consistently by holding down buttons. This makes certain actions easier (tested with Red Steel) --- Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp index 46dbd63c49..0c27e30298 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp @@ -40,10 +40,7 @@ void Force::GetState(ControlState* axis) controls[i + 1]->control_ref->State() - controls[i]->control_ref->State(); if (fabs(state) > deadzone) tmpf = ((state - (deadzone * sign(state))) / (1 - deadzone)); - - ControlState& ax = m_swing[i >> 1]; - *axis++ = (tmpf - ax); - ax = tmpf; + *axis++ = tmpf; } } } // namespace ControllerEmu From fb7a6a1bbe03acb530db0b2b4cfcb1fe15df0d03 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 21 Jan 2018 15:42:01 -0600 Subject: [PATCH 02/15] Wiimote Emulation: Add game-configurable shake/swing commands for the wiimote at three intensities --- Source/Core/Core/CMakeLists.txt | 1 + .../Core/Core/Config/WiimoteInputSettings.cpp | 20 ++++++++++ .../Core/Core/Config/WiimoteInputSettings.h | 23 +++++++++++ Source/Core/Core/Core.vcxproj | 4 +- Source/Core/Core/Core.vcxproj.filters | 6 +++ .../Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp | 4 +- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 40 +++++++++++++------ Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h | 13 ++++-- 8 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 Source/Core/Core/Config/WiimoteInputSettings.cpp create mode 100644 Source/Core/Core/Config/WiimoteInputSettings.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 0fecda7e8b..f5d65c0588 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -30,6 +30,7 @@ add_library(core Config/NetplaySettings.cpp Config/SYSCONFSettings.cpp Config/UISettings.cpp + Config/WiimoteInputSettings.cpp ConfigLoaders/BaseConfigLoader.cpp ConfigLoaders/GameConfigLoader.cpp ConfigLoaders/IsSettingSaveable.cpp diff --git a/Source/Core/Core/Config/WiimoteInputSettings.cpp b/Source/Core/Core/Config/WiimoteInputSettings.cpp new file mode 100644 index 0000000000..408e9f68a3 --- /dev/null +++ b/Source/Core/Core/Config/WiimoteInputSettings.cpp @@ -0,0 +1,20 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "Core/Config/WiimoteInputSettings.h" + +namespace Config +{ + // Configuration Information + + // WiimoteInput.Settings + + const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_FAST{ { System::WiiPad, "Swing", "Fast" }, 4.5 }; + const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM{ { System::WiiPad, "Swing", "Medium" }, 2.5 }; + const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_SLOW{ { System::WiiPad, "Swing", "Slow" }, 1.5 }; + + const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Shake", "Hard" }, 5.0 }; + const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Shake", "Medium" }, 3.0 }; + const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Shake", "Soft" }, 2.0 }; +} diff --git a/Source/Core/Core/Config/WiimoteInputSettings.h b/Source/Core/Core/Config/WiimoteInputSettings.h new file mode 100644 index 0000000000..c9946af046 --- /dev/null +++ b/Source/Core/Core/Config/WiimoteInputSettings.h @@ -0,0 +1,23 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "Common/Config/Config.h" + +namespace Config +{ + // Configuration Information + + // WiimoteInput.Settings + + extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_FAST; + extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM; + extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_SLOW; + + extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_HARD; + extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM; + extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT; + +} // namespace Config diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 9039da4443..cb9d82584b 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -56,6 +56,7 @@ + @@ -321,6 +322,7 @@ + @@ -600,4 +602,4 @@ - + \ No newline at end of file diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index b9a979df78..b60f775010 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -910,6 +910,9 @@ Config + + Config + @@ -1604,6 +1607,9 @@ Config + + Config + diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp index 95d61417d2..092ef0c36d 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp @@ -91,9 +91,9 @@ void Nunchuk::GetState(u8* const data) EmulateTilt(&accel, m_tilt); // swing - EmulateSwing(&accel, m_swing); + EmulateSwing(&accel, m_swing, 2.5); // shake - EmulateShake(&accel, m_shake, m_shake_step.data()); + EmulateShake(&accel, m_shake, 3.0, m_shake_step.data()); // buttons m_buttons->GetState(&nc_data.bt.hex, nunchuk_button_bitmasks.data()); diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 72e6dc3bed..308ba5e904 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -17,6 +17,7 @@ #include "Common/MsgHandler.h" #include "Core/Config/SYSCONFSettings.h" +#include "Core/Config/WiimoteInputSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/Wiimote.h" @@ -99,15 +100,12 @@ static const ReportFeatures reporting_mode_features[] = { }; void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_group, - u8* const shake_step) + const double intensity, u8* const shake_step) { // frame count of one up/down shake // < 9 no shake detection in "Wario Land: Shake It" auto const shake_step_max = 15; - // peak G-force - auto const shake_intensity = 3.0; - // shake is a bitfield of X,Y,Z shake button states static const unsigned int btns[] = {0x01, 0x02, 0x04}; unsigned int shake = 0; @@ -117,7 +115,7 @@ void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_ { if (shake & (1 << i)) { - (&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * shake_intensity; + (&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * intensity; shake_step[i] = (shake_step[i] + 1) % shake_step_max; } else @@ -160,10 +158,8 @@ void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group, (&accel->x)[fb] = sin(pitch) * sgn[fb]; } -#define SWING_INTENSITY 2.5 //-uncalibrated(aprox) 0x40-calibrated - void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const swing_group, - const bool sideways, const bool upright) + const double intensity, const bool sideways, const bool upright) { ControlState swing[3]; swing_group->GetState(swing); @@ -184,7 +180,7 @@ void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const swing_grou g_dir[axis_map[0]] *= -1; for (unsigned int i = 0; i < 3; ++i) - (&accel->x)[axis_map[i]] += swing[i] * g_dir[i] * SWING_INTENSITY; + (&accel->x)[axis_map[i]] += swing[i] * g_dir[i] * intensity; } static const u16 button_bitmasks[] = { @@ -238,7 +234,9 @@ void Wiimote::Reset() // 0x55 - 0xff: level 4 m_status.battery = (u8)(m_battery_setting->GetValue() * 100); - memset(m_shake_step, 0, sizeof(m_shake_step)); + m_shake_step = {}; + m_shake_soft_step = {}; + m_shake_hard_step = {}; // clear read request queue while (!m_read_requests.empty()) @@ -271,6 +269,8 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1 // swing groups.emplace_back(m_swing = new ControllerEmu::Force(_trans("Swing"))); + groups.emplace_back(m_swing_slow = new ControllerEmu::Force("SwingSlow")); + groups.emplace_back(m_swing_fast = new ControllerEmu::Force("SwingFast")); // tilt groups.emplace_back(m_tilt = new ControllerEmu::Tilt(_trans("Tilt"))); @@ -284,6 +284,16 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1 // i18n: Refers to a 3D axis (used when mapping motion controls) m_shake->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::Translate, _trans("Z"))); + groups.emplace_back(m_shake_soft = new ControllerEmu::Buttons("ShakeSoft")); + m_shake_soft->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "X")); + m_shake_soft->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); + m_shake_soft->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); + + groups.emplace_back(m_shake_hard = new ControllerEmu::Buttons("ShakeHard")); + m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "X")); + m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); + m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); + // extension groups.emplace_back(m_extension = new ControllerEmu::Extension(_trans("Extension"))); m_extension->attachments.emplace_back(new WiimoteEmu::None(m_reg_ext)); @@ -481,8 +491,14 @@ void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf) m_upright_setting->GetValue() ^ upright_modifier_toggle ^ upright_modifier_switch; EmulateTilt(&m_accel, m_tilt, is_sideways, is_upright); - EmulateSwing(&m_accel, m_swing, is_sideways, is_upright); - EmulateShake(&m_accel, m_shake, m_shake_step); + + EmulateSwing(&m_accel, m_swing, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM), is_sideways, is_upright); + EmulateSwing(&m_accel, m_swing_slow, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW), is_sideways, is_upright); + EmulateSwing(&m_accel, m_swing_fast, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_FAST), is_sideways, is_upright); + + EmulateShake(&m_accel, m_shake, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM), m_shake_step.data()); + EmulateShake(&m_accel, m_shake_soft, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT), m_shake_soft_step.data()); + EmulateShake(&m_accel, m_shake_hard, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_HARD), m_shake_hard_step.data()); wm_accel& accel = *reinterpret_cast(data + rptf.accel); wm_buttons& core = *reinterpret_cast(data + rptf.core); diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 812b7988de..57f8f3e636 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include @@ -154,13 +155,13 @@ struct ExtensionReg #pragma pack(pop) void EmulateShake(AccelData* const accel_data, ControllerEmu::Buttons* const buttons_group, - u8* const shake_step); + const double intensity, u8* const shake_step); void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group, const bool sideways = false, const bool upright = false); void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const tilt_group, - const bool sideways = false, const bool upright = false); + const double intensity, const bool sideways = false, const bool upright = false); enum { @@ -247,9 +248,13 @@ private: ControllerEmu::Buttons* m_buttons; ControllerEmu::Buttons* m_dpad; ControllerEmu::Buttons* m_shake; + ControllerEmu::Buttons* m_shake_soft; + ControllerEmu::Buttons* m_shake_hard; ControllerEmu::Cursor* m_ir; ControllerEmu::Tilt* m_tilt; ControllerEmu::Force* m_swing; + ControllerEmu::Force* m_swing_slow; + ControllerEmu::Force* m_swing_fast; ControllerEmu::ControlGroup* m_rumble; ControllerEmu::Output* m_motor; ControllerEmu::Extension* m_extension; @@ -274,7 +279,9 @@ private: u8 m_reporting_mode; u16 m_reporting_channel; - u8 m_shake_step[3]; + std::array m_shake_step{}; + std::array m_shake_soft_step{}; + std::array m_shake_hard_step{}; bool m_sensor_bar_on_top; From 9936a83a1b56b6e7b6f170c112caa683a125b356 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Wed, 21 Mar 2018 22:48:17 -0500 Subject: [PATCH 03/15] Add game-configurable shake/swing commands for the nunchuk at three intensities --- .../Core/Core/Config/WiimoteInputSettings.cpp | 10 ++++++++ .../Core/Core/Config/WiimoteInputSettings.h | 10 ++++++++ .../Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp | 23 +++++++++++++++++-- .../Core/HW/WiimoteEmu/Attachment/Nunchuk.h | 6 +++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Config/WiimoteInputSettings.cpp b/Source/Core/Core/Config/WiimoteInputSettings.cpp index 408e9f68a3..a60ed45e9f 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.cpp +++ b/Source/Core/Core/Config/WiimoteInputSettings.cpp @@ -17,4 +17,14 @@ namespace Config const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Shake", "Hard" }, 5.0 }; const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Shake", "Medium" }, 3.0 }; const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Shake", "Soft" }, 2.0 }; + + // NunchuckInput.Settings + + const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST{ { System::WiiPad, "Nunchuk_Swing", "Fast" }, 4.5 }; + const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_MEDIUM{ { System::WiiPad, "Nunchuk_Swing", "Medium" }, 2.5 }; + const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_SLOW{ { System::WiiPad, "Nunchuk_Swing", "Slow" }, 1.5 }; + + const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Nunchuk_Shake", "Hard" }, 5.0 }; + const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Nunchuk_Shake", "Medium" }, 3.0 }; + const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Nunchuk_Shake", "Soft" }, 2.0 }; } diff --git a/Source/Core/Core/Config/WiimoteInputSettings.h b/Source/Core/Core/Config/WiimoteInputSettings.h index c9946af046..44ab85b37d 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.h +++ b/Source/Core/Core/Config/WiimoteInputSettings.h @@ -20,4 +20,14 @@ namespace Config extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM; extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT; + // NunchuckInput.Settings + + extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST; + extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_MEDIUM; + extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_SLOW; + + extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD; + extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM; + extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT; + } // namespace Config diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp index 092ef0c36d..9ba2a8e079 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp @@ -11,6 +11,7 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" #include "Common/MathUtil.h" +#include "Core/Config/WiimoteInputSettings.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "InputCommon/ControllerEmu/Control/Input.h" @@ -42,6 +43,8 @@ Nunchuk::Nunchuk(ExtensionReg& reg) : Attachment(_trans("Nunchuk"), reg) // swing groups.emplace_back(m_swing = new ControllerEmu::Force(_trans("Swing"))); + groups.emplace_back(m_swing_slow = new ControllerEmu::Force("SwingSlow")); + groups.emplace_back(m_swing_fast = new ControllerEmu::Force("SwingFast")); // tilt groups.emplace_back(m_tilt = new ControllerEmu::Tilt(_trans("Tilt"))); @@ -55,6 +58,16 @@ Nunchuk::Nunchuk(ExtensionReg& reg) : Attachment(_trans("Nunchuk"), reg) // i18n: Refers to a 3D axis (used when mapping motion controls) m_shake->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::Translate, _trans("Z"))); + groups.emplace_back(m_shake_soft = new ControllerEmu::Buttons("ShakeSoft")); + m_shake_soft->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "X")); + m_shake_soft->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); + m_shake_soft->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); + + groups.emplace_back(m_shake_hard = new ControllerEmu::Buttons("ShakeHard")); + m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "X")); + m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); + m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); + m_id = nunchuk_id; } @@ -91,9 +104,15 @@ void Nunchuk::GetState(u8* const data) EmulateTilt(&accel, m_tilt); // swing - EmulateSwing(&accel, m_swing, 2.5); + EmulateSwing(&accel, m_swing, Config::Get(Config::NUNCHUK_INPUT_SWING_INTENSITY_MEDIUM)); + EmulateSwing(&accel, m_swing_slow, Config::Get(Config::NUNCHUK_INPUT_SWING_INTENSITY_SLOW)); + EmulateSwing(&accel, m_swing_fast, Config::Get(Config::NUNCHUK_INPUT_SWING_INTENSITY_FAST)); + // shake - EmulateShake(&accel, m_shake, 3.0, m_shake_step.data()); + EmulateShake(&accel, m_shake, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM), m_shake_step.data()); + EmulateShake(&accel, m_shake_soft, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT), m_shake_soft_step.data()); + EmulateShake(&accel, m_shake_hard, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_HARD), m_shake_hard_step.data()); + // buttons m_buttons->GetState(&nc_data.bt.hex, nunchuk_button_bitmasks.data()); diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.h b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.h index 48ec942672..8a8f5d5d08 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.h +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.h @@ -55,12 +55,18 @@ public: private: ControllerEmu::Tilt* m_tilt; ControllerEmu::Force* m_swing; + ControllerEmu::Force* m_swing_slow; + ControllerEmu::Force* m_swing_fast; ControllerEmu::Buttons* m_shake; + ControllerEmu::Buttons* m_shake_soft; + ControllerEmu::Buttons* m_shake_hard; ControllerEmu::Buttons* m_buttons; ControllerEmu::AnalogStick* m_stick; std::array m_shake_step{}; + std::array m_shake_soft_step{}; + std::array m_shake_hard_step{}; }; } From 5cbc825bc9679df1ef6f452ce6cf8b6f8b35a6e6 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 7 Apr 2018 21:13:01 -0500 Subject: [PATCH 04/15] Wiimote Emulation: add 'dynamic' swing/shake options that vary based on how long the key is pressed --- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 131 ++++++++++++++++++ Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h | 36 +++++ 2 files changed, 167 insertions(+) diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 308ba5e904..2e4d359878 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -123,6 +123,58 @@ void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_ } } +void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, ControllerEmu::Buttons* const buttons_group, + const DynamicConfiguration& config, u8* const shake_step) +{ + // frame count of one up/down shake + // < 9 no shake detection in "Wario Land: Shake It" + auto const shake_step_max = 15; + + // shake is a bitfield of X,Y,Z shake button states + static const unsigned int btns[] = { 0x01, 0x02, 0x04 }; + unsigned int shake = 0; + buttons_group->GetState(&shake, btns); + + static const int frames_high = 45; + static const int frames_low = 15; + static const int frames_to_execute = 31; // about 2 shake-loops + + for (int i = 0; i != 3; ++i) + { + if ((shake & (1 << i)) && dynamic_data.executing_frames_left[i] == 0) + { + dynamic_data.timing[i]++; + } + else if (dynamic_data.executing_frames_left[i] > 0) + { + (&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * dynamic_data.intensity[i]; + shake_step[i] = (shake_step[i] + 1) % shake_step_max; + dynamic_data.executing_frames_left[i]--; + } + else if (shake == 0 && dynamic_data.timing[i] > 0) + { + if (dynamic_data.timing[i] > frames_high) + { + dynamic_data.intensity[i] = config.high_intensity; + } + else if (dynamic_data.timing[i] < frames_low) + { + dynamic_data.intensity[i] = config.low_intensity; + } + else + { + dynamic_data.intensity[i] = config.med_intensity; + } + dynamic_data.timing[i] = 0; + dynamic_data.executing_frames_left[i] = frames_to_execute; + } + else + { + shake_step[i] = 0; + } + } +} + void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group, const bool sideways, const bool upright) { @@ -183,6 +235,62 @@ void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const swing_grou (&accel->x)[axis_map[i]] += swing[i] * g_dir[i] * intensity; } +void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data, + ControllerEmu::Force* const swing_group, const DynamicConfiguration& config, const bool sideways, const bool upright) +{ + ControlState swing[3]; + swing_group->GetState(swing); + + s8 g_dir[3] = { -1, -1, -1 }; + u8 axis_map[3]; + + // determine which axis is which direction + axis_map[0] = upright ? (sideways ? 0 : 1) : 2; // up/down + axis_map[1] = sideways; // left|right + axis_map[2] = upright ? 2 : (sideways ? 0 : 1); // forward/backward + + // some orientations have up as positive, some as negative + // same with forward + if (sideways && !upright) + g_dir[axis_map[2]] *= -1; + if (!sideways && upright) + g_dir[axis_map[0]] *= -1; + + static const int frames_high = 100; + static const int frames_low = 30; + static const int frames_to_execute = 30; + + for (unsigned int i = 0; i < 3; ++i) + { + if (swing[i] > 0 && dynamic_data.executing_frames_left[i] == 0) + { + dynamic_data.timing[i]++; + } + else if (dynamic_data.executing_frames_left[i] > 0) + { + (&accel->x)[axis_map[i]] += g_dir[i] * dynamic_data.intensity[i]; + dynamic_data.executing_frames_left[i]--; + } + else if (swing[i] == 0 && dynamic_data.timing[i] > 0) + { + if (dynamic_data.timing[i] > frames_high) + { + dynamic_data.intensity[i] = config.high_intensity; + } + else if (dynamic_data.timing[i] < frames_low) + { + dynamic_data.intensity[i] = config.low_intensity; + } + else + { + dynamic_data.intensity[i] = config.med_intensity; + } + dynamic_data.timing[i] = 0; + dynamic_data.executing_frames_left[i] = frames_to_execute; + } + } +} + static const u16 button_bitmasks[] = { Wiimote::BUTTON_A, Wiimote::BUTTON_B, Wiimote::BUTTON_ONE, Wiimote::BUTTON_TWO, Wiimote::BUTTON_MINUS, Wiimote::BUTTON_PLUS, Wiimote::BUTTON_HOME}; @@ -237,6 +345,8 @@ void Wiimote::Reset() m_shake_step = {}; m_shake_soft_step = {}; m_shake_hard_step = {}; + m_swing_dynamic_data = {}; + m_shake_dynamic_data = {}; // clear read request queue while (!m_read_requests.empty()) @@ -271,6 +381,7 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1 groups.emplace_back(m_swing = new ControllerEmu::Force(_trans("Swing"))); groups.emplace_back(m_swing_slow = new ControllerEmu::Force("SwingSlow")); groups.emplace_back(m_swing_fast = new ControllerEmu::Force("SwingFast")); + groups.emplace_back(m_swing_dynamic = new ControllerEmu::Force("Swing Dynamic")); // tilt groups.emplace_back(m_tilt = new ControllerEmu::Tilt(_trans("Tilt"))); @@ -294,6 +405,11 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1 m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); + groups.emplace_back(m_shake_dynamic = new ControllerEmu::Buttons("Shake Dynamic")); + m_shake_dynamic->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "X")); + m_shake_dynamic->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); + m_shake_dynamic->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); + // extension groups.emplace_back(m_extension = new ControllerEmu::Extension(_trans("Extension"))); m_extension->attachments.emplace_back(new WiimoteEmu::None(m_reg_ext)); @@ -492,13 +608,28 @@ void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf) EmulateTilt(&m_accel, m_tilt, is_sideways, is_upright); + DynamicConfiguration swing_config; + swing_config.low_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW); + swing_config.med_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM); + swing_config.high_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_FAST); + EmulateSwing(&m_accel, m_swing, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM), is_sideways, is_upright); EmulateSwing(&m_accel, m_swing_slow, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW), is_sideways, is_upright); EmulateSwing(&m_accel, m_swing_fast, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_FAST), is_sideways, is_upright); + EmulateDynamicSwing(&m_accel, m_swing_dynamic_data, m_swing_dynamic, swing_config, is_sideways, + is_upright); + + DynamicConfiguration shake_config; + shake_config.low_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT); + shake_config.med_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM); + shake_config.high_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_HARD); EmulateShake(&m_accel, m_shake, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM), m_shake_step.data()); EmulateShake(&m_accel, m_shake_soft, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT), m_shake_soft_step.data()); EmulateShake(&m_accel, m_shake_hard, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_HARD), m_shake_hard_step.data()); + EmulateDynamicShake(&m_accel, m_shake_dynamic_data, m_shake_dynamic, shake_config, + m_shake_dynamic_step.data()); + wm_accel& accel = *reinterpret_cast(data + rptf.accel); wm_buttons& core = *reinterpret_cast(data + rptf.core); diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 57f8f3e636..6c22a9e2f8 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -124,6 +124,26 @@ struct AccelData double x, y, z; }; +// Used for a dynamic swing or +// shake +struct DynamicData +{ + std::array timing; // Hold length in frames for each axis + std::array intensity; // Swing or shake intensity + std::array executing_frames_left; // Number of frames to execute the intensity operation +}; + +// Used for a dynamic swing or +// shake. This is used to pass +// in data that defines the dynamic +// action +struct DynamicConfiguration +{ + double low_intensity; + double med_intensity; + double high_intensity; +}; + struct ADPCMState { s32 predictor, step; @@ -157,12 +177,22 @@ struct ExtensionReg void EmulateShake(AccelData* const accel_data, ControllerEmu::Buttons* const buttons_group, const double intensity, u8* const shake_step); +void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, + ControllerEmu::Buttons* const buttons_group, + const DynamicConfiguration& config, + u8* const shake_step); + void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group, const bool sideways = false, const bool upright = false); void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const tilt_group, const double intensity, const bool sideways = false, const bool upright = false); +void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data, + ControllerEmu::Force* const swing_group, + const DynamicConfiguration& config, + const bool sideways = false, const bool upright = false); + enum { ACCEL_ZERO_G = 0x80, @@ -250,11 +280,13 @@ private: ControllerEmu::Buttons* m_shake; ControllerEmu::Buttons* m_shake_soft; ControllerEmu::Buttons* m_shake_hard; + ControllerEmu::Buttons* m_shake_dynamic; ControllerEmu::Cursor* m_ir; ControllerEmu::Tilt* m_tilt; ControllerEmu::Force* m_swing; ControllerEmu::Force* m_swing_slow; ControllerEmu::Force* m_swing_fast; + ControllerEmu::Force* m_swing_dynamic; ControllerEmu::ControlGroup* m_rumble; ControllerEmu::Output* m_motor; ControllerEmu::Extension* m_extension; @@ -264,6 +296,9 @@ private: ControllerEmu::NumericSetting* m_battery_setting; ControllerEmu::ModifySettingsButton* m_hotkeys; + DynamicData m_swing_dynamic_data; + DynamicData m_shake_dynamic_data; + // Wiimote accel data AccelData m_accel; @@ -282,6 +317,7 @@ private: std::array m_shake_step{}; std::array m_shake_soft_step{}; std::array m_shake_hard_step{}; + std::array m_shake_dynamic_step{}; bool m_sensor_bar_on_top; From 6194badeda7052d3162f43a5c7888646eab23e01 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 7 Apr 2018 21:13:54 -0500 Subject: [PATCH 05/15] Add 'Boom Blox' ini that contains Hard/Soft/Medium shake speeds and Fast/Slow/Medium swing speeds --- Data/Sys/GameSettings/RBK.ini | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Data/Sys/GameSettings/RBK.ini diff --git a/Data/Sys/GameSettings/RBK.ini b/Data/Sys/GameSettings/RBK.ini new file mode 100644 index 0000000000..3fb30e2eb9 --- /dev/null +++ b/Data/Sys/GameSettings/RBK.ini @@ -0,0 +1,26 @@ +# RBKJ13, RBKK69, RBKP69, RBKE69 - Boom Blox + +[Core] +# Values set here will override the main Dolphin settings. + +[OnLoad] +# Add memory patches to be loaded once on boot here. + +[OnFrame] +# Add memory patches to be applied every frame here. + +[ActionReplay] +# Add action replay cheats here. + +[Video_Settings] +# Add any video settings here + +[Wiimote.Shake] +Soft = 3.0 +Medium = 4.0 +Hard = 4.8 + +[Wiimote.Swing] +Slow = 3.5 +Medium = 4.8 +Fast = 6 \ No newline at end of file From 29b71fb9ce5d28e84a7aaabc1a3a65f2a551d42d Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 7 Apr 2018 21:30:54 -0500 Subject: [PATCH 06/15] Wiimote Emulation: increase left/right bounds for IR calculation, to fix games that previously you couldn't reach the left/right edges (ex: system menu) --- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 2e4d359878..b45942c2e6 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -706,8 +706,8 @@ void Wiimote::GetIRData(u8* const data, bool use_accel) static const int camHeight = 768; static const double bndup = -0.315447; static const double bnddown = 0.85; - static const double bndleft = 0.443364; - static const double bndright = -0.443364; + static const double bndleft = 0.78820266; + static const double bndright = -0.78820266; static const double dist1 = 100.0 / camWidth; // this seems the optimal distance for zelda static const double dist2 = 1.2 * dist1; From 3969bf6d1c83acb7e3699bcd3c2715d5b85e2ea0 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Fri, 13 Apr 2018 23:51:32 -0500 Subject: [PATCH 07/15] Input: Add hotkey to cycle the wiimote profile forward or backward Co-authored-by: Barath Kannan --- Source/Core/Core/HotkeyManager.cpp | 4 + Source/Core/Core/HotkeyManager.h | 4 + Source/Core/DolphinQt/CMakeLists.txt | 1 + .../Mapping/HotkeyControllerProfile.cpp | 39 +++++++ .../Config/Mapping/HotkeyControllerProfile.h | 26 +++++ .../Config/Mapping/MappingWindow.cpp | 2 + Source/Core/DolphinQt/DolphinQt.vcxproj | 3 + Source/Core/DolphinQt/HotkeyScheduler.cpp | 5 + Source/Core/DolphinQt/HotkeyScheduler.h | 3 + Source/Core/InputCommon/CMakeLists.txt | 1 + Source/Core/InputCommon/InputCommon.vcxproj | 2 + .../InputCommon/InputCommon.vcxproj.filters | 2 + Source/Core/InputCommon/InputConfig.cpp | 5 + Source/Core/InputCommon/InputConfig.h | 1 + Source/Core/InputCommon/InputProfile.cpp | 100 ++++++++++++++++++ Source/Core/InputCommon/InputProfile.h | 39 +++++++ 16 files changed, 237 insertions(+) create mode 100644 Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp create mode 100644 Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h create mode 100644 Source/Core/InputCommon/InputProfile.cpp create mode 100644 Source/Core/InputCommon/InputProfile.h diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index 80b293f940..113f4db737 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -69,6 +69,9 @@ constexpr std::array s_hotkey_labels{{ _trans("Connect Wii Remote 4"), _trans("Connect Balance Board"), + _trans("Next Wii Remote Profile"), + _trans("Previous Wii Remote Profile"), + _trans("Toggle Crop"), _trans("Toggle Aspect Ratio"), _trans("Toggle EFB Copies"), @@ -255,6 +258,7 @@ constexpr std::array s_groups_info = { {_trans("Program Counter"), HK_SHOW_PC, HK_SET_PC}, {_trans("Breakpoint"), HK_BP_TOGGLE, HK_MBP_ADD}, {_trans("Wii"), HK_TRIGGER_SYNC_BUTTON, HK_BALANCEBOARD_CONNECT}, + {_trans("Controller Profile"), HK_NEXT_WIIMOTE_PROFILE, HK_PREV_WIIMOTE_PROFILE}, {_trans("Graphics Toggles"), HK_TOGGLE_CROP, HK_TOGGLE_TEXTURES}, {_trans("Internal Resolution"), HK_INCREASE_IR, HK_DECREASE_IR}, {_trans("Freelook"), HK_FREELOOK_DECREASE_SPEED, HK_FREELOOK_RESET}, diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h index 8505412d16..8b639f59fd 100644 --- a/Source/Core/Core/HotkeyManager.h +++ b/Source/Core/Core/HotkeyManager.h @@ -67,6 +67,9 @@ enum Hotkey HK_WIIMOTE4_CONNECT, HK_BALANCEBOARD_CONNECT, + HK_NEXT_WIIMOTE_PROFILE, + HK_PREV_WIIMOTE_PROFILE, + HK_TOGGLE_CROP, HK_TOGGLE_AR, HK_TOGGLE_EFBCOPIES, @@ -166,6 +169,7 @@ enum HotkeyGroup : int HKGP_PC, HKGP_BREAKPOINT, HKGP_WII, + HKGP_CONTROLLER_PROFILE, HKGP_GRAPHICS_TOGGLES, HKGP_IR, HKGP_FREELOOK, diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 8ff38fe645..b7c3c5c12e 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -50,6 +50,7 @@ add_executable(dolphin-emu Config/Mapping/GCPadEmu.cpp Config/Mapping/GCPadWiiUConfigDialog.cpp Config/Mapping/Hotkey3D.cpp + Config/Mapping/HotkeyControllerProfile.cpp Config/Mapping/HotkeyDebugging.cpp Config/Mapping/HotkeyGeneral.cpp Config/Mapping/HotkeyGraphics.cpp diff --git a/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp new file mode 100644 index 0000000000..14ae68f749 --- /dev/null +++ b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp @@ -0,0 +1,39 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/Config/Mapping/HotkeyControllerProfile.h" + +#include +#include + +#include "Core/HotkeyManager.h" + +HotkeyControllerProfile::HotkeyControllerProfile(MappingWindow* window) : MappingWidget(window) +{ + CreateMainLayout(); +} + +void HotkeyControllerProfile::CreateMainLayout() +{ + m_main_layout = new QHBoxLayout(); + + m_main_layout->addWidget(CreateGroupBox(tr("Controller Profile"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_CONTROLLER_PROFILE))); + + setLayout(m_main_layout); +} + +InputConfig* HotkeyControllerProfile::GetConfig() +{ + return HotkeyManagerEmu::GetConfig(); +} + +void HotkeyControllerProfile::LoadSettings() +{ + HotkeyManagerEmu::LoadConfig(); +} + +void HotkeyControllerProfile::SaveSettings() +{ + HotkeyManagerEmu::GetConfig()->SaveConfig(); +} diff --git a/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h new file mode 100644 index 0000000000..04c5435b27 --- /dev/null +++ b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h @@ -0,0 +1,26 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include "DolphinQt/Config/Mapping/MappingWidget.h" + +class QHBoxLayout; + +class HotkeyControllerProfile final : public MappingWidget +{ + Q_OBJECT +public: + explicit HotkeyControllerProfile(MappingWindow* window); + + InputConfig* GetConfig() override; + +private: + void LoadSettings() override; + void SaveSettings() override; + void CreateMainLayout(); + + // Main + QHBoxLayout* m_main_layout; +}; diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp index 48e5a5f0f2..5424888ef5 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp @@ -25,6 +25,7 @@ #include "DolphinQt/Config/Mapping/GCMicrophone.h" #include "DolphinQt/Config/Mapping/GCPadEmu.h" #include "DolphinQt/Config/Mapping/Hotkey3D.h" +#include "DolphinQt/Config/Mapping/HotkeyControllerProfile.h" #include "DolphinQt/Config/Mapping/HotkeyDebugging.h" #include "DolphinQt/Config/Mapping/HotkeyGeneral.h" #include "DolphinQt/Config/Mapping/HotkeyGraphics.h" @@ -310,6 +311,7 @@ void MappingWindow::SetMappingType(MappingWindow::Type type) AddWidget(tr("Debugging"), new HotkeyDebugging(this)); AddWidget(tr("Wii and Wii Remote"), new HotkeyWii(this)); + AddWidget(tr("Controller Profile"), new HotkeyControllerProfile(this)); AddWidget(tr("Graphics"), new HotkeyGraphics(this)); AddWidget(tr("3D"), new Hotkey3D(this)); AddWidget(tr("Save and Load State"), new HotkeyStates(this)); diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index b87180eb2d..db2d90c4b2 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -70,6 +70,7 @@ + @@ -203,6 +204,7 @@ + @@ -283,6 +285,7 @@ + diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index 4853fd4517..6f29aa8431 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -240,6 +240,11 @@ void HotkeyScheduler::Run() emit ConnectWiiRemote(wiimote_id); } + if (IsHotkey(HK_PREV_WIIMOTE_PROFILE)) + m_profile_cycler.PreviousWiimoteProfile(); + else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE)) + m_profile_cycler.NextWiimoteProfile(); + const auto show_msg = [](OSDMessage message) { if (g_renderer) g_renderer->ShowOSDMessage(message); diff --git a/Source/Core/DolphinQt/HotkeyScheduler.h b/Source/Core/DolphinQt/HotkeyScheduler.h index 673f6fcab7..998bda3a02 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.h +++ b/Source/Core/DolphinQt/HotkeyScheduler.h @@ -9,6 +9,7 @@ #include #include "Common/Flag.h" +#include "InputCommon/InputProfile.h" class HotkeyScheduler : public QObject { @@ -64,4 +65,6 @@ private: Common::Flag m_stop_requested; std::thread m_thread; + + InputProfile::ProfileCycler m_profile_cycler; }; diff --git a/Source/Core/InputCommon/CMakeLists.txt b/Source/Core/InputCommon/CMakeLists.txt index 99cf2f9679..a3ef2722d8 100644 --- a/Source/Core/InputCommon/CMakeLists.txt +++ b/Source/Core/InputCommon/CMakeLists.txt @@ -1,5 +1,6 @@ add_library(inputcommon InputConfig.cpp + InputProfile.cpp ControllerEmu/ControllerEmu.cpp ControllerEmu/Control/Control.cpp ControllerEmu/Control/Input.cpp diff --git a/Source/Core/InputCommon/InputCommon.vcxproj b/Source/Core/InputCommon/InputCommon.vcxproj index 84ad406de1..6d0efb2c91 100644 --- a/Source/Core/InputCommon/InputCommon.vcxproj +++ b/Source/Core/InputCommon/InputCommon.vcxproj @@ -71,6 +71,7 @@ 4200;%(DisableSpecificWarnings) + @@ -105,6 +106,7 @@ + diff --git a/Source/Core/InputCommon/InputCommon.vcxproj.filters b/Source/Core/InputCommon/InputCommon.vcxproj.filters index 600a77727d..c67333497c 100644 --- a/Source/Core/InputCommon/InputCommon.vcxproj.filters +++ b/Source/Core/InputCommon/InputCommon.vcxproj.filters @@ -110,6 +110,7 @@ ControllerInterface + @@ -202,6 +203,7 @@ ControllerInterface + diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp index 2a5766fbbe..989c1bdce9 100644 --- a/Source/Core/InputCommon/InputConfig.cpp +++ b/Source/Core/InputCommon/InputConfig.cpp @@ -128,6 +128,11 @@ bool InputConfig::ControllersNeedToBeCreated() const return m_controllers.empty(); } +std::size_t InputConfig::GetControllerCount() const +{ + return m_controllers.size(); +} + bool InputConfig::IsControllerControlledByGamepadDevice(int index) const { if (static_cast(index) >= m_controllers.size()) diff --git a/Source/Core/InputCommon/InputConfig.h b/Source/Core/InputCommon/InputConfig.h index a993a412b1..004e4be8bb 100644 --- a/Source/Core/InputCommon/InputConfig.h +++ b/Source/Core/InputCommon/InputConfig.h @@ -38,6 +38,7 @@ public: std::string GetGUIName() const { return m_gui_name; } std::string GetProfileName() const { return m_profile_name; } + std::size_t GetControllerCount() const; private: std::vector> m_controllers; diff --git a/Source/Core/InputCommon/InputProfile.cpp b/Source/Core/InputCommon/InputProfile.cpp new file mode 100644 index 0000000000..87d8c5bcab --- /dev/null +++ b/Source/Core/InputCommon/InputProfile.cpp @@ -0,0 +1,100 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "Common/FileSearch.h" +#include "Common/FileUtil.h" + +#include "Core/Core.h" +#include "Core/HW/Wiimote.h" +#include "Core/HotkeyManager.h" + +#include "InputCommon/ControllerInterface/ControllerInterface.h" +#include "InputCommon/InputConfig.h" +#include "InputCommon/InputProfile.h" + +namespace InputProfile +{ + + namespace + { + constexpr int display_message_ms = 3000; + } + + std::vector ProfileCycler::GetProfilesForDevice(InputConfig* device_configuration) + { + const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + device_configuration->GetProfileName()); + return Common::DoFileSearch({ device_profile_root_location }, { ".ini" }); + } + + std::string ProfileCycler::GetProfile(CycleDirection cycle_direction, int& profile_index, const std::vector& profiles) + { + // update the index and bind it to the number of available strings + auto positive_modulo = [](int& i, int n) {i = (i % n + n) % n;}; + profile_index += static_cast(cycle_direction); + positive_modulo(profile_index, static_cast(profiles.size())); + + return profiles[profile_index]; + } + + void ProfileCycler::UpdateToProfile(const std::string& profile_filename, const std::vector& controllers) + { + std::string base; + SplitPath(profile_filename, nullptr, &base, nullptr); + + IniFile ini_file; + if (ini_file.Load(profile_filename)) + { + Core::DisplayMessage("Loading input profile: " + base, display_message_ms); + + for (auto* controller : controllers) + { + controller->LoadConfig(ini_file.GetOrCreateSection("Profile")); + controller->UpdateReferences(g_controller_interface); + } + } + else + { + Core::DisplayMessage("Unable to load input profile: " + base, display_message_ms); + } + } + + std::vector ProfileCycler::GetControllersForDevice(InputConfig* device_configuration) + { + const std::size_t size = device_configuration->GetControllerCount(); + + std::vector result(size); + + for (int i = 0; i < static_cast(size); i++) + { + result[i] = device_configuration->GetController(i); + } + + return result; + } + + void ProfileCycler::CycleProfile(CycleDirection cycle_direction, + InputConfig* device_configuration, int& profile_index) + { + const auto& profiles = GetProfilesForDevice(device_configuration); + if (profiles.empty()) + { + Core::DisplayMessage("No input profiles found", display_message_ms); + return; + } + const std::string profile = GetProfile(cycle_direction, profile_index, profiles); + + const auto& controllers = GetControllersForDevice(device_configuration); + UpdateToProfile(profile, controllers); + } + + void ProfileCycler::NextWiimoteProfile() + { + CycleProfile(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index); + } + + void ProfileCycler::PreviousWiimoteProfile() + { + CycleProfile(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index); + } +} diff --git a/Source/Core/InputCommon/InputProfile.h b/Source/Core/InputCommon/InputProfile.h new file mode 100644 index 0000000000..09b617c398 --- /dev/null +++ b/Source/Core/InputCommon/InputProfile.h @@ -0,0 +1,39 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +class InputConfig; + +namespace ControllerEmu +{ + class EmulatedController; +} + +#include +#include + +namespace InputProfile +{ + enum class CycleDirection : int + { + Forward = 1, + Backward = -1 + }; + + class ProfileCycler + { + public: + void NextWiimoteProfile(); + void PreviousWiimoteProfile(); + private: + void CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index); + std::vector GetProfilesForDevice(InputConfig* device_configuration); + std::string GetProfile(CycleDirection cycle_direction, int& profile_index, const std::vector& profiles); + void UpdateToProfile(const std::string& profile_filename, const std::vector& controllers); + std::vector GetControllersForDevice(InputConfig* device_configuration); + + int m_wiimote_profile_index = 0; + }; +} From 485285eadc71a8ca7055b9fc6b5da13c8b0251f4 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Tue, 17 Apr 2018 00:43:56 -0500 Subject: [PATCH 08/15] Input: Add cycling between game specific profiles --- .../Core/Core/Config/WiimoteInputSettings.cpp | 3 + .../Core/Core/Config/WiimoteInputSettings.h | 4 + Source/Core/Core/HotkeyManager.cpp | 8 +- Source/Core/Core/HotkeyManager.h | 2 + Source/Core/DolphinQt/HotkeyScheduler.cpp | 5 ++ Source/Core/InputCommon/InputProfile.cpp | 83 +++++++++++++++++++ Source/Core/InputCommon/InputProfile.h | 5 ++ 7 files changed, 107 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Config/WiimoteInputSettings.cpp b/Source/Core/Core/Config/WiimoteInputSettings.cpp index a60ed45e9f..3dac7e5851 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.cpp +++ b/Source/Core/Core/Config/WiimoteInputSettings.cpp @@ -27,4 +27,7 @@ namespace Config const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Nunchuk_Shake", "Hard" }, 5.0 }; const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Nunchuk_Shake", "Medium" }, 3.0 }; const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Nunchuk_Shake", "Soft" }, 2.0 }; + + // Other Settings + const ConfigInfo WIIMOTE_PROFILES{ {System::WiiPad, "InputProfiles", "List"}, "" }; } diff --git a/Source/Core/Core/Config/WiimoteInputSettings.h b/Source/Core/Core/Config/WiimoteInputSettings.h index 44ab85b37d..e6db349c07 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.h +++ b/Source/Core/Core/Config/WiimoteInputSettings.h @@ -30,4 +30,8 @@ namespace Config extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM; extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT; + // Other settings + + extern const ConfigInfo WIIMOTE_PROFILES; + } // namespace Config diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index 113f4db737..6e844ce7ea 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -69,8 +69,10 @@ constexpr std::array s_hotkey_labels{{ _trans("Connect Wii Remote 4"), _trans("Connect Balance Board"), - _trans("Next Wii Remote Profile"), - _trans("Previous Wii Remote Profile"), + _trans("Next Wii Remote Profile"), + _trans("Previous Wii Remote Profile"), + _trans("Next Wii Remote Profile For Current Game"), + _trans("Previous Wii Remote Profile For Current Game"), _trans("Toggle Crop"), _trans("Toggle Aspect Ratio"), @@ -258,7 +260,7 @@ constexpr std::array s_groups_info = { {_trans("Program Counter"), HK_SHOW_PC, HK_SET_PC}, {_trans("Breakpoint"), HK_BP_TOGGLE, HK_MBP_ADD}, {_trans("Wii"), HK_TRIGGER_SYNC_BUTTON, HK_BALANCEBOARD_CONNECT}, - {_trans("Controller Profile"), HK_NEXT_WIIMOTE_PROFILE, HK_PREV_WIIMOTE_PROFILE}, + {_trans("Controller Profile"), HK_NEXT_WIIMOTE_PROFILE, HK_PREV_GAME_WIIMOTE_PROFILE}, {_trans("Graphics Toggles"), HK_TOGGLE_CROP, HK_TOGGLE_TEXTURES}, {_trans("Internal Resolution"), HK_INCREASE_IR, HK_DECREASE_IR}, {_trans("Freelook"), HK_FREELOOK_DECREASE_SPEED, HK_FREELOOK_RESET}, diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h index 8b639f59fd..fb67cfbc4c 100644 --- a/Source/Core/Core/HotkeyManager.h +++ b/Source/Core/Core/HotkeyManager.h @@ -69,6 +69,8 @@ enum Hotkey HK_NEXT_WIIMOTE_PROFILE, HK_PREV_WIIMOTE_PROFILE, + HK_NEXT_GAME_WIIMOTE_PROFILE, + HK_PREV_GAME_WIIMOTE_PROFILE, HK_TOGGLE_CROP, HK_TOGGLE_AR, diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index 6f29aa8431..8a8c243abc 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -245,6 +245,11 @@ void HotkeyScheduler::Run() else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE)) m_profile_cycler.NextWiimoteProfile(); + if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE)) + m_profile_cycler.PreviousWiimoteProfileForGame(); + else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE)) + m_profile_cycler.NextWiimoteProfileForGame(); + const auto show_msg = [](OSDMessage message) { if (g_renderer) g_renderer->ShowOSDMessage(message); diff --git a/Source/Core/InputCommon/InputProfile.cpp b/Source/Core/InputCommon/InputProfile.cpp index 87d8c5bcab..07fa1f7795 100644 --- a/Source/Core/InputCommon/InputProfile.cpp +++ b/Source/Core/InputCommon/InputProfile.cpp @@ -5,6 +5,7 @@ #include "Common/FileSearch.h" #include "Common/FileUtil.h" +#include "Core/Config/WiimoteInputSettings.h" #include "Core/Core.h" #include "Core/HW/Wiimote.h" #include "Core/HotkeyManager.h" @@ -13,6 +14,9 @@ #include "InputCommon/InputConfig.h" #include "InputCommon/InputProfile.h" +#include +#include + namespace InputProfile { @@ -73,6 +77,35 @@ namespace InputProfile return result; } + std::vector ProfileCycler::GetProfilesFromSetting(const std::string& setting, InputConfig* device_configuration) + { + const auto& profiles = SplitString(setting, ','); + + const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + device_configuration->GetProfileName()); + + std::vector result(profiles.size()); + std::transform(profiles.begin(), profiles.end(), result.begin(), [&device_profile_root_location](const std::string& profile) + { + return device_profile_root_location + "/" + profile; + }); + + return result; + } + + std::vector ProfileCycler::GetMatchingProfilesFromSetting(const std::string& setting, const std::vector& profiles, InputConfig* device_configuration) + { + const auto& profiles_from_setting = GetProfilesFromSetting(setting, device_configuration); + if (profiles_from_setting.empty()) + { + return {}; + } + + std::vector result; + std::set_intersection(profiles.begin(), profiles.end(), profiles_from_setting.begin(), + profiles_from_setting.end(), std::back_inserter(result)); + return result; + } + void ProfileCycler::CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index) { @@ -88,6 +121,44 @@ namespace InputProfile UpdateToProfile(profile, controllers); } + void ProfileCycler::CycleProfileForGame(CycleDirection cycle_direction, + InputConfig* device_configuration, int& profile_index, + const std::string& setting) + { + const auto& profiles = GetProfilesForDevice(device_configuration); + if (profiles.empty()) + { + Core::DisplayMessage("No input profiles found", display_message_ms); + return; + } + + if (setting.empty()) + { + Core::DisplayMessage("No setting found for game", display_message_ms); + return; + } + + const auto& profiles_for_game = GetMatchingProfilesFromSetting(setting, profiles, + device_configuration); + if (profiles_for_game.empty()) + { + Core::DisplayMessage("No input profiles found for game", display_message_ms); + return; + } + + const std::string profile = GetProfile(cycle_direction, profile_index, profiles_for_game); + + auto* controller = device_configuration->GetController(controller_index); + if (controller) + { + UpdateToProfile(profile, controller); + } + else + { + Core::DisplayMessage("No controller found for index: " + std::to_string(controller_index), display_message_ms); + } + } + void ProfileCycler::NextWiimoteProfile() { CycleProfile(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index); @@ -97,4 +168,16 @@ namespace InputProfile { CycleProfile(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index); } + + void ProfileCycler::NextWiimoteProfileForGame() + { + CycleProfileForGame(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index, + Config::Get(Config::WIIMOTE_PROFILES)); + } + + void ProfileCycler::PreviousWiimoteProfileForGame() + { + CycleProfileForGame(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index, + Config::Get(Config::WIIMOTE_PROFILES)); + } } diff --git a/Source/Core/InputCommon/InputProfile.h b/Source/Core/InputCommon/InputProfile.h index 09b617c398..ec0344b23f 100644 --- a/Source/Core/InputCommon/InputProfile.h +++ b/Source/Core/InputCommon/InputProfile.h @@ -27,10 +27,15 @@ namespace InputProfile public: void NextWiimoteProfile(); void PreviousWiimoteProfile(); + void NextWiimoteProfileForGame(); + void PreviousWiimoteProfileForGame(); private: void CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index); + void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, const std::string& setting); std::vector GetProfilesForDevice(InputConfig* device_configuration); + std::vector GetProfilesFromSetting(const std::string& setting, InputConfig* device_configuration); std::string GetProfile(CycleDirection cycle_direction, int& profile_index, const std::vector& profiles); + std::vector GetMatchingProfilesFromSetting(const std::string& setting, const std::vector& profiles, InputConfig* device_configuration); void UpdateToProfile(const std::string& profile_filename, const std::vector& controllers); std::vector GetControllersForDevice(InputConfig* device_configuration); From 14482a72af9e70667cb0e8477f4c14feb2c7a762 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 22 Apr 2018 16:27:10 -0500 Subject: [PATCH 09/15] Input: Allow cycling to occur for each individual controller --- .../Core/Core/Config/WiimoteInputSettings.cpp | 3 - .../Core/Core/Config/WiimoteInputSettings.h | 4 - Source/Core/Core/HotkeyManager.cpp | 24 ++++-- Source/Core/Core/HotkeyManager.h | 20 ++++- Source/Core/DolphinQt/HotkeyScheduler.cpp | 46 +++++++++-- Source/Core/InputCommon/InputConfig.cpp | 13 +++- Source/Core/InputCommon/InputProfile.cpp | 77 ++++++++++--------- Source/Core/InputCommon/InputProfile.h | 16 ++-- 8 files changed, 131 insertions(+), 72 deletions(-) diff --git a/Source/Core/Core/Config/WiimoteInputSettings.cpp b/Source/Core/Core/Config/WiimoteInputSettings.cpp index 3dac7e5851..a60ed45e9f 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.cpp +++ b/Source/Core/Core/Config/WiimoteInputSettings.cpp @@ -27,7 +27,4 @@ namespace Config const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Nunchuk_Shake", "Hard" }, 5.0 }; const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Nunchuk_Shake", "Medium" }, 3.0 }; const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Nunchuk_Shake", "Soft" }, 2.0 }; - - // Other Settings - const ConfigInfo WIIMOTE_PROFILES{ {System::WiiPad, "InputProfiles", "List"}, "" }; } diff --git a/Source/Core/Core/Config/WiimoteInputSettings.h b/Source/Core/Core/Config/WiimoteInputSettings.h index e6db349c07..44ab85b37d 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.h +++ b/Source/Core/Core/Config/WiimoteInputSettings.h @@ -30,8 +30,4 @@ namespace Config extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM; extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT; - // Other settings - - extern const ConfigInfo WIIMOTE_PROFILES; - } // namespace Config diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index 6e844ce7ea..5905ea0ad1 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -20,7 +20,7 @@ #include "InputCommon/GCPadStatus.h" // clang-format off -constexpr std::array s_hotkey_labels{{ +constexpr std::array s_hotkey_labels{{ _trans("Open"), _trans("Change Disc"), _trans("Eject Disc"), @@ -69,10 +69,22 @@ constexpr std::array s_hotkey_labels{{ _trans("Connect Wii Remote 4"), _trans("Connect Balance Board"), - _trans("Next Wii Remote Profile"), - _trans("Previous Wii Remote Profile"), - _trans("Next Wii Remote Profile For Current Game"), - _trans("Previous Wii Remote Profile For Current Game"), + _trans("Next Profile for Wii Remote 1"), + _trans("Previous Profile for Wii Remote 1"), + _trans("Next Game Profile for Wii Remote 1"), + _trans("Previous Game Profile for Wii Remote 1"), + _trans("Next Profile for Wii Remote 2"), + _trans("Previous Profile for Wii Remote 2"), + _trans("Next Game Profile for Wii Remote 2"), + _trans("Previous Game Profile for Wii Remote 2"), + _trans("Next Profile for Wii Remote 3"), + _trans("Previous Profile for Wii Remote 3"), + _trans("Next Game Profile for Wii Remote 3"), + _trans("Previous Game Profile for Wii Remote 3"), + _trans("Next Profile for Wii Remote 4"), + _trans("Previous Profile for Wii Remote 4"), + _trans("Next Game Profile for Wii Remote 4"), + _trans("Previous Game Profile for Wii Remote 4"), _trans("Toggle Crop"), _trans("Toggle Aspect Ratio"), @@ -260,7 +272,7 @@ constexpr std::array s_groups_info = { {_trans("Program Counter"), HK_SHOW_PC, HK_SET_PC}, {_trans("Breakpoint"), HK_BP_TOGGLE, HK_MBP_ADD}, {_trans("Wii"), HK_TRIGGER_SYNC_BUTTON, HK_BALANCEBOARD_CONNECT}, - {_trans("Controller Profile"), HK_NEXT_WIIMOTE_PROFILE, HK_PREV_GAME_WIIMOTE_PROFILE}, + {_trans("Controller Profile"), HK_NEXT_WIIMOTE_PROFILE_1, HK_PREV_GAME_WIIMOTE_PROFILE_4}, {_trans("Graphics Toggles"), HK_TOGGLE_CROP, HK_TOGGLE_TEXTURES}, {_trans("Internal Resolution"), HK_INCREASE_IR, HK_DECREASE_IR}, {_trans("Freelook"), HK_FREELOOK_DECREASE_SPEED, HK_FREELOOK_RESET}, diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h index fb67cfbc4c..7b72478a4d 100644 --- a/Source/Core/Core/HotkeyManager.h +++ b/Source/Core/Core/HotkeyManager.h @@ -67,10 +67,22 @@ enum Hotkey HK_WIIMOTE4_CONNECT, HK_BALANCEBOARD_CONNECT, - HK_NEXT_WIIMOTE_PROFILE, - HK_PREV_WIIMOTE_PROFILE, - HK_NEXT_GAME_WIIMOTE_PROFILE, - HK_PREV_GAME_WIIMOTE_PROFILE, + HK_NEXT_WIIMOTE_PROFILE_1, + HK_PREV_WIIMOTE_PROFILE_1, + HK_NEXT_GAME_WIIMOTE_PROFILE_1, + HK_PREV_GAME_WIIMOTE_PROFILE_1, + HK_NEXT_WIIMOTE_PROFILE_2, + HK_PREV_WIIMOTE_PROFILE_2, + HK_NEXT_GAME_WIIMOTE_PROFILE_2, + HK_PREV_GAME_WIIMOTE_PROFILE_2, + HK_NEXT_WIIMOTE_PROFILE_3, + HK_PREV_WIIMOTE_PROFILE_3, + HK_NEXT_GAME_WIIMOTE_PROFILE_3, + HK_PREV_GAME_WIIMOTE_PROFILE_3, + HK_NEXT_WIIMOTE_PROFILE_4, + HK_PREV_WIIMOTE_PROFILE_4, + HK_NEXT_GAME_WIIMOTE_PROFILE_4, + HK_PREV_GAME_WIIMOTE_PROFILE_4, HK_TOGGLE_CROP, HK_TOGGLE_AR, diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index 8a8c243abc..8def220bad 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -240,15 +240,45 @@ void HotkeyScheduler::Run() emit ConnectWiiRemote(wiimote_id); } - if (IsHotkey(HK_PREV_WIIMOTE_PROFILE)) - m_profile_cycler.PreviousWiimoteProfile(); - else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE)) - m_profile_cycler.NextWiimoteProfile(); + if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_1)) + m_profile_cycler.PreviousWiimoteProfile(0); + else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_1)) + m_profile_cycler.NextWiimoteProfile(0); - if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE)) - m_profile_cycler.PreviousWiimoteProfileForGame(); - else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE)) - m_profile_cycler.NextWiimoteProfileForGame(); + if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_2)) + m_profile_cycler.PreviousWiimoteProfile(1); + else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_2)) + m_profile_cycler.NextWiimoteProfile(1); + + if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_3)) + m_profile_cycler.PreviousWiimoteProfile(2); + else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_3)) + m_profile_cycler.NextWiimoteProfile(2); + + if (IsHotkey(HK_PREV_WIIMOTE_PROFILE_4)) + m_profile_cycler.PreviousWiimoteProfile(3); + else if (IsHotkey(HK_NEXT_WIIMOTE_PROFILE_4)) + m_profile_cycler.NextWiimoteProfile(3); + + if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_1)) + m_profile_cycler.PreviousWiimoteProfileForGame(0); + else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_1)) + m_profile_cycler.NextWiimoteProfileForGame(0); + + if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_2)) + m_profile_cycler.PreviousWiimoteProfileForGame(1); + else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_2)) + m_profile_cycler.NextWiimoteProfileForGame(1); + + if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_3)) + m_profile_cycler.PreviousWiimoteProfileForGame(2); + else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_3)) + m_profile_cycler.NextWiimoteProfileForGame(2); + + if (IsHotkey(HK_PREV_GAME_WIIMOTE_PROFILE_4)) + m_profile_cycler.PreviousWiimoteProfileForGame(3); + else if (IsHotkey(HK_NEXT_GAME_WIIMOTE_PROFILE_4)) + m_profile_cycler.NextWiimoteProfileForGame(3); const auto show_msg = [](OSDMessage message) { if (g_renderer) diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp index 989c1bdce9..9ca3e1708d 100644 --- a/Source/Core/InputCommon/InputConfig.cpp +++ b/Source/Core/InputCommon/InputConfig.cpp @@ -7,6 +7,7 @@ #include "Common/FileUtil.h" #include "Common/IniFile.h" #include "Common/MsgHandler.h" +#include "Common/StringUtil.h" #include "Core/ConfigManager.h" #include "Core/HW/Wiimote.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" @@ -51,8 +52,16 @@ bool InputConfig::LoadConfig(bool isGC) { if (control_section->Exists(type + "Profile" + num[i])) { - if (control_section->Get(type + "Profile" + num[i], &profile[i])) + std::string profile_setting; + if (control_section->Get(type + "Profile" + num[i], &profile_setting)) { + // Setting can contain commas, which means there are multiple profiles specified + // this is used for controller cycling + const auto& profile_options = SplitString(profile_setting, ','); + + // Use the first profile by default + profile[i] = profile_options[0]; + if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile[i] + ".ini")) { useProfile[i] = true; @@ -76,7 +85,7 @@ bool InputConfig::LoadConfig(bool isGC) if (useProfile[n]) { IniFile profile_ini; - profile_ini.Load(File::GetUserPath(D_CONFIG_IDX) + path + profile[n] + ".ini"); + profile_ini.Load(profile[n]); controller->LoadConfig(profile_ini.GetOrCreateSection("Profile")); } else diff --git a/Source/Core/InputCommon/InputProfile.cpp b/Source/Core/InputCommon/InputProfile.cpp index 07fa1f7795..7cefa5122c 100644 --- a/Source/Core/InputCommon/InputProfile.cpp +++ b/Source/Core/InputCommon/InputProfile.cpp @@ -4,8 +4,9 @@ #include "Common/FileSearch.h" #include "Common/FileUtil.h" +#include "Common/StringUtil.h" -#include "Core/Config/WiimoteInputSettings.h" +#include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/HW/Wiimote.h" #include "Core/HotkeyManager.h" @@ -41,7 +42,7 @@ namespace InputProfile return profiles[profile_index]; } - void ProfileCycler::UpdateToProfile(const std::string& profile_filename, const std::vector& controllers) + void ProfileCycler::UpdateToProfile(const std::string& profile_filename, ControllerEmu::EmulatedController* controller) { std::string base; SplitPath(profile_filename, nullptr, &base, nullptr); @@ -49,34 +50,16 @@ namespace InputProfile IniFile ini_file; if (ini_file.Load(profile_filename)) { - Core::DisplayMessage("Loading input profile: " + base, display_message_ms); - - for (auto* controller : controllers) - { - controller->LoadConfig(ini_file.GetOrCreateSection("Profile")); - controller->UpdateReferences(g_controller_interface); - } + Core::DisplayMessage("Loading input profile '" + base + "' for device '" + controller->GetName() + "'", display_message_ms); + controller->LoadConfig(ini_file.GetOrCreateSection("Profile")); + controller->UpdateReferences(g_controller_interface); } else { - Core::DisplayMessage("Unable to load input profile: " + base, display_message_ms); + Core::DisplayMessage("Unable to load input profile '" + base + "' for device '" + controller->GetName() + "'", display_message_ms); } } - std::vector ProfileCycler::GetControllersForDevice(InputConfig* device_configuration) - { - const std::size_t size = device_configuration->GetControllerCount(); - - std::vector result(size); - - for (int i = 0; i < static_cast(size); i++) - { - result[i] = device_configuration->GetController(i); - } - - return result; - } - std::vector ProfileCycler::GetProfilesFromSetting(const std::string& setting, InputConfig* device_configuration) { const auto& profiles = SplitString(setting, ','); @@ -86,7 +69,7 @@ namespace InputProfile std::vector result(profiles.size()); std::transform(profiles.begin(), profiles.end(), result.begin(), [&device_profile_root_location](const std::string& profile) { - return device_profile_root_location + "/" + profile; + return device_profile_root_location + "/" + profile + ".ini"; }); return result; @@ -107,7 +90,8 @@ namespace InputProfile } void ProfileCycler::CycleProfile(CycleDirection cycle_direction, - InputConfig* device_configuration, int& profile_index) + InputConfig* device_configuration, int& profile_index, + int controller_index) { const auto& profiles = GetProfilesForDevice(device_configuration); if (profiles.empty()) @@ -117,13 +101,20 @@ namespace InputProfile } const std::string profile = GetProfile(cycle_direction, profile_index, profiles); - const auto& controllers = GetControllersForDevice(device_configuration); - UpdateToProfile(profile, controllers); + auto* controller = device_configuration->GetController(controller_index); + if (controller) + { + UpdateToProfile(profile, controller); + } + else + { + Core::DisplayMessage("No controller found for index: " + std::to_string(controller_index), display_message_ms); + } } void ProfileCycler::CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, - const std::string& setting) + const std::string& setting, int controller_index) { const auto& profiles = GetProfilesForDevice(device_configuration); if (profiles.empty()) @@ -159,25 +150,37 @@ namespace InputProfile } } - void ProfileCycler::NextWiimoteProfile() + std::string ProfileCycler::GetWiimoteInputProfilesForGame(int controller_index) { - CycleProfile(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index); + IniFile game_ini = SConfig::GetInstance().LoadGameIni(); + const IniFile::Section* const control_section = game_ini.GetOrCreateSection("Controls"); + + std::string result; + control_section->Get(StringFromFormat("WiimoteProfile%d", controller_index+1), &result); + return result; } - void ProfileCycler::PreviousWiimoteProfile() + void ProfileCycler::NextWiimoteProfile(int controller_index) { - CycleProfile(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index); + CycleProfile(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index, + controller_index); } - void ProfileCycler::NextWiimoteProfileForGame() + void ProfileCycler::PreviousWiimoteProfile(int controller_index) + { + CycleProfile(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index, + controller_index); + } + + void ProfileCycler::NextWiimoteProfileForGame(int controller_index) { CycleProfileForGame(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index, - Config::Get(Config::WIIMOTE_PROFILES)); + GetWiimoteInputProfilesForGame(controller_index), controller_index); } - void ProfileCycler::PreviousWiimoteProfileForGame() + void ProfileCycler::PreviousWiimoteProfileForGame(int controller_index) { CycleProfileForGame(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index, - Config::Get(Config::WIIMOTE_PROFILES)); + GetWiimoteInputProfilesForGame(controller_index), controller_index); } } diff --git a/Source/Core/InputCommon/InputProfile.h b/Source/Core/InputCommon/InputProfile.h index ec0344b23f..6cf2b05716 100644 --- a/Source/Core/InputCommon/InputProfile.h +++ b/Source/Core/InputCommon/InputProfile.h @@ -25,19 +25,19 @@ namespace InputProfile class ProfileCycler { public: - void NextWiimoteProfile(); - void PreviousWiimoteProfile(); - void NextWiimoteProfileForGame(); - void PreviousWiimoteProfileForGame(); + void NextWiimoteProfile(int controller_index); + void PreviousWiimoteProfile(int controller_index); + void NextWiimoteProfileForGame(int controller_index); + void PreviousWiimoteProfileForGame(int controller_index); private: - void CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index); - void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, const std::string& setting); + void CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, int controller_index); + void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, const std::string& setting, int controller_index); std::vector GetProfilesForDevice(InputConfig* device_configuration); std::vector GetProfilesFromSetting(const std::string& setting, InputConfig* device_configuration); std::string GetProfile(CycleDirection cycle_direction, int& profile_index, const std::vector& profiles); std::vector GetMatchingProfilesFromSetting(const std::string& setting, const std::vector& profiles, InputConfig* device_configuration); - void UpdateToProfile(const std::string& profile_filename, const std::vector& controllers); - std::vector GetControllersForDevice(InputConfig* device_configuration); + void UpdateToProfile(const std::string& profile_filename, ControllerEmu::EmulatedController* controller); + std::string GetWiimoteInputProfilesForGame(int controller_index); int m_wiimote_profile_index = 0; }; From e10abaed3e4aa48379dc1a052d2d9a2851e8464d Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 28 Apr 2018 13:07:26 -0500 Subject: [PATCH 10/15] InputConfig: Show display message when game specific input profile is loaded; matching how cycling works --- Source/Core/InputCommon/InputConfig.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp index 9ca3e1708d..d929356d3c 100644 --- a/Source/Core/InputCommon/InputConfig.cpp +++ b/Source/Core/InputCommon/InputConfig.cpp @@ -9,6 +9,7 @@ #include "Common/MsgHandler.h" #include "Common/StringUtil.h" #include "Core/ConfigManager.h" +#include "Core/Core.h" #include "Core/HW/Wiimote.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" @@ -84,6 +85,12 @@ bool InputConfig::LoadConfig(bool isGC) // Load settings from ini if (useProfile[n]) { + std::string base; + SplitPath(profile[n], nullptr, &base, nullptr); + Core::DisplayMessage("Loading game specific input profile '" + base + + "' for device '" + controller->GetName() + "'", + 6000); + IniFile profile_ini; profile_ini.Load(profile[n]); controller->LoadConfig(profile_ini.GetOrCreateSection("Profile")); From 83c94feb3d6bd60a23e57cdb0afd837172fa3a31 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 28 Apr 2018 13:54:00 -0500 Subject: [PATCH 11/15] Input: Trim profile names to allow spaces between ','s --- Source/Core/InputCommon/InputProfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/InputCommon/InputProfile.cpp b/Source/Core/InputCommon/InputProfile.cpp index 7cefa5122c..dc76c83fa8 100644 --- a/Source/Core/InputCommon/InputProfile.cpp +++ b/Source/Core/InputCommon/InputProfile.cpp @@ -69,7 +69,7 @@ namespace InputProfile std::vector result(profiles.size()); std::transform(profiles.begin(), profiles.end(), result.begin(), [&device_profile_root_location](const std::string& profile) { - return device_profile_root_location + "/" + profile + ".ini"; + return device_profile_root_location + "/" + StripSpaces(profile) + ".ini"; }); return result; From 230af569ed80772cf149020f1f8dfb88fe5059c8 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 5 May 2018 23:08:37 -0500 Subject: [PATCH 12/15] Input - Make dynamic rules be definable per game. Configuration can now define how many frames constitute a high or a low swing/shake when the button is down. Also configurable is the number of frames to execute the swing/shake after the button is released. --- .../Core/Core/Config/WiimoteInputSettings.cpp | 9 +++++++ .../Core/Core/Config/WiimoteInputSettings.h | 10 +++++++ Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 26 +++++++++---------- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h | 7 +++++ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/Config/WiimoteInputSettings.cpp b/Source/Core/Core/Config/WiimoteInputSettings.cpp index a60ed45e9f..ebe61bfc68 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.cpp +++ b/Source/Core/Core/Config/WiimoteInputSettings.cpp @@ -18,6 +18,15 @@ namespace Config const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Shake", "Medium" }, 3.0 }; const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Shake", "Soft" }, 2.0 }; + // Dynamic settings + const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST{ { System::WiiPad, "Dynamic_Swing", "FramesHeldFast" }, 100 }; + const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW{ { System::WiiPad, "Dynamic_Swing", "FramesHeldSlow" }, 30 }; + const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH{ { System::WiiPad, "Dynamic_Swing", "FrameCount" }, 30 }; + + const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD{ { System::WiiPad, "Dynamic_Shake", "FramesHeldHard" }, 45 }; + const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT{ { System::WiiPad, "Dynamic_Shake", "FramesHeldSoft" }, 15 }; + const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH{ { System::WiiPad, "Dynamic_Shake", "FrameCount" }, 30 }; + // NunchuckInput.Settings const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST{ { System::WiiPad, "Nunchuk_Swing", "Fast" }, 4.5 }; diff --git a/Source/Core/Core/Config/WiimoteInputSettings.h b/Source/Core/Core/Config/WiimoteInputSettings.h index 44ab85b37d..17cacffbc4 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.h +++ b/Source/Core/Core/Config/WiimoteInputSettings.h @@ -20,6 +20,16 @@ namespace Config extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM; extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT; + // Below settings are for dynamic input only (based on how long the user holds a button) + + extern const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST; // How long button held constitutes a fast swing + extern const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW; // How long button held constitutes a slow swing + extern const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH; // How long to execute the swing + + extern const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD; // How long button held constitutes a hard shake + extern const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT; // How long button held constitutes a soft shake + extern const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH; // How long to execute a shake + // NunchuckInput.Settings extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST; diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index b45942c2e6..14853484bb 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -135,10 +135,6 @@ void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, Cont unsigned int shake = 0; buttons_group->GetState(&shake, btns); - static const int frames_high = 45; - static const int frames_low = 15; - static const int frames_to_execute = 31; // about 2 shake-loops - for (int i = 0; i != 3; ++i) { if ((shake & (1 << i)) && dynamic_data.executing_frames_left[i] == 0) @@ -153,11 +149,11 @@ void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, Cont } else if (shake == 0 && dynamic_data.timing[i] > 0) { - if (dynamic_data.timing[i] > frames_high) + if (dynamic_data.timing[i] > config.frames_needed_for_high_intensity) { dynamic_data.intensity[i] = config.high_intensity; } - else if (dynamic_data.timing[i] < frames_low) + else if (dynamic_data.timing[i] < config.frames_needed_for_low_intensity) { dynamic_data.intensity[i] = config.low_intensity; } @@ -166,7 +162,7 @@ void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, Cont dynamic_data.intensity[i] = config.med_intensity; } dynamic_data.timing[i] = 0; - dynamic_data.executing_frames_left[i] = frames_to_execute; + dynamic_data.executing_frames_left[i] = config.frames_to_execute; } else { @@ -256,10 +252,6 @@ void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data, if (!sideways && upright) g_dir[axis_map[0]] *= -1; - static const int frames_high = 100; - static const int frames_low = 30; - static const int frames_to_execute = 30; - for (unsigned int i = 0; i < 3; ++i) { if (swing[i] > 0 && dynamic_data.executing_frames_left[i] == 0) @@ -273,11 +265,11 @@ void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data, } else if (swing[i] == 0 && dynamic_data.timing[i] > 0) { - if (dynamic_data.timing[i] > frames_high) + if (dynamic_data.timing[i] > config.frames_needed_for_high_intensity) { dynamic_data.intensity[i] = config.high_intensity; } - else if (dynamic_data.timing[i] < frames_low) + else if (dynamic_data.timing[i] < config.frames_needed_for_low_intensity) { dynamic_data.intensity[i] = config.low_intensity; } @@ -286,7 +278,7 @@ void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data, dynamic_data.intensity[i] = config.med_intensity; } dynamic_data.timing[i] = 0; - dynamic_data.executing_frames_left[i] = frames_to_execute; + dynamic_data.executing_frames_left[i] = config.frames_to_execute; } } } @@ -612,6 +604,9 @@ void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf) swing_config.low_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW); swing_config.med_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM); swing_config.high_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_FAST); + swing_config.frames_needed_for_high_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST); + swing_config.frames_needed_for_low_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW); + swing_config.frames_to_execute = Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH); EmulateSwing(&m_accel, m_swing, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM), is_sideways, is_upright); EmulateSwing(&m_accel, m_swing_slow, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW), is_sideways, is_upright); @@ -623,6 +618,9 @@ void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf) shake_config.low_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT); shake_config.med_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM); shake_config.high_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_HARD); + shake_config.frames_needed_for_high_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD); + shake_config.frames_needed_for_low_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT); + shake_config.frames_to_execute = Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH); EmulateShake(&m_accel, m_shake, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM), m_shake_step.data()); EmulateShake(&m_accel, m_shake_soft, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT), m_shake_soft_step.data()); diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 6c22a9e2f8..8fbb761b13 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -140,8 +140,15 @@ struct DynamicData struct DynamicConfiguration { double low_intensity; + int frames_needed_for_low_intensity; + double med_intensity; + // Frames needed for med intensity can be calculated between high & low + double high_intensity; + int frames_needed_for_high_intensity; + + int frames_to_execute; // How many frames should we execute the action for? }; struct ADPCMState From b5db180ac4dad3b0de143a3f3d4d061ba79e709a Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 6 May 2018 12:48:55 -0500 Subject: [PATCH 13/15] Add 'Boom Blox Bash Party' ini that contains Hard/Soft/Medium shake speeds and Fast/Slow/Medium swing speeds. It mimics the 'Boom Blox' ini --- Data/Sys/GameSettings/RYB.ini | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Data/Sys/GameSettings/RYB.ini diff --git a/Data/Sys/GameSettings/RYB.ini b/Data/Sys/GameSettings/RYB.ini new file mode 100644 index 0000000000..ad69b55675 --- /dev/null +++ b/Data/Sys/GameSettings/RYB.ini @@ -0,0 +1,26 @@ +# RYBP69, RYBE69 - Boom Blox Bash Party + +[Core] +# Values set here will override the main Dolphin settings. + +[OnLoad] +# Add memory patches to be loaded once on boot here. + +[OnFrame] +# Add memory patches to be applied every frame here. + +[ActionReplay] +# Add action replay cheats here. + +[Video_Settings] +# Add any video settings here + +[Wiimote.Shake] +Soft = 3.0 +Medium = 4.0 +Hard = 4.8 + +[Wiimote.Swing] +Slow = 3.5 +Medium = 4.8 +Fast = 6 \ No newline at end of file From 3b11066e6168a4c266ab30dd2805f8148c00f1a1 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Wed, 23 May 2018 22:20:58 -0500 Subject: [PATCH 14/15] Fix lint bugs --- .../Core/Core/Config/WiimoteInputSettings.cpp | 58 ++-- .../Core/Core/Config/WiimoteInputSettings.h | 50 +-- .../Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp | 9 +- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp | 53 ++- Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h | 11 +- .../Mapping/HotkeyControllerProfile.cpp | 15 +- .../Config/Mapping/HotkeyControllerProfile.h | 16 +- .../Config/Mapping/MappingWindow.cpp | 2 +- Source/Core/InputCommon/InputConfig.cpp | 4 +- Source/Core/InputCommon/InputProfile.cpp | 328 +++++++++--------- Source/Core/InputCommon/InputProfile.h | 56 +-- 11 files changed, 330 insertions(+), 272 deletions(-) diff --git a/Source/Core/Core/Config/WiimoteInputSettings.cpp b/Source/Core/Core/Config/WiimoteInputSettings.cpp index ebe61bfc68..db8ff55597 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.cpp +++ b/Source/Core/Core/Config/WiimoteInputSettings.cpp @@ -6,34 +6,48 @@ namespace Config { - // Configuration Information +// Configuration Information - // WiimoteInput.Settings +// WiimoteInput.Settings - const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_FAST{ { System::WiiPad, "Swing", "Fast" }, 4.5 }; - const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM{ { System::WiiPad, "Swing", "Medium" }, 2.5 }; - const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_SLOW{ { System::WiiPad, "Swing", "Slow" }, 1.5 }; +const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_FAST{{System::WiiPad, "Swing", "Fast"}, 4.5}; +const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM{{System::WiiPad, "Swing", "Medium"}, + 2.5}; +const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_SLOW{{System::WiiPad, "Swing", "Slow"}, 1.5}; - const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Shake", "Hard" }, 5.0 }; - const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Shake", "Medium" }, 3.0 }; - const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Shake", "Soft" }, 2.0 }; +const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_HARD{{System::WiiPad, "Shake", "Hard"}, 5.0}; +const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM{{System::WiiPad, "Shake", "Medium"}, + 3.0}; +const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT{{System::WiiPad, "Shake", "Soft"}, 2.0}; - // Dynamic settings - const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST{ { System::WiiPad, "Dynamic_Swing", "FramesHeldFast" }, 100 }; - const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW{ { System::WiiPad, "Dynamic_Swing", "FramesHeldSlow" }, 30 }; - const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH{ { System::WiiPad, "Dynamic_Swing", "FrameCount" }, 30 }; +// Dynamic settings +const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST{ + {System::WiiPad, "Dynamic_Swing", "FramesHeldFast"}, 100}; +const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW{ + {System::WiiPad, "Dynamic_Swing", "FramesHeldSlow"}, 30}; +const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH{ + {System::WiiPad, "Dynamic_Swing", "FrameCount"}, 30}; - const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD{ { System::WiiPad, "Dynamic_Shake", "FramesHeldHard" }, 45 }; - const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT{ { System::WiiPad, "Dynamic_Shake", "FramesHeldSoft" }, 15 }; - const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH{ { System::WiiPad, "Dynamic_Shake", "FrameCount" }, 30 }; +const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD{ + {System::WiiPad, "Dynamic_Shake", "FramesHeldHard"}, 45}; +const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT{ + {System::WiiPad, "Dynamic_Shake", "FramesHeldSoft"}, 15}; +const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH{ + {System::WiiPad, "Dynamic_Shake", "FrameCount"}, 30}; - // NunchuckInput.Settings +// NunchuckInput.Settings - const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST{ { System::WiiPad, "Nunchuk_Swing", "Fast" }, 4.5 }; - const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_MEDIUM{ { System::WiiPad, "Nunchuk_Swing", "Medium" }, 2.5 }; - const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_SLOW{ { System::WiiPad, "Nunchuk_Swing", "Slow" }, 1.5 }; +const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST{ + {System::WiiPad, "Nunchuk_Swing", "Fast"}, 4.5}; +const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_MEDIUM{ + {System::WiiPad, "Nunchuk_Swing", "Medium"}, 2.5}; +const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_SLOW{ + {System::WiiPad, "Nunchuk_Swing", "Slow"}, 1.5}; - const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Nunchuk_Shake", "Hard" }, 5.0 }; - const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Nunchuk_Shake", "Medium" }, 3.0 }; - const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Nunchuk_Shake", "Soft" }, 2.0 }; +const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD{ + {System::WiiPad, "Nunchuk_Shake", "Hard"}, 5.0}; +const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM{ + {System::WiiPad, "Nunchuk_Shake", "Medium"}, 3.0}; +const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT{ + {System::WiiPad, "Nunchuk_Shake", "Soft"}, 2.0}; } diff --git a/Source/Core/Core/Config/WiimoteInputSettings.h b/Source/Core/Core/Config/WiimoteInputSettings.h index 17cacffbc4..de7ffc0241 100644 --- a/Source/Core/Core/Config/WiimoteInputSettings.h +++ b/Source/Core/Core/Config/WiimoteInputSettings.h @@ -8,36 +8,42 @@ namespace Config { - // Configuration Information +// Configuration Information - // WiimoteInput.Settings +// WiimoteInput.Settings - extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_FAST; - extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM; - extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_SLOW; +extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_FAST; +extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM; +extern const ConfigInfo WIIMOTE_INPUT_SWING_INTENSITY_SLOW; - extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_HARD; - extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM; - extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT; +extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_HARD; +extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM; +extern const ConfigInfo WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT; - // Below settings are for dynamic input only (based on how long the user holds a button) +// Below settings are for dynamic input only (based on how long the user holds a button) - extern const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST; // How long button held constitutes a fast swing - extern const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW; // How long button held constitutes a slow swing - extern const ConfigInfo WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH; // How long to execute the swing +extern const ConfigInfo + WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST; // How long button held constitutes a fast swing +extern const ConfigInfo + WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW; // How long button held constitutes a slow swing +extern const ConfigInfo + WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH; // How long to execute the swing - extern const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD; // How long button held constitutes a hard shake - extern const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT; // How long button held constitutes a soft shake - extern const ConfigInfo WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH; // How long to execute a shake +extern const ConfigInfo + WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD; // How long button held constitutes a hard shake +extern const ConfigInfo + WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT; // How long button held constitutes a soft shake +extern const ConfigInfo + WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH; // How long to execute a shake - // NunchuckInput.Settings +// NunchuckInput.Settings - extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST; - extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_MEDIUM; - extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_SLOW; +extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_FAST; +extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_MEDIUM; +extern const ConfigInfo NUNCHUK_INPUT_SWING_INTENSITY_SLOW; - extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD; - extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM; - extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT; +extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_HARD; +extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM; +extern const ConfigInfo NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT; } // namespace Config diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp index 9ba2a8e079..b2a6f04ccb 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp @@ -109,9 +109,12 @@ void Nunchuk::GetState(u8* const data) EmulateSwing(&accel, m_swing_fast, Config::Get(Config::NUNCHUK_INPUT_SWING_INTENSITY_FAST)); // shake - EmulateShake(&accel, m_shake, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM), m_shake_step.data()); - EmulateShake(&accel, m_shake_soft, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT), m_shake_soft_step.data()); - EmulateShake(&accel, m_shake_hard, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_HARD), m_shake_hard_step.data()); + EmulateShake(&accel, m_shake, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_MEDIUM), + m_shake_step.data()); + EmulateShake(&accel, m_shake_soft, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_SOFT), + m_shake_soft_step.data()); + EmulateShake(&accel, m_shake_hard, Config::Get(Config::NUNCHUK_INPUT_SHAKE_INTENSITY_HARD), + m_shake_hard_step.data()); // buttons m_buttons->GetState(&nc_data.bt.hex, nunchuk_button_bitmasks.data()); diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 14853484bb..453b42381f 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -123,15 +123,16 @@ void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_ } } -void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, ControllerEmu::Buttons* const buttons_group, - const DynamicConfiguration& config, u8* const shake_step) +void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, + ControllerEmu::Buttons* const buttons_group, + const DynamicConfiguration& config, u8* const shake_step) { // frame count of one up/down shake // < 9 no shake detection in "Wario Land: Shake It" auto const shake_step_max = 15; // shake is a bitfield of X,Y,Z shake button states - static const unsigned int btns[] = { 0x01, 0x02, 0x04 }; + static const unsigned int btns[] = {0x01, 0x02, 0x04}; unsigned int shake = 0; buttons_group->GetState(&shake, btns); @@ -232,12 +233,14 @@ void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const swing_grou } void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data, - ControllerEmu::Force* const swing_group, const DynamicConfiguration& config, const bool sideways, const bool upright) + ControllerEmu::Force* const swing_group, + const DynamicConfiguration& config, const bool sideways, + const bool upright) { ControlState swing[3]; swing_group->GetState(swing); - s8 g_dir[3] = { -1, -1, -1 }; + s8 g_dir[3] = {-1, -1, -1}; u8 axis_map[3]; // determine which axis is which direction @@ -398,9 +401,12 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1 m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); groups.emplace_back(m_shake_dynamic = new ControllerEmu::Buttons("Shake Dynamic")); - m_shake_dynamic->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "X")); - m_shake_dynamic->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); - m_shake_dynamic->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); + m_shake_dynamic->controls.emplace_back( + new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "X")); + m_shake_dynamic->controls.emplace_back( + new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Y")); + m_shake_dynamic->controls.emplace_back( + new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z")); // extension groups.emplace_back(m_extension = new ControllerEmu::Extension(_trans("Extension"))); @@ -604,13 +610,18 @@ void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf) swing_config.low_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW); swing_config.med_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM); swing_config.high_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_FAST); - swing_config.frames_needed_for_high_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST); - swing_config.frames_needed_for_low_intensity = Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW); + swing_config.frames_needed_for_high_intensity = + Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_FAST); + swing_config.frames_needed_for_low_intensity = + Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_HELD_SLOW); swing_config.frames_to_execute = Config::Get(Config::WIIMOTE_INPUT_SWING_DYNAMIC_FRAMES_LENGTH); - EmulateSwing(&m_accel, m_swing, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM), is_sideways, is_upright); - EmulateSwing(&m_accel, m_swing_slow, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW), is_sideways, is_upright); - EmulateSwing(&m_accel, m_swing_fast, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_FAST), is_sideways, is_upright); + EmulateSwing(&m_accel, m_swing, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM), + is_sideways, is_upright); + EmulateSwing(&m_accel, m_swing_slow, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_SLOW), + is_sideways, is_upright); + EmulateSwing(&m_accel, m_swing_fast, Config::Get(Config::WIIMOTE_INPUT_SWING_INTENSITY_FAST), + is_sideways, is_upright); EmulateDynamicSwing(&m_accel, m_swing_dynamic_data, m_swing_dynamic, swing_config, is_sideways, is_upright); @@ -618,17 +629,21 @@ void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf) shake_config.low_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT); shake_config.med_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM); shake_config.high_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_HARD); - shake_config.frames_needed_for_high_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD); - shake_config.frames_needed_for_low_intensity = Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT); + shake_config.frames_needed_for_high_intensity = + Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_HARD); + shake_config.frames_needed_for_low_intensity = + Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_HELD_SOFT); shake_config.frames_to_execute = Config::Get(Config::WIIMOTE_INPUT_SHAKE_DYNAMIC_FRAMES_LENGTH); - EmulateShake(&m_accel, m_shake, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM), m_shake_step.data()); - EmulateShake(&m_accel, m_shake_soft, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT), m_shake_soft_step.data()); - EmulateShake(&m_accel, m_shake_hard, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_HARD), m_shake_hard_step.data()); + EmulateShake(&m_accel, m_shake, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM), + m_shake_step.data()); + EmulateShake(&m_accel, m_shake_soft, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT), + m_shake_soft_step.data()); + EmulateShake(&m_accel, m_shake_hard, Config::Get(Config::WIIMOTE_INPUT_SHAKE_INTENSITY_HARD), + m_shake_hard_step.data()); EmulateDynamicShake(&m_accel, m_shake_dynamic_data, m_shake_dynamic, shake_config, m_shake_dynamic_step.data()); - wm_accel& accel = *reinterpret_cast(data + rptf.accel); wm_buttons& core = *reinterpret_cast(data + rptf.core); diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index 8fbb761b13..f190220502 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -128,8 +128,8 @@ struct AccelData // shake struct DynamicData { - std::array timing; // Hold length in frames for each axis - std::array intensity; // Swing or shake intensity + std::array timing; // Hold length in frames for each axis + std::array intensity; // Swing or shake intensity std::array executing_frames_left; // Number of frames to execute the intensity operation }; @@ -186,8 +186,7 @@ void EmulateShake(AccelData* const accel_data, ControllerEmu::Buttons* const but void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data, ControllerEmu::Buttons* const buttons_group, - const DynamicConfiguration& config, - u8* const shake_step); + const DynamicConfiguration& config, u8* const shake_step); void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group, const bool sideways = false, const bool upright = false); @@ -197,8 +196,8 @@ void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const tilt_group void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data, ControllerEmu::Force* const swing_group, - const DynamicConfiguration& config, - const bool sideways = false, const bool upright = false); + const DynamicConfiguration& config, const bool sideways = false, + const bool upright = false); enum { diff --git a/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp index 14ae68f749..044b10485d 100644 --- a/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.cpp @@ -11,29 +11,30 @@ HotkeyControllerProfile::HotkeyControllerProfile(MappingWindow* window) : MappingWidget(window) { - CreateMainLayout(); + CreateMainLayout(); } void HotkeyControllerProfile::CreateMainLayout() { - m_main_layout = new QHBoxLayout(); + m_main_layout = new QHBoxLayout(); - m_main_layout->addWidget(CreateGroupBox(tr("Controller Profile"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_CONTROLLER_PROFILE))); + m_main_layout->addWidget(CreateGroupBox( + tr("Controller Profile"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_CONTROLLER_PROFILE))); - setLayout(m_main_layout); + setLayout(m_main_layout); } InputConfig* HotkeyControllerProfile::GetConfig() { - return HotkeyManagerEmu::GetConfig(); + return HotkeyManagerEmu::GetConfig(); } void HotkeyControllerProfile::LoadSettings() { - HotkeyManagerEmu::LoadConfig(); + HotkeyManagerEmu::LoadConfig(); } void HotkeyControllerProfile::SaveSettings() { - HotkeyManagerEmu::GetConfig()->SaveConfig(); + HotkeyManagerEmu::GetConfig()->SaveConfig(); } diff --git a/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h index 04c5435b27..6884275b63 100644 --- a/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h +++ b/Source/Core/DolphinQt/Config/Mapping/HotkeyControllerProfile.h @@ -10,17 +10,17 @@ class QHBoxLayout; class HotkeyControllerProfile final : public MappingWidget { - Q_OBJECT + Q_OBJECT public: - explicit HotkeyControllerProfile(MappingWindow* window); + explicit HotkeyControllerProfile(MappingWindow* window); - InputConfig* GetConfig() override; + InputConfig* GetConfig() override; private: - void LoadSettings() override; - void SaveSettings() override; - void CreateMainLayout(); + void LoadSettings() override; + void SaveSettings() override; + void CreateMainLayout(); - // Main - QHBoxLayout* m_main_layout; + // Main + QHBoxLayout* m_main_layout; }; diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp index 5424888ef5..9676569168 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp @@ -311,7 +311,7 @@ void MappingWindow::SetMappingType(MappingWindow::Type type) AddWidget(tr("Debugging"), new HotkeyDebugging(this)); AddWidget(tr("Wii and Wii Remote"), new HotkeyWii(this)); - AddWidget(tr("Controller Profile"), new HotkeyControllerProfile(this)); + AddWidget(tr("Controller Profile"), new HotkeyControllerProfile(this)); AddWidget(tr("Graphics"), new HotkeyGraphics(this)); AddWidget(tr("3D"), new Hotkey3D(this)); AddWidget(tr("Save and Load State"), new HotkeyStates(this)); diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp index d929356d3c..1ba44c047e 100644 --- a/Source/Core/InputCommon/InputConfig.cpp +++ b/Source/Core/InputCommon/InputConfig.cpp @@ -87,8 +87,8 @@ bool InputConfig::LoadConfig(bool isGC) { std::string base; SplitPath(profile[n], nullptr, &base, nullptr); - Core::DisplayMessage("Loading game specific input profile '" + base + - "' for device '" + controller->GetName() + "'", + Core::DisplayMessage("Loading game specific input profile '" + base + "' for device '" + + controller->GetName() + "'", 6000); IniFile profile_ini; diff --git a/Source/Core/InputCommon/InputProfile.cpp b/Source/Core/InputCommon/InputProfile.cpp index dc76c83fa8..2ca7b46096 100644 --- a/Source/Core/InputCommon/InputProfile.cpp +++ b/Source/Core/InputCommon/InputProfile.cpp @@ -20,167 +20,179 @@ namespace InputProfile { +namespace +{ +constexpr int display_message_ms = 3000; +} - namespace +std::vector ProfileCycler::GetProfilesForDevice(InputConfig* device_configuration) +{ + const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + + device_configuration->GetProfileName()); + return Common::DoFileSearch({device_profile_root_location}, {".ini"}); +} + +std::string ProfileCycler::GetProfile(CycleDirection cycle_direction, int& profile_index, + const std::vector& profiles) +{ + // update the index and bind it to the number of available strings + auto positive_modulo = [](int& i, int n) { i = (i % n + n) % n; }; + profile_index += static_cast(cycle_direction); + positive_modulo(profile_index, static_cast(profiles.size())); + + return profiles[profile_index]; +} + +void ProfileCycler::UpdateToProfile(const std::string& profile_filename, + ControllerEmu::EmulatedController* controller) +{ + std::string base; + SplitPath(profile_filename, nullptr, &base, nullptr); + + IniFile ini_file; + if (ini_file.Load(profile_filename)) { - constexpr int display_message_ms = 3000; + Core::DisplayMessage("Loading input profile '" + base + "' for device '" + + controller->GetName() + "'", + display_message_ms); + controller->LoadConfig(ini_file.GetOrCreateSection("Profile")); + controller->UpdateReferences(g_controller_interface); } - - std::vector ProfileCycler::GetProfilesForDevice(InputConfig* device_configuration) + else { - const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + device_configuration->GetProfileName()); - return Common::DoFileSearch({ device_profile_root_location }, { ".ini" }); - } - - std::string ProfileCycler::GetProfile(CycleDirection cycle_direction, int& profile_index, const std::vector& profiles) - { - // update the index and bind it to the number of available strings - auto positive_modulo = [](int& i, int n) {i = (i % n + n) % n;}; - profile_index += static_cast(cycle_direction); - positive_modulo(profile_index, static_cast(profiles.size())); - - return profiles[profile_index]; - } - - void ProfileCycler::UpdateToProfile(const std::string& profile_filename, ControllerEmu::EmulatedController* controller) - { - std::string base; - SplitPath(profile_filename, nullptr, &base, nullptr); - - IniFile ini_file; - if (ini_file.Load(profile_filename)) - { - Core::DisplayMessage("Loading input profile '" + base + "' for device '" + controller->GetName() + "'", display_message_ms); - controller->LoadConfig(ini_file.GetOrCreateSection("Profile")); - controller->UpdateReferences(g_controller_interface); - } - else - { - Core::DisplayMessage("Unable to load input profile '" + base + "' for device '" + controller->GetName() + "'", display_message_ms); - } - } - - std::vector ProfileCycler::GetProfilesFromSetting(const std::string& setting, InputConfig* device_configuration) - { - const auto& profiles = SplitString(setting, ','); - - const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + device_configuration->GetProfileName()); - - std::vector result(profiles.size()); - std::transform(profiles.begin(), profiles.end(), result.begin(), [&device_profile_root_location](const std::string& profile) - { - return device_profile_root_location + "/" + StripSpaces(profile) + ".ini"; - }); - - return result; - } - - std::vector ProfileCycler::GetMatchingProfilesFromSetting(const std::string& setting, const std::vector& profiles, InputConfig* device_configuration) - { - const auto& profiles_from_setting = GetProfilesFromSetting(setting, device_configuration); - if (profiles_from_setting.empty()) - { - return {}; - } - - std::vector result; - std::set_intersection(profiles.begin(), profiles.end(), profiles_from_setting.begin(), - profiles_from_setting.end(), std::back_inserter(result)); - return result; - } - - void ProfileCycler::CycleProfile(CycleDirection cycle_direction, - InputConfig* device_configuration, int& profile_index, - int controller_index) - { - const auto& profiles = GetProfilesForDevice(device_configuration); - if (profiles.empty()) - { - Core::DisplayMessage("No input profiles found", display_message_ms); - return; - } - const std::string profile = GetProfile(cycle_direction, profile_index, profiles); - - auto* controller = device_configuration->GetController(controller_index); - if (controller) - { - UpdateToProfile(profile, controller); - } - else - { - Core::DisplayMessage("No controller found for index: " + std::to_string(controller_index), display_message_ms); - } - } - - void ProfileCycler::CycleProfileForGame(CycleDirection cycle_direction, - InputConfig* device_configuration, int& profile_index, - const std::string& setting, int controller_index) - { - const auto& profiles = GetProfilesForDevice(device_configuration); - if (profiles.empty()) - { - Core::DisplayMessage("No input profiles found", display_message_ms); - return; - } - - if (setting.empty()) - { - Core::DisplayMessage("No setting found for game", display_message_ms); - return; - } - - const auto& profiles_for_game = GetMatchingProfilesFromSetting(setting, profiles, - device_configuration); - if (profiles_for_game.empty()) - { - Core::DisplayMessage("No input profiles found for game", display_message_ms); - return; - } - - const std::string profile = GetProfile(cycle_direction, profile_index, profiles_for_game); - - auto* controller = device_configuration->GetController(controller_index); - if (controller) - { - UpdateToProfile(profile, controller); - } - else - { - Core::DisplayMessage("No controller found for index: " + std::to_string(controller_index), display_message_ms); - } - } - - std::string ProfileCycler::GetWiimoteInputProfilesForGame(int controller_index) - { - IniFile game_ini = SConfig::GetInstance().LoadGameIni(); - const IniFile::Section* const control_section = game_ini.GetOrCreateSection("Controls"); - - std::string result; - control_section->Get(StringFromFormat("WiimoteProfile%d", controller_index+1), &result); - return result; - } - - void ProfileCycler::NextWiimoteProfile(int controller_index) - { - CycleProfile(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index, - controller_index); - } - - void ProfileCycler::PreviousWiimoteProfile(int controller_index) - { - CycleProfile(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index, - controller_index); - } - - void ProfileCycler::NextWiimoteProfileForGame(int controller_index) - { - CycleProfileForGame(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index, - GetWiimoteInputProfilesForGame(controller_index), controller_index); - } - - void ProfileCycler::PreviousWiimoteProfileForGame(int controller_index) - { - CycleProfileForGame(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index, - GetWiimoteInputProfilesForGame(controller_index), controller_index); + Core::DisplayMessage("Unable to load input profile '" + base + "' for device '" + + controller->GetName() + "'", + display_message_ms); } } + +std::vector ProfileCycler::GetProfilesFromSetting(const std::string& setting, + InputConfig* device_configuration) +{ + const auto& profiles = SplitString(setting, ','); + + const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + + device_configuration->GetProfileName()); + + std::vector result(profiles.size()); + std::transform(profiles.begin(), profiles.end(), result.begin(), + [&device_profile_root_location](const std::string& profile) { + return device_profile_root_location + "/" + StripSpaces(profile) + ".ini"; + }); + + return result; +} + +std::vector +ProfileCycler::GetMatchingProfilesFromSetting(const std::string& setting, + const std::vector& profiles, + InputConfig* device_configuration) +{ + const auto& profiles_from_setting = GetProfilesFromSetting(setting, device_configuration); + if (profiles_from_setting.empty()) + { + return {}; + } + + std::vector result; + std::set_intersection(profiles.begin(), profiles.end(), profiles_from_setting.begin(), + profiles_from_setting.end(), std::back_inserter(result)); + return result; +} + +void ProfileCycler::CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, + int& profile_index, int controller_index) +{ + const auto& profiles = GetProfilesForDevice(device_configuration); + if (profiles.empty()) + { + Core::DisplayMessage("No input profiles found", display_message_ms); + return; + } + const std::string profile = GetProfile(cycle_direction, profile_index, profiles); + + auto* controller = device_configuration->GetController(controller_index); + if (controller) + { + UpdateToProfile(profile, controller); + } + else + { + Core::DisplayMessage("No controller found for index: " + std::to_string(controller_index), + display_message_ms); + } +} + +void ProfileCycler::CycleProfileForGame(CycleDirection cycle_direction, + InputConfig* device_configuration, int& profile_index, + const std::string& setting, int controller_index) +{ + const auto& profiles = GetProfilesForDevice(device_configuration); + if (profiles.empty()) + { + Core::DisplayMessage("No input profiles found", display_message_ms); + return; + } + + if (setting.empty()) + { + Core::DisplayMessage("No setting found for game", display_message_ms); + return; + } + + const auto& profiles_for_game = + GetMatchingProfilesFromSetting(setting, profiles, device_configuration); + if (profiles_for_game.empty()) + { + Core::DisplayMessage("No input profiles found for game", display_message_ms); + return; + } + + const std::string profile = GetProfile(cycle_direction, profile_index, profiles_for_game); + + auto* controller = device_configuration->GetController(controller_index); + if (controller) + { + UpdateToProfile(profile, controller); + } + else + { + Core::DisplayMessage("No controller found for index: " + std::to_string(controller_index), + display_message_ms); + } +} + +std::string ProfileCycler::GetWiimoteInputProfilesForGame(int controller_index) +{ + IniFile game_ini = SConfig::GetInstance().LoadGameIni(); + const IniFile::Section* const control_section = game_ini.GetOrCreateSection("Controls"); + + std::string result; + control_section->Get(StringFromFormat("WiimoteProfile%d", controller_index + 1), &result); + return result; +} + +void ProfileCycler::NextWiimoteProfile(int controller_index) +{ + CycleProfile(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index, + controller_index); +} + +void ProfileCycler::PreviousWiimoteProfile(int controller_index) +{ + CycleProfile(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index, + controller_index); +} + +void ProfileCycler::NextWiimoteProfileForGame(int controller_index) +{ + CycleProfileForGame(CycleDirection::Forward, Wiimote::GetConfig(), m_wiimote_profile_index, + GetWiimoteInputProfilesForGame(controller_index), controller_index); +} + +void ProfileCycler::PreviousWiimoteProfileForGame(int controller_index) +{ + CycleProfileForGame(CycleDirection::Backward, Wiimote::GetConfig(), m_wiimote_profile_index, + GetWiimoteInputProfilesForGame(controller_index), controller_index); +} +} diff --git a/Source/Core/InputCommon/InputProfile.h b/Source/Core/InputCommon/InputProfile.h index 6cf2b05716..503f2bafcc 100644 --- a/Source/Core/InputCommon/InputProfile.h +++ b/Source/Core/InputCommon/InputProfile.h @@ -8,7 +8,7 @@ class InputConfig; namespace ControllerEmu { - class EmulatedController; +class EmulatedController; } #include @@ -16,29 +16,37 @@ namespace ControllerEmu namespace InputProfile { - enum class CycleDirection : int - { - Forward = 1, - Backward = -1 - }; +enum class CycleDirection : int +{ + Forward = 1, + Backward = -1 +}; - class ProfileCycler - { - public: - void NextWiimoteProfile(int controller_index); - void PreviousWiimoteProfile(int controller_index); - void NextWiimoteProfileForGame(int controller_index); - void PreviousWiimoteProfileForGame(int controller_index); - private: - void CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, int controller_index); - void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, const std::string& setting, int controller_index); - std::vector GetProfilesForDevice(InputConfig* device_configuration); - std::vector GetProfilesFromSetting(const std::string& setting, InputConfig* device_configuration); - std::string GetProfile(CycleDirection cycle_direction, int& profile_index, const std::vector& profiles); - std::vector GetMatchingProfilesFromSetting(const std::string& setting, const std::vector& profiles, InputConfig* device_configuration); - void UpdateToProfile(const std::string& profile_filename, ControllerEmu::EmulatedController* controller); - std::string GetWiimoteInputProfilesForGame(int controller_index); +class ProfileCycler +{ +public: + void NextWiimoteProfile(int controller_index); + void PreviousWiimoteProfile(int controller_index); + void NextWiimoteProfileForGame(int controller_index); + void PreviousWiimoteProfileForGame(int controller_index); - int m_wiimote_profile_index = 0; - }; +private: + void CycleProfile(CycleDirection cycle_direction, InputConfig* device_configuration, + int& profile_index, int controller_index); + void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration, + int& profile_index, const std::string& setting, int controller_index); + std::vector GetProfilesForDevice(InputConfig* device_configuration); + std::vector GetProfilesFromSetting(const std::string& setting, + InputConfig* device_configuration); + std::string GetProfile(CycleDirection cycle_direction, int& profile_index, + const std::vector& profiles); + std::vector GetMatchingProfilesFromSetting(const std::string& setting, + const std::vector& profiles, + InputConfig* device_configuration); + void UpdateToProfile(const std::string& profile_filename, + ControllerEmu::EmulatedController* controller); + std::string GetWiimoteInputProfilesForGame(int controller_index); + + int m_wiimote_profile_index = 0; +}; } From bce8041cce88926adf68c7b35b4e79d72420bb36 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 26 May 2018 17:19:13 -0500 Subject: [PATCH 15/15] Input: Allow per-game configuration to specify directories for input-profiles. If specified, the directories are searched recursively for inis --- Source/Core/InputCommon/InputConfig.cpp | 28 ++++++------- Source/Core/InputCommon/InputProfile.cpp | 50 +++++++++++++++--------- Source/Core/InputCommon/InputProfile.h | 5 ++- 3 files changed, 48 insertions(+), 35 deletions(-) diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp index 1ba44c047e..ac74c0ea7e 100644 --- a/Source/Core/InputCommon/InputConfig.cpp +++ b/Source/Core/InputCommon/InputConfig.cpp @@ -15,6 +15,7 @@ #include "InputCommon/ControllerEmu/ControllerEmu.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/InputConfig.h" +#include "InputCommon/InputProfile.h" InputConfig::InputConfig(const std::string& ini_name, const std::string& gui_name, const std::string& profile_name) @@ -56,22 +57,21 @@ bool InputConfig::LoadConfig(bool isGC) std::string profile_setting; if (control_section->Get(type + "Profile" + num[i], &profile_setting)) { - // Setting can contain commas, which means there are multiple profiles specified - // this is used for controller cycling - const auto& profile_options = SplitString(profile_setting, ','); + auto profiles = InputProfile::GetProfilesFromSetting( + profile_setting, File::GetUserPath(D_CONFIG_IDX) + path); + + if (profiles.empty()) + { + const std::string error = + "No profiles found for game setting '" + profile_setting + "'"; + // TODO: PanicAlert shouldn't be used for this. + PanicAlertT("%s", error.c_str()); + continue; + } // Use the first profile by default - profile[i] = profile_options[0]; - - if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile[i] + ".ini")) - { - useProfile[i] = true; - } - else - { - // TODO: PanicAlert shouldn't be used for this. - PanicAlertT("Selected controller profile does not exist"); - } + profile[i] = profiles[0]; + useProfile[i] = true; } } } diff --git a/Source/Core/InputCommon/InputProfile.cpp b/Source/Core/InputCommon/InputProfile.cpp index 2ca7b46096..c78c1fbfd6 100644 --- a/Source/Core/InputCommon/InputProfile.cpp +++ b/Source/Core/InputCommon/InputProfile.cpp @@ -25,11 +25,37 @@ namespace constexpr int display_message_ms = 3000; } +std::vector GetProfilesFromSetting(const std::string& setting, const std::string& root) +{ + const auto& setting_choices = SplitString(setting, ','); + + std::vector result; + for (const std::string& setting_choice : setting_choices) + { + const std::string path = root + StripSpaces(setting_choice); + if (File::IsDirectory(path)) + { + const auto files_under_directory = Common::DoFileSearch({path}, {".ini"}, true); + result.insert(result.end(), files_under_directory.begin(), files_under_directory.end()); + } + else + { + const std::string file_path = path + ".ini"; + if (File::Exists(file_path)) + { + result.push_back(file_path); + } + } + } + + return result; +} + std::vector ProfileCycler::GetProfilesForDevice(InputConfig* device_configuration) { const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + device_configuration->GetProfileName()); - return Common::DoFileSearch({device_profile_root_location}, {".ini"}); + return Common::DoFileSearch({device_profile_root_location}, {".ini"}, true); } std::string ProfileCycler::GetProfile(CycleDirection cycle_direction, int& profile_index, @@ -66,29 +92,15 @@ void ProfileCycler::UpdateToProfile(const std::string& profile_filename, } } -std::vector ProfileCycler::GetProfilesFromSetting(const std::string& setting, - InputConfig* device_configuration) -{ - const auto& profiles = SplitString(setting, ','); - - const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + - device_configuration->GetProfileName()); - - std::vector result(profiles.size()); - std::transform(profiles.begin(), profiles.end(), result.begin(), - [&device_profile_root_location](const std::string& profile) { - return device_profile_root_location + "/" + StripSpaces(profile) + ".ini"; - }); - - return result; -} - std::vector ProfileCycler::GetMatchingProfilesFromSetting(const std::string& setting, const std::vector& profiles, InputConfig* device_configuration) { - const auto& profiles_from_setting = GetProfilesFromSetting(setting, device_configuration); + const std::string device_profile_root_location(File::GetUserPath(D_CONFIG_IDX) + "Profiles/" + + device_configuration->GetProfileName() + "/"); + + const auto& profiles_from_setting = GetProfilesFromSetting(setting, device_profile_root_location); if (profiles_from_setting.empty()) { return {}; diff --git a/Source/Core/InputCommon/InputProfile.h b/Source/Core/InputCommon/InputProfile.h index 503f2bafcc..ccb4fbf4db 100644 --- a/Source/Core/InputCommon/InputProfile.h +++ b/Source/Core/InputCommon/InputProfile.h @@ -16,6 +16,9 @@ class EmulatedController; namespace InputProfile { +std::vector GetProfilesFromSetting(const std::string& setting, + const std::string& root); + enum class CycleDirection : int { Forward = 1, @@ -36,8 +39,6 @@ private: void CycleProfileForGame(CycleDirection cycle_direction, InputConfig* device_configuration, int& profile_index, const std::string& setting, int controller_index); std::vector GetProfilesForDevice(InputConfig* device_configuration); - std::vector GetProfilesFromSetting(const std::string& setting, - InputConfig* device_configuration); std::string GetProfile(CycleDirection cycle_direction, int& profile_index, const std::vector& profiles); std::vector GetMatchingProfilesFromSetting(const std::string& setting,