mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Split out code for serializing/deserializing cheat lines
This commit is contained in:
@ -26,6 +26,7 @@
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
@ -215,42 +216,14 @@ std::vector<ARCode> LoadCodes(const IniFile& global_ini, const IniFile& local_in
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<std::string> pieces = SplitString(line, ' ');
|
||||
const auto parse_result = DeserializeLine(line);
|
||||
|
||||
// Check if the AR code is decrypted
|
||||
if (pieces.size() == 2 && pieces[0].size() == 8 && pieces[1].size() == 8)
|
||||
{
|
||||
AREntry op;
|
||||
bool success_addr = TryParse(pieces[0], &op.cmd_addr, 16);
|
||||
bool success_val = TryParse(pieces[1], &op.value, 16);
|
||||
|
||||
if (success_addr && success_val)
|
||||
{
|
||||
current_code.ops.push_back(op);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlertFmtT("Action Replay Error: invalid AR code line: {0}", line);
|
||||
|
||||
if (!success_addr)
|
||||
PanicAlertFmtT("The address is invalid");
|
||||
|
||||
if (!success_val)
|
||||
PanicAlertFmtT("The value is invalid");
|
||||
}
|
||||
}
|
||||
if (std::holds_alternative<AREntry>(parse_result))
|
||||
current_code.ops.push_back(std::get<AREntry>(parse_result));
|
||||
else if (std::holds_alternative<EncryptedLine>(parse_result))
|
||||
encrypted_lines.emplace_back(std::get<EncryptedLine>(parse_result));
|
||||
else
|
||||
{
|
||||
pieces = SplitString(line, '-');
|
||||
if (pieces.size() == 3 && pieces[0].size() == 4 && pieces[1].size() == 4 &&
|
||||
pieces[2].size() == 5)
|
||||
{
|
||||
// Encrypted AR code
|
||||
// Decryption is done in "blocks", so we must push blocks into a vector,
|
||||
// then send to decrypt when a new block is encountered, or if it's the last block.
|
||||
encrypted_lines.emplace_back(pieces[0] + pieces[1] + pieces[2]);
|
||||
}
|
||||
}
|
||||
PanicAlertFmtT("Action Replay Error: invalid AR code line: {0}", line);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,7 +266,7 @@ void SaveCodes(IniFile* local_ini, const std::vector<ARCode>& codes)
|
||||
lines.emplace_back('$' + code.name);
|
||||
for (const ActionReplay::AREntry& op : code.ops)
|
||||
{
|
||||
lines.emplace_back(fmt::format("{:08X} {:08X}", op.cmd_addr, op.value));
|
||||
lines.emplace_back(SerializeLine(op));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -303,6 +276,39 @@ void SaveCodes(IniFile* local_ini, const std::vector<ARCode>& codes)
|
||||
local_ini->SetLines("ActionReplay", lines);
|
||||
}
|
||||
|
||||
std::variant<std::monostate, AREntry, EncryptedLine> DeserializeLine(const std::string& line)
|
||||
{
|
||||
std::vector<std::string> pieces = SplitString(line, ' ');
|
||||
|
||||
// Decrypted AR code
|
||||
if (pieces.size() == 2 && pieces[0].size() == 8 && pieces[1].size() == 8)
|
||||
{
|
||||
AREntry op;
|
||||
bool success_addr = TryParse(pieces[0], &op.cmd_addr, 16);
|
||||
bool success_val = TryParse(pieces[1], &op.value, 16);
|
||||
|
||||
if (success_addr && success_val)
|
||||
return op;
|
||||
}
|
||||
|
||||
// Encrypted AR code
|
||||
pieces = SplitString(line, '-');
|
||||
if (pieces.size() == 3 && pieces[0].size() == 4 && pieces[1].size() == 4 && pieces[2].size() == 5)
|
||||
{
|
||||
// Decryption is done in "blocks", so we can't decrypt right away. Instead we push blocks into
|
||||
// a vector, then send to decrypt when a new block is encountered, or if it's the last block.
|
||||
return pieces[0] + pieces[1] + pieces[2];
|
||||
}
|
||||
|
||||
// Parsing failed
|
||||
return std::monostate{};
|
||||
}
|
||||
|
||||
std::string SerializeLine(const AREntry& op)
|
||||
{
|
||||
return fmt::format("{:08X} {:08X}", op.cmd_addr, op.value);
|
||||
}
|
||||
|
||||
static void VLogInfo(std::string_view format, fmt::format_args args)
|
||||
{
|
||||
if (s_disable_logging)
|
||||
|
Reference in New Issue
Block a user