mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-18 14:40:56 +00:00
Create MappingManager class to handle gamepad mappings (currently only saving custom mappings)
This commit is contained in:
+4
-2
@@ -107,7 +107,8 @@ SOURCES += \
|
|||||||
gui/appmodel.cpp \
|
gui/appmodel.cpp \
|
||||||
streaming/streamutils.cpp \
|
streaming/streamutils.cpp \
|
||||||
backend/autoupdatechecker.cpp \
|
backend/autoupdatechecker.cpp \
|
||||||
path.cpp
|
path.cpp \
|
||||||
|
settings/mappingmanager.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
utils.h \
|
utils.h \
|
||||||
@@ -128,7 +129,8 @@ HEADERS += \
|
|||||||
streaming/video/decoder.h \
|
streaming/video/decoder.h \
|
||||||
streaming/streamutils.h \
|
streaming/streamutils.h \
|
||||||
backend/autoupdatechecker.h \
|
backend/autoupdatechecker.h \
|
||||||
path.h
|
path.h \
|
||||||
|
settings/mappingmanager.h
|
||||||
|
|
||||||
# Platform-specific renderers and decoders
|
# Platform-specific renderers and decoders
|
||||||
ffmpeg {
|
ffmpeg {
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
#include "mappingmanager.h"
|
||||||
|
#include "path.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#define SER_GAMEPADMAPPING "gcmapping"
|
||||||
|
|
||||||
|
#define SER_GUID "guid"
|
||||||
|
#define SER_MAPPING "mapping"
|
||||||
|
|
||||||
|
MappingManager::MappingManager()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
|
||||||
|
// First load existing saved mappings. This ensures the user's
|
||||||
|
// hints can always override the old data.
|
||||||
|
int mappingCount = settings.beginReadArray(SER_GAMEPADMAPPING);
|
||||||
|
for (int i = 0; i < mappingCount; i++) {
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
|
||||||
|
SdlGamepadMapping mapping(settings.value(SER_GUID).toString(), settings.value(SER_MAPPING).toString());
|
||||||
|
addMapping(mapping);
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
|
||||||
|
// Finally load mappings from SDL_HINT_GAMECONTROLLERCONFIG
|
||||||
|
QStringList sdlMappings = QString::fromLocal8Bit(SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG)).split('\n', QString::SkipEmptyParts);
|
||||||
|
for (QString sdlMapping : sdlMappings) {
|
||||||
|
SdlGamepadMapping mapping(sdlMapping);
|
||||||
|
addMapping(mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the updated mappings to settings
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingManager::save()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
|
||||||
|
settings.remove(SER_GAMEPADMAPPING);
|
||||||
|
settings.beginWriteArray(SER_GAMEPADMAPPING);
|
||||||
|
QList<SdlGamepadMapping> mappings = m_Mappings.values();
|
||||||
|
for (int i = 0; i < mappings.count(); i++) {
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
|
||||||
|
settings.setValue(SER_GUID, mappings[i].getGuid());
|
||||||
|
settings.setValue(SER_MAPPING, mappings[i].getMapping());
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingManager::applyMappings()
|
||||||
|
{
|
||||||
|
QString mappingFile = Path::getGamepadMappingFile();
|
||||||
|
if (!mappingFile.isEmpty()) {
|
||||||
|
std::string mappingFileNative = QDir::toNativeSeparators(mappingFile).toStdString();
|
||||||
|
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Loading gamepad mappings from: %s",
|
||||||
|
mappingFileNative.c_str());
|
||||||
|
|
||||||
|
int newMappings = SDL_GameControllerAddMappingsFromFile(mappingFileNative.c_str());
|
||||||
|
if (newMappings < 0) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Error loading gamepad mappings: %s",
|
||||||
|
SDL_GetError());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Loaded %d new gamepad mappings",
|
||||||
|
newMappings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"No gamepad mapping file found");
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<SdlGamepadMapping> mappings = m_Mappings.values();
|
||||||
|
for (const SdlGamepadMapping& mapping : mappings) {
|
||||||
|
QString sdlMappingString = mapping.getSdlMappingString();
|
||||||
|
int ret = SDL_GameControllerAddMapping(qPrintable(sdlMappingString));
|
||||||
|
if (ret < 0) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Unable to add mapping: %s",
|
||||||
|
qPrintable(sdlMappingString));
|
||||||
|
}
|
||||||
|
else if (ret == 1) {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Loaded saved user mapping: %s",
|
||||||
|
qPrintable(sdlMappingString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingManager::addMapping(QString mappingString)
|
||||||
|
{
|
||||||
|
SdlGamepadMapping mapping(mappingString);
|
||||||
|
addMapping(mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingManager::addMapping(SdlGamepadMapping& mapping)
|
||||||
|
{
|
||||||
|
m_Mappings[mapping.getGuid()] = mapping;
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
class SdlGamepadMapping
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SdlGamepadMapping() {}
|
||||||
|
|
||||||
|
SdlGamepadMapping(QString string)
|
||||||
|
{
|
||||||
|
QStringList mapping = string.split(",");
|
||||||
|
if (!mapping.isEmpty()) {
|
||||||
|
m_Guid = mapping[0];
|
||||||
|
|
||||||
|
string.remove(0, m_Guid.length() + 1);
|
||||||
|
m_Mapping = string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SdlGamepadMapping(QString guid, QString mapping)
|
||||||
|
: m_Guid(guid),
|
||||||
|
m_Mapping(mapping)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const SdlGamepadMapping& other) const
|
||||||
|
{
|
||||||
|
return m_Guid == other.m_Guid && m_Mapping == other.m_Mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getGuid() const
|
||||||
|
{
|
||||||
|
return m_Guid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getMapping() const
|
||||||
|
{
|
||||||
|
return m_Mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getSdlMappingString() const
|
||||||
|
{
|
||||||
|
if (m_Guid.isEmpty() || m_Mapping.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return m_Guid + "," + m_Mapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_Guid;
|
||||||
|
QString m_Mapping;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MappingManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MappingManager();
|
||||||
|
|
||||||
|
void addMapping(QString gamepadString);
|
||||||
|
|
||||||
|
void addMapping(SdlGamepadMapping& gamepadMapping);
|
||||||
|
|
||||||
|
void applyMappings();
|
||||||
|
|
||||||
|
void save();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMap<QString, SdlGamepadMapping> m_Mappings;
|
||||||
|
};
|
||||||
|
|
||||||
+6
-24
@@ -1,6 +1,7 @@
|
|||||||
#include <Limelight.h>
|
#include <Limelight.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include "streaming/session.h"
|
#include "streaming/session.h"
|
||||||
|
#include "settings/mappingmanager.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
@@ -48,30 +49,8 @@ SdlInputHandler::SdlInputHandler(StreamingPreferences& prefs, NvComputer* comput
|
|||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString mappingFile = Path::getGamepadMappingFile();
|
MappingManager mappingManager;
|
||||||
if (!mappingFile.isEmpty()) {
|
mappingManager.applyMappings();
|
||||||
std::string mappingFileNative = QDir::toNativeSeparators(mappingFile).toStdString();
|
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Loading gamepad mappings from: %s",
|
|
||||||
mappingFileNative.c_str());
|
|
||||||
|
|
||||||
int newMappings = SDL_GameControllerAddMappingsFromFile(mappingFileNative.c_str());
|
|
||||||
if (newMappings < 0) {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Error loading gamepad mappings: %s",
|
|
||||||
SDL_GetError());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Loaded %d new gamepad mappings",
|
|
||||||
newMappings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"No gamepad mapping file found");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_MultiController) {
|
if (!m_MultiController) {
|
||||||
// Player 1 is always present in non-MC mode
|
// Player 1 is always present in non-MC mode
|
||||||
@@ -727,6 +706,9 @@ QString SdlInputHandler::getUnmappedGamepads()
|
|||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MappingManager mappingManager;
|
||||||
|
mappingManager.applyMappings();
|
||||||
|
|
||||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
||||||
if (!SDL_IsGameController(i)) {
|
if (!SDL_IsGameController(i)) {
|
||||||
char guidStr[33];
|
char guidStr[33];
|
||||||
|
|||||||
Reference in New Issue
Block a user