diff --git a/payload/Autobleem 0.8.0 release notes.txt b/payload/Autobleem 0.8.1 release notes.txt similarity index 85% rename from payload/Autobleem 0.8.0 release notes.txt rename to payload/Autobleem 0.8.1 release notes.txt index 1ba8441..6587cef 100644 --- a/payload/Autobleem 0.8.0 release notes.txt +++ b/payload/Autobleem 0.8.1 release notes.txt @@ -1,5 +1,21 @@ + ***************************** + Autobleem-0.8.1 Release Notes + ***************************** + +Fixes two problems in 0.8.0. + +1) Fixes a crash when you start Evo UI if the /Games directory is empty. + +2) Fixes always forcing a rescan if there are games that failed the verify + step and were removed from the game list display. + +In addition Autobleem now splashes a message on screen if a game fails the verify. +The reason or reasons the game failed to verify are also output to +/Autobleem/bin/autobleem/gamesThatFailedVerifyCheck.txt. + + ***************************** Autobleem-0.8.0 Release Notes ***************************** diff --git a/src/code/engine/GetGameDirHierarchy.cpp b/src/code/engine/GetGameDirHierarchy.cpp index cc7b49e..5b5aeb0 100644 --- a/src/code/engine/GetGameDirHierarchy.cpp +++ b/src/code/engine/GetGameDirHierarchy.cpp @@ -174,10 +174,16 @@ void GamesHierarchy::getHierarchy(const std::string & path) { gameSubDirRows.emplace_back(top); top->scanAll(); - // remove and any thaat have nothing to display - auto it = remove_if(begin(gameSubDirRows), end(gameSubDirRows), [&] (GameSubDirPtr &subdir) { return subdir->gamesToDisplay.size() == 0; }); + // remove and any that have nothing to display + auto it = remove_if(begin(gameSubDirRows), end(gameSubDirRows), [&] (GameSubDirPtr &subdir) + { return subdir->gamesToDisplay.size() == 0; }); gameSubDirRows.erase(it, end(gameSubDirRows)); + // if we removed top because there no games at all then put it back so we can display that /Games + // has 0 games + if (gameSubDirRows.size() == 0) + gameSubDirRows.emplace_back(top); + int rowIndex = 0; for (auto & row : gameSubDirRows) { row->displayRowIndex = rowIndex++; // put the row index into the row for print and debugging convenience. diff --git a/src/code/engine/game.cpp b/src/code/engine/game.cpp index bb052eb..e8423d6 100644 --- a/src/code/engine/game.cpp +++ b/src/code/engine/game.cpp @@ -13,6 +13,7 @@ #include #include "../engine/scanner.h" #include "../environment.h" +#include "../lang.h" using namespace std; @@ -74,33 +75,63 @@ string USBGame::valueOrDefault(string name, string def, bool setAutomationIfDefa //******************************* // USBGame::verify //******************************* -bool USBGame::verify() { +bool USBGame::verify(std::vector *failureReasons) { bool result = true; - if (discs.size() == 0) + if (discs.size() == 0) { + if (failureReasons) + failureReasons->emplace_back(_("No discs")); result = false; + } for (int i = 0; i < discs.size(); i++) { - if (discs[i].diskName.length() == 0) + if (discs[i].diskName.length() == 0) { + if (failureReasons) + failureReasons->emplace_back(_("No disc name")); result = false; - if (!discs[i].cueFound) + } + if (!discs[i].cueFound) { + if (failureReasons) + failureReasons->emplace_back(_("Cue file not found")); result = false; - if (!discs[i].binVerified) + } + if (!discs[i].binVerified) { + if (failureReasons) + failureReasons->emplace_back(_("Bin file failed to verify")); result = false; + } } - if (!gameDataFound) + if (!gameDataFound) { + if (failureReasons) + failureReasons->emplace_back(_("Game file not found")); result = false; - if (!gameIniFound) + } + if (!gameIniFound) { + if (failureReasons) + failureReasons->emplace_back(_("Game.ini file not found")); result = false; - if (!gameIniValid) + } + if (!gameIniValid) { + if (failureReasons) + failureReasons->emplace_back(_("Game.ini file not valid")); result = false; - if (!coverImageFound) + } + if (!coverImageFound) { + if (failureReasons) + failureReasons->emplace_back(_("Cover image file not found")); result = false; - if (!licFound) + } + if (!licFound) { + if (failureReasons) + failureReasons->emplace_back(_(".lic file not found")); result = false; - if (!pcsxCfgFound) + } + if (!pcsxCfgFound) { + if (failureReasons) + failureReasons->emplace_back(_("pcsx.cfg file not found")); result = false; + } if (!result) { cerr << "Game: " << title << " Validation Failed" << endl; @@ -139,11 +170,14 @@ bool USBGame::print() { cout << " BIN correct: " << discs[i].binVerified << endl; } - bool result = verify(); + vector failureReasons; + bool result = verify(&failureReasons); if (result) { - cout << "-------OK-------" << endl; + cout << "-------Game Verify OK-------" << endl; } else { - cout << "------FAIL------" << endl; + cout << "------Game Verify FAIL------" << endl; + for (const auto & reason : failureReasons) + cout << "Reason: " << reason << endl; } return result; diff --git a/src/code/engine/game.h b/src/code/engine/game.h index 4a3e881..5e13307 100644 --- a/src/code/engine/game.h +++ b/src/code/engine/game.h @@ -61,7 +61,7 @@ class USBGame { void readIni(std::string path); void saveIni(std::string path); void recoverMissingFiles(); - bool verify(); + bool verify(std::vector *failureReasons = nullptr); bool print(); void updateObj(); bool validateCue(std::string cuePath, std::string path); diff --git a/src/code/engine/inifile.cpp b/src/code/engine/inifile.cpp index df175ba..9496597 100644 --- a/src/code/engine/inifile.cpp +++ b/src/code/engine/inifile.cpp @@ -12,6 +12,7 @@ using namespace std; //******************************* // Inifile::load +// warning: load()is being used to append/overwrite default theme.ini values to an existing theme.ini values //******************************* void Inifile::load(const string & _path) { this->path = _path; diff --git a/src/code/engine/inifile.h b/src/code/engine/inifile.h index cebd21d..9b368ac 100644 --- a/src/code/engine/inifile.h +++ b/src/code/engine/inifile.h @@ -30,6 +30,7 @@ class Inifile { std::string entry=""; // example: "007 Racing (USA)" std::map values; // see example data above + // warning: load()is being used to append/overwrite default theme.ini values to an existing theme.ini values void load(const std::string & path); void save(const std::string & path); void print(); diff --git a/src/code/engine/scanner.cpp b/src/code/engine/scanner.cpp index 833602d..fbe5e21 100644 --- a/src/code/engine/scanner.cpp +++ b/src/code/engine/scanner.cpp @@ -403,7 +403,7 @@ void Scanner::scanUSBGamesDirectory(GamesHierarchy &gamesHierarchy) { //cout << "serial: " << game->serial << ", region: " << game->region << ", " << game->title <gameIniFound || game->automationUsed) { + if ( !game->gameIniFound || game->automationUsed || (game->discs.size()==0) ) { if (!game->serial.empty()) { //cout << "Accessing metadata for serial: " << game->serial << endl; @@ -446,7 +446,8 @@ void Scanner::scanUSBGamesDirectory(GamesHierarchy &gamesHierarchy) { game->readIni(gameIniPath); // the updated iniValues are needed for updateObj //game->print(); - if (game->verify()) { + vector failureReasons; + if (game->verify(&failureReasons)) { gamesToAddToDB.push_back(game); string memcardPath = game->saveStatePath + sep + "memcards/"; @@ -465,7 +466,11 @@ void Scanner::scanUSBGamesDirectory(GamesHierarchy &gamesHierarchy) { DirEntry::generateM3UForDirectory(game->fullPath, game->discs[0].cueName); } else { + splash->logText(_("Game failed to verify:") + " " + game->fullPath); + sleep(3); badGameFile << "Game failed to verify: " << game->fullPath << endl; + for (const auto & reason : failureReasons) + badGameFile << "Reason: " << reason << endl; // the game did not pass the verify step and was not added to the DB. // remove the game everywhere in the gamesHierarchy @@ -489,6 +494,7 @@ void Scanner::scanUSBGamesDirectory(GamesHierarchy &gamesHierarchy) { gamesHierarchy.dumpRowDisplayGameInfo(outfile, true); outfile.close(); + noGamesFoundDuringScan = (gamesToAddToDB.size() == 0); complete = true; } diff --git a/src/code/engine/scanner.h b/src/code/engine/scanner.h index a294b47..5798278 100644 --- a/src/code/engine/scanner.h +++ b/src/code/engine/scanner.h @@ -21,7 +21,7 @@ class Scanner { Scanner() {} USBGames gamesToAddToDB; bool forceScan=false; - bool noGamesFound=false; + bool noGamesFoundDuringScan=false; void scanUSBGamesDirectory(GamesHierarchy &gamesHierarchy); void repairBrokenCueFiles(const std::string & path); diff --git a/src/code/environment.cpp b/src/code/environment.cpp index b5bf3a4..7d02740 100644 --- a/src/code/environment.cpp +++ b/src/code/environment.cpp @@ -93,6 +93,16 @@ string Environment::getWorkingPath() { #endif } +//******************************* +// Environment::getSonyPath +// 1 arg: "usb:/Autobleem/bin/autobleem/sony" +// 2 arg: autobleem-gui executable dir + sep + "sony" +// PSC: autobleem-gui executable dir +//******************************* +string Environment::getSonyPath() { + return getWorkingPath() + sep + "sony"; +} + #if 0 //******************************* // Environment::getPathToWorkingPathFile diff --git a/src/code/environment.h b/src/code/environment.h index eed384b..823e9b6 100644 --- a/src/code/environment.h +++ b/src/code/environment.h @@ -16,6 +16,7 @@ struct Environment { static std::string getPathToInternalDBFile(); // includes the "internal.db" filename static std::string getWorkingPath(); // 1 arg: "usb:/Autobleem/bin/autobleem", 2 arg: autobleem-gui executable dir + static std::string getSonyPath(); // 1 arg: "usb:/Autobleem/bin/autobleem/sony", 2 arg: "" + sep + "sony" // static std::string getPathToWorkingPathFile(const std::string &filename); // return path to file in working path static std::string getPathToThemesDir(); // "usb:/themes" or "./themes" diff --git a/src/code/gui/gui.cpp b/src/code/gui/gui.cpp index 958b167..dfa5102 100644 --- a/src/code/gui/gui.cpp +++ b/src/code/gui/gui.cpp @@ -70,7 +70,7 @@ string GuiBase::getCurrentThemePath() { #if defined(__x86_64__) || defined(_M_X64) string path = Env::getPathToThemesDir() + sep + cfg.inifile.values["theme"]; if (!DirEntry::exists(path)) { - path = "./sony"; + path = Env::getSonyPath(); } return path; #else @@ -90,7 +90,7 @@ string GuiBase::getCurrentThemeImagePath() { #if defined(__x86_64__) || defined(_M_X64) string path = getCurrentThemePath() + sep + "images"; if (!DirEntry::exists(path)) { - path = "./sony/images"; + path = Env::getSonyPath() + sep + "images"; } return path; #else @@ -110,7 +110,7 @@ string GuiBase::getCurrentThemeSoundPath() { #if defined(__x86_64__) || defined(_M_X64) string path = getCurrentThemePath() + sep + "sounds"; if (!DirEntry::exists(path)) { - path = "./sony/sounds"; + path = Env::getSonyPath() + sep + "sounds"; } return path; #else @@ -130,7 +130,7 @@ string GuiBase::getCurrentThemeFontPath() { #if defined(__x86_64__) || defined(_M_X64) string path = getCurrentThemePath() + sep + "font"; if (!DirEntry::exists(path)) { - path = "./sony/font"; + path = Env::getSonyPath() + sep + "font"; } return path; #else @@ -561,7 +561,7 @@ void Gui::menuSelection() { cout << "--" << SDL_JoystickName(joystick) << endl; } // Check if all OK - if (scanner->noGamesFound) { + if (scanner->noGamesFoundDuringScan) { criticalException(_("WARNING: NO GAMES FOUND. PRESS ANY BUTTON.")); } // diff --git a/src/code/launcher/gui_launcher.cpp b/src/code/launcher/gui_launcher.cpp index ddb2f7e..96f038a 100644 --- a/src/code/launcher/gui_launcher.cpp +++ b/src/code/launcher/gui_launcher.cpp @@ -59,6 +59,8 @@ void GuiLauncher::getGames_SET_FAVORITE(PsGames* gamesList) { void GuiLauncher::getGames_SET_SUBDIR(int rowIndex, PsGames* gamesList) { GameRowInfos gameRowInfos; gui->db->getGameRowInfos(&gameRowInfos); + if (gameRowInfos.size() == 0) + return; // no games! currentUSBGameDirName = gameRowInfos[rowIndex].rowName; #if 0 for (auto &gameRowInfo : gameRowInfos) diff --git a/src/code/launcher/gui_launcher_loop.cpp b/src/code/launcher/gui_launcher_loop.cpp index d8b7eac..7c7072b 100644 --- a/src/code/launcher/gui_launcher_loop.cpp +++ b/src/code/launcher/gui_launcher_loop.cpp @@ -298,7 +298,7 @@ void GuiLauncher::loop_chooseGameDir() { GameRowInfos gameRowInfos; gui->db->getGameRowInfos(&gameRowInfos); if (gameRowInfos.size() == 0) { - // abort + return; // no games! } auto guiGameDirMenu = new GuiGameDirMenu(renderer); for (auto &rowInfo : gameRowInfos) { @@ -315,7 +315,9 @@ void GuiLauncher::loop_chooseGameDir() { guiGameDirMenu->show(); bool cancelled = guiGameDirMenu->cancelled; currentUSBGameDirIndex = guiGameDirMenu->selected; - currentUSBGameDirName = gameRowInfos[currentUSBGameDirIndex].rowName; + currentUSBGameDirName = ""; + if (currentUSBGameDirIndex < gameRowInfos.size()) + currentUSBGameDirName = gameRowInfos[currentUSBGameDirIndex].rowName; delete guiGameDirMenu; if (cancelled) diff --git a/src/code/launcher/ra_integrator.cpp b/src/code/launcher/ra_integrator.cpp index 91402aa..a2c3f6e 100644 --- a/src/code/launcher/ra_integrator.cpp +++ b/src/code/launcher/ra_integrator.cpp @@ -125,7 +125,10 @@ void RAIntegrator::reloadFavorites() { } } - auto [found, index] = playlistNameToIndex(favoritesDisplayName); + + std::tuple restuple = playlistNameToIndex(favoritesDisplayName); + bool found = std::get<0>(restuple); + int index = std::get<1>(restuple); if (found) { // the prior favorites is in the list. modify the existing entry RAPlaylistInfo & fav = playlistInfos[index]; @@ -199,7 +202,9 @@ vector RAIntegrator::getPlaylists() { //******************** PsGames RAIntegrator::getGames(string playlist) { PsGames games; - auto [found, index] = playlistNameToIndex(playlist); + std::tuple restuple = playlistNameToIndex(playlist); + bool found = std::get<0>(restuple); + int index = std::get<1>(restuple); if (found) games = playlistInfos[index].psGames; return games; @@ -209,7 +214,9 @@ PsGames RAIntegrator::getGames(string playlist) { // RAIntegrator::getGamesNumber //******************** int RAIntegrator::getGamesNumber(string playlist) { - auto [found, index] = playlistNameToIndex(playlist); + std::tuple restuple = playlistNameToIndex(playlist); + bool found = std::get<0>(restuple); + int index = std::get<1>(restuple); if (found) return playlistInfos[index].psGames.size(); else diff --git a/src/code/main.cpp b/src/code/main.cpp index 778b889..0de8732 100644 --- a/src/code/main.cpp +++ b/src/code/main.cpp @@ -210,16 +210,15 @@ int main(int argc, char *argv[]) { USBGame::sortByFullPath(allGames); bool autobleemPrevOutOfDate = gamesHierarchy.gamesDoNotMatchAutobleemPrev(prevPath); - bool thereAreGameFilesInGamesDir = scanner->areThereGameFilesInDir(pathToGamesDir); + bool thereAreRawGameFilesInGamesDir = scanner->areThereGameFilesInDir(pathToGamesDir); - if (!prevFileExists || thereAreGameFilesInGamesDir || autobleemPrevOutOfDate || - db->subDirRowsTableIsEmpty() || db->getNumGames() == 0) { + if (!prevFileExists || thereAreRawGameFilesInGamesDir || autobleemPrevOutOfDate) { scanner->forceScan = true; } gui->display(scanner->forceScan, pathToGamesDir, db, false); - if (thereAreGameFilesInGamesDir) + if (thereAreRawGameFilesInGamesDir) copyGameFilesInGamesDirToSubDirs(pathToGamesDir); // calls splash() so the gui->display needs to be up first while (gui->menuOption == MENU_OPTION_SCAN || gui->menuOption == MENU_OPTION_START) { @@ -228,8 +227,10 @@ int main(int argc, char *argv[]) { gui->saveSelection(); if (gui->menuOption == MENU_OPTION_SCAN) { gamesHierarchy.getHierarchy(pathToGamesDir); - scanGames(gamesHierarchy); + // write the prev file now. if you call it after scanGames the games that failed to verify will have been + // removed from the hierarchy and it force you to rescan on every boot. gamesHierarchy.writeAutobleemPrev(prevPath); + scanGames(gamesHierarchy); if (gui->forceScan) { gui->forceScan = false; } else { diff --git a/src/resources/config.ini b/src/resources/config.ini index df672d4..1bbdca4 100644 --- a/src/resources/config.ini +++ b/src/resources/config.ini @@ -1,5 +1,5 @@ [AutoBleem] -Version=v0.8.0 +Version=v0.8.1 Pcsx=bleemsync Mip=false Autoregion=true