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

View File

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

View File

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

View File

@ -106,19 +106,18 @@ void Guitar::GetState(u8* const data)
// stick
{
ControlState x, y;
m_stick->GetState(&x, &y);
const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState();
guitar_data.sx = static_cast<u8>((x * 0x1F) + 0x20);
guitar_data.sy = static_cast<u8>((y * 0x1F) + 0x20);
guitar_data.sx = static_cast<u8>((stick_state.x * 0x1F) + 0x20);
guitar_data.sy = static_cast<u8>((stick_state.y * 0x1F) + 0x20);
}
// slider bar
if (m_slider_bar->controls[0]->control_ref->BoundCount())
{
ControlState slider_bar;
m_slider_bar->GetState(&slider_bar);
guitar_data.sb = s_slider_bar_control_codes.lower_bound(slider_bar)->second;
const ControllerEmu::Slider::StateData slider_data = m_slider_bar->GetState();
guitar_data.sb = s_slider_bar_control_codes.lower_bound(slider_data.value)->second;
}
else
{
@ -127,14 +126,15 @@ void Guitar::GetState(u8* const data)
}
// whammy bar
ControlState whammy;
m_whammy->GetState(&whammy);
guitar_data.whammy = static_cast<u8>(whammy * 0x1F);
const ControllerEmu::Triggers::StateData whammy_state = m_whammy->GetState();
guitar_data.whammy = static_cast<u8>(whammy_state.data[0] * 0x1F);
// buttons
m_buttons->GetState(&guitar_data.bt, guitar_button_bitmasks.data());
// frets
m_frets->GetState(&guitar_data.bt, guitar_fret_bitmasks.data());
// strum
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 = {};
// stick
double jx, jy;
m_stick->GetState(&jx, &jy);
nc_data.jx = u8(STICK_CENTER + jx * STICK_RADIUS);
nc_data.jy = u8(STICK_CENTER + jy * STICK_RADIUS);
const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState();
nc_data.jx = u8(STICK_CENTER + stick_state.x * STICK_RADIUS);
nc_data.jy = u8(STICK_CENTER + stick_state.y * STICK_RADIUS);
// 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
{
ControlState x, y;
m_stick->GetState(&x, &y);
const ControllerEmu::AnalogStick::StateData stick_state = m_stick->GetState();
tt_data.sx = static_cast<u8>((x * 0x1F) + 0x20);
tt_data.sy = static_cast<u8>((y * 0x1F) + 0x20);
tt_data.sx = static_cast<u8>((stick_state.x * 0x1F) + 0x20);
tt_data.sy = static_cast<u8>((stick_state.y * 0x1F) + 0x20);
}
// left table
{
ControlState tt;
m_left_table->GetState(&tt);
const ControllerEmu::Slider::StateData lt = m_left_table->GetState();
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
{
ControlState tt;
m_right_table->GetState(&tt);
const ControllerEmu::Slider::StateData rt = m_right_table->GetState();
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.rtable3 = tt_ >> 3;
tt_data.rtable4 = tt_ >> 5;
tt_data.rtable1 = tt;
tt_data.rtable2 = tt >> 1;
tt_data.rtable3 = tt >> 3;
tt_data.rtable4 = tt >> 5;
}
// effect dial
{
ControlState dial;
m_effect_dial->GetState(&dial);
const ControllerEmu::Triggers::StateData state = m_effect_dial->GetState();
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
{
ControlState cfs;
m_crossfade->GetState(&cfs);
const ControllerEmu::Slider::StateData cfs = m_crossfade->GetState();
tt_data.slider = static_cast<u8>((cfs * 0x07) + 0x08);
tt_data.slider = static_cast<u8>((cfs.value * 0x07) + 0x08);
}
// buttons

View File

@ -5,8 +5,10 @@
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstring>
#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,
const bool upright)
{
ControlState roll, pitch;
// 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;
pitch *= PI;
unsigned int ud = 0, lr = 0, fb = 0;
// some notes that no one will understand but me :p
// Some notes that no one will understand but me :p
// left, forward, up
// lr/ left == negative for all orientations
// ud/ up == negative for upright longways
// fb/ forward == positive for (sideways flat)
// determine which axis is which direction
ud = upright ? (sideways ? 0 : 1) : 2;
lr = sideways;
fb = upright ? 2 : (sideways ? 0 : 1);
int sgn[3] = {-1, 1, 1}; // sign fix
// Determine which axis is which direction
const u32 ud = upright ? (sideways ? 0 : 1) : 2;
const u32 lr = sideways;
const u32 fb = upright ? 2 : (sideways ? 0 : 1);
// Sign fix
std::array<int, 3> sgn{{-1, 1, 1}};
if (sideways && !upright)
sgn[fb] *= -1;
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,
const double intensity, const bool sideways, const bool upright)
{
ControlState swing[3];
swing_group->GetState(swing);
const ControllerEmu::Force::StateData swing = swing_group->GetState();
s8 g_dir[3] = {-1, -1, -1};
u8 axis_map[3];
// Determine which axis is which direction
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
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
// Some orientations have up as positive, some as negative
// same with forward
std::array<s8, 3> g_dir{{-1, -1, -1}};
if (sideways && !upright)
g_dir[axis_map[2]] *= -1;
if (!sideways && upright)
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;
}
@ -237,25 +234,24 @@ void EmulateDynamicSwing(AccelData* const accel, DynamicData& dynamic_data,
const DynamicConfiguration& config, const bool sideways,
const bool upright)
{
ControlState swing[3];
swing_group->GetState(swing);
const ControllerEmu::Force::StateData swing = swing_group->GetState();
s8 g_dir[3] = {-1, -1, -1};
u8 axis_map[3];
// Determine which axis is which direction
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
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
// Some orientations have up as positive, some as negative
// same with forward
std::array<s8, 3> g_dir{{-1, -1, -1}};
if (sideways && !upright)
g_dir[axis_map[2]] *= -1;
if (!sideways && upright)
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)
{
@ -432,9 +428,9 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), ir_sin(0), ir_cos(1
// options
groups.emplace_back(m_options = new ControllerEmu::ControlGroup(_trans("Options")));
m_options->boolean_settings.emplace_back(new ControllerEmu::BooleanSetting(
"Forward Wiimote", _trans("Forward Wii Remote"),
true, ControllerEmu::SettingType::NORMAL, true));
m_options->boolean_settings.emplace_back(
new ControllerEmu::BooleanSetting("Forward Wiimote", _trans("Forward Wii Remote"), true,
ControllerEmu::SettingType::NORMAL, true));
m_options->boolean_settings.emplace_back(m_upright_setting = new ControllerEmu::BooleanSetting(
"Upright Wiimote", _trans("Upright Wii Remote"),
false, ControllerEmu::SettingType::NORMAL, true));
@ -682,15 +678,14 @@ void Wiimote::GetIRData(u8* const data, bool use_accel)
u16 x[4], y[4];
memset(x, 0xFF, sizeof(x));
ControlState xx = 10000, yy = 0, zz = 0;
double nsin, ncos;
if (use_accel)
{
double ax, az, len;
ax = m_accel.x;
az = m_accel.z;
len = sqrt(ax * ax + az * az);
double ax = m_accel.x;
double az = m_accel.z;
const double len = sqrt(ax * ax + az * az);
if (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_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];
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;
const ControllerEmu::Cursor::StateData cursor_state = m_ir->GetState(true);
std::array<Vertex, 4> 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)
vtx.y = yy * (bndup - bnddown) / 2 + (bndup + bnddown) / 2;
vtx.y = cursor_state.y * (bndup - bnddown) / 2 + (bndup + bnddown) / 2;
else
vtx.y = yy * (bndup - bnddown) / 2 - (bndup + bnddown) / 2;
vtx.y = cursor_state.y * (bndup - bnddown) / 2 - (bndup + bnddown) / 2;
vtx.z = 0;
}
v[0].x -= (zz * 0.5 + 1) * dist1;
v[1].x += (zz * 0.5 + 1) * dist1;
v[2].x -= (zz * 0.5 + 1) * dist2;
v[3].x += (zz * 0.5 + 1) * dist2;
v[0].x -= (cursor_state.z * 0.5 + 1) * dist1;
v[1].x += (cursor_state.z * 0.5 + 1) * dist1;
v[2].x -= (cursor_state.z * 0.5 + 1) * dist2;
v[3].x += (cursor_state.z * 0.5 + 1) * dist2;
#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], \
@ -752,14 +748,17 @@ void Wiimote::GetIRData(u8* const data, bool use_accel)
MatrixRotationByZ(rot, ir_sin, ir_cos);
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]);
if ((v[i].x < -1) || (v[i].x > 1) || (v[i].y < -1) || (v[i].y > 1))
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
if (m_reg_ir.data[0x30])
// 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));
}
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 xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState y = controls[0]->control_ref->State() - controls[1]->control_ref->State();
ControlState x = controls[3]->control_ref->State() - controls[2]->control_ref->State();
ControlState radius = numeric_settings[SETTING_RADIUS]->GetValue();
ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue();
ControlState m = controls[4]->control_ref->State();
const ControlState radius = numeric_settings[SETTING_RADIUS]->GetValue();
const ControlState deadzone = numeric_settings[SETTING_DEADZONE]->GetValue();
const ControlState m = controls[4]->control_ref->State();
ControlState ang = atan2(yy, xx);
ControlState ang_sin = sin(ang);
ControlState ang_cos = cos(ang);
const ControlState ang = atan2(y, x);
const ControlState ang_sin = sin(ang);
const ControlState ang_cos = cos(ang);
ControlState dist = sqrt(xx * xx + yy * yy);
ControlState dist = sqrt(x * x + y * y);
// dead zone code
dist = std::max(0.0, dist - deadzone);
@ -63,10 +63,9 @@ void AnalogStick::GetState(ControlState* const x, ControlState* const y)
if (m)
dist *= 0.5;
yy = std::max(-1.0, std::min(1.0, ang_sin * dist));
xx = std::max(-1.0, std::min(1.0, ang_cos * dist));
y = std::max(-1.0, std::min(1.0, ang_sin * dist));
x = std::max(-1.0, std::min(1.0, ang_cos * dist));
*y = yy;
*x = xx;
return {x, y};
}
} // namespace ControllerEmu

View File

@ -18,10 +18,16 @@ public:
SETTING_DEADZONE,
};
struct StateData
{
ControlState x{};
ControlState y{};
};
// The GameCube controller and Wiimote attachments have a different default radius
AnalogStick(const char* 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

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));
}
void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState* const z,
const bool adjusted)
Cursor::StateData Cursor::GetState(const bool adjusted)
{
const ControlState zz = controls[4]->control_ref->State() - controls[5]->control_ref->State();
// silly being here
if (zz > m_z)
m_z = std::min(m_z + 0.1, zz);
else if (zz < m_z)
m_z = std::max(m_z - 0.1, zz);
if (zz > m_state.z)
m_state.z = std::min(m_state.z + 0.1, zz);
else if (zz < m_state.z)
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)
{
@ -69,11 +69,11 @@ void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState
}
// 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)
{
*x = 10000;
*y = 0;
result.x = 10000;
result.y = 0;
}
else
{
@ -90,28 +90,30 @@ void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState
{
// deadzone to avoid the cursor slowly drifting
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)
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
if (controls[7]->control_ref->State() > 0.5)
{
m_x = 0.0;
m_y = 0.0;
m_state.x = 0.0;
m_state.y = 0.0;
}
}
else
{
m_x = xx;
m_y = yy;
m_state.x = xx;
m_state.y = yy;
}
*x = m_x;
*y = m_y;
result.x = m_state.x;
result.y = m_state.y;
}
m_prev_xx = xx;
m_prev_yy = yy;
return result;
}
} // namespace ControllerEmu

View File

@ -13,9 +13,16 @@ namespace ControllerEmu
class Cursor : public ControlGroup
{
public:
struct StateData
{
ControlState x{};
ControlState y{};
ControlState z{};
};
explicit Cursor(const std::string& name);
void GetState(ControlState* x, ControlState* y, ControlState* z, bool adjusted = false);
StateData GetState(bool adjusted = false);
private:
// This is used to reduce the cursor speed for relative input
@ -25,9 +32,7 @@ private:
// Sets the length for the auto-hide timer
static constexpr int TIMER_VALUE = 500;
ControlState m_x = 0.0;
ControlState m_y = 0.0;
ControlState m_z = 0.0;
StateData m_state;
int m_autohide_timer = TIMER_VALUE;
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));
}
void Force::GetState(ControlState* axis)
Force::StateData Force::GetState()
{
StateData state_data;
const ControlState deadzone = numeric_settings[0]->GetValue();
for (u32 i = 0; i < 6; i += 2)
{
ControlState tmpf = 0;
const ControlState state =
controls[i + 1]->control_ref->State() - controls[i]->control_ref->State();
ControlState tmpf = 0;
if (fabs(state) > deadzone)
tmpf = ((state - (deadzone * sign(state))) / (1 - deadzone));
*axis++ = tmpf;
state_data[i / 2] = tmpf;
}
return state_data;
}
} // namespace ControllerEmu

View File

@ -14,11 +14,13 @@ namespace ControllerEmu
class Force : public ControlGroup
{
public:
using StateData = std::array<ControlState, 3>;
explicit Force(const std::string& name);
void GetState(ControlState* axis);
StateData GetState();
private:
std::array<ControlState, 3> m_swing{};
StateData m_swing{};
};
} // 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 state = controls[1]->control_ref->State() - controls[0]->control_ref->State();
if (fabs(state) > deadzone)
*slider = (state - (deadzone * sign(state))) / (1 - deadzone);
else
*slider = 0;
return {(state - (deadzone * sign(state))) / (1 - deadzone)};
return {0.0};
}
} // namespace ControllerEmu

View File

@ -13,9 +13,14 @@ namespace ControllerEmu
class Slider : public ControlGroup
{
public:
struct StateData
{
ControlState value{};
};
Slider(const std::string& name_, const std::string& ui_name_);
explicit Slider(const std::string& name_);
void GetState(ControlState* slider);
StateData GetState();
};
} // 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));
}
void Tilt::GetState(ControlState* const x, ControlState* const y, const bool step)
Tilt::StateData Tilt::GetState(const bool step)
{
// this is all a mess
@ -80,18 +80,17 @@ void Tilt::GetState(ControlState* const x, ControlState* const y, const bool ste
// silly
if (step)
{
if (xx > m_tilt[0])
m_tilt[0] = std::min(m_tilt[0] + 0.1, xx);
else if (xx < m_tilt[0])
m_tilt[0] = std::max(m_tilt[0] - 0.1, xx);
if (xx > m_tilt.x)
m_tilt.x = std::min(m_tilt.x + 0.1, xx);
else if (xx < m_tilt.x)
m_tilt.x = std::max(m_tilt.x - 0.1, xx);
if (yy > m_tilt[1])
m_tilt[1] = std::min(m_tilt[1] + 0.1, yy);
else if (yy < m_tilt[1])
m_tilt[1] = std::max(m_tilt[1] - 0.1, yy);
if (yy > m_tilt.y)
m_tilt.y = std::min(m_tilt.y + 0.1, yy);
else if (yy < m_tilt.y)
m_tilt.y = std::max(m_tilt.y - 0.1, yy);
}
*y = m_tilt[1] * angle;
*x = m_tilt[0] * angle;
return {m_tilt.x * angle, m_tilt.y * angle};
}
} // namespace ControllerEmu

View File

@ -4,7 +4,6 @@
#pragma once
#include <array>
#include <string>
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
#include "InputCommon/ControllerInterface/Device.h"
@ -14,11 +13,17 @@ namespace ControllerEmu
class Tilt : public ControlGroup
{
public:
struct StateData
{
ControlState x{};
ControlState y{};
};
explicit Tilt(const std::string& name);
void GetState(ControlState* x, ControlState* y, bool step = true);
StateData GetState(bool step = true);
private:
std::array<ControlState, 2> m_tilt{};
StateData m_tilt;
};
} // 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));
}
void Triggers::GetState(ControlState* analog)
Triggers::StateData Triggers::GetState()
{
const size_t trigger_count = controls.size();
const ControlState deadzone = numeric_settings[0]->GetValue();
for (size_t i = 0; i < trigger_count; ++i, ++analog)
*analog = std::max(controls[i]->control_ref->State() - deadzone, 0.0) / (1 - deadzone);
StateData result(trigger_count);
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

View File

@ -5,6 +5,8 @@
#pragma once
#include <string>
#include <vector>
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
#include "InputCommon/ControllerInterface/Device.h"
@ -13,8 +15,16 @@ namespace ControllerEmu
class Triggers : public ControlGroup
{
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);
void GetState(ControlState* analog);
StateData GetState();
};
} // namespace ControllerEmu