-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RMG: implement netplay cheats support (WIP)
- Loading branch information
1 parent
7b4629b
commit 6b1ccd2
Showing
10 changed files
with
378 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
201 changes: 201 additions & 0 deletions
201
Source/RMG/UserInterface/Dialog/Cheats/CheatsCommon.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
/* | ||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG | ||
* Copyright (C) 2020 Rosalie Wanders <[email protected]> | ||
* | ||
* 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 "CheatsCommon.hpp" | ||
|
||
#include <QJsonObject> | ||
|
||
#include <RMG-Core/Core.hpp> | ||
|
||
using namespace CheatsCommon; | ||
|
||
// | ||
// Local Functions | ||
// | ||
|
||
static int find_json_cheat(const CoreCheat& cheat, const QJsonArray& json) | ||
{ | ||
QJsonObject cheatObject; | ||
QString targetCheatName = QString::fromStdString(cheat.Name); | ||
|
||
for (qsizetype i = 0; i < json.size(); i++) | ||
{ | ||
cheatObject = json[i].toObject(); | ||
|
||
if (cheatObject["name"].toString() == targetCheatName) | ||
{ | ||
return (int)i; | ||
} | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
// | ||
// Exported Function | ||
// | ||
|
||
bool CheatsCommon::IsCheatEnabled(bool netplay, const QJsonArray& json, const CoreCheat& cheat) | ||
{ | ||
if (netplay) | ||
{ | ||
int index = find_json_cheat(cheat, json); | ||
return index != -1 && json[index].toObject().contains("codes"); | ||
} | ||
else | ||
{ | ||
return CoreIsCheatEnabled(cheat); | ||
} | ||
} | ||
|
||
bool CheatsCommon::EnableCheat(bool netplay, QJsonArray& json, const CoreCheat& cheat, bool enabled) | ||
{ | ||
if (netplay) | ||
{ | ||
QJsonObject cheatObject; | ||
QJsonArray codesArray; | ||
QString targetCheatName = QString::fromStdString(cheat.Name); | ||
|
||
if (enabled) | ||
{ | ||
for (const auto& cheatCode : cheat.CheatCodes) | ||
{ | ||
QJsonObject codeObject; | ||
codeObject["address"] = (qint64)cheatCode.Address; | ||
codeObject["value"] = (qint64)cheatCode.Value; | ||
codeObject["use_option"] = cheatCode.UseOptions; | ||
codeObject["option_index"] = cheatCode.OptionIndex; | ||
codeObject["option_size"] = cheatCode.OptionSize; | ||
codesArray.push_back(codeObject); | ||
} | ||
|
||
cheatObject["name"] = targetCheatName; | ||
cheatObject["codes"] = codesArray; | ||
|
||
int index = find_json_cheat(cheat, json); | ||
if (index != -1) | ||
{ | ||
// copy over the option object | ||
cheatObject["option"] = json[index].toObject().value("option").toObject(); | ||
json[index] = cheatObject; | ||
} | ||
else | ||
{ | ||
json.push_back(cheatObject); | ||
} | ||
} | ||
else | ||
{ | ||
int index = find_json_cheat(cheat, json); | ||
if (index != -1) | ||
{ | ||
cheatObject = json[index].toObject(); | ||
|
||
// if cheat object has an option key | ||
// we have to keep that key because | ||
// else the UI will behave inconsistent | ||
// with the non-netplay cheats dialog | ||
if (cheatObject.contains("option")) | ||
{ | ||
cheatObject.remove("codes"); | ||
json[index] = cheatObject; | ||
} | ||
else | ||
{ | ||
json.removeAt(index); | ||
} | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
else | ||
{ | ||
return CoreEnableCheat(cheat, enabled); | ||
} | ||
} | ||
|
||
bool CheatsCommon::HasCheatOptionSet(bool netplay, const QJsonArray& json, const CoreCheat& cheat) | ||
{ | ||
if (netplay) | ||
{ | ||
int index = find_json_cheat(cheat, json); | ||
return index != -1 && json[index].toObject().contains("option"); | ||
} | ||
else | ||
{ | ||
return CoreHasCheatOptionSet(cheat); | ||
} | ||
} | ||
|
||
bool CheatsCommon::GetCheatOption(bool netplay, const QJsonArray& json, const CoreCheat& cheat, CoreCheatOption& option) | ||
{ | ||
if (netplay) | ||
{ | ||
QJsonObject cheatObject; | ||
QJsonObject optionObject; | ||
|
||
int index = find_json_cheat(cheat, json); | ||
if (index == -1) | ||
{ | ||
return false; | ||
} | ||
|
||
cheatObject = json[index].toObject(); | ||
optionObject = cheatObject["option"].toObject(); | ||
option.Name = optionObject["name"].toString().toStdString(); | ||
option.Size = optionObject["size"].toInt(); | ||
option.Value = optionObject["value"].toInteger(); | ||
return true; | ||
} | ||
else | ||
{ | ||
return CoreGetCheatOption(cheat, option); | ||
} | ||
} | ||
bool CheatsCommon::SetCheatOption(bool netplay, QJsonArray& json, const CoreCheat& cheat, CoreCheatOption& option) | ||
{ | ||
if (netplay) | ||
{ | ||
QJsonObject cheatObject; | ||
QJsonObject optionObject; | ||
QString targetCheatName = QString::fromStdString(cheat.Name); | ||
|
||
int index = find_json_cheat(cheat, json); | ||
if (index != -1) | ||
{ | ||
cheatObject = json[index].toObject(); | ||
optionObject["name"] = QString::fromStdString(option.Name); | ||
optionObject["size"] = option.Size; | ||
optionObject["value"] = (qint64)option.Value; | ||
|
||
cheatObject["option"] = optionObject; | ||
|
||
json[index] = cheatObject; | ||
} | ||
else | ||
{ // create dummy object when option has been set | ||
// without the user having the cheat enabled | ||
optionObject["name"] = QString::fromStdString(option.Name); | ||
optionObject["size"] = option.Size; | ||
optionObject["value"] = (qint64)option.Value; | ||
|
||
cheatObject["name"] = targetCheatName; | ||
cheatObject["option"] = optionObject; | ||
|
||
json.append(cheatObject); | ||
} | ||
|
||
return true; | ||
} | ||
else | ||
{ | ||
return CoreGetCheatOption(cheat, option); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG | ||
* Copyright (C) 2020 Rosalie Wanders <[email protected]> | ||
* | ||
* 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/>. | ||
*/ | ||
#ifndef CHEATSCOMMONH_HPP | ||
#define CHEATSCOMMONH_HPP | ||
|
||
#include <QJsonArray> | ||
#include <QComboBox> | ||
#include <QString> | ||
|
||
#include <RMG-Core/Core.hpp> | ||
|
||
namespace CheatsCommon | ||
{ | ||
// Checks whether cheat is enabled | ||
bool IsCheatEnabled(bool netplay, const QJsonArray& json, const CoreCheat& cheat); | ||
|
||
// Enables Cheat | ||
bool EnableCheat(bool netplay, QJsonArray& json, const CoreCheat& cheat, bool enabled); | ||
|
||
// Returns whether cheat has option set | ||
bool HasCheatOptionSet(bool netplay, const QJsonArray& json, const CoreCheat& cheat); | ||
|
||
// Retrieves cheat option | ||
bool GetCheatOption(bool netplay, const QJsonArray& json, const CoreCheat& cheat, CoreCheatOption& option); | ||
|
||
// Sets cheat option | ||
bool SetCheatOption(bool netplay, QJsonArray& json, const CoreCheat& cheat, CoreCheatOption& option); | ||
} | ||
|
||
#endif // CHEATSCOMMONH_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.