Compare commits

...

3 Commits

Author SHA1 Message Date
patchzyy 4b91ed0541 wait for rumble before closing device 2026-10-18 13:20:06 +02:00
patchzyy f62f73161e Update AuroraSDL3Patches.cmake 2026-10-18 11:58:07 +02:00
patchzyy 90589131b5 Fix the date 2026-10-18 00:09:54 +02:00
2 changed files with 85 additions and 1 deletions
+46
View File
@@ -32,6 +32,52 @@ function(aurora_sdl3_apply_patches sdl_source_dir)
if (NOT EXISTS "${_wii}")
message(FATAL_ERROR "aurora: SDL3 source tree at ${sdl_source_dir} has no SDL_hidapi_wii.c")
endif ()
set(_rumble "${sdl_source_dir}/src/joystick/hidapi/SDL_hidapi_rumble.c")
if (NOT EXISTS "${_rumble}")
message(FATAL_ERROR "aurora: SDL3 source tree at ${sdl_source_dir} has no SDL_hidapi_rumble.c")
endif ()
set(_hidapi "${sdl_source_dir}/src/joystick/hidapi/SDL_hidapijoystick.c")
if (NOT EXISTS "${_hidapi}")
message(FATAL_ERROR "aurora: SDL3 source tree at ${sdl_source_dir} has no SDL_hidapijoystick.c")
endif ()
# Backport of SDL 71f4af732 (drop once SDL includes it): rumble writes must not hold dev_lock.
_aurora_sdl3_replace("${_rumble}" "HIDAPI rumble writes no longer hold the device lock"
[==[ if (request) {
SDL_LockMutex(request->device->dev_lock);
if (request->device->dev) {
#ifdef DEBUG_RUMBLE
HIDAPI_DumpPacket("Rumble packet: size = %d", request->data, request->size);
#endif
SDL_hid_write(request->device->dev, request->data, request->size);
}
SDL_UnlockMutex(request->device->dev_lock);
]==]
[==[ if (request) {
if (request->device->dev) {
#ifdef DEBUG_RUMBLE
HIDAPI_DumpPacket("Rumble packet: size = %d", request->data, request->size);
#endif
SDL_hid_write(request->device->dev, request->data, request->size);
}
]==])
# Without the lock, closing the handle must wait for in-flight rumble writes.
_aurora_sdl3_replace("${_hidapi}" "HIDAPI device close waits for pending rumble"
[==[ device->driver->FreeDevice(device);
device->driver = NULL;
SDL_LockMutex(device->dev_lock);
]==]
[==[ device->driver->FreeDevice(device);
device->driver = NULL;
while (SDL_GetAtomicInt(&device->rumble_pending) > 0) {
SDL_Delay(10);
}
SDL_LockMutex(device->dev_lock);
]==])
# Wii Remote: rebuild the joystick in place after an extension change.
#
+39 -1
View File
@@ -12,6 +12,7 @@
#include <cmath>
#include <cstdint>
#include <cstdlib>
#include <ctime>
#include <stdexcept>
#include <limits>
@@ -44,11 +45,48 @@ uint32_t g_reservationAddr = 0;
bool g_hasReservation = false;
const auto g_timeBaseStart = std::chrono::steady_clock::now();
// Days from 1970-01-01 to the given civil date (Howard Hinnant's algorithm).
constexpr int64_t DaysFromCivil(int64_t y, unsigned m, unsigned d)
{
y -= m <= 2;
const int64_t era = (y >= 0 ? y : y - 399) / 400;
const unsigned yoe = static_cast<unsigned>(y - era * 400);
const unsigned doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1;
const unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
return era * 146097 + static_cast<int64_t>(doe) - 719468;
}
// The Wii RTC holds local time; the OS counts ticks from 2000-01-01.
uint64_t InitialTimeBase()
{
const std::time_t now = std::time(nullptr);
std::tm local{};
#if defined(_WIN32)
if (localtime_s(&local, &now) != 0) {
return 0;
}
#else
if (localtime_r(&now, &local) == nullptr) {
return 0;
}
#endif
const int64_t days = DaysFromCivil(local.tm_year + 1900, static_cast<unsigned>(local.tm_mon + 1),
static_cast<unsigned>(local.tm_mday)) -
DaysFromCivil(2000, 1, 1);
const int64_t seconds = days * 86400 + local.tm_hour * 3600 + local.tm_min * 60 + local.tm_sec;
if (seconds <= 0) {
return 0;
}
return static_cast<uint64_t>(seconds) * TimeBaseContract::kTicksPerSecond;
}
const uint64_t g_timeBaseOrigin = InitialTimeBase();
uint64_t GetTimeBase() {
const auto elapsed = std::chrono::steady_clock::now() - g_timeBaseStart;
const auto nanoseconds =
std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count();
return TimeBaseContract::NanosecondsToTicks(static_cast<uint64_t>(nanoseconds));
return g_timeBaseOrigin + TimeBaseContract::NanosecondsToTicks(static_cast<uint64_t>(nanoseconds));
}
constexpr uint32_t kFpscrFx = 1u << 31;