Skip to content

Commit

Permalink
ruby: Update to SDL3
Browse files Browse the repository at this point in the history
  • Loading branch information
jcm93 committed Feb 19, 2025
1 parent b225130 commit 9f9d296
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 42 deletions.
6 changes: 3 additions & 3 deletions cmake/finders/FindSDL.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ include(FindPackageHandleStandardArgs)

find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_search_module(PC_SDL QUIET sdl2)
pkg_search_module(PC_SDL QUIET sdl3)
endif()

# SDL_set_soname: Set SONAME on imported library target
Expand All @@ -66,7 +66,7 @@ endmacro()

find_path(
SDL_INCLUDE_DIR
NAMES SDL.h SDL2/SDL.h
NAMES SDL.h SDL3/SDL.h
HINTS ${PC_SDL_INCLUDE_DIRS}
PATHS ${CMAKE_SOURCE_DIR}/.deps /usr/include /usr/local/include
DOC "SDL include directory"
Expand All @@ -84,7 +84,7 @@ endif()

find_library(
SDL_LIBRARY
NAMES SDL2 SDL2-2.0.0 SDL2-2.0
NAMES SDL3 SDL3-3.0.0 SDL3-3.0
HINTS ${PC_SDL_LIBRARY_DIRS}
PATHS ${CMAKE_SOURCE_DIR}/.deps /usr/lib /usr/local/lib
DOC "SDL location"
Expand Down
2 changes: 1 addition & 1 deletion cmake/macos/defaults.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
include_guard(GLOBAL)

# Required to avoid us finding a system SDL2.framework before our provided SDL2.dylib
set(CMAKE_FIND_FRAMEWORK LAST)
# set(CMAKE_FIND_FRAMEWORK LAST)

# Set empty codesigning team if not specified as cache variable
if(NOT ARES_CODESIGN_TEAM)
Expand Down
43 changes: 24 additions & 19 deletions ruby/audio/sdl.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <SDL2/SDL.h>
#include <SDL3/SDL.h>

struct AudioSDL : AudioDriver {
AudioSDL& self = *this;
Expand Down Expand Up @@ -34,32 +34,32 @@ struct AudioSDL : AudioDriver {

auto clear() -> void override {
if(!ready()) return;
SDL_ClearQueuedAudio(_device);
SDL_ClearAudioStream(_stream);
}

auto output(const f64 samples[]) -> void override {
if(!ready()) return;

if(self.blocking) {
auto bytesRemaining = SDL_GetQueuedAudioSize(_device);
auto bytesRemaining = SDL_GetAudioStreamAvailable(_stream);
while(bytesRemaining > _bufferSize) {
//wait for audio to drain
auto bytesToWait = bytesRemaining - _bufferSize;
auto bytesPerSample = bitsPerSample / 8.0;
auto samplesRemaining = bytesToWait / bytesPerSample;
auto secondsRemaining = samplesRemaining / frequency;
usleep(secondsRemaining * 1000000);
bytesRemaining = SDL_GetQueuedAudioSize(_device);
bytesRemaining = SDL_GetAudioStreamAvailable(_stream);
}
}

std::unique_ptr<f32[]> output = std::make_unique<f32[]>(channels);
for(auto n : range(channels)) output[n] = samples[n];
SDL_QueueAudio(_device, &output[0], channels * sizeof(f32));
SDL_PutAudioStreamData(_stream, &output[0], channels * sizeof(f32));
}

auto level() -> f64 override {
return SDL_GetQueuedAudioSize(_device) / ((f64)_bufferSize);
return SDL_GetAudioStreamAvailable(_stream) / ((f64)_bufferSize);
}

private:
Expand All @@ -72,20 +72,24 @@ struct AudioSDL : AudioDriver {

SDL_InitSubSystem(SDL_INIT_AUDIO);

SDL_AudioSpec want{}, have{};
want.freq = frequency;
want.format = AUDIO_F32SYS;
want.channels = 2;

SDL_AudioSpec spec;
spec.format = SDL_AUDIO_F32;
spec.channels = 2;
spec.freq = frequency;
auto desired_samples = (latency * frequency) / 1000.0f;
want.samples = pow(2, ceil(log2(desired_samples))); // SDL2 requires power-of-two buffer sizes

_device = SDL_OpenAudioDevice(NULL,0,&want,&have,0);
frequency = have.freq;
channels = have.channels;
bitsPerSample = SDL_AUDIO_BITSIZE(have.format);
_bufferSize = have.size;
SDL_PauseAudioDevice(_device, 0);
string desired_samples_string = (string)desired_samples;
SDL_SetHint(SDL_HINT_AUDIO_DEVICE_SAMPLE_FRAMES, desired_samples_string);

SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, NULL, NULL);
_device = SDL_GetAudioStreamDevice(stream);
SDL_ResumeAudioDevice(_device);
_stream = stream;
frequency = spec.freq;
channels = spec.channels;
int bufferFrameSize;
SDL_GetAudioDeviceFormat(_device, &spec, &bufferFrameSize);
bitsPerSample = SDL_AUDIO_BITSIZE(spec.format);
_bufferSize = bufferFrameSize * channels * 4;

_ready = true;
clear();
Expand All @@ -105,5 +109,6 @@ struct AudioSDL : AudioDriver {
bool _ready = false;

SDL_AudioDeviceID _device = 0;
SDL_AudioStream *_stream;
u32 _bufferSize = 0;
};
37 changes: 19 additions & 18 deletions ruby/input/joypad/sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,27 @@ struct InputJoypadSDL {
}

auto poll(vector<shared_pointer<HID::Device>>& devices) -> void {
SDL_JoystickUpdate();
SDL_UpdateJoysticks();
SDL_Event event;
while(SDL_PollEvent(&event)) {
if(event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED) {
if(event.type == SDL_EVENT_JOYSTICK_ADDED || event.type == SDL_EVENT_JOYSTICK_REMOVED) {
enumerate();
}
}

for(auto& jp : joypads) {
for(u32 n : range(jp.hid->axes().size())) {
assign(jp, HID::Joypad::GroupID::Axis, n, (s16)SDL_JoystickGetAxis(jp.handle, n));
assign(jp, HID::Joypad::GroupID::Axis, n, (s16)SDL_GetJoystickAxis(jp.handle, n));
}

for(s32 n = 0; n < (s32)jp.hid->hats().size() - 1; n += 2) {
u8 state = SDL_JoystickGetHat(jp.handle, n >> 1);
u8 state = SDL_GetJoystickHat(jp.handle, n >> 1);
assign(jp, HID::Joypad::GroupID::Hat, n + 0, state & SDL_HAT_LEFT ? -32767 : state & SDL_HAT_RIGHT ? +32767 : 0);
assign(jp, HID::Joypad::GroupID::Hat, n + 1, state & SDL_HAT_UP ? -32767 : state & SDL_HAT_DOWN ? +32767 : 0);
}

for(u32 n : range(jp.hid->buttons().size())) {
assign(jp, HID::Joypad::GroupID::Button, n, (bool)SDL_JoystickGetButton(jp.handle, n));
assign(jp, HID::Joypad::GroupID::Button, n, (bool)SDL_GetJoystickButton(jp.handle, n));
}

devices.append(jp.hid);
Expand All @@ -59,7 +59,7 @@ struct InputJoypadSDL {
for(auto& jp : joypads) {
if(jp.hid->id() != id) continue;

SDL_JoystickRumble(jp.handle, strong, weak, 0);
SDL_RumbleJoystick(jp.handle, strong, weak, 0);
return true;
}

Expand All @@ -70,14 +70,14 @@ struct InputJoypadSDL {
terminate();
SDL_Init(SDL_INIT_EVENTS);
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
SDL_JoystickEventState(SDL_ENABLE);
//SDL_JoystickEventState(1);
enumerate();
return true;
}

auto terminate() -> void {
for(auto& jp : joypads) {
SDL_JoystickClose(jp.handle);
SDL_CloseJoystick(jp.handle);
}
joypads.reset();
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
Expand All @@ -86,21 +86,22 @@ struct InputJoypadSDL {
private:
auto enumerate() -> void {
for(auto& joypad : joypads) {
SDL_JoystickClose(joypad.handle);
SDL_CloseJoystick(joypad.handle);
}
joypads.reset();

for(u32 id : range(SDL_NumJoysticks())) {
int num_joysticks;
SDL_GetJoysticks(&num_joysticks);
for(u32 id : range(num_joysticks)) {
Joypad jp;
jp.id = id;
jp.handle = SDL_JoystickOpen(jp.id);
jp.handle = SDL_OpenJoystick(jp.id);

u32 axes = SDL_JoystickNumAxes(jp.handle);
u32 hats = SDL_JoystickNumHats(jp.handle) * 2;
u32 buttons = SDL_JoystickNumButtons(jp.handle);
u32 axes = SDL_GetNumJoystickAxes(jp.handle);
u32 hats = SDL_GetNumJoystickHats(jp.handle) * 2;
u32 buttons = SDL_GetNumJoystickButtons(jp.handle);

u16 vid = SDL_JoystickGetVendor(jp.handle);
u16 pid = SDL_JoystickGetProduct(jp.handle);
u16 vid = SDL_GetJoystickVendor(jp.handle);
u16 pid = SDL_GetJoystickProduct(jp.handle);
if(vid == 0) vid = HID::Joypad::GenericVendorID;
if(pid == 0) pid = HID::Joypad::GenericProductID;

Expand All @@ -115,6 +116,6 @@ struct InputJoypadSDL {
joypads.append(jp);
}

SDL_JoystickUpdate();
SDL_UpdateJoysticks();
}
};
2 changes: 1 addition & 1 deletion ruby/input/sdl.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <SDL2/SDL.h>
#include <SDL3/SDL.h>

#if defined(PLATFORM_WINDOWS)
#include "shared/rawinput.cpp"
Expand Down

0 comments on commit 9f9d296

Please sign in to comment.