From 6ad6781bd3b3a9d84c149037aaef2d2d4e1d2173 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 27 May 2018 21:57:50 -0400 Subject: [PATCH] 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. --- .../Core/HW/WiimoteEmu/Attachment/Classic.cpp | 43 ++++++++++--------- .../Core/HW/WiimoteEmu/Attachment/Drums.cpp | 16 ++++--- .../Core/HW/WiimoteEmu/Attachment/Guitar.cpp | 25 +++++------ .../Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp | 36 ++++++++-------- .../HW/WiimoteEmu/Attachment/Turntable.cpp | 41 +++++++++--------- 5 files changed, 83 insertions(+), 78 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Classic.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Classic.cpp index 9b5b739c9e..654c7a0cec 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Classic.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Classic.cpp @@ -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(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(Classic::LEFT_STICK_CENTER_X + (x * Classic::LEFT_STICK_RADIUS)); - ccdata->regular_data.ly = + classic_data.regular_data.ly = static_cast(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(Classic::RIGHT_STICK_CENTER_X + (x * Classic::RIGHT_STICK_RADIUS)); - y_ = static_cast(Classic::RIGHT_STICK_CENTER_Y + (y * Classic::RIGHT_STICK_RADIUS)); + const u8 x_ = + static_cast(Classic::RIGHT_STICK_CENTER_X + (x * Classic::RIGHT_STICK_RADIUS)); + const u8 y_ = + static_cast(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(trigs[0] * Classic::LEFT_TRIGGER_RANGE); - rt = static_cast(trigs[1] * Classic::RIGHT_TRIGGER_RANGE); + const u8 lt = static_cast(trigs[0] * Classic::LEFT_TRIGGER_RANGE); + const u8 rt = static_cast(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 diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Drums.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Drums.cpp index 7d317ad0c7..ac4600b184 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Drums.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Drums.cpp @@ -6,6 +6,7 @@ #include #include +#include #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(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((x * 0x1F) + 0x20); - ddata->sy = static_cast((y * 0x1F) + 0x20); + drum_data.sx = static_cast((x * 0x1F) + 0x20); + drum_data.sy = static_cast((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 diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp index 6792108c10..d096257e74 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp @@ -6,7 +6,7 @@ #include #include - +#include #include #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(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((x * 0x1F) + 0x20); - gdata->sy = static_cast((y * 0x1F) + 0x20); + guitar_data.sx = static_cast((x * 0x1F) + 0x20); + guitar_data.sy = static_cast((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(whammy * 0x1F); + guitar_data.whammy = static_cast(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 diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp index 8762a7a123..95d61417d2 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Nunchuk.cpp @@ -6,6 +6,7 @@ #include #include +#include #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(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(accel_y, 0, 1024); accel_z = MathUtil::Clamp(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 diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Turntable.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Turntable.cpp index 2bcd64ad34..94c66a46bb 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Turntable.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Turntable.cpp @@ -6,6 +6,7 @@ #include #include +#include #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(data); - ttdata->bt = 0; + wm_turntable_extension tt_data = {}; // stick { ControlState x, y; m_stick->GetState(&x, &y); - ttdata->sx = static_cast((x * 0x1F) + 0x20); - ttdata->sy = static_cast((y * 0x1F) + 0x20); + tt_data.sx = static_cast((x * 0x1F) + 0x20); + tt_data.sy = static_cast((y * 0x1F) + 0x20); } // left table { ControlState tt; - s8 tt_; m_left_table->GetState(&tt); - tt_ = static_cast(tt * 0x1F); + const s8 tt_ = static_cast(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(tt * 0x1F); + const s8 tt_ = static_cast(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(dial * 0x0F); + const u8 dial_ = static_cast(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((cfs * 0x07) + 0x08); + tt_data.slider = static_cast((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