ControlGroup/Cursor: Return state data by value

Makes it less error-prone to get state data from cursors (no need
to pass any pointers to locals), and also allows direct assignment,
letting the retrieved data be const.
This commit is contained in:
Lioncash 2018-07-13 11:38:26 -04:00
parent d05f490caa
commit ef1240b0c7
3 changed files with 58 additions and 48 deletions

View File

@ -682,15 +682,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 +713,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 +752,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

@ -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;