mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Move CheatFileParser out to the header, remove the line_ mmember variable
This commit is contained in:
1 parent
9c5b1c1b8b
commit
f21876b0b7
2 files changed
+70
-70
No files matched your search
+35
-69
@@ -43,75 +43,37 @@ using namespace SceCtrl;
|
||||
|
||||
void hleCheat(u64 userdata, int cyclesLate);
|
||||
|
||||
static inline std::string TrimString(const std::string &s) {
|
||||
static inline std::string TrimString(std::string_view s) {
|
||||
auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) {
|
||||
// isspace() expects 0 - 255, so convert any sign-extended value.
|
||||
return std::isspace(c & 0xFF);
|
||||
return std::isspace((u8)c);
|
||||
});
|
||||
auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c){
|
||||
return std::isspace(c & 0xFF);
|
||||
return std::isspace((u8)c);
|
||||
}).base();
|
||||
return wsback > wsfront ? std::string(wsfront, wsback) : std::string();
|
||||
}
|
||||
|
||||
class CheatFileParser {
|
||||
public:
|
||||
CheatFileParser(const Path &filename, const std::string &gameID = "") {
|
||||
fp_ = File::OpenCFile(filename, "rt");
|
||||
validGameID_ = ReplaceAll(gameID, "-", "");
|
||||
}
|
||||
~CheatFileParser() {
|
||||
if (fp_)
|
||||
fclose(fp_);
|
||||
}
|
||||
CheatFileParser::CheatFileParser(const Path &filename, std::string_view gameID) {
|
||||
fp_ = File::OpenCFile(filename, "rt");
|
||||
validGameID_ = ReplaceAll(gameID, "-", "");
|
||||
}
|
||||
|
||||
bool Parse();
|
||||
|
||||
std::vector<std::string> GetErrors() const {
|
||||
return errors_;
|
||||
}
|
||||
|
||||
std::vector<CheatCode> GetCheats() const {
|
||||
return cheats_;
|
||||
}
|
||||
|
||||
std::vector<CheatFileInfo> GetFileInfo() const {
|
||||
return cheatInfo_;
|
||||
}
|
||||
|
||||
protected:
|
||||
void Flush();
|
||||
void FlushCheatInfo();
|
||||
void AddError(const std::string &msg);
|
||||
void ParseLine(const std::string &line);
|
||||
void ParseDataLine(const std::string &line);
|
||||
bool ValidateGameID(const std::string &gameID);
|
||||
|
||||
FILE *fp_ = nullptr;
|
||||
std::string validGameID_;
|
||||
|
||||
int line_ = 0;
|
||||
int games_ = 0;
|
||||
std::vector<std::string> errors_;
|
||||
std::vector<CheatFileInfo> cheatInfo_;
|
||||
std::vector<CheatCode> cheats_;
|
||||
std::vector<CheatLine> pendingLines_;
|
||||
CheatFileInfo lastCheatInfo_;
|
||||
bool gameEnabled_ = true;
|
||||
bool gameRiskyEnabled_ = false;
|
||||
bool cheatEnabled_ = false;
|
||||
};
|
||||
CheatFileParser::~CheatFileParser() {
|
||||
if (fp_)
|
||||
fclose(fp_);
|
||||
}
|
||||
|
||||
bool CheatFileParser::Parse() {
|
||||
// Ugh, using a member variable as loop counter is bad.
|
||||
for (line_ = 1; fp_ && !feof(fp_); ++line_) {
|
||||
for (int lineNumber = 1; fp_ && !feof(fp_); ++lineNumber) {
|
||||
char temp[2048];
|
||||
char *tempLine = fgets(temp, sizeof(temp), fp_);
|
||||
if (!tempLine)
|
||||
continue;
|
||||
|
||||
// Detect UTF-8 BOM sequence, and ignore it.
|
||||
if (line_ == 1 && memcmp(tempLine, "\xEF\xBB\xBF", 3) == 0)
|
||||
if (lineNumber == 1 && memcmp(tempLine, "\xEF\xBB\xBF", 3) == 0)
|
||||
tempLine += 3;
|
||||
std::string line = TrimString(tempLine);
|
||||
|
||||
@@ -119,13 +81,13 @@ bool CheatFileParser::Parse() {
|
||||
// and a minimum of 1 displayable character in cheat name string "_C0 1"
|
||||
// which both equal to 5 characters.
|
||||
if (line.length() >= 5 && line[0] == '_') {
|
||||
ParseLine(line);
|
||||
ParseLine(line, lineNumber);
|
||||
} else if (line.length() >= 2 && line[0] == '/' && line[1] == '/') {
|
||||
// Comment, ignore.
|
||||
} else if (line.length() >= 1 && line[0] == '#') {
|
||||
// Comment, ignore.
|
||||
} else if (line.length() > 0) {
|
||||
errors_.push_back(StringFromFormat("Unrecognized content on line %d: expecting _", line_));
|
||||
errors_.push_back(StringFromFormat("Unrecognized content on line %d: expecting _", lineNumber));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,11 +111,11 @@ void CheatFileParser::FlushCheatInfo() {
|
||||
}
|
||||
}
|
||||
|
||||
void CheatFileParser::AddError(const std::string &err) {
|
||||
errors_.push_back(StringFromFormat("Error on line %d: %s", line_, err.c_str()));
|
||||
void CheatFileParser::AddError(const std::string &err, int lineNumber) {
|
||||
errors_.push_back(StringFromFormat("Error on line %d: %s", lineNumber, err.c_str()));
|
||||
}
|
||||
|
||||
void CheatFileParser::ParseLine(const std::string &line) {
|
||||
void CheatFileParser::ParseLine(const std::string &line, int lineNumber) {
|
||||
switch (line[1]) {
|
||||
case 'S':
|
||||
// Disc ID, validate (for multi-disc cheat files)?
|
||||
@@ -193,13 +155,13 @@ void CheatFileParser::ParseLine(const std::string &line) {
|
||||
|
||||
// Cheat name and activation status.
|
||||
if (line.length() >= 3 && line[2] >= '1' && line[2] <= '9') {
|
||||
lastCheatInfo_ = { line_, line.length() >= 5 ? line.substr(4) : "", true };
|
||||
lastCheatInfo_ = { lineNumber, line.length() >= 5 ? line.substr(4) : "", true };
|
||||
cheatEnabled_ = true;
|
||||
} else if (line.length() >= 3 && line[2] == '0') {
|
||||
lastCheatInfo_ = { line_, line.length() >= 5 ? line.substr(4) : "", false };
|
||||
lastCheatInfo_ = { lineNumber, line.length() >= 5 ? line.substr(4) : "", false };
|
||||
cheatEnabled_ = false;
|
||||
} else {
|
||||
AddError("could not parse cheat name line");
|
||||
AddError("could not parse cheat name line", lineNumber);
|
||||
cheatEnabled_ = false;
|
||||
return;
|
||||
}
|
||||
@@ -207,24 +169,25 @@ void CheatFileParser::ParseLine(const std::string &line) {
|
||||
|
||||
case 'L':
|
||||
// CwCheat data line.
|
||||
ParseDataLine(line.substr(2));
|
||||
ParseDataLine(line.substr(2), lineNumber);
|
||||
return;
|
||||
|
||||
case 'M':
|
||||
// TempAR data line.
|
||||
AddError("TempAR codes not supported");
|
||||
AddError("TempAR codes not supported", lineNumber);
|
||||
return;
|
||||
|
||||
default:
|
||||
AddError("unknown line type");
|
||||
AddError("unknown line type", lineNumber);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CheatFileParser::ParseDataLine(const std::string &line) {
|
||||
void CheatFileParser::ParseDataLine(const std::string &line, int lineNumber) {
|
||||
if (!gameEnabled_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cheatEnabled_) {
|
||||
FlushCheatInfo();
|
||||
return;
|
||||
@@ -234,15 +197,15 @@ void CheatFileParser::ParseDataLine(const std::string &line) {
|
||||
int len = 0;
|
||||
if (sscanf(line.c_str(), "%x %x %n", &cheatLine.part1, &cheatLine.part2, &len) == 2) {
|
||||
if ((size_t)len < line.length()) {
|
||||
AddError("junk after line data");
|
||||
AddError("junk after line data", lineNumber);
|
||||
}
|
||||
pendingLines_.push_back(cheatLine);
|
||||
} else {
|
||||
AddError("expecting two values");
|
||||
AddError("expecting two values", lineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
bool CheatFileParser::ValidateGameID(const std::string &gameID) {
|
||||
bool CheatFileParser::ValidateGameID(std::string_view gameID) {
|
||||
return validGameID_.empty() || ReplaceAll(TrimString(gameID), "-", "") == validGameID_;
|
||||
}
|
||||
|
||||
@@ -359,14 +322,14 @@ void hleCheat(u64 userdata, int cyclesLate) {
|
||||
if (!cheatEngine || !cheatsEnabled)
|
||||
return;
|
||||
|
||||
if (g_Config.bReloadCheats) { //Checks if the "reload cheats" button has been pressed.
|
||||
if (g_Config.bReloadCheats) { // Checks if the "reload cheats" button has been pressed.
|
||||
cheatEngine->ParseCheats();
|
||||
g_Config.bReloadCheats = false;
|
||||
}
|
||||
cheatEngine->Run();
|
||||
}
|
||||
|
||||
CWCheatEngine::CWCheatEngine(const std::string &gameID) : gameID_(gameID) {
|
||||
CWCheatEngine::CWCheatEngine(std::string_view gameID) : gameID_(gameID) {
|
||||
filename_ = GetSysDirectory(DIRECTORY_CHEATS) / (gameID_ + ".ini");
|
||||
}
|
||||
|
||||
@@ -390,7 +353,10 @@ void CWCheatEngine::ParseCheats() {
|
||||
CheatFileParser parser(filename_, gameID_);
|
||||
|
||||
parser.Parse();
|
||||
// TODO: Report errors.
|
||||
// TODO: Report errors in a user-visible way.
|
||||
for (auto &error : parser.GetErrors()) {
|
||||
ERROR_LOG(Log::System, "CwCheat error: %s", error.c_str());
|
||||
}
|
||||
|
||||
cheats_ = parser.GetCheats();
|
||||
}
|
||||
|
||||
+35
-1
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -39,7 +40,7 @@ struct CheatOperation;
|
||||
|
||||
class CWCheatEngine {
|
||||
public:
|
||||
CWCheatEngine(const std::string &gameID);
|
||||
CWCheatEngine(std::string_view gameID);
|
||||
std::vector<CheatFileInfo> FileInfo() const;
|
||||
void ParseCheats();
|
||||
void CreateCheatFile();
|
||||
@@ -69,3 +70,36 @@ private:
|
||||
std::string gameID_;
|
||||
Path filename_;
|
||||
};
|
||||
|
||||
class CheatFileParser {
|
||||
public:
|
||||
CheatFileParser(const Path &filename, std::string_view gameID = "");
|
||||
~CheatFileParser();
|
||||
|
||||
bool Parse();
|
||||
|
||||
const std::vector<std::string> &GetErrors() const { return errors_; }
|
||||
const std::vector<CheatCode> &GetCheats() const { return cheats_; }
|
||||
const std::vector<CheatFileInfo> &GetFileInfo() const { return cheatInfo_; }
|
||||
|
||||
protected:
|
||||
void Flush();
|
||||
void FlushCheatInfo();
|
||||
void AddError(const std::string &msg, int lineNumber);
|
||||
void ParseLine(const std::string &line, int lineNumber);
|
||||
void ParseDataLine(const std::string &line, int lineNumber);
|
||||
bool ValidateGameID(std::string_view gameID);
|
||||
|
||||
FILE *fp_ = nullptr;
|
||||
std::string validGameID_;
|
||||
|
||||
int games_ = 0;
|
||||
std::vector<std::string> errors_;
|
||||
std::vector<CheatFileInfo> cheatInfo_;
|
||||
std::vector<CheatCode> cheats_;
|
||||
std::vector<CheatLine> pendingLines_;
|
||||
CheatFileInfo lastCheatInfo_;
|
||||
bool gameEnabled_ = true;
|
||||
bool gameRiskyEnabled_ = false;
|
||||
bool cheatEnabled_ = false;
|
||||
};
|
||||
Reference in new issue
Block a user