diff --git a/Core/Config.cpp b/Core/Config.cpp index ff381e219e..0418eac3a5 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1215,8 +1215,7 @@ void Config::Save(const char *saveReason) { g_Config.iCpuCore = (int)CPUCore::JIT; } if (iniFilename_.size() && g_Config.bSaveSettings) { - - saveGameConfig(gameId_); + saveGameConfig(gameId_, gameIdTitle_); CleanRecent(); IniFile iniFile; @@ -1452,9 +1451,10 @@ bool Config::hasGameConfig(const std::string &pGameId) { return File::Exists(fullIniFilePath); } -void Config::changeGameSpecific(const std::string &pGameId) { +void Config::changeGameSpecific(const std::string &pGameId, const std::string &title) { Save("changeGameSpecific"); gameId_ = pGameId; + gameIdTitle_ = title; bGameSpecific = !pGameId.empty(); } @@ -1484,7 +1484,7 @@ std::string Config::getGameConfigFile(const std::string &pGameId) { return iniFileNameFull; } -bool Config::saveGameConfig(const std::string &pGameId) { +bool Config::saveGameConfig(const std::string &pGameId, const std::string &title) { if (pGameId.empty()) { return false; } @@ -1493,6 +1493,9 @@ bool Config::saveGameConfig(const std::string &pGameId) { IniFile iniFile; + IniFile::Section *top = iniFile.GetOrCreateSection(""); + top->AddComment(StringFromFormat("Game config for %s - %s", pGameId.c_str(), title.c_str())); + IterateSettings(iniFile, [](IniFile::Section *section, ConfigSetting *setting) { if (setting->perGame_) { setting->Set(section); diff --git a/Core/Config.h b/Core/Config.h index ae736a912a..a81a7f05e8 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -410,11 +410,11 @@ public: void RestoreDefaults(); //per game config managment, should maybe be in it's own class - void changeGameSpecific(const std::string &gameId = ""); + void changeGameSpecific(const std::string &gameId = "", const std::string &title = ""); bool createGameConfig(const std::string &game_id); bool deleteGameConfig(const std::string& pGameId); bool loadGameConfig(const std::string &game_id); - bool saveGameConfig(const std::string &pGameId); + bool saveGameConfig(const std::string &pGameId, const std::string &title); void unloadGameConfig(); std::string getGameConfigFile(const std::string &gameId); bool hasGameConfig(const std::string &game_id); @@ -446,6 +446,7 @@ protected: private: std::string gameId_; + std::string gameIdTitle_; std::string iniFilename_; std::string controllerIniFilename_; std::vector searchPath_; diff --git a/Core/Util/GameManager.cpp b/Core/Util/GameManager.cpp index 909f798a73..62d1da47cb 100644 --- a/Core/Util/GameManager.cpp +++ b/Core/Util/GameManager.cpp @@ -287,7 +287,7 @@ bool GameManager::ExtractFile(struct zip *z, int file_index, std::string outFile while (pos < size) { size_t readSize = std::min(blockSize, size - pos); ssize_t retval = zip_fread(zf, buffer, readSize); - if (retval < readSize) { + if (retval < 0 || (size_t)retval < readSize) { ERROR_LOG(HLE, "Failed to read %d bytes from zip (%d) - archive corrupt?", (int)readSize, (int)retval); delete[] buffer; fclose(f); diff --git a/UI/GameScreen.cpp b/UI/GameScreen.cpp index b48ef1c7d4..98f235d187 100644 --- a/UI/GameScreen.cpp +++ b/UI/GameScreen.cpp @@ -159,7 +159,7 @@ UI::EventReturn GameScreen::OnCreateConfig(UI::EventParams &e) { return UI::EVENT_SKIPPED; } g_Config.createGameConfig(info->id); - g_Config.saveGameConfig(info->id); + g_Config.saveGameConfig(info->id, info->GetTitle()); info->hasConfig = true; screenManager()->topScreen()->RecreateViews(); diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index f99e5e8f9a..2d17643cdd 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -472,11 +472,11 @@ void GamePauseScreen::CallbackDeleteConfig(bool yes) UI::EventReturn GamePauseScreen::OnCreateConfig(UI::EventParams &e) { + std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0); std::string gameId = g_paramSFO.GetDiscID(); g_Config.createGameConfig(gameId); - g_Config.changeGameSpecific(gameId); - g_Config.saveGameConfig(gameId); - std::shared_ptr info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0); + g_Config.changeGameSpecific(gameId, info->GetTitle()); + g_Config.saveGameConfig(gameId, info->GetTitle()); if (info) { info->hasConfig = true; } diff --git a/ext/native/file/ini_file.cpp b/ext/native/file/ini_file.cpp index 6ce218441d..99bdcd163a 100644 --- a/ext/native/file/ini_file.cpp +++ b/ext/native/file/ini_file.cpp @@ -237,11 +237,15 @@ void IniFile::Section::Set(const char* key, const std::vector& newV temp += (*it) + ","; } // remove last , - if (temp.length()) - temp.resize(temp.length() - 1); + if (temp.length()) + temp.resize(temp.length() - 1); Set(key, temp.c_str()); } +void IniFile::Section::AddComment(const std::string &comment) { + lines.push_back("# " + comment); +} + bool IniFile::Section::Get(const char* key, std::vector& values) { std::string temp; @@ -549,28 +553,25 @@ bool IniFile::Load(std::istream &in) { } #endif - if (line.size() > 0) - { - if (line[0] == '[') - { - size_t endpos = line.find("]"); - - if (endpos != std::string::npos) - { - // New section! - std::string sub = line.substr(1, endpos - 1); - sections.push_back(Section(sub)); - - if (endpos + 1 < line.size()) - { - sections[sections.size() - 1].comment = line.substr(endpos + 1); - } - } + if (!line.empty()) { + size_t sectionNameEnd = std::string::npos; + if (line[0] == '[') { + sectionNameEnd = line.find(']'); } - else - { - if (sections.size() > 0) - sections[sections.size() - 1].lines.push_back(line); + + if (sectionNameEnd != std::string::npos) { + // New section! + std::string sub = line.substr(1, sectionNameEnd - 1); + sections.push_back(Section(sub)); + + if (sectionNameEnd + 1 < line.size()) { + sections[sections.size() - 1].comment = line.substr(sectionNameEnd + 1); + } + } else { + if (sections.empty()) { + sections.push_back(Section("")); + } + sections[sections.size() - 1].lines.push_back(line); } } } @@ -595,22 +596,12 @@ bool IniFile::Save(const char* filename) // UTF-8 byte order mark. To make sure notepad doesn't go nuts. out << "\xEF\xBB\xBF"; - // Currently testing if dolphin community can handle the requirements of C++11 compilation - // If you get a compiler error on this line, your compiler is probably old. - // Update to g++ 4.4 or a recent version of clang (XCode 4.2 on OS X). - // If you don't want to update, complain in a google code issue, the dolphin forums or #dolphin-emu. - for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) - { - const Section& section = *iter; - - if (section.name() != "") - { + for (const Section §ion : sections) { + if (!section.name().empty() && (!section.lines.empty() || !section.comment.empty())) { out << "[" << section.name() << "]" << section.comment << std::endl; } - for (std::vector::const_iterator liter = section.lines.begin(); liter != section.lines.end(); ++liter) - { - std::string s = *liter; + for (const std::string &s : section.lines) { out << s << std::endl; } } diff --git a/ext/native/file/ini_file.h b/ext/native/file/ini_file.h index e64238b62d..ba63ab1ab5 100644 --- a/ext/native/file/ini_file.h +++ b/ext/native/file/ini_file.h @@ -76,6 +76,8 @@ public: template void Set(const char *key, T *ptr); + void AddComment(const std::string &comment); + bool Get(const char* key, int* value, int defaultValue = 0); bool Get(const char* key, uint32_t* value, uint32_t defaultValue = 0); bool Get(const char* key, bool* value, bool defaultValue = false);