mirror of https://github.com/AxioDL/metaforce.git
aurora: Null graphics backend with SDL_Renderer fallback
This commit is contained in:
parent
4048492279
commit
40a444d800
|
@ -17,7 +17,10 @@ add_library(aurora STATIC
|
||||||
target_compile_definitions(aurora PRIVATE IMGUI_USER_CONFIG="imconfig_user.h") # IMGUI_USE_WCHAR32
|
target_compile_definitions(aurora PRIVATE IMGUI_USER_CONFIG="imconfig_user.h") # IMGUI_USE_WCHAR32
|
||||||
target_include_directories(aurora PUBLIC include ../)
|
target_include_directories(aurora PUBLIC include ../)
|
||||||
target_include_directories(aurora PRIVATE ../imgui ../extern/imgui)
|
target_include_directories(aurora PRIVATE ../imgui ../extern/imgui)
|
||||||
target_link_libraries(aurora PRIVATE dawn_native dawncpp webgpu_dawn zeus logvisor SDL2-static xxhash
|
if(NOT TARGET SDL2::SDL2-static)
|
||||||
|
find_package(SDL2 REQUIRED)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(aurora PRIVATE dawn_native dawncpp webgpu_dawn zeus logvisor SDL2::SDL2-static xxhash
|
||||||
absl::btree absl::flat_hash_map)
|
absl::btree absl::flat_hash_map)
|
||||||
if (DAWN_ENABLE_VULKAN)
|
if (DAWN_ENABLE_VULKAN)
|
||||||
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_VULKAN)
|
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_VULKAN)
|
||||||
|
@ -36,3 +39,7 @@ if (DAWN_ENABLE_DESKTOP_GL)
|
||||||
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_OPENGL DAWN_ENABLE_BACKEND_DESKTOP_GL)
|
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_OPENGL DAWN_ENABLE_BACKEND_DESKTOP_GL)
|
||||||
target_sources(aurora PRIVATE lib/dawn/OpenGLBinding.cpp)
|
target_sources(aurora PRIVATE lib/dawn/OpenGLBinding.cpp)
|
||||||
endif ()
|
endif ()
|
||||||
|
if (DAWN_ENABLE_NULL)
|
||||||
|
target_compile_definitions(aurora PRIVATE DAWN_ENABLE_BACKEND_NULL)
|
||||||
|
target_sources(aurora PRIVATE lib/dawn/NullBinding.cpp)
|
||||||
|
endif ()
|
||||||
|
|
|
@ -65,7 +65,9 @@ static bool poll_events() noexcept {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_WINDOWEVENT_EXPOSED:
|
case SDL_WINDOWEVENT_EXPOSED:
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
||||||
case SDL_WINDOWEVENT_DISPLAY_CHANGED:
|
case SDL_WINDOWEVENT_DISPLAY_CHANGED:
|
||||||
|
#endif
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
case SDL_WINDOWEVENT_RESIZED:
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||||
case SDL_WINDOWEVENT_MINIMIZED:
|
case SDL_WINDOWEVENT_MINIMIZED:
|
||||||
|
@ -224,7 +226,7 @@ static bool poll_events() noexcept {
|
||||||
|
|
||||||
static SDL_Window* create_window(wgpu::BackendType type) {
|
static SDL_Window* create_window(wgpu::BackendType type) {
|
||||||
Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI;
|
Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI;
|
||||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
#if TARGET_OS_IOS || TARGET_OS_TV || defined(__SWITCH__)
|
||||||
flags |= SDL_WINDOW_FULLSCREEN;
|
flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
#else
|
#else
|
||||||
flags |= SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
flags |= SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE;
|
||||||
|
@ -267,9 +269,12 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||||
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
|
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
|
||||||
#endif
|
#endif
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE, "1");
|
#if SDL_VERSION_ATLEAST(2, 0, 18)
|
||||||
|
|
||||||
SDL_SetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME, "Metaforce");
|
SDL_SetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME, "Metaforce");
|
||||||
|
#endif
|
||||||
|
#ifdef SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE
|
||||||
|
SDL_SetHint(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE, "1");
|
||||||
|
#endif
|
||||||
|
|
||||||
SDL_DisableScreenSaver();
|
SDL_DisableScreenSaver();
|
||||||
/* TODO: Make this an option rather than hard coding it */
|
/* TODO: Make this an option rather than hard coding it */
|
||||||
|
@ -292,8 +297,23 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
unreachable();
|
unreachable();
|
||||||
}
|
}
|
||||||
set_window_icon(std::move(icon));
|
set_window_icon(std::move(icon));
|
||||||
SDL_ShowWindow(g_window);
|
|
||||||
|
|
||||||
|
// Initialize SDL_Renderer for ImGui when we can't use a Dawn backend
|
||||||
|
SDL_Renderer* renderer = nullptr;
|
||||||
|
if (gpu::g_backendType == wgpu::BackendType::Null) {
|
||||||
|
const auto flags = SDL_RENDERER_PRESENTVSYNC;
|
||||||
|
renderer = SDL_CreateRenderer(g_window, -1, flags | SDL_RENDERER_ACCELERATED);
|
||||||
|
if (renderer == nullptr) {
|
||||||
|
// Attempt fallback to SW renderer
|
||||||
|
renderer = SDL_CreateRenderer(g_window, -1, flags);
|
||||||
|
}
|
||||||
|
if (renderer == nullptr) {
|
||||||
|
Log.report(logvisor::Fatal, FMT_STRING("Failed to initialize SDL renderer: {}"), SDL_GetError());
|
||||||
|
unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_ShowWindow(g_window);
|
||||||
gfx::initialize();
|
gfx::initialize();
|
||||||
|
|
||||||
imgui::create_context();
|
imgui::create_context();
|
||||||
|
@ -301,7 +321,7 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
Log.report(logvisor::Info, FMT_STRING("Using framebuffer size {}x{} scale {}"), size.fb_width, size.fb_height,
|
Log.report(logvisor::Info, FMT_STRING("Using framebuffer size {}x{} scale {}"), size.fb_width, size.fb_height,
|
||||||
size.scale);
|
size.scale);
|
||||||
g_AppDelegate->onImGuiInit(size.scale);
|
g_AppDelegate->onImGuiInit(size.scale);
|
||||||
imgui::initialize(g_window);
|
imgui::initialize(g_window, renderer);
|
||||||
g_AppDelegate->onImGuiAddTextures();
|
g_AppDelegate->onImGuiAddTextures();
|
||||||
|
|
||||||
g_AppDelegate->onAppLaunched();
|
g_AppDelegate->onAppLaunched();
|
||||||
|
@ -360,6 +380,9 @@ void app_run(std::unique_ptr<AppDelegate> app, Icon icon, int argc, char** argv,
|
||||||
imgui::shutdown();
|
imgui::shutdown();
|
||||||
gfx::shutdown();
|
gfx::shutdown();
|
||||||
gpu::shutdown();
|
gpu::shutdown();
|
||||||
|
if (renderer != nullptr) {
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
}
|
||||||
SDL_DestroyWindow(g_window);
|
SDL_DestroyWindow(g_window);
|
||||||
SDL_EnableScreenSaver();
|
SDL_EnableScreenSaver();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
#include <SDL_video.h>
|
#include <SDL_video.h>
|
||||||
#include <dawn/native/OpenGLBackend.h>
|
#include <dawn/native/OpenGLBackend.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DAWN_ENABLE_BACKEND_NULL)
|
||||||
|
#include <dawn/native/NullBackend.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace aurora::gpu::utils {
|
namespace aurora::gpu::utils {
|
||||||
|
|
||||||
|
@ -69,6 +72,11 @@ bool DiscoverAdapter(dawn::native::Instance* instance, SDL_Window* window, wgpu:
|
||||||
return instance->DiscoverAdapters(&adapterOptions);
|
return instance->DiscoverAdapters(&adapterOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(DAWN_ENABLE_BACKEND_NULL)
|
||||||
|
case wgpu::BackendType::Null:
|
||||||
|
instance->DiscoverDefaultAdapters();
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "BackendBinding.hpp"
|
||||||
|
|
||||||
|
#include <SDL_video.h>
|
||||||
|
#include <dawn/native/NullBackend.h>
|
||||||
|
|
||||||
|
namespace aurora::gpu::utils {
|
||||||
|
class NullBinding : public BackendBinding {
|
||||||
|
public:
|
||||||
|
NullBinding(SDL_Window* window, WGPUDevice device) : BackendBinding(window, device) {}
|
||||||
|
|
||||||
|
uint64_t GetSwapChainImplementation() override {
|
||||||
|
if (m_swapChainImpl.userData == nullptr) {
|
||||||
|
m_swapChainImpl = dawn::native::null::CreateNativeSwapChainImpl();
|
||||||
|
}
|
||||||
|
return reinterpret_cast<uint64_t>(&m_swapChainImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
WGPUTextureFormat GetPreferredSwapChainTextureFormat() override {
|
||||||
|
return WGPUTextureFormat_RGBA8Unorm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DawnSwapChainImplementation m_swapChainImpl{};
|
||||||
|
};
|
||||||
|
|
||||||
|
BackendBinding* CreateNullBinding(SDL_Window* window, WGPUDevice device) { return new NullBinding(window, device); }
|
||||||
|
} // namespace aurora::gpu::utils
|
|
@ -265,7 +265,7 @@ const stream::State& get_state() {
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
void push_draw_command(stream::DrawData data) {
|
void push_draw_command(stream::DrawData data) {
|
||||||
push_draw_command({.type = ShaderType::Stream, .stream = data});
|
push_draw_command(ShaderDrawCommand{.type = ShaderType::Stream, .stream = data});
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
PipelineRef pipeline_ref(stream::PipelineConfig config) {
|
PipelineRef pipeline_ref(stream::PipelineConfig config) {
|
||||||
|
@ -274,7 +274,7 @@ PipelineRef pipeline_ref(stream::PipelineConfig config) {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void push_draw_command(model::DrawData data) {
|
void push_draw_command(model::DrawData data) {
|
||||||
push_draw_command({.type = ShaderType::Model, .model = data});
|
push_draw_command(ShaderDrawCommand{.type = ShaderType::Model, .model = data});
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
PipelineRef pipeline_ref(model::PipelineConfig config) {
|
PipelineRef pipeline_ref(model::PipelineConfig config) {
|
||||||
|
|
|
@ -29,6 +29,8 @@ static inline std::string_view chan_comp(GX::TevColorChan chan) noexcept {
|
||||||
return "b";
|
return "b";
|
||||||
case GX::CH_ALPHA:
|
case GX::CH_ALPHA:
|
||||||
return "a";
|
return "a";
|
||||||
|
default:
|
||||||
|
return "?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,26 +118,6 @@ static void color_arg_reg_info(GX::TevColorArg arg, const TevStage& stage, Shade
|
||||||
|
|
||||||
static bool formatHasAlpha(GX::TextureFormat format) {
|
static bool formatHasAlpha(GX::TextureFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case GX::TF_I4:
|
|
||||||
case GX::TF_I8:
|
|
||||||
case GX::TF_RGB565:
|
|
||||||
case GX::TF_C4:
|
|
||||||
case GX::TF_C8:
|
|
||||||
case GX::TF_C14X2:
|
|
||||||
case GX::TF_Z8:
|
|
||||||
case GX::TF_Z16:
|
|
||||||
case GX::TF_Z24X8:
|
|
||||||
case GX::CTF_R4:
|
|
||||||
case GX::CTF_R8:
|
|
||||||
case GX::CTF_G8:
|
|
||||||
case GX::CTF_B8:
|
|
||||||
case GX::CTF_RG8:
|
|
||||||
case GX::CTF_GB8:
|
|
||||||
case GX::CTF_Z4:
|
|
||||||
case GX::CTF_Z8M:
|
|
||||||
case GX::CTF_Z8L:
|
|
||||||
case GX::CTF_Z16L:
|
|
||||||
return false;
|
|
||||||
case GX::TF_IA4:
|
case GX::TF_IA4:
|
||||||
case GX::TF_IA8:
|
case GX::TF_IA8:
|
||||||
case GX::TF_RGB5A3:
|
case GX::TF_RGB5A3:
|
||||||
|
@ -146,6 +128,8 @@ static bool formatHasAlpha(GX::TextureFormat format) {
|
||||||
case GX::CTF_YUVA8:
|
case GX::CTF_YUVA8:
|
||||||
case GX::CTF_A8:
|
case GX::CTF_A8:
|
||||||
return true;
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ constexpr std::array PreferredBackendOrder{
|
||||||
#ifdef DAWN_ENABLE_BACKEND_OPENGLES
|
#ifdef DAWN_ENABLE_BACKEND_OPENGLES
|
||||||
wgpu::BackendType::OpenGLES,
|
wgpu::BackendType::OpenGLES,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DAWN_ENABLE_BACKEND_NULL
|
||||||
|
wgpu::BackendType::Null,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern wgpu::Device g_device;
|
extern wgpu::Device g_device;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <dawn/webgpu_cpp.h>
|
#include <dawn/webgpu_cpp.h>
|
||||||
|
|
||||||
#include "../extern/imgui/backends/imgui_impl_sdl.cpp"
|
#include "../extern/imgui/backends/imgui_impl_sdl.cpp"
|
||||||
|
#include "../extern/imgui/backends/imgui_impl_sdlrenderer.cpp"
|
||||||
#include "../extern/imgui/backends/imgui_impl_wgpu.cpp"
|
#include "../extern/imgui/backends/imgui_impl_wgpu.cpp"
|
||||||
|
|
||||||
namespace aurora::imgui {
|
namespace aurora::imgui {
|
||||||
|
@ -29,17 +30,27 @@ void create_context() noexcept {
|
||||||
io.LogFilename = g_imguiLog.c_str();
|
io.LogFilename = g_imguiLog.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize(SDL_Window* window) noexcept {
|
static bool g_useSdlRenderer = false;
|
||||||
ImGui_ImplSDL2_Init(window, nullptr);
|
void initialize(SDL_Window* window, SDL_Renderer* renderer) noexcept {
|
||||||
|
ImGui_ImplSDL2_Init(window, renderer);
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// Disable MouseCanUseGlobalState for scaling purposes
|
// Disable MouseCanUseGlobalState for scaling purposes
|
||||||
ImGui_ImplSDL2_GetBackendData()->MouseCanUseGlobalState = false;
|
ImGui_ImplSDL2_GetBackendData()->MouseCanUseGlobalState = false;
|
||||||
#endif
|
#endif
|
||||||
ImGui_ImplWGPU_Init(g_device.Get(), 1, static_cast<WGPUTextureFormat>(gpu::g_graphicsConfig.colorFormat));
|
g_useSdlRenderer = renderer != nullptr;
|
||||||
|
if (g_useSdlRenderer) {
|
||||||
|
ImGui_ImplSDLRenderer_Init(renderer);
|
||||||
|
} else {
|
||||||
|
ImGui_ImplWGPU_Init(g_device.Get(), 1, static_cast<WGPUTextureFormat>(gpu::g_graphicsConfig.colorFormat));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown() noexcept {
|
void shutdown() noexcept {
|
||||||
ImGui_ImplWGPU_Shutdown();
|
if (g_useSdlRenderer) {
|
||||||
|
ImGui_ImplSDLRenderer_Shutdown();
|
||||||
|
} else {
|
||||||
|
ImGui_ImplWGPU_Shutdown();
|
||||||
|
}
|
||||||
ImGui_ImplSDL2_Shutdown();
|
ImGui_ImplSDL2_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
@ -49,8 +60,7 @@ void process_event(const SDL_Event& event) noexcept {
|
||||||
if (event.type == SDL_MOUSEMOTION) {
|
if (event.type == SDL_MOUSEMOTION) {
|
||||||
auto& io = ImGui::GetIO();
|
auto& io = ImGui::GetIO();
|
||||||
// Scale up mouse coordinates
|
// Scale up mouse coordinates
|
||||||
io.AddMousePosEvent(static_cast<float>(event.motion.x) * g_scale,
|
io.AddMousePosEvent(static_cast<float>(event.motion.x) * g_scale, static_cast<float>(event.motion.y) * g_scale);
|
||||||
static_cast<float>(event.motion.y) * g_scale);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,15 +68,19 @@ void process_event(const SDL_Event& event) noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_frame(const WindowSize& size) noexcept {
|
void new_frame(const WindowSize& size) noexcept {
|
||||||
if (g_scale != size.scale) {
|
if (g_useSdlRenderer) {
|
||||||
if (g_scale > 0.f) {
|
ImGui_ImplSDLRenderer_NewFrame();
|
||||||
// TODO wgpu backend bug: doesn't clear bind groups on invalidate
|
} else {
|
||||||
g_resources.ImageBindGroups.Clear();
|
if (g_scale != size.scale) {
|
||||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
if (g_scale > 0.f) {
|
||||||
|
// TODO wgpu backend bug: doesn't clear bind groups on invalidate
|
||||||
|
g_resources.ImageBindGroups.Clear();
|
||||||
|
ImGui_ImplWGPU_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
g_scale = size.scale;
|
||||||
}
|
}
|
||||||
g_scale = size.scale;
|
ImGui_ImplWGPU_NewFrame();
|
||||||
}
|
}
|
||||||
ImGui_ImplWGPU_NewFrame();
|
|
||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
|
|
||||||
// Render at full DPI
|
// Render at full DPI
|
||||||
|
@ -80,10 +94,24 @@ void render(const wgpu::RenderPassEncoder& pass) noexcept {
|
||||||
auto* data = ImGui::GetDrawData();
|
auto* data = ImGui::GetDrawData();
|
||||||
// io.DisplayFramebufferScale is informational; we're rendering at full DPI
|
// io.DisplayFramebufferScale is informational; we're rendering at full DPI
|
||||||
data->FramebufferScale = {1.f, 1.f};
|
data->FramebufferScale = {1.f, 1.f};
|
||||||
ImGui_ImplWGPU_RenderDrawData(data, pass.Get());
|
if (g_useSdlRenderer) {
|
||||||
|
SDL_Renderer* renderer = ImGui_ImplSDLRenderer_GetBackendData()->SDLRenderer;
|
||||||
|
SDL_RenderClear(renderer);
|
||||||
|
ImGui_ImplSDLRenderer_RenderDrawData(data);
|
||||||
|
SDL_RenderPresent(renderer);
|
||||||
|
} else {
|
||||||
|
ImGui_ImplWGPU_RenderDrawData(data, pass.Get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImTextureID add_texture(uint32_t width, uint32_t height, ArrayRef<uint8_t> data) noexcept {
|
ImTextureID add_texture(uint32_t width, uint32_t height, ArrayRef<uint8_t> data) noexcept {
|
||||||
|
if (g_useSdlRenderer) {
|
||||||
|
SDL_Renderer* renderer = ImGui_ImplSDLRenderer_GetBackendData()->SDLRenderer;
|
||||||
|
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||||
|
SDL_UpdateTexture(texture, nullptr, data.data(), width * 4);
|
||||||
|
SDL_SetTextureScaleMode(texture, SDL_ScaleModeLinear);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
const auto size = wgpu::Extent3D{
|
const auto size = wgpu::Extent3D{
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height,
|
.height = height,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
struct SDL_Renderer;
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ struct WindowSize;
|
||||||
|
|
||||||
namespace aurora::imgui {
|
namespace aurora::imgui {
|
||||||
void create_context() noexcept;
|
void create_context() noexcept;
|
||||||
void initialize(SDL_Window* window) noexcept;
|
void initialize(SDL_Window* window, SDL_Renderer* renderer) noexcept;
|
||||||
void shutdown() noexcept;
|
void shutdown() noexcept;
|
||||||
|
|
||||||
void process_event(const SDL_Event& event) noexcept;
|
void process_event(const SDL_Event& event) noexcept;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "magic_enum.hpp"
|
#include "magic_enum.hpp"
|
||||||
|
|
||||||
#include <SDL_haptic.h>
|
#include <SDL_haptic.h>
|
||||||
|
#include <SDL_version.h>
|
||||||
|
|
||||||
#include <absl/container/btree_map.h>
|
#include <absl/container/btree_map.h>
|
||||||
#include <absl/container/flat_hash_map.h>
|
#include <absl/container/flat_hash_map.h>
|
||||||
|
@ -103,7 +104,7 @@ static std::optional<std::string> remap_controller_layout(std::string_view mappi
|
||||||
Log.report(logvisor::Error, FMT_STRING("Controller has unsupported layout: {}"), mapping);
|
Log.report(logvisor::Error, FMT_STRING("Controller has unsupported layout: {}"), mapping);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
for (const auto [k, v] : entries) {
|
for (auto [k, v] : entries) {
|
||||||
newMapping.push_back(',');
|
newMapping.push_back(',');
|
||||||
newMapping.append(k);
|
newMapping.append(k);
|
||||||
newMapping.push_back(':');
|
newMapping.push_back(':');
|
||||||
|
@ -140,7 +141,11 @@ Sint32 add_controller(Sint32 which) noexcept {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
controller.m_isGameCube = controller.m_vid == 0x057E && controller.m_pid == 0x0337;
|
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);
|
controller.m_hasRumble = (SDL_GameControllerHasRumble(ctrl) != 0u);
|
||||||
|
#else
|
||||||
|
controller.m_hasRumble = true;
|
||||||
|
#endif
|
||||||
Sint32 instance = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ctrl));
|
Sint32 instance = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(ctrl));
|
||||||
g_GameControllers[instance] = controller;
|
g_GameControllers[instance] = controller;
|
||||||
return instance;
|
return instance;
|
||||||
|
|
Loading…
Reference in New Issue