Merge pull request #7262 from lioncash/force

ControlGroup: Return state data via GetState() by value where applicable
This commit is contained in:
Léo Lam 2018-09-16 16:04:21 +02:00 committed by GitHub
commit e90bd035cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 234 additions and 205 deletions

View File

@ -4,6 +4,8 @@
#include "Core/HW/GCPadEmu.h" #include "Core/HW/GCPadEmu.h"
#include <array>
#include "Common/Common.h" #include "Common/Common.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -133,8 +135,6 @@ ControllerEmu::ControlGroup* GCPad::GetGroup(PadGroup group)
GCPadStatus GCPad::GetInput() const GCPadStatus GCPad::GetInput() const
{ {
const auto lock = GetStateLock(); const auto lock = GetStateLock();
ControlState x, y, triggers[2];
GCPadStatus pad = {}; GCPadStatus pad = {};
if (!(m_always_connected->GetValue() || IsDefaultDeviceConnected())) if (!(m_always_connected->GetValue() || IsDefaultDeviceConnected()))
@ -156,20 +156,21 @@ GCPadStatus GCPad::GetInput() const
m_dpad->GetState(&pad.button, dpad_bitmasks); m_dpad->GetState(&pad.button, dpad_bitmasks);
// sticks // sticks
m_main_stick->GetState(&x, &y); const ControllerEmu::AnalogStick::StateData main_stick_state = m_main_stick->GetState();
pad.stickX = pad.stickX = static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_X +
static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_X + (x * GCPadStatus::MAIN_STICK_RADIUS)); (main_stick_state.x * GCPadStatus::MAIN_STICK_RADIUS));
pad.stickY = pad.stickY = static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_Y +
static_cast<u8>(GCPadStatus::MAIN_STICK_CENTER_Y + (y * GCPadStatus::MAIN_STICK_RADIUS)); (main_stick_state.y * GCPadStatus::MAIN_STICK_RADIUS));
m_c_stick->GetState(&x, &y); const ControllerEmu::AnalogStick::StateData c_stick_state = m_c_stick->GetState();
pad.substickX = pad.substickX = static_cast<u8>(GCPadStatus::C_STICK_CENTER_X +
static_cast<u8>(GCPadStatus::C_STICK_CENTER_X + (x * GCPadStatus::C_STICK_RADIUS)); (c_stick_state.x * GCPadStatus::C_STICK_RADIUS));
pad.substickY = pad.substickY = static_cast<u8>(GCPadStatus::C_STICK_CENTER_Y +
static_cast<u8>(GCPadStatus::C_STICK_CENTER_Y + (y * GCPadStatus::C_STICK_RADIUS)); (c_stick_state.y * GCPadStatus::C_STICK_RADIUS));
// triggers // triggers
m_triggers->GetState(&pad.button, trigger_bitmasks, triggers); std::array<ControlState, 2> triggers;
m_triggers->GetState(&pad.button, trigger_bitmasks, triggers.data());
pad.triggerLeft = static_cast<u8>(triggers[0] * 0xFF); pad.triggerLeft = static_cast<u8>(triggers[0] * 0xFF);
pad.triggerRight = static_cast<u8>(triggers[1] * 0xFF); pad.triggerRight = static_cast<u8>(triggers[1] * 0xFF);

View File

@ -137,29 +137,27 @@ void Classic::GetState(u8* const data)
// left stick // left stick
{ {
ControlState x, y; const ControllerEmu::AnalogStick::StateData left_stick_state = m_left_stick->GetState();
m_left_stick->GetState(&x, &y);
classic_data.regular_data.lx = classic_data.regular_data.lx = static_cast<u8>(
static_cast<u8>(Classic::LEFT_STICK_CENTER_X + (x * Classic::LEFT_STICK_RADIUS)); Classic::LEFT_STICK_CENTER_X + (left_stick_state.x * Classic::LEFT_STICK_RADIUS));
classic_data.regular_data.ly = classic_data.regular_data.ly = static_cast<u8>(
static_cast<u8>(Classic::LEFT_STICK_CENTER_Y + (y * Classic::LEFT_STICK_RADIUS)); Classic::LEFT_STICK_CENTER_Y + (left_stick_state.y * Classic::LEFT_STICK_RADIUS));
} }
// right stick // right stick
{ {
ControlState x, y; const ControllerEmu::AnalogStick::StateData right_stick_data = m_right_stick->GetState();
m_right_stick->GetState(&x, &y);
const u8 x_ = const u8 x = static_cast<u8>(Classic::RIGHT_STICK_CENTER_X +
static_cast<u8>(Classic::RIGHT_STICK_CENTER_X + (x * Classic::RIGHT_STICK_RADIUS)); (right_stick_data.x * Classic::RIGHT_STICK_RADIUS));
const u8 y_ = const u8 y = static_cast<u8>(Classic::RIGHT_STICK_CENTER_Y +
static_cast<u8>(Classic::RIGHT_STICK_CENTER_Y + (y * Classic::RIGHT_STICK_RADIUS)); (right_stick_data.y * Classic::RIGHT_STICK_RADIUS));
classic_data.rx1 = x_; classic_data.rx1 = x;
classic_data.rx2 = x_ >> 1; classic_data.rx2 = x >> 1;
classic_data.rx3 = x_ >> 3; classic_data.rx3 = x >> 3;
classic_data.ry = y_; classic_data.ry = y;
} }
// triggers // triggers

View File

@ -74,11 +74,10 @@ void Drums::GetState(u8* const data)
// stick // stick
{ {
ControlState x, y; const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState();
m_stick->GetState(&x, &y);
drum_data.sx = static_cast<u8>((x * 0x1F) + 0x20); drum_data.sx = static_cast<u8>((stick_state.x * 0x1F) + 0x20);
drum_data.sy = static_cast<u8>((y * 0x1F) + 0x20); drum_data.sy = static_cast<u8>((stick_state.y * 0x1F) + 0x20);
} }
// TODO: softness maybe // TODO: softness maybe
@ -87,6 +86,7 @@ void Drums::GetState(u8* const data)
// buttons // buttons
m_buttons->GetState(&drum_data.bt, drum_button_bitmasks.data()); m_buttons->GetState(&drum_data.bt, drum_button_bitmasks.data());
// pads // pads
m_pads->GetState(&drum_data.bt, drum_pad_bitmasks.data()); m_pads->GetState(&drum_data.bt, drum_pad_bitmasks.data());

View File

@ -106,19 +106,18 @@ void Guitar::GetState(u8* const data)
// stick // stick
{ {
ControlState x, y; const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState();
m_stick->GetState(&x, &y);
guitar_data.sx = static_cast<u8>((x * 0x1F) + 0x20); guitar_data.sx = static_cast<u8>((stick_state.x * 0x1F) + 0x20);
guitar_data.sy = static_cast<u8>((y * 0x1F) + 0x20); guitar_data.sy = static_cast<u8>((stick_state.y * 0x1F) + 0x20);
} }
// slider bar // slider bar
if (m_slider_bar->controls[0]->control_ref->BoundCount()) if (m_slider_bar->controls[0]->control_ref->BoundCount())
{ {
ControlState slider_bar; const ControllerEmu::Slider::StateData slider_data = m_slider_bar->GetState();
m_slider_bar->GetState(&slider_bar);
guitar_data.sb = s_slider_bar_control_codes.lower_bound(slider_bar)->second; guitar_data.sb = s_slider_bar_control_codes.lower_bound(slider_data.value)->second;
} }
else else
{ {
@ -127,14 +126,15 @@ void Guitar::GetState(u8* const data)
} }
// whammy bar // whammy bar
ControlState whammy; const ControllerEmu::Triggers::StateData whammy_state = m_whammy->GetState();
m_whammy->GetState(&whammy); guitar_data.whammy = static_cast<u8>(whammy_state.data[0] * 0x1F);
guitar_data.whammy = static_cast<u8>(whammy * 0x1F);
// buttons // buttons
m_buttons->GetState(&guitar_data.bt, guitar_button_bitmasks.data()); m_buttons->GetState(&guitar_data.bt, guitar_button_bitmasks.data());
// frets // frets
m_frets->GetState(&guitar_data.bt, guitar_fret_bitmasks.data()); m_frets->GetState(&guitar_data.bt, guitar_fret_bitmasks.data());
// strum // strum
m_strum->GetState(&guitar_data.bt, guitar_strum_bitmasks.data()); m_strum->GetState(&guitar_data.bt, guitar_strum_bitmasks.data());

View File

@ -76,11 +76,9 @@ void Nunchuk::GetState(u8* const data)
wm_nc nc_data = {}; wm_nc nc_data = {};
// stick // stick
double jx, jy; const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState();
m_stick->GetState(&jx, &jy); nc_data.jx = u8(STICK_CENTER + stick_state.x * STICK_RADIUS);
nc_data.jy = u8(STICK_CENTER + stick_state.y * STICK_RADIUS);
nc_data.jx = u8(STICK_CENTER + jx * STICK_RADIUS);
nc_data.jy = u8(STICK_CENTER + jy * STICK_RADIUS);
// Some terribly coded games check whether to move with a check like // Some terribly coded games check whether to move with a check like
// //

View File

@ -90,54 +90,46 @@ void Turntable::GetState(u8* const data)
// stick // stick
{ {
ControlState x, y; const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState();
m_stick->GetState(&x, &y);
tt_data.sx = static_cast<u8>((x * 0x1F) + 0x20); tt_data.sx = static_cast<u8>((stick_state.x * 0x1F) + 0x20);
tt_data.sy = static_cast<u8>((y * 0x1F) + 0x20); tt_data.sy = static_cast<u8>((stick_state.y * 0x1F) + 0x20);
} }
// left table // left table
{ {
ControlState tt; const ControllerEmu::Slider::StateData lt = m_left_table->GetState();
m_left_table->GetState(&tt); const s8 tt = static_cast<s8>(lt.value * 0x1F);
const s8 tt_ = static_cast<s8>(tt * 0x1F); tt_data.ltable1 = tt;
tt_data.ltable2 = tt >> 5;
tt_data.ltable1 = tt_;
tt_data.ltable2 = tt_ >> 5;
} }
// right table // right table
{ {
ControlState tt; const ControllerEmu::Slider::StateData rt = m_right_table->GetState();
m_right_table->GetState(&tt); const s8 tt = static_cast<s8>(rt.value * 0x1F);
const s8 tt_ = static_cast<s8>(tt * 0x1F); tt_data.rtable1 = tt;
tt_data.rtable2 = tt >> 1;
tt_data.rtable1 = tt_; tt_data.rtable3 = tt >> 3;
tt_data.rtable2 = tt_ >> 1; tt_data.rtable4 = tt >> 5;
tt_data.rtable3 = tt_ >> 3;
tt_data.rtable4 = tt_ >> 5;
} }
// effect dial // effect dial
{ {
ControlState dial; const ControllerEmu::Triggers::StateData state = m_effect_dial->GetState();
m_effect_dial->GetState(&dial); const u8 dial = static_cast<u8>(state.data[0] * 0x0F);
const u8 dial_ = static_cast<u8>(dial * 0x0F); tt_data.dial1 = dial;
tt_data.dial2 = dial >> 3;
tt_data.dial1 = dial_;
tt_data.dial2 = dial_ >> 3;
} }
// crossfade slider // crossfade slider
{ {
ControlState cfs; const ControllerEmu::Slider::StateData cfs = m_crossfade->GetState();
m_crossfade->GetState(&cfs);
tt_data.slider = static_cast<u8>((cfs * 0x07) + 0x08); tt_data.slider = static_cast<u8>((cfs.value * 0x07) + 0x08);
} }
// buttons // buttons

View File

@ -5,8 +5,10 @@
#include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h"
#include <algorithm> #include <algorithm>
#include <array>
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <cstddef>
#include <cstring> #include <cstring>
#include <mutex> #include <mutex>
@ -175,28 +177,24 @@ void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data,
void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group, const bool sideways, void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group, const bool sideways,
const bool upright) const bool upright)
{ {
ControlState roll, pitch;
// 180 degrees // 180 degrees
tilt_group->GetState(&roll, &pitch); const ControllerEmu::Tilt::StateData state = tilt_group->GetState();
const ControlState roll = state.x * PI;
const ControlState pitch = state.y * PI;
roll *= PI; // Some notes that no one will understand but me :p
pitch *= PI;
unsigned int ud = 0, lr = 0, fb = 0;
// some notes that no one will understand but me :p
// left, forward, up // left, forward, up
// lr/ left == negative for all orientations // lr/ left == negative for all orientations
// ud/ up == negative for upright longways // ud/ up == negative for upright longways
// fb/ forward == positive for (sideways flat) // fb/ forward == positive for (sideways flat)
// determine which axis is which direction // Determine which axis is which direction
ud = upright ? (sideways ? 0 : 1) : 2; const u32 ud = upright ? (sideways ? 0 : 1) : 2;
lr = sideways; const u32 lr = sideways;
fb = upright ? 2 : (sideways ? 0 : 1); const u32 fb = upright ? 2 : (sideways ? 0 : 1);
int sgn[3] = {-1, 1, 1}; // sign fix
// Sign fix
std::array<int, 3> sgn{{-1, 1, 1}};
if (sideways && !upright) if (sideways && !upright)
sgn[fb] *= -1; sgn[fb] *= -1;
if (!sideways && upright) if (!sideways && upright)
@ -210,25 +208,24 @@ void EmulateTilt(AccelData* const accel, ControllerEmu::Tilt* const tilt_group,
void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const swing_group, void EmulateSwing(AccelData* const accel, ControllerEmu::Force* const swing_group,
const double intensity, const bool sideways, const bool upright) const double intensity, const bool sideways, const bool upright)
{ {
ControlState swing[3]; const ControllerEmu::Force::StateData swing = swing_group->GetState();
swing_group->GetState(swing);
s8 g_dir[3] = {-1, -1, -1}; // Determine which axis is which direction
u8 axis_map[3]; const std::array<int, 3> axis_map{{
upright ? (sideways ? 0 : 1) : 2, // up/down
sideways, // left/right
upright ? 2 : (sideways ? 0 : 1), // forward/backward
}};
// determine which axis is which direction // Some orientations have up as positive, some as negative
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 // same with forward
std::array<s8, 3> g_dir{{-1, -1, -1}};
if (sideways && !upright) if (sideways && !upright)
g_dir[axis_map[2]] *= -1; g_dir[axis_map[2]] *= -1;
if (!sideways && upright) if (!sideways && upright)
g_dir[axis_map[0]] *= -1; g_dir[axis_map[0]] *= -1;
for (unsigned int i = 0; i < 3; ++i) for (std::size_t i = 0; i < swing.size(); ++i)
(&accel->x)[axis_map[i]] += swing[i] * g_dir[i] * intensity; (&accel->x)[axis_map[i]] += swing[i] * g_dir[i] * intensity;
} }
@ -237,25 +234,24 @@ void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data,
const DynamicConfiguration& config, const bool sideways, const DynamicConfiguration& config, const bool sideways,
const bool upright) const bool upright)
{ {
ControlState swing[3]; const ControllerEmu::Force::StateData swing = swing_group->GetState();
swing_group->GetState(swing);
s8 g_dir[3] = {-1, -1, -1}; // Determine which axis is which direction
u8 axis_map[3]; const std::array<int, 3> axis_map{{
upright ? (sideways ? 0 : 1) : 2, // up/down
sideways, // left/right
upright ? 2 : (sideways ? 0 : 1), // forward/backward
}};
// determine which axis is which direction // Some orientations have up as positive, some as negative
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 // same with forward
std::array<s8, 3> g_dir{{-1, -1, -1}};
if (sideways && !upright) if (sideways && !upright)
g_dir[axis_map[2]] *= -1; g_dir[axis_map[2]] *= -1;
if (!sideways && upright) if (!sideways && upright)
g_dir[axis_map[0]] *= -1; g_dir[axis_map[0]] *= -1;
for (unsigned int i = 0; i < 3; ++i) for (std::size_t i = 0; i < swing.size(); ++i)
{ {
if (swing[i] > 0 && dynamic_data.executing_frames_left[i] == 0) if (swing[i] > 0 && dynamic_data.executing_frames_left[i] == 0)
{ {
@ -432,9 +428,9 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1
// options // options
groups.emplace_back(m_options = new ControllerEmu::ControlGroup(_trans("Options"))); groups.emplace_back(m_options = new ControllerEmu::ControlGroup(_trans("Options")));
m_options->boolean_settings.emplace_back(new ControllerEmu::BooleanSetting( m_options->boolean_settings.emplace_back(
"Forward Wiimote", _trans("Forward Wii Remote"), new ControllerEmu::BooleanSetting("Forward Wiimote", _trans("Forward Wii Remote"), true,
true, ControllerEmu::SettingType::NORMAL, true)); ControllerEmu::SettingType::NORMAL, true));
m_options->boolean_settings.emplace_back(m_upright_setting = new ControllerEmu::BooleanSetting( m_options->boolean_settings.emplace_back(m_upright_setting = new ControllerEmu::BooleanSetting(
"Upright Wiimote", _trans("Upright Wii Remote"), "Upright Wiimote", _trans("Upright Wii Remote"),
false, ControllerEmu::SettingType::NORMAL, true)); false, ControllerEmu::SettingType::NORMAL, true));
@ -682,15 +678,14 @@ void Wiimote::GetIRData(u8* const data, bool use_accel)
u16 x[4], y[4]; u16 x[4], y[4];
memset(x, 0xFF, sizeof(x)); memset(x, 0xFF, sizeof(x));
ControlState xx = 10000, yy = 0, zz = 0;
double nsin, ncos; double nsin, ncos;
if (use_accel) if (use_accel)
{ {
double ax, az, len; double ax = m_accel.x;
ax = m_accel.x; double az = m_accel.z;
az = m_accel.z; const double len = sqrt(ax * ax + az * az);
len = sqrt(ax * ax + az * az);
if (len) if (len)
{ {
ax /= len; ax /= len;
@ -714,33 +709,34 @@ void Wiimote::GetIRData(u8* const data, bool use_accel)
LowPassFilter(ir_sin, nsin, 1.0 / 60); LowPassFilter(ir_sin, nsin, 1.0 / 60);
LowPassFilter(ir_cos, ncos, 1.0 / 60); LowPassFilter(ir_cos, ncos, 1.0 / 60);
m_ir->GetState(&xx, &yy, &zz, true); static constexpr int camWidth = 1024;
static constexpr int camHeight = 768;
static constexpr double bndup = -0.315447;
static constexpr double bnddown = 0.85;
static constexpr double bndleft = 0.78820266;
static constexpr double bndright = -0.78820266;
static constexpr double dist1 = 100.0 / camWidth; // this seems the optimal distance for zelda
static constexpr double dist2 = 1.2 * dist1;
Vertex v[4]; const ControllerEmu::Cursor::StateData cursor_state = m_ir->GetState(true);
static const int camWidth = 1024;
static const int camHeight = 768;
static const double bndup = -0.315447;
static const double bnddown = 0.85;
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;
std::array<Vertex, 4> v;
for (auto& vtx : v) for (auto& vtx : v)
{ {
vtx.x = xx * (bndright - bndleft) / 2 + (bndleft + bndright) / 2; vtx.x = cursor_state.x * (bndright - bndleft) / 2 + (bndleft + bndright) / 2;
if (m_sensor_bar_on_top) if (m_sensor_bar_on_top)
vtx.y = yy * (bndup - bnddown) / 2 + (bndup + bnddown) / 2; vtx.y = cursor_state.y * (bndup - bnddown) / 2 + (bndup + bnddown) / 2;
else else
vtx.y = yy * (bndup - bnddown) / 2 - (bndup + bnddown) / 2; vtx.y = cursor_state.y * (bndup - bnddown) / 2 - (bndup + bnddown) / 2;
vtx.z = 0; vtx.z = 0;
} }
v[0].x -= (zz * 0.5 + 1) * dist1; v[0].x -= (cursor_state.z * 0.5 + 1) * dist1;
v[1].x += (zz * 0.5 + 1) * dist1; v[1].x += (cursor_state.z * 0.5 + 1) * dist1;
v[2].x -= (zz * 0.5 + 1) * dist2; v[2].x -= (cursor_state.z * 0.5 + 1) * dist2;
v[3].x += (zz * 0.5 + 1) * dist2; v[3].x += (cursor_state.z * 0.5 + 1) * dist2;
#define printmatrix(m) \ #define printmatrix(m) \
PanicAlert("%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n", m[0][0], m[0][1], m[0][2], \ PanicAlert("%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n", m[0][0], m[0][1], m[0][2], \
@ -752,14 +748,17 @@ void Wiimote::GetIRData(u8* const data, bool use_accel)
MatrixRotationByZ(rot, ir_sin, ir_cos); MatrixRotationByZ(rot, ir_sin, ir_cos);
MatrixMultiply(tot, scale, rot); MatrixMultiply(tot, scale, rot);
for (int i = 0; i < 4; i++) for (std::size_t i = 0; i < v.size(); i++)
{ {
MatrixTransformVertex(tot, v[i]); MatrixTransformVertex(tot, v[i]);
if ((v[i].x < -1) || (v[i].x > 1) || (v[i].y < -1) || (v[i].y > 1)) if ((v[i].x < -1) || (v[i].x > 1) || (v[i].y < -1) || (v[i].y > 1))
continue; continue;
x[i] = (u16)lround((v[i].x + 1) / 2 * (camWidth - 1));
y[i] = (u16)lround((v[i].y + 1) / 2 * (camHeight - 1)); x[i] = static_cast<u16>(lround((v[i].x + 1) / 2 * (camWidth - 1)));
y[i] = static_cast<u16>(lround((v[i].y + 1) / 2 * (camHeight - 1)));
} }
// Fill report with valid data when full handshake was done // Fill report with valid data when full handshake was done
if (m_reg_ir.data[0x30]) if (m_reg_ir.data[0x30])
// ir mode // ir mode

View File

@ -36,20 +36,20 @@ AnalogStick::AnalogStick(const char* const name_, const char* const ui_name_,
numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50));
} }
void AnalogStick::GetState(ControlState* const x, ControlState* const y) AnalogStick::StateData AnalogStick::GetState()
{ {
ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); ControlState y = controls[0]->control_ref->State() - controls[1]->control_ref->State();
ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); ControlState x = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState radius = numeric_settings[SETTING_RADIUS]->GetValue(); const ControlState radius = numeric_settings[SETTING_RADIUS]->GetValue();
ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue(); const ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue();
ControlState m = controls[4]->control_ref->State(); const ControlState m = controls[4]->control_ref->State();
ControlState ang = atan2(yy, xx); const ControlState ang = atan2(y, x);
ControlState ang_sin = sin(ang); const ControlState ang_sin = sin(ang);
ControlState ang_cos = cos(ang); const ControlState ang_cos = cos(ang);
ControlState dist = sqrt(xx * xx + yy * yy); ControlState dist = sqrt(x * x + y * y);
// dead zone code // dead zone code
dist = std::max(0.0, dist - deadzone); dist = std::max(0.0, dist - deadzone);
@ -63,10 +63,9 @@ void AnalogStick::GetState(ControlState* const x, ControlState* const y)
if (m) if (m)
dist *= 0.5; dist *= 0.5;
yy = std::max(-1.0, std::min(1.0, ang_sin * dist)); y = std::max(-1.0, std::min(1.0, ang_sin * dist));
xx = std::max(-1.0, std::min(1.0, ang_cos * dist)); x = std::max(-1.0, std::min(1.0, ang_cos * dist));
*y = yy; return {x, y};
*x = xx;
} }
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -18,10 +18,16 @@ public:
SETTING_DEADZONE, SETTING_DEADZONE,
}; };
struct StateData
{
ControlState x{};
ControlState y{};
};
// The GameCube controller and Wiimote attachments have a different default radius // The GameCube controller and Wiimote attachments have a different default radius
AnalogStick(const char* name, ControlState default_radius); AnalogStick(const char* name, ControlState default_radius);
AnalogStick(const char* name, const char* ui_name, ControlState default_radius); AnalogStick(const char* name, const char* ui_name, ControlState default_radius);
void GetState(ControlState* x, ControlState* y); StateData GetState();
}; };
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -39,18 +39,18 @@ Cursor::Cursor(const std::string& name_) : ControlGroup(name_, GroupType::Cursor
boolean_settings.emplace_back(std::make_unique<BooleanSetting>(_trans("Auto-Hide"), false)); boolean_settings.emplace_back(std::make_unique<BooleanSetting>(_trans("Auto-Hide"), false));
} }
void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState* const z, Cursor::StateData Cursor::GetState(const bool adjusted)
const bool adjusted)
{ {
const ControlState zz = controls[4]->control_ref->State() - controls[5]->control_ref->State(); const ControlState zz = controls[4]->control_ref->State() - controls[5]->control_ref->State();
// silly being here // silly being here
if (zz > m_z) if (zz > m_state.z)
m_z = std::min(m_z + 0.1, zz); m_state.z = std::min(m_state.z + 0.1, zz);
else if (zz < m_z) else if (zz < m_state.z)
m_z = std::max(m_z - 0.1, zz); m_state.z = std::max(m_state.z - 0.1, zz);
*z = m_z; StateData result;
result.z = m_state.z;
if (m_autohide_timer > -1) if (m_autohide_timer > -1)
{ {
@ -69,11 +69,11 @@ void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState
} }
// hide // hide
bool autohide = boolean_settings[1]->GetValue() && m_autohide_timer < 0; const bool autohide = boolean_settings[1]->GetValue() && m_autohide_timer < 0;
if (controls[6]->control_ref->State() > 0.5 || autohide) if (controls[6]->control_ref->State() > 0.5 || autohide)
{ {
*x = 10000; result.x = 10000;
*y = 0; result.y = 0;
} }
else else
{ {
@ -90,28 +90,30 @@ void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState
{ {
// deadzone to avoid the cursor slowly drifting // deadzone to avoid the cursor slowly drifting
if (std::abs(xx) > deadzone) if (std::abs(xx) > deadzone)
m_x = MathUtil::Clamp(m_x + xx * SPEED_MULTIPLIER, -1.0, 1.0); m_state.x = MathUtil::Clamp(m_state.x + xx * SPEED_MULTIPLIER, -1.0, 1.0);
if (std::abs(yy) > deadzone) if (std::abs(yy) > deadzone)
m_y = MathUtil::Clamp(m_y + yy * SPEED_MULTIPLIER, -1.0, 1.0); m_state.y = MathUtil::Clamp(m_state.y + yy * SPEED_MULTIPLIER, -1.0, 1.0);
// recenter // recenter
if (controls[7]->control_ref->State() > 0.5) if (controls[7]->control_ref->State() > 0.5)
{ {
m_x = 0.0; m_state.x = 0.0;
m_y = 0.0; m_state.y = 0.0;
} }
} }
else else
{ {
m_x = xx; m_state.x = xx;
m_y = yy; m_state.y = yy;
} }
*x = m_x; result.x = m_state.x;
*y = m_y; result.y = m_state.y;
} }
m_prev_xx = xx; m_prev_xx = xx;
m_prev_yy = yy; m_prev_yy = yy;
return result;
} }
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -13,9 +13,16 @@ namespace ControllerEmu
class Cursor : public ControlGroup class Cursor : public ControlGroup
{ {
public: public:
struct StateData
{
ControlState x{};
ControlState y{};
ControlState z{};
};
explicit Cursor(const std::string& name); explicit Cursor(const std::string& name);
void GetState(ControlState* x, ControlState* y, ControlState* z, bool adjusted = false); StateData GetState(bool adjusted = false);
private: private:
// This is used to reduce the cursor speed for relative input // This is used to reduce the cursor speed for relative input
@ -25,9 +32,7 @@ private:
// Sets the length for the auto-hide timer // Sets the length for the auto-hide timer
static constexpr int TIMER_VALUE = 500; static constexpr int TIMER_VALUE = 500;
ControlState m_x = 0.0; StateData m_state;
ControlState m_y = 0.0;
ControlState m_z = 0.0;
int m_autohide_timer = TIMER_VALUE; int m_autohide_timer = TIMER_VALUE;
ControlState m_prev_xx; ControlState m_prev_xx;

View File

@ -29,18 +29,23 @@ Force::Force(const std::string& name_) : ControlGroup(name_, GroupType::Force)
numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50));
} }
void Force::GetState(ControlState* axis) Force::StateData Force::GetState()
{ {
StateData state_data;
const ControlState deadzone = numeric_settings[0]->GetValue(); const ControlState deadzone = numeric_settings[0]->GetValue();
for (u32 i = 0; i < 6; i += 2) for (u32 i = 0; i < 6; i += 2)
{ {
ControlState tmpf = 0;
const ControlState state = const ControlState state =
controls[i + 1]->control_ref->State() - controls[i]->control_ref->State(); controls[i + 1]->control_ref->State() - controls[i]->control_ref->State();
ControlState tmpf = 0;
if (fabs(state) > deadzone) if (fabs(state) > deadzone)
tmpf = ((state - (deadzone * sign(state))) / (1 - deadzone)); tmpf = ((state - (deadzone * sign(state))) / (1 - deadzone));
*axis++ = tmpf;
state_data[i / 2] = tmpf;
} }
return state_data;
} }
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -14,11 +14,13 @@ namespace ControllerEmu
class Force : public ControlGroup class Force : public ControlGroup
{ {
public: public:
using StateData = std::array<ControlState, 3>;
explicit Force(const std::string& name); explicit Force(const std::string& name);
void GetState(ControlState* axis); StateData GetState();
private: private:
std::array<ControlState, 3> m_swing{}; StateData m_swing{};
}; };
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -30,14 +30,14 @@ Slider::Slider(const std::string& name_) : Slider(name_, name_)
{ {
} }
void Slider::GetState(ControlState* const slider) Slider::StateData Slider::GetState()
{ {
const ControlState deadzone = numeric_settings[0]->GetValue(); const ControlState deadzone = numeric_settings[0]->GetValue();
const ControlState state = controls[1]->control_ref->State() - controls[0]->control_ref->State(); const ControlState state = controls[1]->control_ref->State() - controls[0]->control_ref->State();
if (fabs(state) > deadzone) if (fabs(state) > deadzone)
*slider = (state - (deadzone * sign(state))) / (1 - deadzone); return {(state - (deadzone * sign(state))) / (1 - deadzone)};
else
*slider = 0; return {0.0};
} }
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -13,9 +13,14 @@ namespace ControllerEmu
class Slider : public ControlGroup class Slider : public ControlGroup
{ {
public: public:
struct StateData
{
ControlState value{};
};
Slider(const std::string& name_, const std::string& ui_name_); Slider(const std::string& name_, const std::string& ui_name_);
explicit Slider(const std::string& name_); explicit Slider(const std::string& name_);
void GetState(ControlState* slider); StateData GetState();
}; };
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -31,7 +31,7 @@ Tilt::Tilt(const std::string& name_) : ControlGroup(name_, GroupType::Tilt)
numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Angle"), 0.9, 0, 180)); numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Angle"), 0.9, 0, 180));
} }
void Tilt::GetState(ControlState* const x, ControlState* const y, const bool step) Tilt::StateData Tilt::GetState(const bool step)
{ {
// this is all a mess // this is all a mess
@ -80,18 +80,17 @@ void Tilt::GetState(ControlState* const x, ControlState* const y, const bool ste
// silly // silly
if (step) if (step)
{ {
if (xx > m_tilt[0]) if (xx > m_tilt.x)
m_tilt[0] = std::min(m_tilt[0] + 0.1, xx); m_tilt.x = std::min(m_tilt.x + 0.1, xx);
else if (xx < m_tilt[0]) else if (xx < m_tilt.x)
m_tilt[0] = std::max(m_tilt[0] - 0.1, xx); m_tilt.x = std::max(m_tilt.x - 0.1, xx);
if (yy > m_tilt[1]) if (yy > m_tilt.y)
m_tilt[1] = std::min(m_tilt[1] + 0.1, yy); m_tilt.y = std::min(m_tilt.y + 0.1, yy);
else if (yy < m_tilt[1]) else if (yy < m_tilt.y)
m_tilt[1] = std::max(m_tilt[1] - 0.1, yy); m_tilt.y = std::max(m_tilt.y - 0.1, yy);
} }
*y = m_tilt[1] * angle; return {m_tilt.x * angle, m_tilt.y * angle};
*x = m_tilt[0] * angle;
} }
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include <array>
#include <string> #include <string>
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
#include "InputCommon/ControllerInterface/Device.h" #include "InputCommon/ControllerInterface/Device.h"
@ -14,11 +13,17 @@ namespace ControllerEmu
class Tilt : public ControlGroup class Tilt : public ControlGroup
{ {
public: public:
struct StateData
{
ControlState x{};
ControlState y{};
};
explicit Tilt(const std::string& name); explicit Tilt(const std::string& name);
void GetState(ControlState* x, ControlState* y, bool step = true); StateData GetState(bool step = true);
private: private:
std::array<ControlState, 2> m_tilt{}; StateData m_tilt;
}; };
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -21,12 +21,15 @@ Triggers::Triggers(const std::string& name_) : ControlGroup(name_, GroupType::Tr
numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50));
} }
void Triggers::GetState(ControlState* analog) Triggers::StateData Triggers::GetState()
{ {
const size_t trigger_count = controls.size(); const size_t trigger_count = controls.size();
const ControlState deadzone = numeric_settings[0]->GetValue(); const ControlState deadzone = numeric_settings[0]->GetValue();
for (size_t i = 0; i < trigger_count; ++i, ++analog) StateData result(trigger_count);
*analog = std::max(controls[i]->control_ref->State() - deadzone, 0.0) / (1 - deadzone); for (size_t i = 0; i < trigger_count; ++i)
result.data[i] = std::max(controls[i]->control_ref->State() - deadzone, 0.0) / (1 - deadzone);
return result;
} }
} // namespace ControllerEmu } // namespace ControllerEmu

View File

@ -5,6 +5,8 @@
#pragma once #pragma once
#include <string> #include <string>
#include <vector>
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
#include "InputCommon/ControllerInterface/Device.h" #include "InputCommon/ControllerInterface/Device.h"
@ -13,8 +15,16 @@ namespace ControllerEmu
class Triggers : public ControlGroup class Triggers : public ControlGroup
{ {
public: public:
struct StateData
{
StateData() = default;
explicit StateData(std::size_t trigger_count) : data(trigger_count) {}
std::vector<ControlState> data;
};
explicit Triggers(const std::string& name); explicit Triggers(const std::string& name);
void GetState(ControlState* analog); StateData GetState();
}; };
} // namespace ControllerEmu } // namespace ControllerEmu