diff --git a/.gitmodules b/.gitmodules index 5ca641c..ceda66e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index a3e22e4..7dde9a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 5d2288b..a064947 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -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 () diff --git a/extern/SDL b/extern/SDL index 9b3d146..976c92a 160000 --- a/extern/SDL +++ b/extern/SDL @@ -1 +1 @@ -Subproject commit 9b3d146ea1949831d11eaf04c38d167f4efc6549 +Subproject commit 976c92a2fb71673445440585a22d4b948286f67f diff --git a/extern/imgui b/extern/imgui index 1d8e48c..4806a19 160000 --- a/extern/imgui +++ b/extern/imgui @@ -1 +1 @@ -Subproject commit 1d8e48c161370c37628c4f37f3f87cb19fbcb723 +Subproject commit 4806a1924ff6181180bf5e4b8b79ab4394118875 diff --git a/include/aurora/event.h b/include/aurora/event.h index 3af13f0..e2652f1 100644 --- a/include/aurora/event.h +++ b/include/aurora/event.h @@ -3,7 +3,8 @@ #include "aurora.h" -#include +#include +#include #ifdef __cplusplus #include @@ -31,7 +32,7 @@ struct AuroraEvent { SDL_Event sdl; AuroraWindowPos windowPos; AuroraWindowSize windowSize; - int32_t controller; + SDL_JoystickID controller; }; }; diff --git a/lib/aurora.cpp b/lib/aurora.cpp index 013264d..103a2a5 100644 --- a/lib/aurora.cpp +++ b/lib/aurora.cpp @@ -7,8 +7,8 @@ #include "webgpu/gpu.hpp" #include "window.hpp" -#include -#include +#include +#include #include 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; diff --git a/lib/dawn/BackendBinding.cpp b/lib/dawn/BackendBinding.cpp index d3f5f3d..1e1aa35 100644 --- a/lib/dawn/BackendBinding.cpp +++ b/lib/dawn/BackendBinding.cpp @@ -1,6 +1,5 @@ #include "BackendBinding.hpp" -#include #include #if defined(DAWN_ENABLE_BACKEND_D3D11) @@ -16,7 +15,7 @@ #include #endif #if defined(DAWN_ENABLE_BACKEND_OPENGL) -#include +#include #include #endif #if defined(DAWN_ENABLE_BACKEND_NULL) @@ -36,7 +35,7 @@ void GLMakeCurrent(void* userData) { } void GLDestroy(void* userData) { auto* data = static_cast(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(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(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 SetupWindowAndGetSurfaceDescriptorCocoa(SDL_Window* window); std::unique_ptr 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 desc = std::make_unique(); 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 desc = std::make_unique(); - 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 desc = std::make_unique(); - 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 } diff --git a/lib/dawn/D3D12Binding.cpp b/lib/dawn/D3D12Binding.cpp index dbd2af4..8fd3ff0 100644 --- a/lib/dawn/D3D12Binding.cpp +++ b/lib/dawn/D3D12Binding.cpp @@ -1,6 +1,6 @@ #include "BackendBinding.hpp" -#include +#include #include namespace aurora::webgpu::utils { diff --git a/lib/dawn/MetalBinding.mm b/lib/dawn/MetalBinding.mm index d2b4787..380dccb 100644 --- a/lib/dawn/MetalBinding.mm +++ b/lib/dawn/MetalBinding.mm @@ -1,6 +1,6 @@ #include "BackendBinding.hpp" -#include +#include namespace aurora::webgpu::utils { std::unique_ptr SetupWindowAndGetSurfaceDescriptorCocoa(SDL_Window* window) { diff --git a/lib/dawn/OpenGLBinding.cpp b/lib/dawn/OpenGLBinding.cpp index 5e0e7ed..7a5974d 100644 --- a/lib/dawn/OpenGLBinding.cpp +++ b/lib/dawn/OpenGLBinding.cpp @@ -1,6 +1,6 @@ #include "BackendBinding.hpp" -#include +#include #include namespace aurora::webgpu::utils { diff --git a/lib/dawn/VulkanBinding.cpp b/lib/dawn/VulkanBinding.cpp index d37d96a..b4173ee 100644 --- a/lib/dawn/VulkanBinding.cpp +++ b/lib/dawn/VulkanBinding.cpp @@ -2,7 +2,7 @@ #include "../internal.hpp" -#include +#include #include namespace aurora::webgpu::utils { diff --git a/lib/imgui.cpp b/lib/imgui.cpp index ab78631..c61f9c8 100644 --- a/lib/imgui.cpp +++ b/lib/imgui.cpp @@ -4,11 +4,11 @@ #include "internal.hpp" #include "window.hpp" -#include +#include #include -#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(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(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(textureView.Release()); } } // namespace aurora::imgui diff --git a/lib/imgui_impl_wgpu.cpp b/lib/imgui_impl_wgpu.cpp index d5745c2..77ccbd3 100644 --- a/lib/imgui_impl_wgpu.cpp +++ b/lib/imgui_impl_wgpu.cpp @@ -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]); diff --git a/lib/input.cpp b/lib/input.cpp index 286b074..b303083 100644 --- a/lib/input.cpp +++ b/lib/input.cpp @@ -6,9 +6,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -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 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 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(mapping.nativeButton))) { - status[i].button |= mapping.padButton; - } - }); + 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(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(x); status[i].stickY = static_cast(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(x); status[i].substickY = static_cast(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(button)); + return SDL_GetGamepadStringForButton(static_cast(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(i)) != 0u) { + for (uint32_t i = 0; i < SDL_GAMEPAD_BUTTON_COUNT; ++i) { + if (SDL_GetGamepadButton(controller->m_controller, static_cast(i)) != 0u) { return i; } } diff --git a/lib/input.hpp b/lib/input.hpp index 5e92faf..9099c7d 100644 --- a/lib/input.hpp +++ b/lib/input.hpp @@ -2,14 +2,14 @@ #include -#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; diff --git a/lib/internal.hpp b/lib/internal.hpp index b54d7a7..9256938 100644 --- a/lib/internal.hpp +++ b/lib/internal.hpp @@ -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; diff --git a/lib/main.cpp b/lib/main.cpp index 8dc1871..8a7fbee 100644 --- a/lib/main.cpp +++ b/lib/main.cpp @@ -1,6 +1,6 @@ #include #undef main -#include +#include int main(int argc, char** argv) { return aurora_main(argc, argv); } diff --git a/lib/webgpu/gpu.cpp b/lib/webgpu/gpu.cpp index 1eead6f..8e40915 100644 --- a/lib/webgpu/gpu.cpp +++ b/lib/webgpu/gpu.cpp @@ -5,7 +5,7 @@ #include "../window.hpp" #include "../internal.hpp" -#include +#include #include #include #include diff --git a/lib/window.cpp b/lib/window.cpp index 8965baa..848da52 100644 --- a/lib/window.cpp +++ b/lib/window.cpp @@ -6,7 +6,7 @@ #include "internal.hpp" #include -#include +#include namespace aurora::window { static Module Log("aurora::window"); @@ -43,57 +43,52 @@ const AuroraEvent* poll_events() { imgui::process_event(event); switch (event.type) { - case SDL_WINDOWEVENT: { - switch (event.window.event) { - case SDL_WINDOWEVENT_MINIMIZED: { - // Android/iOS: Application backgrounded - g_events.push_back(AuroraEvent{ - .type = AURORA_PAUSED, - }); - break; - } - case SDL_WINDOWEVENT_RESTORED: { - // Android/iOS: Application focused - g_events.push_back(AuroraEvent{ - .type = AURORA_UNPAUSED, - }); - break; - } - case SDL_WINDOWEVENT_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: { - resize_swapchain(false); - g_events.push_back(AuroraEvent{ - .type = AURORA_WINDOW_RESIZED, - .windowSize = get_window_size(), - }); - break; - } - } + case SDL_EVENT_WINDOW_MINIMIZED: { + // Android/iOS: Application backgrounded + g_events.push_back(AuroraEvent{ + .type = AURORA_PAUSED, + }); break; } - case SDL_CONTROLLERDEVICEADDED: { - auto instance = input::add_controller(event.cdevice.which); + case SDL_EVENT_WINDOW_RESTORED: { + // Android/iOS: Application focused + g_events.push_back(AuroraEvent{ + .type = AURORA_UNPAUSED, + }); + break; + } + 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_EVENT_WINDOW_PIXEL_SIZE_CHANGED: { + resize_swapchain(false); + g_events.push_back(AuroraEvent{ + .type = AURORA_WINDOW_RESIZED, + .windowSize = get_window_size(), + }); + break; + } + 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(fb_w) / static_cast(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(width), .height = static_cast(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; }