mirror of
https://github.com/Rosalie241/RMG.git
synced 2026-09-03 19:04:34 +02:00
159 lines
5.5 KiB
C++
159 lines
5.5 KiB
C++
/*
|
|
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
|
|
* Copyright (C) 2020-2026 Rosalie Wanders <rosalie@mailbox.org>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 3.
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "InputProfileDB.hpp"
|
|
#include "main.hpp"
|
|
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QJsonArray>
|
|
#include <QFile>
|
|
|
|
#include <RMG-Core/m64p/api/m64p_types.h>
|
|
#include <RMG-Core/Directories.hpp>
|
|
|
|
|
|
//
|
|
// Public Functions
|
|
//
|
|
|
|
bool Utilities::InputProfileDB::Load(void)
|
|
{
|
|
std::filesystem::path profileDatabaseFilePath;
|
|
profileDatabaseFilePath = CoreGetSharedDataDirectory();
|
|
profileDatabaseFilePath += "/InputProfileDB.json";
|
|
|
|
QFile jsonFile(profileDatabaseFilePath);
|
|
|
|
if (!jsonFile.open(QFile::ReadOnly))
|
|
{
|
|
std::string message = "InputProfileDB::Load(): Failed to open DB";
|
|
PluginDebugMessage(M64MSG_WARNING, message);
|
|
return false;
|
|
}
|
|
|
|
QJsonParseError error;
|
|
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonFile.readAll(), &error);
|
|
if (error.error != QJsonParseError::NoError)
|
|
{
|
|
std::string message = "InputProfileDB::Load(): Failed to load json: ";
|
|
message += error.errorString().toStdString();
|
|
PluginDebugMessage(M64MSG_WARNING, message);
|
|
return false;
|
|
}
|
|
|
|
const struct
|
|
{
|
|
N64ControllerButton button;
|
|
InputAxisDirection axis;
|
|
QString baseKey;
|
|
} jsonButtonMappings[] =
|
|
{
|
|
{ N64ControllerButton::A, InputAxisDirection::Invalid, "A_" },
|
|
{ N64ControllerButton::B, InputAxisDirection::Invalid, "B_" },
|
|
{ N64ControllerButton::Start, InputAxisDirection::Invalid, "Start_" },
|
|
{ N64ControllerButton::DpadUp, InputAxisDirection::Invalid, "DpadUp_" },
|
|
{ N64ControllerButton::DpadDown, InputAxisDirection::Invalid, "DpadDown_" },
|
|
{ N64ControllerButton::DpadLeft, InputAxisDirection::Invalid, "DpadLeft_" },
|
|
{ N64ControllerButton::DpadRight, InputAxisDirection::Invalid, "DpadRight_" },
|
|
{ N64ControllerButton::CButtonUp, InputAxisDirection::Invalid, "CButtonUp_" },
|
|
{ N64ControllerButton::CButtonDown, InputAxisDirection::Invalid, "CButtonDown_" },
|
|
{ N64ControllerButton::CButtonLeft, InputAxisDirection::Invalid, "CButtonLeft_" },
|
|
{ N64ControllerButton::CButtonRight, InputAxisDirection::Invalid, "CButtonRight_" },
|
|
{ N64ControllerButton::LeftShoulder, InputAxisDirection::Invalid, "LeftTrigger_", },
|
|
{ N64ControllerButton::RightShoulder, InputAxisDirection::Invalid, "RightTrigger_" },
|
|
{ N64ControllerButton::ZTrigger, InputAxisDirection::Invalid, "ZTrigger_" },
|
|
{ N64ControllerButton::Invalid, InputAxisDirection::Up, "AnalogStickUp_" },
|
|
{ N64ControllerButton::Invalid, InputAxisDirection::Down, "AnalogStickDown_" },
|
|
{ N64ControllerButton::Invalid, InputAxisDirection::Left, "AnalogStickLeft_" },
|
|
{ N64ControllerButton::Invalid, InputAxisDirection::Right, "AnalogStickRight_" },
|
|
};
|
|
|
|
|
|
InputProfileDBEntry entry;
|
|
InputProfileDBInputEntry inputEntry;
|
|
|
|
for (const auto& arrayValue : jsonDocument.array())
|
|
{
|
|
// reset entry state
|
|
entry = {};
|
|
entry.valid = true;
|
|
|
|
QJsonObject jsonObject = arrayValue.toObject();
|
|
|
|
QJsonArray deviceNameArray = jsonObject["DeviceName"].toArray();
|
|
for (const auto& deviceName : deviceNameArray)
|
|
{
|
|
entry.deviceNames.push_back(deviceName.toString());
|
|
}
|
|
|
|
entry.deviceType = static_cast<InputDeviceType>(jsonObject["DeviceType"].toInt());
|
|
|
|
// add all button mappings
|
|
for (const auto& buttonMapping : jsonButtonMappings)
|
|
{
|
|
// reset input entry state
|
|
inputEntry = {};
|
|
|
|
QStringList inputTypes = jsonObject[buttonMapping.baseKey + "InputType"].toString().split(';');
|
|
QStringList names = jsonObject[buttonMapping.baseKey + "Name"].toString().split(';');
|
|
QStringList data = jsonObject[buttonMapping.baseKey + "Data"].toString().split(';');
|
|
QStringList extraData = jsonObject[buttonMapping.baseKey + "ExtraData"].toString().split(';');
|
|
|
|
inputEntry.button = buttonMapping.button;
|
|
inputEntry.axis = buttonMapping.axis;
|
|
inputEntry.names = names;
|
|
|
|
size_t size = std::min(inputTypes.size(), std::min(names.size(), std::min(data.size(), extraData.size())));
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
inputEntry.inputTypes.push_back(static_cast<InputType>(inputTypes[i].toInt()));
|
|
inputEntry.data.push_back(data[i].toInt());
|
|
inputEntry.extraData.push_back(extraData[i].toInt());
|
|
}
|
|
|
|
entry.inputEntries.push_back(inputEntry);
|
|
}
|
|
|
|
// add to list
|
|
this->entries.push_back(entry);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
InputProfileDBEntry Utilities::InputProfileDB::FindEntry(const InputDevice& device, bool fallback)
|
|
{
|
|
QString deviceName = QString::fromStdString(device.name);
|
|
|
|
for (const auto& dbEntry : this->entries)
|
|
{
|
|
if (dbEntry.deviceType == device.type)
|
|
{
|
|
for (const auto& name : dbEntry.deviceNames)
|
|
{
|
|
if (name == deviceName)
|
|
{
|
|
return dbEntry;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (fallback)
|
|
{
|
|
return this->FindEntry({ InputDeviceType::Joystick, "fallback_profile" }, false);
|
|
}
|
|
|
|
// nothing found, return invalid entry
|
|
return { false };
|
|
}
|
|
|