// Copyright 2010 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #include #include #include #include "Common/IniFile.h" #include "Common/StringUtil.h" #include "Core/GeckoCodeConfig.h" namespace Gecko { void LoadCodes(const IniFile& globalIni, const IniFile& localIni, std::vector& gcodes) { const IniFile* inis[2] = { &globalIni, &localIni }; for (const IniFile* ini : inis) { std::vector lines; ini->GetLines("Gecko", &lines, false); GeckoCode gcode; for (auto& line : lines) { if (line.empty()) continue; std::istringstream ss(line); switch ((line)[0]) { // enabled or disabled code case '+' : ss.seekg(1); case '$' : if (gcode.name.size()) gcodes.push_back(gcode); gcode = GeckoCode(); gcode.enabled = (1 == ss.tellg()); // silly gcode.user_defined = (ini == &localIni); ss.seekg(1, std::ios_base::cur); // read the code name std::getline(ss, gcode.name, '['); // stop at [ character (beginning of contributor name) gcode.name = StripSpaces(gcode.name); // read the code creator name std::getline(ss, gcode.creator, ']'); break; // notes case '*': gcode.notes.push_back(std::string(++line.begin(), line.end())); break; // either part of the code, or an option choice default : { GeckoCode::Code new_code; // TODO: support options new_code.original_line = line; ss >> std::hex >> new_code.address >> new_code.data; gcode.codes.push_back(new_code); } break; } } // add the last code if (gcode.name.size()) { gcodes.push_back(gcode); } ini->GetLines("Gecko_Enabled", &lines, false); for (const std::string& line : lines) { if (line.size() == 0 || line[0] != '$') { continue; } std::string name = line.substr(1); for (GeckoCode& ogcode : gcodes) { if (ogcode.name == name) { ogcode.enabled = true; } } } } } // used by the SaveGeckoCodes function static void SaveGeckoCode(std::vector& lines, std::vector& enabledLines, const GeckoCode& gcode) { if (gcode.enabled) enabledLines.push_back("$" + gcode.name); if (!gcode.user_defined) return; std::string name; // save the name name += '$'; name += gcode.name; // save the creator name if (gcode.creator.size()) { name += " ["; name += gcode.creator; name += ']'; } lines.push_back(name); // save all the code lines for (const GeckoCode::Code& code : gcode.codes) { //ss << std::hex << codes_iter->address << ' ' << codes_iter->data; //lines.push_back(StringFromFormat("%08X %08X", codes_iter->address, codes_iter->data)); lines.push_back(code.original_line); //ss.clear(); } // save the notes for (const std::string& note : gcode.notes) lines.push_back(std::string("*") + note); } void SaveCodes(IniFile& inifile, const std::vector& gcodes) { std::vector lines; std::vector enabledLines; for (const GeckoCode& geckoCode : gcodes) { SaveGeckoCode(lines, enabledLines, geckoCode); } inifile.SetLines("Gecko", lines); inifile.SetLines("Gecko_Enabled", enabledLines); } }