Skip to content

Commit

Permalink
Port to SDL3 (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
jhasse committed Dec 18, 2024
1 parent 7afd9e8 commit 5f0e37a
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 223 deletions.
38 changes: 19 additions & 19 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ elseif (UNIX)

target_link_libraries(jngl PRIVATE $<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:stdc++fs>)
else() # Windows
set(JNGL_SDL2_DEFAULT OFF)
set(JNGL_SDL_DEFAULT OFF)
if(WINDOWS_STORE)
set(JNGL_SDL2_DEFAULT ON)
set(JNGL_SDL_DEFAULT ON)

FetchContent_Declare(
angle
Expand All @@ -125,10 +125,10 @@ else() # Windows
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD} CACHE BOOL "" FORCE)
endif()
endif()
option(JNGL_SDL2 "Use SDL2 instead of WinAPI" ${JNGL_SDL2_DEFAULT})
option(JNGL_SDL "Use SDL3 instead of WinAPI" ${JNGL_SDL_DEFAULT})

target_compile_definitions(jngl PRIVATE _WIN32_WINNT=0x602 _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS UNICODE)
if(JNGL_SDL2)
if(JNGL_SDL)
file(GLOB SRC src/sdl/*.cpp)
if(WINDOWS_STORE)
target_sources(jngl PRIVATE src/xinput/XinputController.cpp)
Expand Down Expand Up @@ -213,9 +213,9 @@ else()
endif()
if(UNIX AND NOT IOS AND NOT EMSCRIPTEN)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
target_include_directories(jngl PRIVATE ${SDL2_INCLUDE_DIRS})
target_link_libraries(jngl PRIVATE ${SDL2_LINK_LIBRARIES})
pkg_check_modules(SDL3 REQUIRED sdl3)
target_include_directories(jngl PRIVATE ${SDL3_INCLUDE_DIRS})
target_link_libraries(jngl PRIVATE ${SDL3_LINK_LIBRARIES})
endif()

if(NOT IOS AND NOT EMSCRIPTEN)
Expand All @@ -237,17 +237,17 @@ else()

if(MSVC)
target_compile_definitions(jngl PUBLIC _USE_MATH_DEFINES)
if(JNGL_SDL2)
CPMAddPackage(NAME sdl2
URL https://www.libsdl.org/release/SDL2-2.28.4.zip
URL_HASH SHA1=0d9e0da0e935c4f0524cfd16d47d38b6045b9573
if(JNGL_SDL)
CPMAddPackage(NAME sdl3
URL https://www.libsdl.org/release/SDL3-3.1.6.zip
URL_HASH SHA1=b16ad311975378dcc87b11fc02c84eaa1f028b38
OPTIONS
"SDL_SENSOR OFF" # doesn't work with UWP
)
else()
CPMAddPackage(NAME sdl2
URL https://www.libsdl.org/release/SDL2-2.28.4.zip
URL_HASH SHA1=0d9e0da0e935c4f0524cfd16d47d38b6045b9573
CPMAddPackage(NAME sdl3
URL https://www.libsdl.org/release/SDL3-3.1.6.zip
URL_HASH SHA1=b16ad311975378dcc87b11fc02c84eaa1f028b38
OPTIONS
"SDL_ATOMIC OFF"
"SDL_CPUINFO ON"
Expand All @@ -264,10 +264,10 @@ else()
"SDL_TIMERS OFF"
)
endif()
target_link_libraries(jngl PRIVATE SDL2-static)
target_link_libraries(jngl PRIVATE SDL3-static)
if(WINDOWS_STORE)
target_compile_definitions(jngl PUBLIC JNGL_UWP)
target_include_directories(jngl PUBLIC ${sdl2_SOURCE_DIR}/include ${sdl2_BINARY_DIR}/include) # TODO: This should be PRIVATE
target_include_directories(jngl PUBLIC ${sdl3_SOURCE_DIR}/include ${sdl3_BINARY_DIR}/include) # TODO: This should be PRIVATE
target_link_options(jngl PUBLIC $<IF:$<CONFIG:Debug>,/defaultlib:vccorlibd.lib /defaultlib:msvcrtd.lib,/defaultlib:vccorlib.lib /defaultlib:msvcrt.lib>)
endif()
elseif(IOS)
Expand Down Expand Up @@ -309,9 +309,9 @@ else()

find_package(PkgConfig)
if(PkgConfig_FOUND)
pkg_check_modules(SDL2 REQUIRED sdl2)
target_include_directories(jngl PRIVATE ${SDL2_INCLUDE_DIRS})
target_link_libraries(jngl PRIVATE ${SDL2_LINK_LIBRARIES})
pkg_check_modules(SDL3 REQUIRED sdl3)
target_include_directories(jngl PRIVATE ${SDL3_INCLUDE_DIRS})
target_link_libraries(jngl PRIVATE ${SDL3_LINK_LIBRARIES})
if(JNGL_VIDEO)
if(APPLE)
# On macOS we'll build theora from source, since Homebrew's version crashes due
Expand Down
53 changes: 23 additions & 30 deletions src/audio/sdl/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "../Stream.hpp"
#include "../constants.hpp"

#include <SDL.h>
#include <SDL3/SDL.h>

#include <cassert>
#include <vector>
Expand Down Expand Up @@ -78,61 +78,54 @@ struct engine::Impl {
struct SdlImpl : public Backend {
std::shared_ptr<void> sdl_init;

SDL_AudioDeviceID device;
SDL_AudioStream* device = nullptr;

std::vector<float> buffer;

std::shared_ptr<Stream> output;

explicit SdlImpl(std::shared_ptr<Stream> output) : output(std::move(output)) {
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
if (!SDL_Init(SDL_INIT_AUDIO)) {
throw std::runtime_error(SDL_GetError());
}
SDL_AudioSpec desired, obtained;
desired.freq = frequency;
desired.channels = 2;
desired.format = AUDIO_S16SYS;
#ifdef __EMSCRIPTEN__
desired.samples = 2048;
#else
desired.samples = 256;
#endif
desired.callback = &callback;
desired.userdata = this;
if (device = SDL_OpenAudioDevice(nullptr, 0, &desired, &obtained, 0); device == 0) {
SDL_AudioSpec spec;
SDL_zero(spec);
spec.freq = frequency;
spec.channels = 2;
spec.format = SDL_AUDIO_F32;
if (device =
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, &callback, this);
device == 0) {
throw std::runtime_error(SDL_GetError());
}

internal::debug("Initialized audio: {} channels, {} Hz, {} samples",
static_cast<int>(obtained.channels), obtained.freq, obtained.samples);
static_cast<int>(spec.channels), spec.freq, spec.freq);

buffer.resize(obtained.samples * obtained.channels);
SDL_PauseAudioDevice(device, 0);
SDL_ResumeAudioStreamDevice(device);
}
~SdlImpl() override {
SDL_CloseAudioDevice(device);
SDL_DestroyAudioStream(device);
}

static void callback(void* userdata, std::uint8_t* dst_u8, int len) {
static std::string const profiler_str = "audio";
// prof::profiler prof(profiler_str);

static void callback(void* userdata, SDL_AudioStream* stream, int additionalAmount, int totalAmount) {
auto self = static_cast<SdlImpl*>(userdata);
std::int16_t* dst = reinterpret_cast<std::int16_t*>(dst_u8);

std::size_t const size = len / 2;
self->buffer.resize(additionalAmount);
std::size_t const size = additionalAmount;
std::size_t read = 0;
read = self->output->read(self->buffer.data(), size);
std::fill(self->buffer.data() + read, self->buffer.data() + size, 0.f);

for (auto s : self->buffer) {
*dst++ = static_cast<std::int16_t>(
std::max(std::min((65535.f * s - 1.f) / 2.f, 32767.f), -32768.f));
}
SDL_PutAudioStreamData(stream, self->buffer.data(), additionalAmount * sizeof(float));
}

void setPause(bool pause) override {
SDL_PauseAudioDevice(device, pause ? 1 : 0);
if (pause) {
SDL_PauseAudioStreamDevice(device);
} else {
SDL_ResumeAudioStreamDevice(device);
}
}
};
};
Expand Down
Loading

0 comments on commit 5f0e37a

Please sign in to comment.