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/3DSimplexNoise.glsl
./rsc/shaders/filters/source.glsl ./rsc/shaders/filters/source.glsl
./rsc/images/logo.vmx ./rsc/images/logo.vmx
./rsc/gamecontrollerdb.txt
) )
cmrc_add_resource_library(vmix-resources ALIAS vmix::rc NAMESPACE vmix WHENCE rsc ${VMIX_RSC_FILES}) 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/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
**/ **/
#include <cstddef>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <sstream> #include <sstream>
@@ -31,7 +32,9 @@
#include "Log.h" #include "Log.h"
#include "Settings.h" #include "Settings.h"
#include "Resource.h"
#include "Toolkit/BaseToolkit.h" #include "Toolkit/BaseToolkit.h"
#include "Toolkit/SystemToolkit.h"
#include "Mixer.h" #include "Mixer.h"
#include "Source/Source.h" #include "Source/Source.h"
#include "Source/TextSource.h" #include "Source/TextSource.h"
@@ -430,6 +433,27 @@ void Control::resetOscConfig()
translation_["/example/osc/message"] = "/vimix/info/log"; 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() bool Control::init()
{ {
// //
@@ -442,6 +466,11 @@ bool Control::init()
// //
loadOscConfig(); loadOscConfig();
//
// load Gamepad mappings
//
loadGamepadMappings();
// //
// launch OSC listener // launch OSC listener
// //
@@ -472,7 +501,8 @@ bool Control::init()
void Control::update() 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 // read joystick buttons
int num_buttons = 0; int num_buttons = 0;
const unsigned char *state_buttons = glfwGetJoystickButtons(Settings::application.gamepad_id, &num_buttons); 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_; std::map<std::string, std::string> translation_;
void loadOscConfig(); void loadOscConfig();
void resetOscConfig(); void resetOscConfig();
void loadGamepadMappings();
bool input_active[INPUT_MAX]; bool input_active[INPUT_MAX];
float input_values[INPUT_MAX]; float input_values[INPUT_MAX];

View File

@@ -1292,15 +1292,17 @@ void InputMappingWindow::Render()
// selection of device for joystick mode // selection of device for joystick mode
if ( Settings::application.mapping.mode == 3 ){ if ( Settings::application.mapping.mode == 3 ){
char text_buf[512]; 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)); ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s", glfwGetJoystickName(Settings::application.gamepad_id));
else 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); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::BeginCombo("Device", text_buf, ImGuiComboFlags_None)) { if (ImGui::BeginCombo("Device", text_buf, ImGuiComboFlags_None)) {
for( int g = GLFW_JOYSTICK_1; g < GLFW_JOYSTICK_LAST; ++g) { 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)); ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s", glfwGetJoystickName(g));
if (ImGui::Selectable(text_buf, Settings::application.gamepad_id == g) ) { if (ImGui::Selectable(text_buf, Settings::application.gamepad_id == g) ) {
Settings::application.gamepad_id = g; Settings::application.gamepad_id = g;