Update to SDL3 & latest imgui

This commit is contained in:
Luke Street 2025-04-02 19:57:16 -06:00
parent f6d63d7ed5
commit 1b088e79e8
20 changed files with 217 additions and 209 deletions

5
.gitmodules vendored
View File

@ -3,11 +3,12 @@
url = https://github.com/encounter/dawn-cmake.git
[submodule "extern/SDL"]
path = extern/SDL
url = https://github.com/encounter/SDL.git
branch = merged
url = https://github.com/libsdl-org/SDL.git
branch = release-3.2.x
[submodule "extern/imgui"]
path = extern/imgui
url = https://github.com/ocornut/imgui.git
branch = docking
[submodule "extern/fmt"]
path = extern/fmt
url = https://github.com/fmtlib/fmt.git

View File

@ -45,10 +45,10 @@ if (AURORA_NATIVE_MATRIX)
endif ()
target_include_directories(aurora PUBLIC include)
target_include_directories(aurora PRIVATE ../imgui)
if (NOT TARGET SDL2::SDL2-static)
find_package(SDL2 REQUIRED)
if (NOT TARGET SDL3::SDL3-static)
find_package(SDL3 REQUIRED)
endif ()
target_link_libraries(aurora PUBLIC SDL2::SDL2-static fmt::fmt imgui xxhash)
target_link_libraries(aurora PUBLIC SDL3::SDL3-static fmt::fmt imgui xxhash)
if (EMSCRIPTEN)
target_link_options(aurora PUBLIC -sUSE_WEBGPU=1 -sASYNCIFY -sEXIT_RUNTIME)
target_compile_definitions(aurora PRIVATE ENABLE_BACKEND_WEBGPU)
@ -87,7 +87,7 @@ endif ()
add_library(aurora_main STATIC lib/main.cpp)
target_include_directories(aurora_main PUBLIC include)
target_link_libraries(aurora_main PUBLIC SDL2::SDL2-static SDL2::SDL2main)
target_link_libraries(aurora_main PUBLIC SDL3::SDL3-static)
add_library(aurora::main ALIAS aurora_main)
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)

View File

@ -20,13 +20,13 @@ if (NOT EMSCRIPTEN)
endif ()
endif ()
if (NOT TARGET SDL2-static)
if (NOT TARGET SDL3-static)
if (WIN32)
set(SDL_LIBC ON CACHE BOOL "Use the system C library" FORCE)
endif ()
add_subdirectory(SDL EXCLUDE_FROM_ALL)
if (NOT MSVC)
target_compile_options(SDL2-static PRIVATE -Wno-implicit-fallthrough -Wno-shadow)
target_compile_options(SDL3-static PRIVATE -Wno-implicit-fallthrough -Wno-shadow)
endif ()
endif ()
else ()

2
extern/SDL vendored

@ -1 +1 @@
Subproject commit 9b3d146ea1949831d11eaf04c38d167f4efc6549
Subproject commit 976c92a2fb71673445440585a22d4b948286f67f

2
extern/imgui vendored

@ -1 +1 @@
Subproject commit 1d8e48c161370c37628c4f37f3f87cb19fbcb723
Subproject commit 4806a1924ff6181180bf5e4b8b79ab4394118875

View File

@ -3,7 +3,8 @@
#include "aurora.h"
#include <SDL_events.h>
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_joystick.h>
#ifdef __cplusplus
#include <cstdint>
@ -31,7 +32,7 @@ struct AuroraEvent {
SDL_Event sdl;
AuroraWindowPos windowPos;
AuroraWindowSize windowSize;
int32_t controller;
SDL_JoystickID controller;
};
};

View File

@ -7,8 +7,8 @@
#include "webgpu/gpu.hpp"
#include "window.hpp"
#include <SDL.h>
#include <SDL_filesystem.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_filesystem.h>
#include <imgui.h>
namespace aurora {
@ -64,7 +64,7 @@ static AuroraInfo initialize(int argc, char* argv[], const AuroraConfig& config)
if (g_config.maxTextureAnisotropy == 0) {
g_config.maxTextureAnisotropy = 16;
}
window::initialize();
ASSERT(window::initialize(), "Error initializing window");
/* Attempt to create a window using the calling application's desired backend */
AuroraBackend selectedBackend = config.desiredBackend;

View File

@ -1,6 +1,5 @@
#include "BackendBinding.hpp"
#include <SDL_syswm.h>
#include <memory>
#if defined(DAWN_ENABLE_BACKEND_D3D11)
@ -16,7 +15,7 @@
#include <dawn/native/VulkanBackend.h>
#endif
#if defined(DAWN_ENABLE_BACKEND_OPENGL)
#include <SDL_video.h>
#include <SDL3/SDL_video.h>
#include <dawn/native/OpenGLBackend.h>
#endif
#if defined(DAWN_ENABLE_BACKEND_NULL)
@ -36,7 +35,7 @@ void GLMakeCurrent(void* userData) {
}
void GLDestroy(void* userData) {
auto* data = static_cast<GLUserData*>(userData);
SDL_GL_DeleteContext(data->context);
SDL_GL_DestroyContext(data->context);
delete data;
}
#endif
@ -75,7 +74,7 @@ bool DiscoverAdapter(dawn::native::Instance* instance, [[maybe_unused]] SDL_Wind
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
SDL_GLContext context = SDL_GL_CreateContext(window);
dawn::native::opengl::PhysicalDeviceDiscoveryOptions options{WGPUBackendType_OpenGL};
options.getProc = SDL_GL_GetProcAddress;
options.getProc = reinterpret_cast<void* (*)(const char*)>(SDL_GL_GetProcAddress);
options.makeCurrent = GLMakeCurrent;
options.destroy = GLDestroy;
options.userData = new GLUserData{
@ -93,7 +92,7 @@ bool DiscoverAdapter(dawn::native::Instance* instance, [[maybe_unused]] SDL_Wind
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GLContext context = SDL_GL_CreateContext(window);
dawn::native::opengl::PhysicalDeviceDiscoveryOptions options{WGPUBackendType_OpenGLES};
options.getProc = SDL_GL_GetProcAddress;
options.getProc = reinterpret_cast<void* (*)(const char*)>(SDL_GL_GetProcAddress);
options.makeCurrent = GLMakeCurrent;
options.destroy = GLDestroy;
options.userData = new GLUserData{
@ -116,43 +115,36 @@ bool DiscoverAdapter(dawn::native::Instance* instance, [[maybe_unused]] SDL_Wind
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(SDL_Window* window);
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptor(SDL_Window* window) {
#if defined(SDL_VIDEO_DRIVER_COCOA)
#if defined(SDL_PLATFORM_MACOS)
return SetupWindowAndGetSurfaceDescriptorCocoa(window);
#else
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(window, &wmInfo) == SDL_FALSE) {
return nullptr;
}
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
const auto props = SDL_GetWindowProperties(window);
#if defined(SDL_PLATFORM_WIN32)
std::unique_ptr<wgpu::SurfaceDescriptorFromWindowsHWND> desc =
std::make_unique<wgpu::SurfaceDescriptorFromWindowsHWND>();
desc->hwnd = wmInfo.info.win.window;
desc->hinstance = wmInfo.info.win.hinstance;
return std::move(desc);
#elif defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
if (wmInfo.subsystem == SDL_SYSWM_WAYLAND) {
#elif defined(SDL_PLATFORM_LINUX)
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) {
std::unique_ptr<wgpu::SurfaceDescriptorFromWaylandSurface> desc =
std::make_unique<wgpu::SurfaceDescriptorFromWaylandSurface>();
desc->display = wmInfo.info.wl.display;
desc->surface = wmInfo.info.wl.surface;
desc->display =
SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr);
desc->surface =
SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
return std::move(desc);
}
#endif
#if defined(SDL_VIDEO_DRIVER_X11)
if (wmInfo.subsystem == SDL_SYSWM_X11) {
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) {
std::unique_ptr<wgpu::SurfaceDescriptorFromXlibWindow> desc =
std::make_unique<wgpu::SurfaceDescriptorFromXlibWindow>();
desc->display = wmInfo.info.x11.display;
desc->window = wmInfo.info.x11.window;
desc->display =
SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
desc->window = SDL_GetNumberProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
return std::move(desc);
}
#endif
return nullptr;
#else
return nullptr;
#endif
#endif
}

View File

@ -1,6 +1,6 @@
#include "BackendBinding.hpp"
#include <SDL_syswm.h>
#include <SDL3/SDL_syswm.h>
#include <dawn/native/D3D12Backend.h>
namespace aurora::webgpu::utils {

View File

@ -1,6 +1,6 @@
#include "BackendBinding.hpp"
#include <SDL_metal.h>
#include <SDL3/SDL_metal.h>
namespace aurora::webgpu::utils {
std::unique_ptr<wgpu::ChainedStruct> SetupWindowAndGetSurfaceDescriptorCocoa(SDL_Window* window) {

View File

@ -1,6 +1,6 @@
#include "BackendBinding.hpp"
#include <SDL_video.h>
#include <SDL3/SDL_video.h>
#include <dawn/native/OpenGLBackend.h>
namespace aurora::webgpu::utils {

View File

@ -2,7 +2,7 @@
#include "../internal.hpp"
#include <SDL_vulkan.h>
#include <SDL3/SDL_vulkan.h>
#include <dawn/native/VulkanBackend.h>
namespace aurora::webgpu::utils {

View File

@ -4,11 +4,11 @@
#include "internal.hpp"
#include "window.hpp"
#include <SDL.h>
#include <SDL3/SDL.h>
#include <webgpu/webgpu.h>
#include "../imgui/backends/imgui_impl_sdl2.cpp" // NOLINT(bugprone-suspicious-include)
#include "../imgui/backends/imgui_impl_sdlrenderer2.cpp" // NOLINT(bugprone-suspicious-include)
#include "../imgui/backends/imgui_impl_sdl3.cpp" // NOLINT(bugprone-suspicious-include)
#include "../imgui/backends/imgui_impl_sdlrenderer3.cpp" // NOLINT(bugprone-suspicious-include)
// #include "../imgui/backends/imgui_impl_wgpu.cpp" // NOLINT(bugprone-suspicious-include)
// TODO: Transition back to imgui-provided backend when it uses WGSL
#include "imgui_impl_wgpu.cpp" // NOLINT(bugprone-suspicious-include)
@ -34,14 +34,14 @@ void create_context() noexcept {
void initialize() noexcept {
SDL_Renderer* renderer = window::get_sdl_renderer();
ImGui_ImplSDL2_Init(window::get_sdl_window(), renderer, NULL);
ImGui_ImplSDL3_Init(window::get_sdl_window(), renderer, NULL);
#ifdef __APPLE__
// Disable MouseCanUseGlobalState for scaling purposes
ImGui_ImplSDL2_GetBackendData()->MouseCanUseGlobalState = false;
#endif
g_useSdlRenderer = renderer != nullptr;
if (g_useSdlRenderer) {
ImGui_ImplSDLRenderer2_Init(renderer);
ImGui_ImplSDLRenderer3_Init(renderer);
} else {
const auto format = webgpu::g_graphicsConfig.swapChainDescriptor.format;
ImGui_ImplWGPU_Init(webgpu::g_device.Get(), 1, static_cast<WGPUTextureFormat>(format));
@ -50,11 +50,11 @@ void initialize() noexcept {
void shutdown() noexcept {
if (g_useSdlRenderer) {
ImGui_ImplSDLRenderer2_Shutdown();
ImGui_ImplSDLRenderer3_Shutdown();
} else {
ImGui_ImplWGPU_Shutdown();
}
ImGui_ImplSDL2_Shutdown();
ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext();
for (const auto& texture : g_sdlTextures) {
SDL_DestroyTexture(texture);
@ -72,12 +72,12 @@ void process_event(const SDL_Event& event) noexcept {
return;
}
#endif
ImGui_ImplSDL2_ProcessEvent(&event);
ImGui_ImplSDL3_ProcessEvent(&event);
}
void new_frame(const AuroraWindowSize& size) noexcept {
if (g_useSdlRenderer) {
ImGui_ImplSDLRenderer2_NewFrame();
ImGui_ImplSDLRenderer3_NewFrame();
g_scale = size.scale;
} else {
if (g_scale != size.scale) {
@ -90,7 +90,7 @@ void new_frame(const AuroraWindowSize& size) noexcept {
}
ImGui_ImplWGPU_NewFrame();
}
ImGui_ImplSDL2_NewFrame();
ImGui_ImplSDL3_NewFrame();
// Render at full DPI
ImGui::GetIO().DisplaySize = {
@ -107,9 +107,9 @@ void render(const wgpu::RenderPassEncoder& pass) noexcept {
// io.DisplayFramebufferScale is informational; we're rendering at full DPI
data->FramebufferScale = {1.f, 1.f};
if (g_useSdlRenderer) {
SDL_Renderer* renderer = ImGui_ImplSDLRenderer2_GetBackendData()->SDLRenderer;
SDL_Renderer* renderer = ImGui_ImplSDLRenderer3_GetBackendData()->Renderer;
SDL_RenderClear(renderer);
ImGui_ImplSDLRenderer2_RenderDrawData(data);
ImGui_ImplSDLRenderer3_RenderDrawData(data, renderer);
SDL_RenderPresent(renderer);
} else {
ImGui_ImplWGPU_RenderDrawData(data, pass.Get());
@ -118,12 +118,12 @@ void render(const wgpu::RenderPassEncoder& pass) noexcept {
ImTextureID add_texture(uint32_t width, uint32_t height, const uint8_t* data) noexcept {
if (g_useSdlRenderer) {
SDL_Renderer* renderer = ImGui_ImplSDLRenderer2_GetBackendData()->SDLRenderer;
SDL_Renderer* renderer = ImGui_ImplSDLRenderer3_GetBackendData()->Renderer;
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
SDL_UpdateTexture(texture, nullptr, data, width * 4);
SDL_SetTextureScaleMode(texture, SDL_ScaleModeLinear);
SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_LINEAR);
g_sdlTextures.push_back(texture);
return texture;
return reinterpret_cast<ImTextureID>(texture);
}
const wgpu::Extent3D size{
.width = width,
@ -159,7 +159,7 @@ ImTextureID add_texture(uint32_t width, uint32_t height, const uint8_t* data) no
webgpu::g_queue.WriteTexture(&dstView, data, width * height * 4, &dataLayout, &size);
}
g_wgpuTextures.push_back(texture);
return textureView.Release();
return reinterpret_cast<ImTextureID>(textureView.Release());
}
} // namespace aurora::imgui

View File

@ -579,7 +579,7 @@ void ImGui_ImplWGPU_InvalidateDeviceObjects()
SafeRelease(g_resources);
ImGuiIO& io = ImGui::GetIO();
io.Fonts->SetTexID(nullptr); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
io.Fonts->SetTexID(0); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
for (unsigned int i = 0; i < g_numFramesInFlight; i++)
SafeRelease(g_pFrameResources[i]);

View File

@ -6,9 +6,9 @@
#include <dolphin/pad.h>
#include <dolphin/si.h>
#include <SDL_haptic.h>
#include <SDL_version.h>
#include <SDL.h>
#include <SDL3/SDL_haptic.h>
#include <SDL3/SDL_version.h>
#include <SDL3/SDL.h>
#include <absl/container/btree_map.h>
#include <absl/container/flat_hash_map.h>
@ -21,7 +21,7 @@ namespace aurora::input {
static Module Log("aurora::input");
struct GameController {
SDL_GameController* m_controller = nullptr;
SDL_Gamepad* m_controller = nullptr;
bool m_isGameCube = false;
Sint32 m_index = -1;
bool m_hasRumble = false;
@ -130,16 +130,16 @@ static std::optional<std::string> remap_controller_layout(std::string mapping) {
return newMapping;
}
Sint32 add_controller(Sint32 which) noexcept {
auto* ctrl = SDL_GameControllerOpen(which);
SDL_JoystickID add_controller(SDL_JoystickID which) noexcept {
auto* ctrl = SDL_OpenGamepad(which);
if (ctrl != nullptr) {
{
char* mapping = SDL_GameControllerMapping(ctrl);
char* mapping = SDL_GetGamepadMapping(ctrl);
if (mapping != nullptr) {
auto newMapping = remap_controller_layout(mapping);
SDL_free(mapping);
if (newMapping) {
if (SDL_GameControllerAddMapping(newMapping->c_str()) == -1) {
if (SDL_AddGamepadMapping(newMapping->c_str()) == -1) {
Log.report(LOG_ERROR, FMT_STRING("Failed to update controller mapping: {}"), SDL_GetError());
}
}
@ -150,20 +150,17 @@ Sint32 add_controller(Sint32 which) noexcept {
GameController controller;
controller.m_controller = ctrl;
controller.m_index = which;
controller.m_vid = SDL_GameControllerGetVendor(ctrl);
controller.m_pid = SDL_GameControllerGetProduct(ctrl);
controller.m_vid = SDL_GetGamepadVendor(ctrl);
controller.m_pid = SDL_GetGamepadProduct(ctrl);
if (controller.m_vid == 0x05ac /* USB_VENDOR_APPLE */ && controller.m_pid == 3) {
// Ignore Apple TV remote
SDL_GameControllerClose(ctrl);
SDL_CloseGamepad(ctrl);
return -1;
}
controller.m_isGameCube = controller.m_vid == 0x057E && controller.m_pid == 0x0337;
#if SDL_VERSION_ATLEAST(2, 0, 18)
controller.m_hasRumble = (SDL_GameControllerHasRumble(ctrl) != 0u);
#else
controller.m_hasRumble = true;
#endif
Sint32 instance = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ctrl));
const auto props = SDL_GetGamepadProperties(ctrl);
controller.m_hasRumble = SDL_GetBooleanProperty(props, SDL_PROP_GAMEPAD_CAP_RUMBLE_BOOLEAN, true);
SDL_JoystickID instance = SDL_GetJoystickID(SDL_GetGamepadJoystick(ctrl));
g_GameControllers[instance] = controller;
return instance;
}
@ -173,7 +170,7 @@ Sint32 add_controller(Sint32 which) noexcept {
void remove_controller(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
SDL_GameControllerClose(g_GameControllers[instance].m_controller);
SDL_CloseGamepad(g_GameControllers[instance].m_controller);
g_GameControllers.erase(instance);
}
}
@ -187,20 +184,20 @@ bool is_gamecube(Uint32 instance) noexcept {
int32_t player_index(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
return SDL_GameControllerGetPlayerIndex(g_GameControllers[instance].m_controller);
return SDL_GetGamepadPlayerIndex(g_GameControllers[instance].m_controller);
}
return -1;
}
void set_player_index(Uint32 instance, Sint32 index) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
SDL_GameControllerSetPlayerIndex(g_GameControllers[instance].m_controller, index);
SDL_SetGamepadPlayerIndex(g_GameControllers[instance].m_controller, index);
}
}
std::string controller_name(Uint32 instance) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
const auto* name = SDL_GameControllerName(g_GameControllers[instance].m_controller);
const auto* name = SDL_GetGamepadName(g_GameControllers[instance].m_controller);
if (name != nullptr) {
return {name};
}
@ -220,8 +217,7 @@ void controller_rumble(uint32_t instance, uint16_t low_freq_intensity, uint16_t
uint16_t duration_ms) noexcept {
if (g_GameControllers.find(instance) != g_GameControllers.end()) {
SDL_GameControllerRumble(g_GameControllers[instance].m_controller, low_freq_intensity, high_freq_intensity,
duration_ms);
SDL_RumbleGamepad(g_GameControllers[instance].m_controller, low_freq_intensity, high_freq_intensity, duration_ms);
}
}
@ -230,23 +226,24 @@ uint32_t controller_count() noexcept { return g_GameControllers.size(); }
void initialize() noexcept {
/* Make sure we initialize everything input related now, this will automatically add all of the connected controllers
* as expected */
SDL_Init(SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
ASSERT(SDL_Init(SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD), "Failed to initialize SDL subsystems: {}",
SDL_GetError());
}
} // namespace aurora::input
static const std::array<PADButtonMapping, 12> mDefaultButtons{{
{SDL_CONTROLLER_BUTTON_A, PAD_BUTTON_A},
{SDL_CONTROLLER_BUTTON_B, PAD_BUTTON_B},
{SDL_CONTROLLER_BUTTON_X, PAD_BUTTON_X},
{SDL_CONTROLLER_BUTTON_Y, PAD_BUTTON_Y},
{SDL_CONTROLLER_BUTTON_START, PAD_BUTTON_START},
{SDL_CONTROLLER_BUTTON_BACK, PAD_TRIGGER_Z},
{SDL_CONTROLLER_BUTTON_LEFTSHOULDER, PAD_TRIGGER_L},
{SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, PAD_TRIGGER_R},
{SDL_CONTROLLER_BUTTON_DPAD_UP, PAD_BUTTON_UP},
{SDL_CONTROLLER_BUTTON_DPAD_DOWN, PAD_BUTTON_DOWN},
{SDL_CONTROLLER_BUTTON_DPAD_LEFT, PAD_BUTTON_LEFT},
{SDL_CONTROLLER_BUTTON_DPAD_RIGHT, PAD_BUTTON_RIGHT},
{SDL_GAMEPAD_BUTTON_SOUTH, PAD_BUTTON_A},
{SDL_GAMEPAD_BUTTON_EAST, PAD_BUTTON_B},
{SDL_GAMEPAD_BUTTON_WEST, PAD_BUTTON_X},
{SDL_GAMEPAD_BUTTON_NORTH, PAD_BUTTON_Y},
{SDL_GAMEPAD_BUTTON_START, PAD_BUTTON_START},
{SDL_GAMEPAD_BUTTON_BACK, PAD_TRIGGER_Z},
{SDL_GAMEPAD_BUTTON_LEFT_SHOULDER, PAD_TRIGGER_L},
{SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER, PAD_TRIGGER_R},
{SDL_GAMEPAD_BUTTON_DPAD_UP, PAD_BUTTON_UP},
{SDL_GAMEPAD_BUTTON_DPAD_DOWN, PAD_BUTTON_DOWN},
{SDL_GAMEPAD_BUTTON_DPAD_LEFT, PAD_BUTTON_LEFT},
{SDL_GAMEPAD_BUTTON_DPAD_RIGHT, PAD_BUTTON_RIGHT},
}};
void PADSetSpec(u32 spec) {}
@ -281,7 +278,7 @@ const char* PADGetNameForControllerIndex(uint32_t idx) {
return nullptr;
}
return SDL_GameControllerName(ctrl->m_controller);
return SDL_GetGamepadName(ctrl->m_controller);
}
void PADSetPortForIndex(uint32_t idx, int32_t port) {
@ -291,9 +288,9 @@ void PADSetPortForIndex(uint32_t idx, int32_t port) {
return;
}
if (dest != nullptr) {
SDL_GameControllerSetPlayerIndex(dest->m_controller, -1);
SDL_SetGamepadPlayerIndex(dest->m_controller, -1);
}
SDL_GameControllerSetPlayerIndex(ctrl->m_controller, port);
SDL_SetGamepadPlayerIndex(ctrl->m_controller, port);
}
int32_t PADGetIndexForPort(uint32_t port) {
@ -317,11 +314,11 @@ void PADClearPort(uint32_t port) {
if (ctrl == nullptr) {
return;
}
SDL_GameControllerSetPlayerIndex(ctrl->m_controller, -1);
SDL_SetGamepadPlayerIndex(ctrl->m_controller, -1);
}
void __PADLoadMapping(aurora::input::GameController* controller) {
int32_t playerIndex = SDL_GameControllerGetPlayerIndex(controller->m_controller);
int32_t playerIndex = SDL_GetGamepadPlayerIndex(controller->m_controller);
if (playerIndex == -1) {
return;
}
@ -386,16 +383,15 @@ uint32_t PADRead(PADStatus* status) {
__PADLoadMapping(controller);
}
status[i].err = PAD_ERR_NONE;
std::for_each(controller->m_mapping.begin(), controller->m_mapping.end(),
[&controller, &i, &status](const auto& mapping) {
if (SDL_GameControllerGetButton(controller->m_controller,
static_cast<SDL_GameControllerButton>(mapping.nativeButton))) {
std::for_each(
controller->m_mapping.begin(), controller->m_mapping.end(), [&controller, &i, &status](const auto& mapping) {
if (SDL_GetGamepadButton(controller->m_controller, static_cast<SDL_GamepadButton>(mapping.nativeButton))) {
status[i].button |= mapping.padButton;
}
});
Sint16 x = SDL_GameControllerGetAxis(controller->m_controller, SDL_CONTROLLER_AXIS_LEFTX);
Sint16 y = SDL_GameControllerGetAxis(controller->m_controller, SDL_CONTROLLER_AXIS_LEFTY);
Sint16 x = SDL_GetGamepadAxis(controller->m_controller, SDL_GAMEPAD_AXIS_LEFTX);
Sint16 y = SDL_GetGamepadAxis(controller->m_controller, SDL_GAMEPAD_AXIS_LEFTY);
if (controller->m_deadZones.useDeadzones) {
if (std::abs(x) > controller->m_deadZones.stickDeadZone) {
x /= 256;
@ -415,8 +411,8 @@ uint32_t PADRead(PADStatus* status) {
status[i].stickX = static_cast<int8_t>(x);
status[i].stickY = static_cast<int8_t>(y);
x = SDL_GameControllerGetAxis(controller->m_controller, SDL_CONTROLLER_AXIS_RIGHTX);
y = SDL_GameControllerGetAxis(controller->m_controller, SDL_CONTROLLER_AXIS_RIGHTY);
x = SDL_GetGamepadAxis(controller->m_controller, SDL_GAMEPAD_AXIS_RIGHTX);
y = SDL_GetGamepadAxis(controller->m_controller, SDL_GAMEPAD_AXIS_RIGHTY);
if (controller->m_deadZones.useDeadzones) {
if (std::abs(x) > controller->m_deadZones.substickDeadZone) {
x /= 256;
@ -437,8 +433,8 @@ uint32_t PADRead(PADStatus* status) {
status[i].substickX = static_cast<int8_t>(x);
status[i].substickY = static_cast<int8_t>(y);
x = SDL_GameControllerGetAxis(controller->m_controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
y = SDL_GameControllerGetAxis(controller->m_controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
x = SDL_GetGamepadAxis(controller->m_controller, SDL_GAMEPAD_AXIS_LEFT_TRIGGER);
y = SDL_GetGamepadAxis(controller->m_controller, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER);
if (/*!controller->m_isGameCube && */ controller->m_deadZones.emulateTriggers) {
if (x > controller->m_deadZones.leftTriggerActivationZone) {
status[i].button |= PAD_TRIGGER_L;
@ -495,8 +491,8 @@ uint32_t SIProbe(int32_t chan) {
}
if (controller->m_isGameCube) {
auto level = SDL_JoystickCurrentPowerLevel(SDL_GameControllerGetJoystick(controller->m_controller));
if (level == SDL_JOYSTICK_POWER_UNKNOWN) {
auto level = SDL_GetJoystickPowerInfo(SDL_GetGamepadJoystick(controller->m_controller), nullptr);
if (level == SDL_POWERSTATE_UNKNOWN) {
return SI_GC_WAVEBIRD;
}
}
@ -678,7 +674,7 @@ const char* PADGetName(uint32_t port) {
return nullptr;
}
return SDL_GameControllerName(controller->m_controller);
return SDL_GetGamepadName(controller->m_controller);
}
void PADSetButtonMapping(uint32_t port, PADButtonMapping mapping) {
@ -800,7 +796,7 @@ const char* PADGetButtonName(PADButton button) {
}
const char* PADGetNativeButtonName(uint32_t button) {
return SDL_GameControllerGetStringForButton(static_cast<SDL_GameControllerButton>(button));
return SDL_GetGamepadStringForButton(static_cast<SDL_GamepadButton>(button));
}
int32_t PADGetNativeButtonPressed(uint32_t port) {
@ -809,8 +805,8 @@ int32_t PADGetNativeButtonPressed(uint32_t port) {
return -1;
}
for (uint32_t i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) {
if (SDL_GameControllerGetButton(controller->m_controller, static_cast<SDL_GameControllerButton>(i)) != 0u) {
for (uint32_t i = 0; i < SDL_GAMEPAD_BUTTON_COUNT; ++i) {
if (SDL_GetGamepadButton(controller->m_controller, static_cast<SDL_GamepadButton>(i)) != 0u) {
return i;
}
}

View File

@ -2,14 +2,14 @@
#include <string>
#include "SDL_gamecontroller.h"
#include "SDL_keyboard.h"
#include "SDL_keycode.h"
#include "SDL_mouse.h"
#include "SDL3/SDL_gamepad.h"
#include "SDL3/SDL_keyboard.h"
#include "SDL3/SDL_keycode.h"
#include "SDL3/SDL_mouse.h"
namespace aurora::input {
Sint32 get_instance_for_player(uint32_t player) noexcept;
Sint32 add_controller(Sint32 which) noexcept;
SDL_JoystickID add_controller(SDL_JoystickID which) noexcept;
void remove_controller(Uint32 instance) noexcept;
Sint32 player_index(Uint32 instance) noexcept;
void set_player_index(Uint32 instance, Sint32 index) noexcept;

View File

@ -12,7 +12,8 @@ using namespace std::string_view_literals;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#ifndef SBIG
#define SBIG(q) (((q)&0x000000FF) << 24 | ((q)&0x0000FF00) << 8 | ((q)&0x00FF0000) >> 8 | ((q)&0xFF000000) >> 24)
#define SBIG(q) \
(((q) & 0x000000FF) << 24 | ((q) & 0x0000FF00) << 8 | ((q) & 0x00FF0000) >> 8 | ((q) & 0xFF000000) >> 24)
#endif
#else
#ifndef SBIG
@ -29,7 +30,7 @@ using namespace std::string_view_literals;
#endif
#ifndef ALIGN
#define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1))
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#endif
#if !defined(__has_cpp_attribute)
@ -53,7 +54,16 @@ using namespace std::string_view_literals;
#else
#define CHECK(cond, msg, ...) ASSERT(cond, msg, ##__VA_ARGS__)
#endif
#define DEFAULT_FATAL(msg, ...) UNLIKELY default: FATAL(msg, ##__VA_ARGS__)
#define DEFAULT_FATAL(msg, ...) UNLIKELY default : FATAL(msg, ##__VA_ARGS__)
#define TRY(cond, msg, ...) \
if (!(cond)) \
UNLIKELY { \
Log.report(LOG_ERROR, FMT_STRING(msg), ##__VA_ARGS__); \
return false; \
}
#define TRY_WARN(cond, msg, ...) \
if (!(cond)) \
UNLIKELY { Log.report(LOG_WARNING, FMT_STRING(msg), ##__VA_ARGS__); }
namespace aurora {
extern AuroraConfig g_config;

View File

@ -1,6 +1,6 @@
#include <aurora/main.h>
#undef main
#include <SDL_main.h>
#include <SDL3/SDL_main.h>
int main(int argc, char** argv) { return aurora_main(argc, argv); }

View File

@ -5,7 +5,7 @@
#include "../window.hpp"
#include "../internal.hpp"
#include <SDL.h>
#include <SDL3/SDL.h>
#include <magic_enum.hpp>
#include <memory>
#include <algorithm>

View File

@ -6,7 +6,7 @@
#include "internal.hpp"
#include <aurora/event.h>
#include <SDL.h>
#include <SDL3/SDL.h>
namespace aurora::window {
static Module Log("aurora::window");
@ -43,30 +43,28 @@ const AuroraEvent* poll_events() {
imgui::process_event(event);
switch (event.type) {
case SDL_WINDOWEVENT: {
switch (event.window.event) {
case SDL_WINDOWEVENT_MINIMIZED: {
case SDL_EVENT_WINDOW_MINIMIZED: {
// Android/iOS: Application backgrounded
g_events.push_back(AuroraEvent{
.type = AURORA_PAUSED,
});
break;
}
case SDL_WINDOWEVENT_RESTORED: {
case SDL_EVENT_WINDOW_RESTORED: {
// Android/iOS: Application focused
g_events.push_back(AuroraEvent{
.type = AURORA_UNPAUSED,
});
break;
}
case SDL_WINDOWEVENT_MOVED: {
case SDL_EVENT_WINDOW_MOVED: {
g_events.push_back(AuroraEvent{
.type = AURORA_WINDOW_MOVED,
.windowPos = {.x = event.window.data1, .y = event.window.data2},
});
break;
}
case SDL_WINDOWEVENT_SIZE_CHANGED: {
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: {
resize_swapchain(false);
g_events.push_back(AuroraEvent{
.type = AURORA_WINDOW_RESIZED,
@ -74,26 +72,23 @@ const AuroraEvent* poll_events() {
});
break;
}
}
break;
}
case SDL_CONTROLLERDEVICEADDED: {
auto instance = input::add_controller(event.cdevice.which);
case SDL_EVENT_GAMEPAD_ADDED: {
auto instance = input::add_controller(event.gdevice.which);
g_events.push_back(AuroraEvent{
.type = AURORA_CONTROLLER_ADDED,
.controller = instance,
});
break;
}
case SDL_CONTROLLERDEVICEREMOVED: {
input::remove_controller(event.cdevice.which);
case SDL_EVENT_GAMEPAD_REMOVED: {
input::remove_controller(event.gdevice.which);
g_events.push_back(AuroraEvent{
.type = AURORA_CONTROLLER_REMOVED,
.controller = event.cdevice.which,
.controller = event.gdevice.which,
});
break;
}
case SDL_QUIT:
case SDL_EVENT_QUIT:
g_events.push_back(AuroraEvent{
.type = AURORA_EXIT,
});
@ -114,15 +109,17 @@ static void set_window_icon() noexcept {
if (g_config.iconRGBA8 == nullptr) {
return;
}
auto* iconSurface = SDL_CreateRGBSurfaceFrom(g_config.iconRGBA8, g_config.iconWidth, g_config.iconHeight, 32,
4 * g_config.iconWidth, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
auto* iconSurface =
SDL_CreateSurfaceFrom(g_config.iconWidth, g_config.iconHeight,
SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
g_config.iconRGBA8, 4 * g_config.iconWidth);
ASSERT(iconSurface != nullptr, "Failed to create icon surface: {}", SDL_GetError());
SDL_SetWindowIcon(g_window, iconSurface);
SDL_FreeSurface(iconSurface);
TRY_WARN(SDL_SetWindowIcon(g_window, iconSurface), "Failed to set window icon: {}", SDL_GetError());
SDL_DestroySurface(iconSurface);
}
bool create_window(AuroraBackend backend) {
Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI;
Uint32 flags = SDL_WINDOW_HIGH_PIXEL_DENSITY;
#if TARGET_OS_IOS || TARGET_OS_TV
flags |= SDL_WINDOW_FULLSCREEN;
#else
@ -170,9 +167,22 @@ bool create_window(AuroraBackend backend) {
}
#endif
g_window = SDL_CreateWindow(g_config.appName, x, y, width, height, flags);
const auto props = SDL_CreateProperties();
TRY(SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, g_config.appName), "Failed to set {}: {}",
SDL_PROP_WINDOW_CREATE_TITLE_STRING, SDL_GetError());
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x), "Failed to set {}: {}",
SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_GetError());
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y), "Failed to set {}: {}",
SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_GetError());
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width), "Failed to set {}: {}",
SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, SDL_GetError());
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height), "Failed to set {}: {}",
SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, SDL_GetError());
TRY(SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, flags), "Failed to set {}: {}",
SDL_PROP_WINDOW_CREATE_FLAGS_NUMBER, SDL_GetError());
g_window = SDL_CreateWindowWithProperties(props);
if (g_window == nullptr) {
Log.report(LOG_WARNING, FMT_STRING("Failed to create window: {}"), SDL_GetError());
Log.report(LOG_ERROR, FMT_STRING("Failed to create window: {}"), SDL_GetError());
return false;
}
set_window_icon();
@ -183,13 +193,17 @@ bool create_renderer() {
if (g_window == nullptr) {
return false;
}
const auto flags = SDL_RENDERER_PRESENTVSYNC;
g_renderer = SDL_CreateRenderer(g_window, -1, flags | SDL_RENDERER_ACCELERATED);
const auto props = SDL_CreateProperties();
TRY(SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, g_window), "Failed to set {}: {}",
SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, SDL_GetError());
TRY(SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, SDL_RENDERER_VSYNC_ADAPTIVE),
"Failed to set {}: {}", SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, SDL_GetError());
g_renderer = SDL_CreateRendererWithProperties(props);
if (g_renderer == nullptr) {
// Attempt fallback to SW renderer
g_renderer = SDL_CreateRenderer(g_window, -1, flags);
Log.report(LOG_ERROR, FMT_STRING("Failed to create renderer: {}"), SDL_GetError());
return false;
}
return g_renderer != nullptr;
return true;
}
void destroy_window() {
@ -205,28 +219,27 @@ void destroy_window() {
void show_window() {
if (g_window != nullptr) {
SDL_ShowWindow(g_window);
TRY_WARN(SDL_ShowWindow(g_window), "Failed to show window: {}", SDL_GetError());
}
}
bool initialize() {
/* We don't want to initialize anything input related here, otherwise the add events will get lost to the void */
ASSERT(SDL_Init(SDL_INIT_EVERYTHING & ~(SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER)) == 0,
"Error initializing SDL: {}", SDL_GetError());
TRY(SDL_InitSubSystem(SDL_INIT_EVENTS | SDL_INIT_VIDEO), "Error initializing SDL: {}", SDL_GetError());
#if !defined(_WIN32) && !defined(__APPLE__)
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
#endif
#if SDL_VERSION_ATLEAST(2, 0, 18)
SDL_SetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME, g_config.appName);
#endif
#ifdef SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE
SDL_SetHint(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE, "1");
TRY(SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"), "Error setting {}: {}",
SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, SDL_GetError());
#endif
TRY(SDL_SetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME, g_config.appName), "Error setting {}: {}",
SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME, SDL_GetError());
TRY(SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE, "1"), "Error setting {}: {}",
SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE_RUMBLE_BRAKE, SDL_GetError());
SDL_DisableScreenSaver();
TRY(SDL_DisableScreenSaver(), "Error disabling screensaver: {}", SDL_GetError());
if (g_config.allowJoystickBackgroundEvents) {
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
TRY(SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"), "Error setting {}: {}",
SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, SDL_GetError());
}
return true;
@ -234,24 +247,15 @@ bool initialize() {
void shutdown() {
destroy_window();
SDL_EnableScreenSaver();
TRY_WARN(SDL_EnableScreenSaver(), "Error enabling screensaver: {}", SDL_GetError());
SDL_Quit();
}
AuroraWindowSize get_window_size() {
int width, height, fb_w, fb_h;
SDL_GetWindowSize(g_window, &width, &height);
#if DAWN_ENABLE_BACKEND_METAL
SDL_Metal_GetDrawableSize(g_window, &fb_w, &fb_h);
#else
SDL_GL_GetDrawableSize(g_window, &fb_w, &fb_h);
#endif
float scale = static_cast<float>(fb_w) / static_cast<float>(width);
#ifndef __APPLE__
if (SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(g_window), nullptr, &scale, nullptr) == 0) {
scale /= 96.f;
}
#endif
ASSERT(SDL_GetWindowSize(g_window, &width, &height), "Failed to get window size: {}", SDL_GetError());
ASSERT(SDL_GetWindowSizeInPixels(g_window, &fb_w, &fb_h), "Failed to get window size in pixels: {}", SDL_GetError());
float scale = SDL_GetWindowDisplayScale(g_window);
return {
.width = static_cast<uint32_t>(width),
.height = static_cast<uint32_t>(height),
@ -265,9 +269,13 @@ SDL_Window* get_sdl_window() { return g_window; }
SDL_Renderer* get_sdl_renderer() { return g_renderer; }
void set_title(const char* title) { SDL_SetWindowTitle(g_window, title); }
void set_title(const char* title) {
TRY_WARN(SDL_SetWindowTitle(g_window, title), "Failed to set window title: {}", SDL_GetError());
}
void set_fullscreen(bool fullscreen) { SDL_SetWindowFullscreen(g_window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0); }
void set_fullscreen(bool fullscreen) {
TRY_WARN(SDL_SetWindowFullscreen(g_window, fullscreen), "Failed to set window fullscreen: {}", SDL_GetError());
}
bool get_fullscreen() { return (SDL_GetWindowFlags(g_window) & SDL_WINDOW_FULLSCREEN) != 0u; }