CheatList: Allow passing in strings instead of filenames

This commit is contained in:
Connor McLaughlin 2020-11-07 20:36:30 +10:00
parent 6828082f8b
commit b6ec587e5b
2 changed files with 57 additions and 24 deletions

View file

@ -116,19 +116,26 @@ static const std::string* FindKey(const KeyValuePairVector& kvp, const char* sea
bool CheatList::LoadFromPCSXRFile(const char* filename) bool CheatList::LoadFromPCSXRFile(const char* filename)
{ {
auto fp = FileSystem::OpenManagedCFile(filename, "rb"); std::optional<std::string> str = FileSystem::ReadFileToString(filename);
if (!fp) if (!str.has_value() || str->empty())
return false; return false;
char line[1024]; return LoadFromPCSXRString(str.value());
}
bool CheatList::LoadFromPCSXRString(const std::string& str)
{
std::istringstream iss(str);
std::string line;
std::string comments; std::string comments;
std::string group; std::string group;
CheatCode::Type type = CheatCode::Type::Gameshark; CheatCode::Type type = CheatCode::Type::Gameshark;
CheatCode::Activation activation = CheatCode::Activation::EndFrame; CheatCode::Activation activation = CheatCode::Activation::EndFrame;
CheatCode current_code; CheatCode current_code;
while (std::fgets(line, sizeof(line), fp.get())) while (std::getline(iss, line))
{ {
char* start = line; char* start = line.data();
while (*start != '\0' && std::isspace(*start)) while (*start != '\0' && std::isspace(*start))
start++; start++;
@ -227,21 +234,27 @@ bool CheatList::LoadFromPCSXRFile(const char* filename)
m_codes.push_back(std::move(current_code)); m_codes.push_back(std::move(current_code));
} }
Log_InfoPrintf("Loaded %zu cheats from '%s' (PCSXR format)", m_codes.size(), filename); Log_InfoPrintf("Loaded %zu cheats (PCSXR format)", m_codes.size());
return !m_codes.empty(); return !m_codes.empty();
} }
bool CheatList::LoadFromLibretroFile(const char* filename) bool CheatList::LoadFromLibretroFile(const char* filename)
{ {
auto fp = FileSystem::OpenManagedCFile(filename, "rb"); std::optional<std::string> str = FileSystem::ReadFileToString(filename);
if (!fp) if (!str.has_value() || str->empty())
return false; return false;
char line[1024]; return LoadFromLibretroString(str.value());
}
bool CheatList::LoadFromLibretroString(const std::string& str)
{
std::istringstream iss(str);
std::string line;
KeyValuePairVector kvp; KeyValuePairVector kvp;
while (std::fgets(line, sizeof(line), fp.get())) while (std::getline(iss, line))
{ {
char* start = line; char* start = line.data();
while (*start != '\0' && std::isspace(*start)) while (*start != '\0' && std::isspace(*start))
start++; start++;
@ -312,7 +325,7 @@ bool CheatList::LoadFromLibretroFile(const char* filename)
const std::string* enable = FindKey(kvp, TinyString::FromFormat("cheat%u_enable", i)); const std::string* enable = FindKey(kvp, TinyString::FromFormat("cheat%u_enable", i));
if (!desc || !code || !enable) if (!desc || !code || !enable)
{ {
Log_WarningPrintf("Missing desc/code/enable for cheat %u in '%s'", i, filename); Log_WarningPrintf("Missing desc/code/enable for cheat %u", i);
continue; continue;
} }
@ -324,7 +337,7 @@ bool CheatList::LoadFromLibretroFile(const char* filename)
m_codes.push_back(std::move(cc)); m_codes.push_back(std::move(cc));
} }
Log_InfoPrintf("Loaded %zu cheats from '%s' (libretro format)", m_codes.size(), filename); Log_InfoPrintf("Loaded %zu cheats (libretro format)", m_codes.size());
return !m_codes.empty(); return !m_codes.empty();
} }
@ -409,14 +422,20 @@ void CheatList::RemoveCode(u32 i)
std::optional<CheatList::Format> CheatList::DetectFileFormat(const char* filename) std::optional<CheatList::Format> CheatList::DetectFileFormat(const char* filename)
{ {
auto fp = FileSystem::OpenManagedCFile(filename, "rb"); std::optional<std::string> str = FileSystem::ReadFileToString(filename);
if (!fp) if (!str.has_value() || str->empty())
return Format::Count; return std::nullopt;
char line[1024]; return DetectFileFormat(str.value());
while (std::fgets(line, sizeof(line), fp.get())) }
CheatList::Format CheatList::DetectFileFormat(const std::string& str)
{
std::istringstream iss(str);
std::string line;
while (std::getline(iss, line))
{ {
char* start = line; char* start = line.data();
while (*start != '\0' && std::isspace(*start)) while (*start != '\0' && std::isspace(*start))
start++; start++;
@ -431,7 +450,7 @@ std::optional<CheatList::Format> CheatList::DetectFileFormat(const char* filenam
end--; end--;
} }
if (std::strncmp(line, "cheats", 6) == 0) if (std::strncmp(line.data(), "cheats", 6) == 0)
return Format::Libretro; return Format::Libretro;
else else
return Format::PCSXR; return Format::PCSXR;
@ -441,16 +460,25 @@ std::optional<CheatList::Format> CheatList::DetectFileFormat(const char* filenam
} }
bool CheatList::LoadFromFile(const char* filename, Format format) bool CheatList::LoadFromFile(const char* filename, Format format)
{
std::optional<std::string> str = FileSystem::ReadFileToString(filename);
if (!str.has_value() || str->empty())
return false;
return LoadFromString(str.value(), format);
}
bool CheatList::LoadFromString(const std::string& str, Format format)
{ {
if (format == Format::Autodetect) if (format == Format::Autodetect)
format = DetectFileFormat(filename).value_or(Format::Count); format = DetectFileFormat(str);
if (format == Format::PCSXR) if (format == Format::PCSXR)
return LoadFromPCSXRFile(filename); return LoadFromPCSXRString(str);
else if (format == Format::Libretro) else if (format == Format::Libretro)
return LoadFromLibretroFile(filename); return LoadFromLibretroString(str);
Log_ErrorPrintf("Invalid or unknown format for '%s'", filename); Log_ErrorPrintf("Invalid or unknown cheat format");
return false; return false;
} }

View file

@ -116,12 +116,17 @@ public:
void SetCodeEnabled(u32 index, bool state); void SetCodeEnabled(u32 index, bool state);
static std::optional<Format> DetectFileFormat(const char* filename); static std::optional<Format> DetectFileFormat(const char* filename);
static Format DetectFileFormat(const std::string& str);
static bool ParseLibretroCheat(CheatCode* cc, const char* line); static bool ParseLibretroCheat(CheatCode* cc, const char* line);
bool LoadFromFile(const char* filename, Format format); bool LoadFromFile(const char* filename, Format format);
bool LoadFromPCSXRFile(const char* filename); bool LoadFromPCSXRFile(const char* filename);
bool LoadFromLibretroFile(const char* filename); bool LoadFromLibretroFile(const char* filename);
bool LoadFromString(const std::string& str, Format format);
bool LoadFromPCSXRString(const std::string& str);
bool LoadFromLibretroString(const std::string& str);
bool SaveToPCSXRFile(const char* filename); bool SaveToPCSXRFile(const char* filename);
void Apply(); void Apply();