audio & correct mouse/keyboard indexing

Create the mutexes properly
This commit is contained in:
Kylie C 2025-10-14 22:32:30 -04:00
parent 75306f412d
commit 9614c0b97b
4 changed files with 67 additions and 48 deletions

View File

@ -96,10 +96,19 @@ inline SDL_DisplayMode* SDL_GetCurrentDisplayMode(SDL_DisplayID displayID)
#define SDL_RenderTexture(...) (SDL_RenderCopyF(__VA_ARGS__) == 0) #define SDL_RenderTexture(...) (SDL_RenderCopyF(__VA_ARGS__) == 0)
#define SDL_CreateWindowAndRenderer(title, width, height, flags, window, renderer) (SDL_CreateWindowAndRenderer(width, height, flags, window, renderer) == 0)
#define SDL_SetRenderScale(...) (SDL_RenderSetScale(__VA_ARGS__) == 0)
// https://wiki.libsdl.org/SDL3/README-migration#sdl_keyboardh
typedef int SDL_KeyboardID;
#define SDL_GetKeyFromScancode(scancode, modstate, event) SDL_GetKeyFromScancode(scancode)
// https://wiki.libsdl.org/SDL3/README-migration#sdl_haptich // https://wiki.libsdl.org/SDL3/README-migration#sdl_haptich
// SDL_MouseID/SDL_KeyboardID are new // SDL_MouseID/SDL_KeyboardID are new
typedef int SDL_KeyboardID;
#define SDL_GetKeyboardState (const bool*)SDL_GetKeyboardState #define SDL_GetKeyboardState (const bool*)SDL_GetKeyboardState
typedef int SDL_HapticID; typedef int SDL_HapticID;

View File

@ -7,8 +7,6 @@
// https://wiki.libsdl.org/SDL3/README-migration#sdl_audioh // https://wiki.libsdl.org/SDL3/README-migration#sdl_audioh
#define SDL_DestroyAudioStream SDL_FreeAudioStream
#define SDL_AUDIO_F32 AUDIO_F32SYS #define SDL_AUDIO_F32 AUDIO_F32SYS
#define SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK NULL #define SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK NULL
@ -16,40 +14,31 @@
typedef void SDL_AudioStreamCallback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount); typedef void SDL_AudioStreamCallback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount);
struct ShimAudioCtx { struct ShimAudioCtx {
SDL_AudioDeviceID device;
SDL_AudioStream* stream; SDL_AudioStream* stream;
SDL_AudioStreamCallback* callback; SDL_AudioStreamCallback* callback;
void *userdata; void *userdata;
SDL_AudioSpec obtained; SDL_AudioSpec obtained;
}; };
static std::map<SDL_AudioDeviceID, ShimAudioCtx> g_audioCtxs; static std::map<SDL_AudioStream*, ShimAudioCtx*> g_audioCtxs;
static SDL_mutex *g_audioMutex = NULL; static SDL_mutex *g_audioMutex = SDL_CreateMutex();
static void SDLCALL shim_audio_callback(void *userdata, Uint8 *stream, int len) { static void shim_audio_callback(void *userdata, Uint8 *data_stream, int len) {
SDL_AudioDeviceID devid = reinterpret_cast<uintptr_t>(userdata); const auto ctx = static_cast<ShimAudioCtx*>(userdata);
SDL_AudioStream* audio_stream = ctx->stream;
SDL_LockMutex(g_audioMutex); int available = SDL_AudioStreamAvailable(audio_stream);
const auto it = g_audioCtxs.find(devid);
if (it == g_audioCtxs.end()) {
SDL_UnlockMutex(g_audioMutex);
SDL_memset(stream, 0, len);
return;
}
ShimAudioCtx &ctx = it->second; int additional_amount = len - available;
SDL_UnlockMutex(g_audioMutex); if (additional_amount < 0)
additional_amount = 0;
// How many sample frames the device is asking for ctx->callback(ctx->userdata, audio_stream, additional_amount, len);
const int frame_size = (SDL_AUDIO_BITSIZE(ctx.obtained.format) / 8) * ctx.obtained.channels;
const int needed_frames = len / frame_size;
int total = (SDL_AudioStreamAvailable(ctx.stream) / frame_size) + needed_frames; int retrieved = SDL_AudioStreamGet(audio_stream, data_stream, len);
// SDL3 callback pushes more into the stream if (retrieved < len) {
ctx.callback(ctx.userdata, ctx.stream, needed_frames, total); memset(data_stream + retrieved, ctx->obtained.silence, len - retrieved);
int got = SDL_AudioStreamGet(ctx.stream, stream, len);
if (got < len) {
SDL_memset(stream + got, 0, len - got);
} }
} }
@ -59,43 +48,64 @@ static void SDLCALL shim_audio_callback(void *userdata, Uint8 *stream, int len)
inline SDL_AudioDeviceID SDL_GetAudioStreamDevice(SDL_AudioStream* stream) inline SDL_AudioDeviceID SDL_GetAudioStreamDevice(SDL_AudioStream* stream)
{ {
SDL_LockMutex(g_audioMutex); SDL_LockMutex(g_audioMutex);
const auto it = g_audioCtxs.find(reinterpret_cast<uintptr_t>(stream)); const auto it = g_audioCtxs.find(stream);
if (it == g_audioCtxs.end()) { if (it == g_audioCtxs.end()) {
return 0; return 0;
} }
return it->first; SDL_UnlockMutex(g_audioMutex);
return it->second->device;
} }
inline SDL_AudioStream * SDL_OpenAudioDeviceStream(const char* devid, const SDL_AudioSpec* desired, SDL_AudioStreamCallback callback, void* userdata) inline SDL_AudioStream * SDL_OpenAudioDeviceStream(const char* devid, const SDL_AudioSpec* desired, SDL_AudioStreamCallback callback, void* userdata)
{ {
SDL_AudioSpec obtained{}; SDL_AudioSpec obtained{};
SDL_AudioSpec desired2 = *desired; SDL_AudioSpec desired2 = *desired;
auto ctx = new ShimAudioCtx();
ctx->callback = callback;
ctx->userdata = userdata;
ctx->stream = nullptr;
desired2.callback = shim_audio_callback; desired2.callback = shim_audio_callback;
desired2.userdata = reinterpret_cast<void*>(static_cast<uintptr_t>(0)); desired2.userdata = ctx;
SDL_AudioDeviceID device = SDL_OpenAudioDevice(devid, 0, &desired2, &obtained, 0); const SDL_AudioDeviceID device = SDL_OpenAudioDevice(devid, 0, &desired2, &obtained, 0);
if (device <= 0) {
delete ctx;
return NULL;
}
SDL_AudioStream* stream = SDL_NewAudioStream( SDL_AudioStream* stream = SDL_NewAudioStream(
desired->format, desired->channels, desired->freq, desired->format, desired->channels, desired->freq,
obtained.format, obtained.channels, obtained.freq obtained.format, obtained.channels, obtained.freq
); );
if (!stream) { if (!stream) {
SDL_CloseAudioDevice(device); SDL_CloseAudioDevice(device);
return nullptr; delete ctx;
return NULL;
} }
{ ctx->device = device;
SDL_LockMutex(g_audioMutex); ctx->stream = stream;
ShimAudioCtx ctx; ctx->obtained = obtained;
ctx.stream = stream;
ctx.callback = callback;
ctx.userdata = userdata;
ctx.obtained = obtained;
g_audioCtxs[device] = ctx;
SDL_UnlockMutex(g_audioMutex);
}
SDL_LockAudioDevice(device); SDL_LockMutex(g_audioMutex);
desired2.userdata = reinterpret_cast<void*>(static_cast<uintptr_t>(device)); g_audioCtxs[stream] = ctx;
SDL_UnlockAudioDevice(device); SDL_UnlockMutex(g_audioMutex);
return stream; return stream;
} }
inline SDL_bool SDL_DestroyAudioStream(SDL_AudioStream* stream)
{
SDL_LockMutex(g_audioMutex);
if (const auto it = g_audioCtxs.find(stream); it != g_audioCtxs.end()) {
SDL_CloseAudioDevice(it->second->device);
delete it->second;
g_audioCtxs.erase(it);
SDL_UnlockMutex(g_audioMutex);
}
SDL_UnlockMutex(g_audioMutex);
SDL_FreeAudioStream(stream);
return true;
}

View File

@ -22,7 +22,7 @@ struct SDL2TimerShimData {
}; };
static std::map<SDL_TimerID, void*> g_timers; static std::map<SDL_TimerID, void*> g_timers;
static SDL_mutex *g_timerMutex = NULL; static SDL_mutex *g_timerMutex = SDL_CreateMutex();
inline Uint32 shim_timer_callback (Uint32 interval, void *param) inline Uint32 shim_timer_callback (Uint32 interval, void *param)
{ {

View File

@ -785,7 +785,7 @@ void LegoInputManager::UpdateLastInputMethod(SDL_Event* p_event)
#if SDL_MAJOR_VERSION >= 3 #if SDL_MAJOR_VERSION >= 3
m_lastInputMethod = SDL_KeyboardID_v{p_event->key.which}; m_lastInputMethod = SDL_KeyboardID_v{p_event->key.which};
#else #else
m_lastInputMethod = SDL_KeyboardID_v{0}; m_lastInputMethod = SDL_KeyboardID_v{1};
#endif #endif
break; break;
case SDL_EVENT_MOUSE_BUTTON_DOWN: case SDL_EVENT_MOUSE_BUTTON_DOWN:
@ -793,14 +793,14 @@ void LegoInputManager::UpdateLastInputMethod(SDL_Event* p_event)
#if SDL_MAJOR_VERSION >= 3 #if SDL_MAJOR_VERSION >= 3
m_lastInputMethod = SDL_MouseID_v{p_event->button.which}; m_lastInputMethod = SDL_MouseID_v{p_event->button.which};
#else #else
m_lastInputMethod = SDL_MouseID_v{0}; m_lastInputMethod = SDL_MouseID_v{1};
#endif #endif
break; break;
case SDL_EVENT_MOUSE_MOTION: case SDL_EVENT_MOUSE_MOTION:
#if SDL_MAJOR_VERSION >= 3 #if SDL_MAJOR_VERSION >= 3
m_lastInputMethod = SDL_MouseID_v{p_event->motion.which}; m_lastInputMethod = SDL_MouseID_v{p_event->motion.which};
#else #else
m_lastInputMethod = SDL_MouseID_v{0}; m_lastInputMethod = SDL_MouseID_v{1};
#endif #endif
break; break;
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: case SDL_EVENT_GAMEPAD_BUTTON_DOWN: