Merge pull request #7625 from jordan-woyak/emu-shake-fix
WiimoteEmu: Shaking emulation fix
This commit is contained in:
commit
89eedc8c1b
|
@ -23,7 +23,7 @@ enum class ClassicGroup;
|
||||||
enum class GuitarGroup;
|
enum class GuitarGroup;
|
||||||
enum class DrumsGroup;
|
enum class DrumsGroup;
|
||||||
enum class TurntableGroup;
|
enum class TurntableGroup;
|
||||||
}
|
} // namespace WiimoteEmu
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,9 @@ enum class InitializeMode
|
||||||
DO_NOT_WAIT_FOR_WIIMOTES,
|
DO_NOT_WAIT_FOR_WIIMOTES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The Real Wii Remote sends report every ~5ms (200 Hz).
|
||||||
|
constexpr int UPDATE_FREQ = 200;
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Initialize(InitializeMode init_mode);
|
void Initialize(InitializeMode init_mode);
|
||||||
void Connect(unsigned int index, bool connect);
|
void Connect(unsigned int index, bool connect);
|
||||||
|
@ -78,7 +81,7 @@ void InterruptChannel(int number, u16 channel_id, const void* data, u32 size);
|
||||||
bool ButtonPressed(int number);
|
bool ButtonPressed(int number);
|
||||||
void Update(int number, bool connected);
|
void Update(int number, bool connected);
|
||||||
bool NetPlay_GetButtonPress(int wiimote, bool pressed);
|
bool NetPlay_GetButtonPress(int wiimote, bool pressed);
|
||||||
}
|
} // namespace Wiimote
|
||||||
|
|
||||||
namespace WiimoteReal
|
namespace WiimoteReal
|
||||||
{
|
{
|
||||||
|
@ -90,4 +93,4 @@ void Pause();
|
||||||
void Refresh();
|
void Refresh();
|
||||||
|
|
||||||
void LoadSettings();
|
void LoadSettings();
|
||||||
}
|
} // namespace WiimoteReal
|
||||||
|
|
|
@ -21,26 +21,6 @@ namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
constexpr std::array<u8, 6> classic_id{{0x00, 0x00, 0xa4, 0x20, 0x01, 0x01}};
|
constexpr std::array<u8, 6> classic_id{{0x00, 0x00, 0xa4, 0x20, 0x01, 0x01}};
|
||||||
|
|
||||||
// Classic Controller calibration
|
|
||||||
constexpr std::array<u8, 0x10> classic_calibration{{
|
|
||||||
0xff,
|
|
||||||
0x00,
|
|
||||||
0x80,
|
|
||||||
0xff,
|
|
||||||
0x00,
|
|
||||||
0x80,
|
|
||||||
0xff,
|
|
||||||
0x00,
|
|
||||||
0x80,
|
|
||||||
0xff,
|
|
||||||
0x00,
|
|
||||||
0x80,
|
|
||||||
0x00,
|
|
||||||
0x00,
|
|
||||||
0x51,
|
|
||||||
0xa6,
|
|
||||||
}};
|
|
||||||
|
|
||||||
constexpr std::array<u16, 9> classic_button_bitmasks{{
|
constexpr std::array<u16, 9> classic_button_bitmasks{{
|
||||||
Classic::BUTTON_A,
|
Classic::BUTTON_A,
|
||||||
Classic::BUTTON_B,
|
Classic::BUTTON_B,
|
||||||
|
@ -124,9 +104,35 @@ Classic::Classic(ExtensionReg& reg) : Attachment(_trans("Classic"), reg)
|
||||||
new ControllerEmu::Input(ControllerEmu::Translate, named_direction));
|
new ControllerEmu::Input(ControllerEmu::Translate, named_direction));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up register
|
|
||||||
m_calibration = classic_calibration;
|
|
||||||
m_id = classic_id;
|
m_id = classic_id;
|
||||||
|
|
||||||
|
// Build calibration data:
|
||||||
|
m_calibration = {{
|
||||||
|
// Left Stick X max,min,center:
|
||||||
|
CAL_STICK_CENTER + CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER - CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER,
|
||||||
|
// Left Stick Y max,min,center:
|
||||||
|
CAL_STICK_CENTER + CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER - CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER,
|
||||||
|
// Right Stick X max,min,center:
|
||||||
|
CAL_STICK_CENTER + CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER - CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER,
|
||||||
|
// Right Stick Y max,min,center:
|
||||||
|
CAL_STICK_CENTER + CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER - CAL_STICK_RANGE,
|
||||||
|
CAL_STICK_CENTER,
|
||||||
|
// Left/Right trigger range: (assumed based on real calibration data values)
|
||||||
|
LEFT_TRIGGER_RANGE,
|
||||||
|
RIGHT_TRIGGER_RANGE,
|
||||||
|
// 2 checksum bytes calculated below:
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
}};
|
||||||
|
|
||||||
|
UpdateCalibrationDataChecksum(m_calibration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Classic::GetState(u8* const data)
|
void Classic::GetState(u8* const data)
|
||||||
|
@ -213,4 +219,4 @@ ControllerEmu::ControlGroup* Classic::GetGroup(ClassicGroup group)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace WiimoteEmu
|
||||||
|
|
|
@ -12,7 +12,7 @@ class AnalogStick;
|
||||||
class Buttons;
|
class Buttons;
|
||||||
class ControlGroup;
|
class ControlGroup;
|
||||||
class MixedTriggers;
|
class MixedTriggers;
|
||||||
}
|
} // namespace ControllerEmu
|
||||||
|
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
@ -48,16 +48,25 @@ public:
|
||||||
PAD_UP = 0x0100,
|
PAD_UP = 0x0100,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u8 LEFT_STICK_CENTER_X = 0x20;
|
enum
|
||||||
static const u8 LEFT_STICK_CENTER_Y = 0x20;
|
{
|
||||||
static const u8 LEFT_STICK_RADIUS = 0x1F;
|
CAL_STICK_CENTER = 0x80,
|
||||||
|
CAL_STICK_RANGE = 0x7f,
|
||||||
|
CAL_STICK_BITS = 8,
|
||||||
|
|
||||||
static const u8 RIGHT_STICK_CENTER_X = 0x10;
|
LEFT_STICK_BITS = 6,
|
||||||
static const u8 RIGHT_STICK_CENTER_Y = 0x10;
|
LEFT_STICK_CENTER_X = CAL_STICK_CENTER >> (CAL_STICK_BITS - LEFT_STICK_BITS),
|
||||||
static const u8 RIGHT_STICK_RADIUS = 0x0F;
|
LEFT_STICK_CENTER_Y = CAL_STICK_CENTER >> (CAL_STICK_BITS - LEFT_STICK_BITS),
|
||||||
|
LEFT_STICK_RADIUS = CAL_STICK_RANGE >> (CAL_STICK_BITS - LEFT_STICK_BITS),
|
||||||
|
|
||||||
static const u8 LEFT_TRIGGER_RANGE = 0x1F;
|
RIGHT_STICK_BITS = 5,
|
||||||
static const u8 RIGHT_TRIGGER_RANGE = 0x1F;
|
RIGHT_STICK_CENTER_X = CAL_STICK_CENTER >> (CAL_STICK_BITS - RIGHT_STICK_BITS),
|
||||||
|
RIGHT_STICK_CENTER_Y = CAL_STICK_CENTER >> (CAL_STICK_BITS - RIGHT_STICK_BITS),
|
||||||
|
RIGHT_STICK_RADIUS = CAL_STICK_RANGE >> (CAL_STICK_BITS - RIGHT_STICK_BITS),
|
||||||
|
|
||||||
|
LEFT_TRIGGER_RANGE = 0x1F,
|
||||||
|
RIGHT_TRIGGER_RANGE = 0x1F,
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ControllerEmu::Buttons* m_buttons;
|
ControllerEmu::Buttons* m_buttons;
|
||||||
|
@ -66,4 +75,4 @@ private:
|
||||||
ControllerEmu::AnalogStick* m_left_stick;
|
ControllerEmu::AnalogStick* m_left_stick;
|
||||||
ControllerEmu::AnalogStick* m_right_stick;
|
ControllerEmu::AnalogStick* m_right_stick;
|
||||||
};
|
};
|
||||||
}
|
} // namespace WiimoteEmu
|
||||||
|
|
|
@ -69,6 +69,35 @@ Nunchuk::Nunchuk(ExtensionReg& reg) : Attachment(_trans("Nunchuk"), reg)
|
||||||
m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z"));
|
m_shake_hard->controls.emplace_back(new ControllerEmu::Input(ControllerEmu::DoNotTranslate, "Z"));
|
||||||
|
|
||||||
m_id = nunchuk_id;
|
m_id = nunchuk_id;
|
||||||
|
|
||||||
|
// Build calibration data:
|
||||||
|
m_calibration = {{
|
||||||
|
// Accel Zero X,Y,Z:
|
||||||
|
ACCEL_ZERO_G,
|
||||||
|
ACCEL_ZERO_G,
|
||||||
|
ACCEL_ZERO_G,
|
||||||
|
// Possibly LSBs of zero values:
|
||||||
|
0x00,
|
||||||
|
// Accel 1G X,Y,Z:
|
||||||
|
ACCEL_ONE_G,
|
||||||
|
ACCEL_ONE_G,
|
||||||
|
ACCEL_ONE_G,
|
||||||
|
// Possibly LSBs of 1G values:
|
||||||
|
0x00,
|
||||||
|
// Stick X max,min,center:
|
||||||
|
STICK_CENTER + STICK_RADIUS,
|
||||||
|
STICK_CENTER - STICK_RADIUS,
|
||||||
|
STICK_CENTER,
|
||||||
|
// Stick Y max,min,center:
|
||||||
|
STICK_CENTER + STICK_RADIUS,
|
||||||
|
STICK_CENTER - STICK_RADIUS,
|
||||||
|
STICK_CENTER,
|
||||||
|
// 2 checksum bytes calculated below:
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
}};
|
||||||
|
|
||||||
|
UpdateCalibrationDataChecksum(m_calibration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Nunchuk::GetState(u8* const data)
|
void Nunchuk::GetState(u8* const data)
|
||||||
|
@ -125,9 +154,9 @@ void Nunchuk::GetState(u8* const data)
|
||||||
s16 accel_y = (s16)(4 * (accel.y * ACCEL_RANGE + ACCEL_ZERO_G));
|
s16 accel_y = (s16)(4 * (accel.y * ACCEL_RANGE + ACCEL_ZERO_G));
|
||||||
s16 accel_z = (s16)(4 * (accel.z * ACCEL_RANGE + ACCEL_ZERO_G));
|
s16 accel_z = (s16)(4 * (accel.z * ACCEL_RANGE + ACCEL_ZERO_G));
|
||||||
|
|
||||||
accel_x = MathUtil::Clamp<s16>(accel_x, 0, 1024);
|
accel_x = MathUtil::Clamp<s16>(accel_x, 0, 0x3ff);
|
||||||
accel_y = MathUtil::Clamp<s16>(accel_y, 0, 1024);
|
accel_y = MathUtil::Clamp<s16>(accel_y, 0, 0x3ff);
|
||||||
accel_z = MathUtil::Clamp<s16>(accel_z, 0, 1024);
|
accel_z = MathUtil::Clamp<s16>(accel_z, 0, 0x3ff);
|
||||||
|
|
||||||
nc_data.ax = (accel_x >> 2) & 0xFF;
|
nc_data.ax = (accel_x >> 2) & 0xFF;
|
||||||
nc_data.ay = (accel_y >> 2) & 0xFF;
|
nc_data.ay = (accel_y >> 2) & 0xFF;
|
||||||
|
@ -186,4 +215,4 @@ void Nunchuk::LoadDefaults(const ControllerInterface& ciface)
|
||||||
m_buttons->SetControlExpression(1, "Shift_L"); // Z
|
m_buttons->SetControlExpression(1, "Shift_L"); // Z
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
} // namespace WiimoteEmu
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Buttons;
|
||||||
class ControlGroup;
|
class ControlGroup;
|
||||||
class Force;
|
class Force;
|
||||||
class Tilt;
|
class Tilt;
|
||||||
}
|
} // namespace ControllerEmu
|
||||||
|
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
@ -69,4 +69,4 @@ private:
|
||||||
std::array<u8, 3> m_shake_soft_step{};
|
std::array<u8, 3> m_shake_soft_step{};
|
||||||
std::array<u8, 3> m_shake_hard_step{};
|
std::array<u8, 3> m_shake_hard_step{};
|
||||||
};
|
};
|
||||||
}
|
} // namespace WiimoteEmu
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
@ -56,6 +57,11 @@ auto const PI = TAU / 2.0;
|
||||||
|
|
||||||
namespace WiimoteEmu
|
namespace WiimoteEmu
|
||||||
{
|
{
|
||||||
|
constexpr int SHAKE_FREQ = 6;
|
||||||
|
// Frame count of one up/down shake
|
||||||
|
// < 9 no shake detection in "Wario Land: Shake It"
|
||||||
|
constexpr int SHAKE_STEP_MAX = ::Wiimote::UPDATE_FREQ / SHAKE_FREQ;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const u8 eeprom_data_0[] = {
|
static const u8 eeprom_data_0[] = {
|
||||||
// IR, maybe more
|
// IR, maybe more
|
||||||
|
@ -101,13 +107,20 @@ static const ReportFeatures reporting_mode_features[] = {
|
||||||
{0, 0, 0, 0, 23},
|
{0, 0, 0, 0, 23},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used for extension calibration data:
|
||||||
|
void UpdateCalibrationDataChecksum(std::array<u8, 0x10>& data)
|
||||||
|
{
|
||||||
|
// Last two bytes are the sum of the previous bytes plus 0x55 and 0xaa (0x55 + 0x55)
|
||||||
|
const u8 checksum1 = std::accumulate(std::begin(data), std::end(data) - 2, u8(0x55));
|
||||||
|
const u8 checksum2 = checksum1 + 0x55;
|
||||||
|
|
||||||
|
data[0xe] = checksum1;
|
||||||
|
data[0xf] = checksum2;
|
||||||
|
}
|
||||||
|
|
||||||
void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_group,
|
void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_group,
|
||||||
const double intensity, u8* const shake_step)
|
const double intensity, u8* const shake_step)
|
||||||
{
|
{
|
||||||
// frame count of one up/down shake
|
|
||||||
// < 9 no shake detection in "Wario Land: Shake It"
|
|
||||||
auto const shake_step_max = 15;
|
|
||||||
|
|
||||||
// shake is a bitfield of X,Y,Z shake button states
|
// shake is a bitfield of X,Y,Z shake button states
|
||||||
static const unsigned int btns[] = {0x01, 0x02, 0x04};
|
static const unsigned int btns[] = {0x01, 0x02, 0x04};
|
||||||
unsigned int shake = 0;
|
unsigned int shake = 0;
|
||||||
|
@ -117,8 +130,8 @@ void EmulateShake(AccelData* const accel, ControllerEmu::Buttons* const buttons_
|
||||||
{
|
{
|
||||||
if (shake & (1 << i))
|
if (shake & (1 << i))
|
||||||
{
|
{
|
||||||
(&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * intensity;
|
(&(accel->x))[i] += std::sin(TAU * shake_step[i] / SHAKE_STEP_MAX) * intensity;
|
||||||
shake_step[i] = (shake_step[i] + 1) % shake_step_max;
|
shake_step[i] = (shake_step[i] + 1) % SHAKE_STEP_MAX;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
shake_step[i] = 0;
|
shake_step[i] = 0;
|
||||||
|
@ -129,10 +142,6 @@ void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data,
|
||||||
ControllerEmu::Buttons* const buttons_group,
|
ControllerEmu::Buttons* const buttons_group,
|
||||||
const DynamicConfiguration& config, u8* const shake_step)
|
const DynamicConfiguration& config, u8* const shake_step)
|
||||||
{
|
{
|
||||||
// frame count of one up/down shake
|
|
||||||
// < 9 no shake detection in "Wario Land: Shake It"
|
|
||||||
auto const shake_step_max = 15;
|
|
||||||
|
|
||||||
// shake is a bitfield of X,Y,Z shake button states
|
// shake is a bitfield of X,Y,Z shake button states
|
||||||
static const unsigned int btns[] = {0x01, 0x02, 0x04};
|
static const unsigned int btns[] = {0x01, 0x02, 0x04};
|
||||||
unsigned int shake = 0;
|
unsigned int shake = 0;
|
||||||
|
@ -146,8 +155,9 @@ void EmulateDynamicShake(AccelData* const accel, DynamicData& dynamic_data,
|
||||||
}
|
}
|
||||||
else if (dynamic_data.executing_frames_left[i] > 0)
|
else if (dynamic_data.executing_frames_left[i] > 0)
|
||||||
{
|
{
|
||||||
(&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * dynamic_data.intensity[i];
|
(&(accel->x))[i] +=
|
||||||
shake_step[i] = (shake_step[i] + 1) % shake_step_max;
|
std::sin(TAU * shake_step[i] / SHAKE_STEP_MAX) * dynamic_data.intensity[i];
|
||||||
|
shake_step[i] = (shake_step[i] + 1) % SHAKE_STEP_MAX;
|
||||||
dynamic_data.executing_frames_left[i]--;
|
dynamic_data.executing_frames_left[i]--;
|
||||||
}
|
}
|
||||||
else if (shake == 0 && dynamic_data.timing[i] > 0)
|
else if (shake == 0 && dynamic_data.timing[i] > 0)
|
||||||
|
@ -651,9 +661,9 @@ void Wiimote::GetAccelData(u8* const data, const ReportFeatures& rptf)
|
||||||
s16 y = (s16)(4 * (m_accel.y * ACCEL_RANGE + ACCEL_ZERO_G));
|
s16 y = (s16)(4 * (m_accel.y * ACCEL_RANGE + ACCEL_ZERO_G));
|
||||||
s16 z = (s16)(4 * (m_accel.z * ACCEL_RANGE + ACCEL_ZERO_G));
|
s16 z = (s16)(4 * (m_accel.z * ACCEL_RANGE + ACCEL_ZERO_G));
|
||||||
|
|
||||||
x = MathUtil::Clamp<s16>(x, 0, 1024);
|
x = MathUtil::Clamp<s16>(x, 0, 0x3ff);
|
||||||
y = MathUtil::Clamp<s16>(y, 0, 1024);
|
y = MathUtil::Clamp<s16>(y, 0, 0x3ff);
|
||||||
z = MathUtil::Clamp<s16>(z, 0, 1024);
|
z = MathUtil::Clamp<s16>(z, 0, 0x3ff);
|
||||||
|
|
||||||
accel.x = (x >> 2) & 0xFF;
|
accel.x = (x >> 2) & 0xFF;
|
||||||
accel.y = (y >> 2) & 0xFF;
|
accel.y = (y >> 2) & 0xFF;
|
||||||
|
@ -1025,11 +1035,15 @@ void Wiimote::LoadDefaults(const ControllerInterface& ciface)
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
#if defined HAVE_X11 && HAVE_X11
|
#if defined HAVE_X11 && HAVE_X11
|
||||||
m_buttons->SetControlExpression(0, "Click 1"); // A
|
// A
|
||||||
m_buttons->SetControlExpression(1, "Click 3"); // B
|
m_buttons->SetControlExpression(0, "Click 1");
|
||||||
|
// B
|
||||||
|
m_buttons->SetControlExpression(1, "Click 3");
|
||||||
#else
|
#else
|
||||||
m_buttons->SetControlExpression(0, "Click 0"); // A
|
// A
|
||||||
m_buttons->SetControlExpression(1, "Click 1"); // B
|
m_buttons->SetControlExpression(0, "Click 0");
|
||||||
|
// B
|
||||||
|
m_buttons->SetControlExpression(1, "Click 1");
|
||||||
#endif
|
#endif
|
||||||
m_buttons->SetControlExpression(2, "1"); // 1
|
m_buttons->SetControlExpression(2, "1"); // 1
|
||||||
m_buttons->SetControlExpression(3, "2"); // 2
|
m_buttons->SetControlExpression(3, "2"); // 2
|
||||||
|
|
|
@ -34,7 +34,7 @@ class ModifySettingsButton;
|
||||||
class NumericSetting;
|
class NumericSetting;
|
||||||
class Output;
|
class Output;
|
||||||
class Tilt;
|
class Tilt;
|
||||||
}
|
} // namespace ControllerEmu
|
||||||
|
|
||||||
namespace WiimoteReal
|
namespace WiimoteReal
|
||||||
{
|
{
|
||||||
|
@ -181,6 +181,8 @@ struct ExtensionReg
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
void UpdateCalibrationDataChecksum(std::array<u8, 0x10>& data);
|
||||||
|
|
||||||
void EmulateShake(AccelData* accel, ControllerEmu::Buttons* buttons_group, double intensity,
|
void EmulateShake(AccelData* accel, ControllerEmu::Buttons* buttons_group, double intensity,
|
||||||
u8* shake_step);
|
u8* shake_step);
|
||||||
|
|
||||||
|
@ -377,4 +379,4 @@ private:
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
};
|
};
|
||||||
}
|
} // namespace WiimoteEmu
|
||||||
|
|
|
@ -356,8 +356,7 @@ void BluetoothEmu::Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Real Wii Remote sends report every ~5ms (200 Hz).
|
const u64 interval = SystemTimers::GetTicksPerSecond() / Wiimote::UPDATE_FREQ;
|
||||||
const u64 interval = SystemTimers::GetTicksPerSecond() / 200;
|
|
||||||
const u64 now = CoreTiming::GetTicks();
|
const u64 now = CoreTiming::GetTicks();
|
||||||
|
|
||||||
if (now - m_last_ticks > interval)
|
if (now - m_last_ticks > interval)
|
||||||
|
|
Loading…
Reference in New Issue