Wiimote Emulation: Add game-configurable shake/swing commands for the wiimote at three intensities
This commit is contained in:
parent
9f9afeb63e
commit
fb7a6a1bbe
|
@ -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
|
||||||
|
|
|
@ -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 };
|
||||||
|
}
|
|
@ -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
|
|
@ -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" />
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue