Wiimote Emulation: Add game-configurable shake/swing commands for the wiimote at three intensities

This commit is contained in:
iwubcode 2018-01-21 15:42:01 -06:00
parent 9f9afeb63e
commit fb7a6a1bbe
8 changed files with 93 additions and 18 deletions

View File

@ -30,6 +30,7 @@ add_library(core
Config/NetplaySettings.cpp Config/NetplaySettings.cpp
Config/SYSCONFSettings.cpp Config/SYSCONFSettings.cpp
Config/UISettings.cpp Config/UISettings.cpp
Config/WiimoteInputSettings.cpp
ConfigLoaders/BaseConfigLoader.cpp ConfigLoaders/BaseConfigLoader.cpp
ConfigLoaders/GameConfigLoader.cpp ConfigLoaders/GameConfigLoader.cpp
ConfigLoaders/IsSettingSaveable.cpp ConfigLoaders/IsSettingSaveable.cpp

View File

@ -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<double> WIIMOTE_INPUT_SWING_INTENSITY_FAST{ { System::WiiPad, "Swing", "Fast" }, 4.5 };
const ConfigInfo<double> WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM{ { System::WiiPad, "Swing", "Medium" }, 2.5 };
const ConfigInfo<double> WIIMOTE_INPUT_SWING_INTENSITY_SLOW{ { System::WiiPad, "Swing", "Slow" }, 1.5 };
const ConfigInfo<double> WIIMOTE_INPUT_SHAKE_INTENSITY_HARD{ { System::WiiPad, "Shake", "Hard" }, 5.0 };
const ConfigInfo<double> WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM{ { System::WiiPad, "Shake", "Medium" }, 3.0 };
const ConfigInfo<double> WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT{ { System::WiiPad, "Shake", "Soft" }, 2.0 };
}

View File

@ -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<double> WIIMOTE_INPUT_SWING_INTENSITY_FAST;
extern const ConfigInfo<double> WIIMOTE_INPUT_SWING_INTENSITY_MEDIUM;
extern const ConfigInfo<double> WIIMOTE_INPUT_SWING_INTENSITY_SLOW;
extern const ConfigInfo<double> WIIMOTE_INPUT_SHAKE_INTENSITY_HARD;
extern const ConfigInfo<double> WIIMOTE_INPUT_SHAKE_INTENSITY_MEDIUM;
extern const ConfigInfo<double> WIIMOTE_INPUT_SHAKE_INTENSITY_SOFT;
} // namespace Config

View File

@ -56,6 +56,7 @@
<ClCompile Include="ConfigLoaders\MovieConfigLoader.cpp" /> <ClCompile Include="ConfigLoaders\MovieConfigLoader.cpp" />
<ClCompile Include="ConfigLoaders\NetPlayConfigLoader.cpp" /> <ClCompile Include="ConfigLoaders\NetPlayConfigLoader.cpp" />
<ClCompile Include="ConfigManager.cpp" /> <ClCompile Include="ConfigManager.cpp" />
<ClCompile Include="Config\WiimoteInputSettings.cpp" />
<ClCompile Include="Core.cpp" /> <ClCompile Include="Core.cpp" />
<ClCompile Include="CoreTiming.cpp" /> <ClCompile Include="CoreTiming.cpp" />
<ClCompile Include="Debugger\Debugger_SymbolMap.cpp" /> <ClCompile Include="Debugger\Debugger_SymbolMap.cpp" />
@ -321,6 +322,7 @@
<ClInclude Include="ConfigLoaders\NetPlayConfigLoader.h" /> <ClInclude Include="ConfigLoaders\NetPlayConfigLoader.h" />
<ClInclude Include="ConfigManager.h" /> <ClInclude Include="ConfigManager.h" />
<ClInclude Include="Config\UISettings.h" /> <ClInclude Include="Config\UISettings.h" />
<ClInclude Include="Config\WiimoteInputSettings.h" />
<ClInclude Include="Core.h" /> <ClInclude Include="Core.h" />
<ClInclude Include="CoreTiming.h" /> <ClInclude Include="CoreTiming.h" />
<ClInclude Include="Debugger\Debugger_SymbolMap.h" /> <ClInclude Include="Debugger\Debugger_SymbolMap.h" />

View File

@ -910,6 +910,9 @@
<ClCompile Include="Config\UISettings.cpp"> <ClCompile Include="Config\UISettings.cpp">
<Filter>Config</Filter> <Filter>Config</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Config\WiimoteInputSettings.cpp">
<Filter>Config</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="BootManager.h" /> <ClInclude Include="BootManager.h" />
@ -1604,6 +1607,9 @@
<ClInclude Include="Config\UISettings.h"> <ClInclude Include="Config\UISettings.h">
<Filter>Config</Filter> <Filter>Config</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Config\WiimoteInputSettings.h">
<Filter>Config</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="CMakeLists.txt" /> <Text Include="CMakeLists.txt" />

View File

@ -91,9 +91,9 @@ void Nunchuk::GetState(u8* const data)
EmulateTilt(&accel, m_tilt); EmulateTilt(&accel, m_tilt);
// swing // swing
EmulateSwing(&accel, m_swing); EmulateSwing(&accel, m_swing, 2.5);
// shake // shake
EmulateShake(&accel, m_shake, m_shake_step.data()); EmulateShake(&accel, m_shake, 3.0, m_shake_step.data());
// buttons // buttons
m_buttons->GetState(&nc_data.bt.hex, nunchuk_button_bitmasks.data()); m_buttons->GetState(&nc_data.bt.hex, nunchuk_button_bitmasks.data());

View File

@ -17,6 +17,7 @@
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "Core/Config/SYSCONFSettings.h" #include "Core/Config/SYSCONFSettings.h"
#include "Core/Config/WiimoteInputSettings.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/HW/Wiimote.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, 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 // frame count of one up/down shake
// < 9 no shake detection in "Wario Land: Shake It" // < 9 no shake detection in "Wario Land: Shake It"
auto const shake_step_max = 15; 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 // 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; unsigned int shake = 0;
@ -117,7 +115,7 @@ void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_
{ {
if (shake & (1 << i)) 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; shake_step[i] = (shake_step[i] + 1) % shake_step_max;
} }
else else
@ -160,10 +158,8 @@ void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group,
(&accel->x)[fb] = sin(pitch) * sgn[fb]; (&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, 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]; ControlState swing[3];
swing_group->GetState(swing); swing_group->GetState(swing);
@ -184,7 +180,7 @@ void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const swing_grou
g_dir[axis_map[0]] *= -1; g_dir[axis_map[0]] *= -1;
for (unsigned int i = 0; i < 3; ++i) 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[] = { static const u16 button_bitmasks[] = {
@ -238,7 +234,9 @@ void Wiimote::Reset()
// 0x55 - 0xff: level 4 // 0x55 - 0xff: level 4
m_status.battery = (u8)(m_battery_setting->GetValue() * 100); 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 // clear read request queue
while (!m_read_requests.empty()) 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 // swing
groups.emplace_back(m_swing = new ControllerEmu::Force(_trans("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 // tilt
groups.emplace_back(m_tilt = new ControllerEmu::Tilt(_trans("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) // i18n: Refers to a 3D axis (used when mapping motion controls)
m_shake->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::Translate, _trans("Z"))); 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 // extension
groups.emplace_back(m_extension = new ControllerEmu::Extension(_trans("Extension"))); groups.emplace_back(m_extension = new ControllerEmu::Extension(_trans("Extension")));
m_extension->attachments.emplace_back(new WiimoteEmu::None(m_reg_ext)); 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; m_upright_setting->GetValue() ^ upright_modifier_toggle ^ upright_modifier_switch;
EmulateTilt(&m_accel, m_tilt, is_sideways, is_upright); 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<wm_accel*>(data + rptf.accel); wm_accel& accel = *reinterpret_cast<wm_accel*>(data + rptf.accel);
wm_buttons& core = *reinterpret_cast<wm_buttons*>(data + rptf.core); wm_buttons& core = *reinterpret_cast<wm_buttons*>(data + rptf.core);

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <array>
#include <queue> #include <queue>
#include <string> #include <string>
@ -154,13 +155,13 @@ struct ExtensionReg
#pragma pack(pop) #pragma pack(pop)
void EmulateShake(AccelData* const accel_data, ControllerEmu::Buttons* const buttons_group, 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, void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group,
const bool sideways = false, const bool upright = false); const bool sideways = false, const bool upright = false);
void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const tilt_group, 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 enum
{ {
@ -247,9 +248,13 @@ private:
ControllerEmu::Buttons* m_buttons; ControllerEmu::Buttons* m_buttons;
ControllerEmu::Buttons* m_dpad; ControllerEmu::Buttons* m_dpad;
ControllerEmu::Buttons* m_shake; ControllerEmu::Buttons* m_shake;
ControllerEmu::Buttons* m_shake_soft;
ControllerEmu::Buttons* m_shake_hard;
ControllerEmu::Cursor* m_ir; ControllerEmu::Cursor* m_ir;
ControllerEmu::Tilt* m_tilt; ControllerEmu::Tilt* m_tilt;
ControllerEmu::Force* m_swing; ControllerEmu::Force* m_swing;
ControllerEmu::Force* m_swing_slow;
ControllerEmu::Force* m_swing_fast;
ControllerEmu::ControlGroup* m_rumble; ControllerEmu::ControlGroup* m_rumble;
ControllerEmu::Output* m_motor; ControllerEmu::Output* m_motor;
ControllerEmu::Extension* m_extension; ControllerEmu::Extension* m_extension;
@ -274,7 +279,9 @@ private:
u8 m_reporting_mode; u8 m_reporting_mode;
u16 m_reporting_channel; u16 m_reporting_channel;
u8 m_shake_step[3]; std::array<u8, 3> m_shake_step{};
std::array<u8, 3> m_shake_soft_step{};
std::array<u8, 3> m_shake_hard_step{};
bool m_sensor_bar_on_top; bool m_sensor_bar_on_top;