NEW support for Gamepad mapping from SDL database. Plugged gamepads are correctly recognized for input mapping.

This commit is contained in:
brunoherbelin
2025-12-04 00:30:25 +01:00
parent c22d2bb26d
commit 33877cc837
5 changed files with 2240 additions and 4 deletions

View File

@@ -728,6 +728,7 @@ set(VMIX_RSC_FILES
./rsc/shaders/filters/3DSimplexNoise.glsl
./rsc/shaders/filters/source.glsl
./rsc/images/logo.vmx
./rsc/gamecontrollerdb.txt
)
cmrc_add_resource_library(vmix-resources ALIAS vmix::rc NAMESPACE vmix WHENCE rsc ${VMIX_RSC_FILES})

2202
rsc/gamecontrollerdb.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
**/
#include <cstddef>
#include <thread>
#include <mutex>
#include <sstream>
@@ -31,7 +32,9 @@
#include "Log.h"
#include "Settings.h"
#include "Resource.h"
#include "Toolkit/BaseToolkit.h"
#include "Toolkit/SystemToolkit.h"
#include "Mixer.h"
#include "Source/Source.h"
#include "Source/TextSource.h"
@@ -430,6 +433,27 @@ void Control::resetOscConfig()
translation_["/example/osc/message"] = "/vimix/info/log";
}
void Control::loadGamepadMappings()
{
// Load gamepad mappings from embedded SDL GameControllerDB resource
// The database contains mappings for 697+ gamepads on Linux
std::string mappings = Resource::getText("gamecontrollerdb.txt");
if (!mappings.empty()) {
// glfwUpdateGamepadMappings handles the full gamecontrollerdb.txt format
// including comments, empty lines, and filters by platform automatically
if (glfwUpdateGamepadMappings(mappings.c_str()) == GLFW_TRUE) {
Log::Info("Control: Loaded gamepad mappings from database.");
} else {
Log::Warning("Control: Failed to load gamepad mappings from database.");
}
} else {
// Fallback: if resource loading fails, use a generic Xbox 360 mapping
// This ensures at least standard Xbox-compatible controllers work
Log::Warning("Control: gamecontrollerdb.txt not found, gamepad support will be limited.");
}
}
bool Control::init()
{
//
@@ -442,6 +466,11 @@ bool Control::init()
//
loadOscConfig();
//
// load Gamepad mappings
//
loadGamepadMappings();
//
// launch OSC listener
//
@@ -472,7 +501,8 @@ bool Control::init()
void Control::update()
{
if (glfwJoystickPresent(Settings::application.gamepad_id) == GLFW_TRUE) {
if (glfwJoystickPresent(Settings::application.gamepad_id) == GLFW_TRUE &&
glfwJoystickIsGamepad(Settings::application.gamepad_id) == GLFW_TRUE) {
// read joystick buttons
int num_buttons = 0;
const unsigned char *state_buttons = glfwGetJoystickButtons(Settings::application.gamepad_id, &num_buttons);

View File

@@ -195,6 +195,7 @@ private:
std::map<std::string, std::string> translation_;
void loadOscConfig();
void resetOscConfig();
void loadGamepadMappings();
bool input_active[INPUT_MAX];
float input_values[INPUT_MAX];

View File

@@ -1292,15 +1292,17 @@ void InputMappingWindow::Render()
// selection of device for joystick mode
if ( Settings::application.mapping.mode == 3 ){
char text_buf[512];
if ( glfwJoystickPresent( Settings::application.gamepad_id ) )
if ( glfwJoystickPresent( Settings::application.gamepad_id ) == GLFW_TRUE &&
glfwJoystickIsGamepad(Settings::application.gamepad_id) == GLFW_TRUE )
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s", glfwGetJoystickName(Settings::application.gamepad_id));
else
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "Joystick %d", Settings::application.gamepad_id);
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "No gamepad plugged");
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::BeginCombo("Device", text_buf, ImGuiComboFlags_None)) {
for( int g = GLFW_JOYSTICK_1; g < GLFW_JOYSTICK_LAST; ++g) {
if ( glfwJoystickPresent( g ) ) {
if ( glfwJoystickPresent( g ) == GLFW_TRUE &&
glfwJoystickIsGamepad(g) == GLFW_TRUE ) {
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s", glfwGetJoystickName(g));
if (ImGui::Selectable(text_buf, Settings::application.gamepad_id == g) ) {
Settings::application.gamepad_id = g;