WiimoteEmu: Get rid of pointer casting in extension GetState() functions

We can just memcpy the data instead of pointer-casting data, which is
alignment-safe and doesn't run afoul of aliasing rules.

Previously it also made it seem as if data itself pointed to valid
usable data, but it doesn't, it simply functions as an out parameter
where we push data built up from the GetState() functions into it.
This commit is contained in:
Lioncash 2018-05-27 21:57:50 -04:00
parent 686e29f2d3
commit 6ad6781bd3
5 changed files with 83 additions and 78 deletions

View File

@ -131,8 +131,7 @@ Classic::Classic(ExtensionReg& reg) : Attachment(_trans("Classic"), reg)
void Classic::GetState(u8* const data)
{
wm_classic_extension* const ccdata = reinterpret_cast<wm_classic_extension*>(data);
ccdata->bt.hex = 0;
wm_classic_extension classic_data = {};
// not using calibration data, o well
@ -141,48 +140,50 @@ void Classic::GetState(u8* const data)
ControlState x, y;
m_left_stick->GetState(&x, &y);
ccdata->regular_data.lx =
classic_data.regular_data.lx =
static_cast<u8>(Classic::LEFT_STICK_CENTER_X + (x * Classic::LEFT_STICK_RADIUS));
ccdata->regular_data.ly =
classic_data.regular_data.ly =
static_cast<u8>(Classic::LEFT_STICK_CENTER_Y + (y * Classic::LEFT_STICK_RADIUS));
}
// right stick
{
ControlState x, y;
u8 x_, y_;
m_right_stick->GetState(&x, &y);
x_ = static_cast<u8>(Classic::RIGHT_STICK_CENTER_X + (x * Classic::RIGHT_STICK_RADIUS));
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 + (x * Classic::RIGHT_STICK_RADIUS));
const u8 y_ =
static_cast<u8>(Classic::RIGHT_STICK_CENTER_Y + (y * Classic::RIGHT_STICK_RADIUS));
ccdata->rx1 = x_;
ccdata->rx2 = x_ >> 1;
ccdata->rx3 = x_ >> 3;
ccdata->ry = y_;
classic_data.rx1 = x_;
classic_data.rx2 = x_ >> 1;
classic_data.rx3 = x_ >> 3;
classic_data.ry = y_;
}
// triggers
{
ControlState trigs[2] = {0, 0};
u8 lt, rt;
m_triggers->GetState(&ccdata->bt.hex, classic_trigger_bitmasks.data(), trigs);
m_triggers->GetState(&classic_data.bt.hex, classic_trigger_bitmasks.data(), trigs);
lt = static_cast<u8>(trigs[0] * Classic::LEFT_TRIGGER_RANGE);
rt = static_cast<u8>(trigs[1] * Classic::RIGHT_TRIGGER_RANGE);
const u8 lt = static_cast<u8>(trigs[0] * Classic::LEFT_TRIGGER_RANGE);
const u8 rt = static_cast<u8>(trigs[1] * Classic::RIGHT_TRIGGER_RANGE);
ccdata->lt1 = lt;
ccdata->lt2 = lt >> 3;
ccdata->rt = rt;
classic_data.lt1 = lt;
classic_data.lt2 = lt >> 3;
classic_data.rt = rt;
}
// buttons
m_buttons->GetState(&ccdata->bt.hex, classic_button_bitmasks.data());
m_buttons->GetState(&classic_data.bt.hex, classic_button_bitmasks.data());
// dpad
m_dpad->GetState(&ccdata->bt.hex, classic_dpad_bitmasks.data());
m_dpad->GetState(&classic_data.bt.hex, classic_dpad_bitmasks.data());
// flip button bits
ccdata->bt.hex ^= 0xFFFF;
classic_data.bt.hex ^= 0xFFFF;
std::memcpy(data, &classic_data, sizeof(wm_classic_extension));
}
bool Classic::IsButtonPressed() const

View File

@ -6,6 +6,7 @@
#include <array>
#include <cassert>
#include <cstring>
#include "Common/Common.h"
#include "Common/CommonTypes.h"
@ -67,8 +68,7 @@ Drums::Drums(ExtensionReg& reg) : Attachment(_trans("Drums"), reg)
void Drums::GetState(u8* const data)
{
wm_drums_extension* const ddata = reinterpret_cast<wm_drums_extension*>(data);
ddata->bt = 0;
wm_drums_extension drum_data = {};
// calibration data not figured out yet?
@ -77,8 +77,8 @@ void Drums::GetState(u8* const data)
ControlState x, y;
m_stick->GetState(&x, &y);
ddata->sx = static_cast<u8>((x * 0x1F) + 0x20);
ddata->sy = static_cast<u8>((y * 0x1F) + 0x20);
drum_data.sx = static_cast<u8>((x * 0x1F) + 0x20);
drum_data.sy = static_cast<u8>((y * 0x1F) + 0x20);
}
// TODO: softness maybe
@ -86,12 +86,14 @@ void Drums::GetState(u8* const data)
data[3] = 0xFF;
// buttons
m_buttons->GetState(&ddata->bt, drum_button_bitmasks.data());
m_buttons->GetState(&drum_data.bt, drum_button_bitmasks.data());
// pads
m_pads->GetState(&ddata->bt, drum_pad_bitmasks.data());
m_pads->GetState(&drum_data.bt, drum_pad_bitmasks.data());
// flip button bits
ddata->bt ^= 0xFFFF;
drum_data.bt ^= 0xFFFF;
std::memcpy(data, &drum_data, sizeof(wm_drums_extension));
}
bool Drums::IsButtonPressed() const

View File

@ -6,7 +6,7 @@
#include <array>
#include <cassert>
#include <cstring>
#include <map>
#include "Common/Common.h"
@ -100,8 +100,7 @@ Guitar::Guitar(ExtensionReg& reg) : Attachment(_trans("Guitar"), reg)
void Guitar::GetState(u8* const data)
{
wm_guitar_extension* const gdata = reinterpret_cast<wm_guitar_extension*>(data);
gdata->bt = 0;
wm_guitar_extension guitar_data = {};
// calibration data not figured out yet?
@ -110,8 +109,8 @@ void Guitar::GetState(u8* const data)
ControlState x, y;
m_stick->GetState(&x, &y);
gdata->sx = static_cast<u8>((x * 0x1F) + 0x20);
gdata->sy = static_cast<u8>((y * 0x1F) + 0x20);
guitar_data.sx = static_cast<u8>((x * 0x1F) + 0x20);
guitar_data.sy = static_cast<u8>((y * 0x1F) + 0x20);
}
// slider bar
@ -119,28 +118,30 @@ void Guitar::GetState(u8* const data)
{
ControlState slider_bar;
m_slider_bar->GetState(&slider_bar);
gdata->sb = s_slider_bar_control_codes.lower_bound(slider_bar)->second;
guitar_data.sb = s_slider_bar_control_codes.lower_bound(slider_bar)->second;
}
else
{
// if user has not mapped controls for slider bar, tell game it's untouched
gdata->sb = 0x0F;
guitar_data.sb = 0x0F;
}
// whammy bar
ControlState whammy;
m_whammy->GetState(&whammy);
gdata->whammy = static_cast<u8>(whammy * 0x1F);
guitar_data.whammy = static_cast<u8>(whammy * 0x1F);
// buttons
m_buttons->GetState(&gdata->bt, guitar_button_bitmasks.data());
m_buttons->GetState(&guitar_data.bt, guitar_button_bitmasks.data());
// frets
m_frets->GetState(&gdata->bt, guitar_fret_bitmasks.data());
m_frets->GetState(&guitar_data.bt, guitar_fret_bitmasks.data());
// strum
m_strum->GetState(&gdata->bt, guitar_strum_bitmasks.data());
m_strum->GetState(&guitar_data.bt, guitar_strum_bitmasks.data());
// flip button bits
gdata->bt ^= 0xFFFF;
guitar_data.bt ^= 0xFFFF;
std::memcpy(data, &guitar_data, sizeof(wm_guitar_extension));
}
bool Guitar::IsButtonPressed() const

View File

@ -6,6 +6,7 @@
#include <array>
#include <cassert>
#include <cstring>
#include "Common/Common.h"
#include "Common/CommonTypes.h"
@ -59,15 +60,14 @@ Nunchuk::Nunchuk(ExtensionReg& reg) : Attachment(_trans("Nunchuk"), reg)
void Nunchuk::GetState(u8* const data)
{
wm_nc* const ncdata = reinterpret_cast<wm_nc*>(data);
ncdata->bt.hex = 0;
wm_nc nc_data = {};
// stick
double jx, jy;
m_stick->GetState(&jx, &jy);
ncdata->jx = u8(STICK_CENTER + jx * STICK_RADIUS);
ncdata->jy = u8(STICK_CENTER + jy * 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
//
@ -77,12 +77,12 @@ void Nunchuk::GetState(u8* const data)
// With keyboard controls, these games break if you simply hit
// of the axes. Adjust this if you're hitting one of the axes so that
// we slightly tweak the other axis.
if (ncdata->jx != STICK_CENTER || ncdata->jy != STICK_CENTER)
if (nc_data.jx != STICK_CENTER || nc_data.jy != STICK_CENTER)
{
if (ncdata->jx == STICK_CENTER)
++ncdata->jx;
if (ncdata->jy == STICK_CENTER)
++ncdata->jy;
if (nc_data.jx == STICK_CENTER)
++nc_data.jx;
if (nc_data.jy == STICK_CENTER)
++nc_data.jy;
}
AccelData accel;
@ -95,10 +95,10 @@ void Nunchuk::GetState(u8* const data)
// shake
EmulateShake(&accel, m_shake, m_shake_step.data());
// buttons
m_buttons->GetState(&ncdata->bt.hex, nunchuk_button_bitmasks.data());
m_buttons->GetState(&nc_data.bt.hex, nunchuk_button_bitmasks.data());
// flip the button bits :/
ncdata->bt.hex ^= 0x03;
nc_data.bt.hex ^= 0x03;
// We now use 2 bits more precision, so multiply by 4 before converting to int
s16 accel_x = (s16)(4 * (accel.x * ACCEL_RANGE + ACCEL_ZERO_G));
@ -109,12 +109,14 @@ void Nunchuk::GetState(u8* const data)
accel_y = MathUtil::Clamp<s16>(accel_y, 0, 1024);
accel_z = MathUtil::Clamp<s16>(accel_z, 0, 1024);
ncdata->ax = (accel_x >> 2) & 0xFF;
ncdata->ay = (accel_y >> 2) & 0xFF;
ncdata->az = (accel_z >> 2) & 0xFF;
ncdata->bt.acc_x_lsb = accel_x & 0x3;
ncdata->bt.acc_y_lsb = accel_y & 0x3;
ncdata->bt.acc_z_lsb = accel_z & 0x3;
nc_data.ax = (accel_x >> 2) & 0xFF;
nc_data.ay = (accel_y >> 2) & 0xFF;
nc_data.az = (accel_z >> 2) & 0xFF;
nc_data.bt.acc_x_lsb = accel_x & 0x3;
nc_data.bt.acc_y_lsb = accel_y & 0x3;
nc_data.bt.acc_z_lsb = accel_z & 0x3;
std::memcpy(data, &nc_data, sizeof(wm_nc));
}
bool Nunchuk::IsButtonPressed() const

View File

@ -6,6 +6,7 @@
#include <array>
#include <cassert>
#include <cstring>
#include "Common/Common.h"
#include "Common/CommonTypes.h"
@ -85,54 +86,50 @@ Turntable::Turntable(ExtensionReg& reg) : Attachment(_trans("Turntable"), reg)
void Turntable::GetState(u8* const data)
{
wm_turntable_extension* const ttdata = reinterpret_cast<wm_turntable_extension*>(data);
ttdata->bt = 0;
wm_turntable_extension tt_data = {};
// stick
{
ControlState x, y;
m_stick->GetState(&x, &y);
ttdata->sx = static_cast<u8>((x * 0x1F) + 0x20);
ttdata->sy = static_cast<u8>((y * 0x1F) + 0x20);
tt_data.sx = static_cast<u8>((x * 0x1F) + 0x20);
tt_data.sy = static_cast<u8>((y * 0x1F) + 0x20);
}
// left table
{
ControlState tt;
s8 tt_;
m_left_table->GetState(&tt);
tt_ = static_cast<s8>(tt * 0x1F);
const s8 tt_ = static_cast<s8>(tt * 0x1F);
ttdata->ltable1 = tt_;
ttdata->ltable2 = tt_ >> 5;
tt_data.ltable1 = tt_;
tt_data.ltable2 = tt_ >> 5;
}
// right table
{
ControlState tt;
s8 tt_;
m_right_table->GetState(&tt);
tt_ = static_cast<s8>(tt * 0x1F);
const s8 tt_ = static_cast<s8>(tt * 0x1F);
ttdata->rtable1 = tt_;
ttdata->rtable2 = tt_ >> 1;
ttdata->rtable3 = tt_ >> 3;
ttdata->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;
u8 dial_;
m_effect_dial->GetState(&dial);
dial_ = static_cast<u8>(dial * 0x0F);
const u8 dial_ = static_cast<u8>(dial * 0x0F);
ttdata->dial1 = dial_;
ttdata->dial2 = dial_ >> 3;
tt_data.dial1 = dial_;
tt_data.dial2 = dial_ >> 3;
}
// crossfade slider
@ -140,15 +137,17 @@ void Turntable::GetState(u8* const data)
ControlState cfs;
m_crossfade->GetState(&cfs);
ttdata->slider = static_cast<u8>((cfs * 0x07) + 0x08);
tt_data.slider = static_cast<u8>((cfs * 0x07) + 0x08);
}
// buttons
m_buttons->GetState(&ttdata->bt, turntable_button_bitmasks.data());
m_buttons->GetState(&tt_data.bt, turntable_button_bitmasks.data());
// flip button bits :/
ttdata->bt ^= (BUTTON_L_GREEN | BUTTON_L_RED | BUTTON_L_BLUE | BUTTON_R_GREEN | BUTTON_R_RED |
tt_data.bt ^= (BUTTON_L_GREEN | BUTTON_L_RED | BUTTON_L_BLUE | BUTTON_R_GREEN | BUTTON_R_RED |
BUTTON_R_BLUE | BUTTON_MINUS | BUTTON_PLUS | BUTTON_EUPHORIA);
std::memcpy(data, &tt_data, sizeof(wm_turntable_extension));
}
bool Turntable::IsButtonPressed() const