From b0eb271b5bbe30c07131663983ce1d1e28ed33f0 Mon Sep 17 00:00:00 2001 From: KeatonTheBot Date: Thu, 30 Jul 2026 15:51:32 -0500 Subject: [PATCH] SDL: Update game controller database on launch - Downloads updated gamecontrollerdb.txt file on launch, only updates when a new file is available. This keeps the database updated between SDL releases. (cherry picked from commit 0657b0062275d0219786a4bf795d808bd0c91aca) --- src/Ryujinx.SDL3.Common/SDL3Driver.cs | 39 ++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Ryujinx.SDL3.Common/SDL3Driver.cs b/src/Ryujinx.SDL3.Common/SDL3Driver.cs index fdbeeddf4..0fafcc5b0 100644 --- a/src/Ryujinx.SDL3.Common/SDL3Driver.cs +++ b/src/Ryujinx.SDL3.Common/SDL3Driver.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; +using System.Net.Http; using System.Threading; using static SDL.SDL3; @@ -43,6 +44,9 @@ namespace Ryujinx.SDL3.Common private SDL3Driver() { } + private static readonly HttpClient _httpClient = new(); + private const string GamepadDbUrl = "https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt"; + public void Initialize() { lock (_lock) @@ -97,8 +101,10 @@ namespace Ryujinx.SDL3.Common SDL_SetEventEnabled((uint)SDL_EventType.SDL_EVENT_GAMEPAD_SENSOR_UPDATE, false); - string gamepadDbPath = Path.Combine(AppDataManager.BaseDirPath, "SDL_GameControllerDB.txt"); + string gamepadDbPath = Path.Combine(AppDataManager.BaseDirPath, "gamecontrollerdb.txt"); + UpdateGamepadDb(gamepadDbPath); + if (File.Exists(gamepadDbPath)) { SDL_AddGamepadMappingsFromFile(gamepadDbPath); @@ -111,6 +117,37 @@ namespace Ryujinx.SDL3.Common } } + private static void UpdateGamepadDb(string gamepadDbPath) + { + try + { + byte[] remoteBytes = _httpClient.GetByteArrayAsync(GamepadDbUrl).GetAwaiter().GetResult(); + + bool shouldWrite = true; + + if (File.Exists(gamepadDbPath)) + { + byte[] localBytes = File.ReadAllBytes(gamepadDbPath); + + if (localBytes.AsSpan().SequenceEqual(remoteBytes)) + { + shouldWrite = false; + } + } + + if (shouldWrite) + { + File.WriteAllBytes(gamepadDbPath ?? "", remoteBytes); + + Logger.Info?.Print(LogClass.Application, "Updated gamepad database."); + } + } + catch (Exception ex) + { + Logger.Warning?.Print(LogClass.Application, $"Failed to check/download gamepad database, using existing local copy if present: {ex.Message}"); + } + } + public bool RegisterWindow(SDL_WindowID windowId, Action windowEventHandler) { return _registeredWindowHandlers.TryAdd(windowId, windowEventHandler);