MythTV  0.26-pre
gamehandler.cpp
Go to the documentation of this file.
00001 
00002 #include "gamehandler.h"
00003 #include "rominfo.h"
00004 #include "rom_metadata.h"
00005 
00006 #include <QObject>
00007 #include <QRegExp>
00008 #include <QDir>
00009 #include <QList>
00010 
00011 
00012 #include <mythdbcon.h>
00013 #include <mythmiscutil.h>
00014 #include <mythdb.h>
00015 
00016 #include <mythcontext.h>
00017 #include <mythdialogs.h>
00018 
00019 #include <mythuihelper.h>
00020 #include <mythdialogbox.h>
00021 #include <mythmainwindow.h>
00022 
00023 #define LOC_ERR QString("MythGame:GAMEHANDLER Error: ")
00024 #define LOC QString("MythGame:GAMEHANDLER: ")
00025 #include <mythprogressdialog.h>
00026 
00027 static QList<GameHandler*> *handlers = NULL;
00028 
00029 static void checkHandlers(void)
00030 {
00031     // If a handlers list doesn't currently exist create one. Otherwise
00032     // clear the existing list so that we can regenerate a new one.
00033     if (!handlers)
00034         handlers = new QList<GameHandler*>;
00035     else
00036     {
00037         while (!handlers->isEmpty())
00038             delete handlers->takeFirst();
00039         handlers->clear();
00040     }
00041 
00042     MSqlQuery query(MSqlQuery::InitCon());
00043     if (!query.exec("SELECT DISTINCT playername FROM gameplayers "
00044                     "WHERE playername <> '';"))
00045         MythDB::DBError("checkHandlers - selecting playername", query);
00046 
00047     while (query.next())
00048     {
00049         QString name = query.value(0).toString();
00050         GameHandler::registerHandler(GameHandler::newHandler(name));
00051     }
00052 }
00053 
00054 GameHandler *GameHandler::getHandler(uint i)
00055 {
00056     return handlers->at(i);
00057 }
00058 
00059 void GameHandler::updateSettings(GameHandler *handler)
00060 {
00061     MSqlQuery query(MSqlQuery::InitCon());
00062 
00063     query.prepare("SELECT rompath, workingpath, commandline, screenshots, "
00064           "gameplayerid, gametype, extensions, spandisks  "
00065           "FROM gameplayers WHERE playername = :SYSTEM ");
00066 
00067     query.bindValue(":SYSTEM", handler->SystemName());
00068 
00069     if (query.exec() && query.next())
00070     {
00071         handler->rompath = query.value(0).toString();
00072         handler->workingpath = query.value(1).toString();
00073         handler->commandline = query.value(2).toString();
00074         handler->screenshots = query.value(3).toString();
00075         handler->gameplayerid = query.value(4).toInt();
00076         handler->gametype = query.value(5).toString();
00077         handler->validextensions = query.value(6).toString().trimmed()
00078                                         .remove(" ").split(",", QString::SkipEmptyParts);
00079         handler->spandisks = query.value(7).toInt();
00080     }
00081 }
00082 
00083 GameHandler* GameHandler::newInstance = 0;
00084 
00085 GameHandler* GameHandler::newHandler(QString name)
00086 {
00087     newInstance = new GameHandler();
00088     newInstance->systemname = name;
00089 
00090     updateSettings(newInstance);
00091 
00092     return newInstance;
00093 }
00094 
00095 // Creates/rebuilds the handler list and then returns the count.
00096 uint GameHandler::count(void)
00097 {
00098     checkHandlers();
00099     return handlers->count();
00100 }
00101 
00102 void GameHandler::InitMetaDataMap(QString GameType)
00103 {
00104     QString key;
00105 
00106     MSqlQuery query(MSqlQuery::InitCon());
00107     query.prepare("SELECT crc, category, year, country, name, "
00108                   "description, publisher, platform, version, "
00109                   "binfile FROM romdb WHERE platform = :GAMETYPE;");
00110 
00111     query.bindValue(":GAMETYPE",GameType);
00112 
00113     if (query.exec())
00114     {
00115         while (query.next())
00116         {
00117             key = QString("%1:%2")
00118                   .arg(query.value(0).toString())
00119                   .arg(query.value(9).toString());
00120             romDB[key] = RomData(
00121                                          query.value(1).toString(),
00122                                          query.value(2).toString(),
00123                                          query.value(3).toString(),
00124                                          query.value(4).toString(),
00125                                          query.value(5).toString(),
00126                                          query.value(6).toString(),
00127                                          query.value(7).toString(),
00128                                          query.value(8).toString());
00129         }
00130     }
00131 
00132     if (romDB.count() == 0)
00133         LOG(VB_GENERAL, LOG_ERR, LOC + QString("No romDB data read from "
00134             "database for gametype %1 . Not imported?").arg(GameType));
00135     else
00136         LOG(VB_GENERAL, LOG_INFO, LOC +
00137             QString("Loaded %1 items from romDB Database") .arg(romDB.count()));
00138 }
00139 
00140 void GameHandler::GetMetadata(GameHandler *handler, QString rom, QString* Genre, QString* Year,
00141                               QString* Country, QString* CRC32, QString* GameName,
00142                               QString *Plot, QString *Publisher, QString *Version,
00143                               QString* Fanart, QString* Boxart)
00144 {
00145     QString key;
00146     QString tmpcrc;
00147 
00148     *CRC32 = crcinfo(rom, handler->GameType(), &key, &romDB);
00149 
00150 #if 0
00151     LOG(VB_GENERAL, LOG_DEBUG, "Key = " + key);
00152 #endif
00153 
00154     // Set our default values
00155     *Year = QObject::tr("19xx");
00156     *Country = QObject::tr("Unknown");
00157     *GameName = QObject::tr("Unknown");
00158     *Genre = QObject::tr("Unknown");
00159     *Plot = QObject::tr("Unknown");
00160     *Publisher = QObject::tr("Unknown");
00161     *Version = QObject::tr("0");
00162     (*Fanart).clear();
00163     (*Boxart).clear();
00164 
00165     if (!(*CRC32).isEmpty())
00166     {
00167         if (romDB.contains(key))
00168         {
00169             LOG(VB_GENERAL, LOG_INFO, LOC + QString("ROMDB FOUND for %1 - %2")
00170                      .arg(romDB[key].GameName()).arg(key));
00171             *Year = romDB[key].Year();
00172             *Country = romDB[key].Country();
00173             *Genre = romDB[key].Genre();
00174             *Publisher = romDB[key].Publisher();
00175             *GameName = romDB[key].GameName();
00176             *Version = romDB[key].Version();
00177         }
00178         else
00179         {
00180             LOG(VB_GENERAL, LOG_ERR, LOC + QString("NO ROMDB FOUND for %1 (%2)")
00181                     .arg(rom).arg(*CRC32));
00182         }
00183 
00184     };
00185 
00186     if ((*Genre == "Unknown") || (*Genre).isEmpty())
00187         *Genre = QString("Unknown%1").arg( handler->GameType() );
00188 
00189 }
00190 
00191 static void purgeGameDB(QString filename, QString RomPath)
00192 {
00193     LOG(VB_GENERAL, LOG_INFO, LOC + QString("Purging %1 - %2").arg(RomPath)
00194             .arg(filename));
00195 
00196     MSqlQuery query(MSqlQuery::InitCon());
00197 
00198     // This should have the added benefit of removing the rom from
00199     // other games of the same gametype so we wont be asked to remove it
00200     // more than once.
00201     query.prepare("DELETE FROM gamemetadata WHERE "
00202           "romname = :ROMNAME AND "
00203                   "rompath = :ROMPATH ");
00204 
00205     query.bindValue(":ROMNAME",filename);
00206     query.bindValue(":ROMPATH",RomPath);
00207 
00208     if (!query.exec())
00209         MythDB::DBError("purgeGameDB", query);
00210 
00211 }
00212 
00213 void GameHandler::promptForRemoval(GameScan scan)
00214 {
00215     QString filename = scan.Rom();
00216     QString RomPath = scan.RomFullPath();
00217 
00218     if (m_RemoveAll)
00219         purgeGameDB(filename , RomPath);
00220 
00221     if (m_KeepAll || m_RemoveAll)
00222         return;
00223 
00224     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00225     MythDialogBox *removalPopup = new MythDialogBox(
00226         tr("%1 appears to be missing.\nRemove it from the database?")
00227         .arg(filename), popupStack, "chooseSystemPopup");
00228 
00229     if (removalPopup->Create())
00230     {
00231         removalPopup->SetReturnEvent(this, "removalPopup");
00232 
00233         removalPopup->AddButton(tr("No"));
00234         removalPopup->AddButton(tr("No to all"));
00235         removalPopup->AddButton(tr("Yes"), qVariantFromValue(scan));
00236         removalPopup->AddButton(tr("Yes to all"), qVariantFromValue(scan));
00237         popupStack->AddScreen(removalPopup);
00238 }
00239     else
00240         delete removalPopup;
00241 }
00242 
00243 static void updateDisplayRom(QString romname, int display, QString Systemname)
00244 {
00245     MSqlQuery query(MSqlQuery::InitCon());
00246     query.prepare("UPDATE gamemetadata SET display = :DISPLAY "
00247                   "WHERE romname = :ROMNAME AND system = :SYSTEM");
00248 
00249     query.bindValue(":DISPLAY", display);
00250     query.bindValue(":ROMNAME", romname);
00251     query.bindValue(":SYSTEM", Systemname);
00252 
00253     if (!query.exec())
00254         MythDB::DBError("updateDisplayRom", query);
00255 
00256 }
00257 
00258 static void updateDiskCount(QString romname, int diskcount, QString GameType)
00259 {
00260     MSqlQuery query(MSqlQuery::InitCon());
00261     query.prepare("UPDATE gamemetadata SET diskcount = :DISKCOUNT "
00262                   "WHERE romname = :ROMNAME AND gametype = :GAMETYPE ");
00263 
00264     query.bindValue(":DISKCOUNT",diskcount);
00265     query.bindValue(":ROMNAME", romname);
00266     query.bindValue(":GAMETYPE",GameType);
00267 
00268     if (!query.exec())
00269         MythDB::DBError("updateDiskCount", query);
00270 
00271 }
00272 
00273 static void updateGameName(QString romname, QString GameName, QString Systemname)
00274 {
00275     MSqlQuery query(MSqlQuery::InitCon());
00276     query.prepare("UPDATE gamemetadata SET GameName = :GAMENAME "
00277                   "WHERE romname = :ROMNAME AND system = :SYSTEM ");
00278 
00279     query.bindValue(":GAMENAME", GameName);
00280     query.bindValue(":ROMNAME", romname);
00281     query.bindValue(":SYSTEM", Systemname);
00282 
00283     if (!query.exec())
00284         MythDB::DBError("updateGameName", query);
00285 
00286 }
00287 
00288 
00289 static void UpdateGameCounts(QStringList updatelist)
00290 {
00291     MSqlQuery query(MSqlQuery::InitCon());
00292 
00293     QRegExp multiDiskRGXP = QRegExp( "[0-4]$", Qt::CaseSensitive, QRegExp::RegExp);
00294     int diskcount = 0;
00295     int pos = 0;
00296 
00297     QString lastrom, firstname, basename;
00298 
00299     for ( QStringList::Iterator it = updatelist.begin(); it != updatelist.end(); ++it )
00300     {
00301         diskcount = 0;
00302         QString GameType = *it;
00303         LOG(VB_GENERAL, LOG_NOTICE,
00304             LOC + QString("Update gametype %1").arg(GameType));
00305 
00306         query.prepare("SELECT romname,system,spandisks,gamename FROM "
00307               "gamemetadata,gameplayers WHERE "
00308               "gamemetadata.gametype = :GAMETYPE AND "
00309               "playername = system ORDER BY romname");
00310 
00311         query.bindValue(":GAMETYPE",GameType);
00312 
00313         if (query.exec())
00314         {
00315             while (query.next())
00316             {
00317                 QString RomName = query.value(0).toString();
00318                 QString System = query.value(1).toString();
00319                 int spandisks = query.value(2).toInt();
00320                 QString GameName = query.value(3).toString();
00321 
00322                 basename = RomName;
00323 
00324                 if (spandisks)
00325                 {
00326                     int extlength = 0;
00327                     pos = RomName.lastIndexOf(".");
00328                     if (pos > 1)
00329                     {
00330                         extlength = RomName.length() - pos;
00331                         pos--;
00332 
00333                         basename = RomName.mid(pos,1);
00334                     }
00335 
00336                     if (basename.contains(multiDiskRGXP))
00337                     {
00338                         pos = (RomName.length() - extlength) - 1;
00339                         basename = RomName.left(pos);
00340 
00341                         if (basename.right(1) == ".")
00342                             basename = RomName.left(pos - 1);
00343                     }
00344                     else
00345                         basename = GameName;
00346 
00347                     if (basename == lastrom)
00348                     {
00349                         updateDisplayRom(RomName,0,System);
00350                         diskcount++;
00351                         if (diskcount > 1)
00352                             updateDiskCount(firstname,diskcount,GameType);
00353                     }
00354                     else
00355                     {
00356                         firstname = RomName;
00357                         lastrom = basename;
00358                         diskcount = 1;
00359                     }
00360 
00361                     if (basename != GameName)
00362                         updateGameName(RomName,basename,System);
00363                 }
00364                 else
00365                 {
00366                     if (basename == lastrom)
00367                             updateDisplayRom(RomName,0,System);
00368                         else
00369                             lastrom = basename;
00370 
00371                 }
00372             }
00373         }
00374     }
00375 }
00376 
00377 void GameHandler::UpdateGameDB(GameHandler *handler)
00378 {
00379     int counter = 0;
00380     MSqlQuery query(MSqlQuery::InitCon());
00381 
00382     QString message = QObject::tr("Updating %1(%2) ROM database")
00383                                     .arg(handler->SystemName())
00384                                     .arg(handler->GameType());
00385 
00386     CreateProgress(message);
00387 
00388     if (m_progressDlg)
00389         m_progressDlg->SetTotal(m_GameMap.size());
00390 
00391     GameScanMap::Iterator iter;
00392 
00393     QString GameName, Genre, Country, CRC32, Year, Plot;
00394     QString Publisher, Version, Fanart, Boxart, ScreenShot;
00395     QString thequery, queryvalues;
00396 
00397     int removalprompt = gCoreContext->GetSetting("GameRemovalPrompt").toInt();
00398     int indepth = gCoreContext->GetSetting("GameDeepScan").toInt();
00399     QString screenShotPath = gCoreContext->GetSetting("mythgame.screenshotdir");
00400 
00401     for (iter = m_GameMap.begin(); iter != m_GameMap.end(); ++iter)
00402     {
00403 
00404         if (iter.value().FoundLoc() == inFileSystem)
00405         {
00406             if (indepth)
00407             {
00408                 GetMetadata(handler, iter.value().RomFullPath(), &Genre, &Year, &Country, &CRC32, &GameName,
00409                             &Plot, &Publisher, &Version, &Fanart, &Boxart);
00410             }
00411             else
00412             {
00413                 Genre = QObject::tr("Unknown") + handler->GameType();
00414                 Country = QObject::tr("Unknown");
00415                 CRC32.clear();
00416                 Year = QObject::tr("19xx");
00417                 GameName = QObject::tr("Unknown");
00418                 Plot = QObject::tr("Unknown");
00419                 Publisher = QObject::tr("Unknown");
00420                 Version = QObject::tr("0");
00421                 Fanart.clear();
00422                 Boxart.clear();
00423             }
00424 
00425             if (GameName == QObject::tr("Unknown"))
00426                 GameName = iter.value().GameName();
00427 
00428             int suffixPos = iter.value().Rom().lastIndexOf(QChar('.'));
00429             QString baseName = iter.value().Rom();
00430 
00431             if (suffixPos > 0)
00432                 baseName = iter.value().Rom().left(suffixPos);
00433 
00434             baseName = screenShotPath + "/" + baseName;
00435 
00436             if (QFile(baseName + ".png").exists())
00437                 ScreenShot = baseName + ".png";
00438             else if (QFile(baseName + ".jpg").exists())
00439                 ScreenShot = baseName + ".jpg";
00440             else if (QFile(baseName + ".gif").exists())
00441                 ScreenShot = baseName + ".gif";
00442             else
00443                 ScreenShot.clear();
00444 
00445 #if 0
00446             LOG(VB_GENERAL, LOG_INFO, QString("file %1 - genre %2 ")
00447                     .arg(iter.data().Rom()).arg(Genre));
00448             LOG(VB_GENERAL, LOG_INFO, QString("screenshot %1").arg(ScreenShot));
00449 #endif
00450 
00451             query.prepare("INSERT INTO gamemetadata "
00452                           "(system, romname, gamename, genre, year, gametype, "
00453                           "rompath, country, crc_value, diskcount, display, plot, "
00454                           "publisher, version, fanart, boxart, screenshot) "
00455                           "VALUES (:SYSTEM, :ROMNAME, :GAMENAME, :GENRE, :YEAR, "
00456                           ":GAMETYPE, :ROMPATH, :COUNTRY, :CRC32, '1', '1', :PLOT, :PUBLISHER, :VERSION, "
00457                           ":FANART, :BOXART, :SCREENSHOT)");
00458 
00459             query.bindValue(":SYSTEM",handler->SystemName());
00460             query.bindValue(":ROMNAME",iter.value().Rom());
00461             query.bindValue(":GAMENAME",GameName);
00462             query.bindValue(":GENRE",Genre);
00463             query.bindValue(":YEAR",Year);
00464             query.bindValue(":GAMETYPE",handler->GameType());
00465             query.bindValue(":ROMPATH",iter.value().RomPath());
00466             query.bindValue(":COUNTRY",Country);
00467             query.bindValue(":CRC32", CRC32);
00468             query.bindValue(":PLOT", Plot);
00469             query.bindValue(":PUBLISHER", Publisher);
00470             query.bindValue(":VERSION", Version);
00471             query.bindValue(":FANART", Fanart);
00472             query.bindValue(":BOXART", Boxart);
00473             query.bindValue(":SCREENSHOT", ScreenShot);
00474 
00475             if (!query.exec())
00476                 MythDB::DBError("GameHandler::UpdateGameDB - "
00477                                 "insert gamemetadata", query);
00478         }
00479         else if ((iter.value().FoundLoc() == inDatabase) && (removalprompt))
00480         {
00481 
00482             promptForRemoval( iter.value() );
00483         }
00484 
00485         if (m_progressDlg)
00486             m_progressDlg->SetProgress(++counter);
00487     }
00488 
00489     if (m_progressDlg)
00490     {
00491         m_progressDlg->Close();
00492         m_progressDlg = NULL;
00493 }
00494 }
00495 
00496 void GameHandler::VerifyGameDB(GameHandler *handler)
00497 {
00498     int counter = 0;
00499     GameScanMap::Iterator iter;
00500 
00501     MSqlQuery query(MSqlQuery::InitCon());
00502     query.prepare("SELECT romname,rompath,gamename FROM gamemetadata "
00503                   "WHERE system = :SYSTEM");
00504 
00505     query.bindValue(":SYSTEM",handler->SystemName());
00506 
00507     if (!query.exec())
00508         MythDB::DBError("GameHandler::VerifyGameDB - "
00509                         "select", query);
00510 
00511     QString message = QObject::tr("Verifying %1 files...")
00512                                     .arg(handler->SystemName());
00513 
00514     CreateProgress(message);
00515 
00516     if (m_progressDlg)
00517         m_progressDlg->SetTotal(query.size());
00518 
00519     // For every file we know about, check to see if it still exists.
00520     while (query.next())
00521     {
00522         QString RomName = query.value(0).toString();
00523         QString RomPath = query.value(1).toString();
00524         QString GameName = query.value(2).toString();
00525         if (RomName != QString::null)
00526         {
00527             if ((iter = m_GameMap.find(RomName)) != m_GameMap.end())
00528             {
00529                 // If it's both on disk and in the database we're done with it.
00530                 m_GameMap.erase(iter);
00531             }
00532             else
00533             {
00534                 // If it's only in the database add it to our list and mark it for
00535                 // removal.
00536                 m_GameMap[RomName] = GameScan(RomName,RomPath + "/" + RomName,inDatabase,
00537                                         GameName,RomPath);
00538             }
00539         }
00540         if (m_progressDlg)
00541             m_progressDlg->SetProgress(++counter);
00542     }
00543 
00544     if (m_progressDlg)
00545     {
00546         m_progressDlg->Close();
00547         m_progressDlg = NULL;
00548     }
00549 }
00550 
00551 // Recurse through the directory and gather a count on how many files there are to process.
00552 // This is used for the progressbar info.
00553 int GameHandler::buildFileCount(QString directory, GameHandler *handler)
00554 {
00555     int filecount = 0;
00556     QDir RomDir(directory);
00557 
00558     // If we can't read it's contents move on
00559     if (!RomDir.isReadable())
00560         return 0;
00561 
00562     QFileInfoList List = RomDir.entryInfoList();
00563     for (QFileInfoList::const_iterator it = List.begin();
00564          it != List.end(); ++it)
00565     {
00566         QFileInfo Info = *it;
00567         QString RomName = Info.fileName();
00568 
00569         if (RomName == "." ||
00570             RomName == "..")
00571         {
00572             continue;
00573         }
00574 
00575         if (Info.isDir())
00576         {
00577             filecount += buildFileCount(Info.filePath(), handler);
00578             continue;
00579         }
00580         else
00581         {
00582             if (handler->validextensions.count() > 0)
00583             {
00584                 QRegExp r;
00585 
00586                 r.setPattern("^" + Info.suffix() + "$");
00587                 r.setCaseSensitivity(Qt::CaseInsensitive);
00588                 QStringList result;
00589                 for (int x = 0; x < handler->validextensions.size(); x++)
00590                 {
00591                     QString extension = handler->validextensions.at(x);
00592                     if (extension.contains(r))
00593                         result.append(extension);
00594                 }
00595                 if (result.isEmpty())
00596                     continue;
00597             }
00598 
00599             filecount++;
00600         }
00601     }
00602 
00603     return filecount;
00604 }
00605 
00606 void GameHandler::clearAllGameData(void)
00607 {
00608     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00609     MythDialogBox *clearPopup = new MythDialogBox(tr("This will clear all game metadata "
00610                             "from the database. Are you sure you "
00611                             "want to do this?"), popupStack, "clearAllPopup");
00612 
00613     if (clearPopup->Create())
00614     {
00615         clearPopup->SetReturnEvent(this, "clearAllPopup");
00616         clearPopup->AddButton(tr("No"));
00617         clearPopup->AddButton(tr("Yes"));
00618         popupStack->AddScreen(clearPopup);
00619     }
00620     else
00621         delete clearPopup;
00622 }
00623 
00624 void GameHandler::buildFileList(QString directory, GameHandler *handler,
00625                                 int* filecount)
00626 {
00627     QDir RomDir(directory);
00628 
00629                                 // If we can't read it's contents move on
00630     if (!RomDir.isReadable())
00631         return;
00632 
00633     RomDir.setSorting( QDir:: DirsFirst | QDir::Name );
00634     QFileInfoList List = RomDir.entryInfoList();
00635     for (QFileInfoList::const_iterator it = List.begin();
00636          it != List.end(); ++it)
00637     {
00638         QFileInfo Info = *it;
00639         QString RomName = Info.fileName();
00640         QString GameName = Info.completeBaseName();
00641 
00642         if (RomName == "." ||
00643             RomName == "..")
00644         {
00645             continue;
00646         }
00647 
00648         if (Info.isDir())
00649         {
00650             buildFileList(Info.filePath(), handler, filecount);
00651             continue;
00652         }
00653         else
00654         {
00655 
00656             if (handler->validextensions.count() > 0)
00657             {
00658                 QRegExp r;
00659 
00660                 r.setPattern("^" + Info.suffix() + "$");
00661                 r.setCaseSensitivity(Qt::CaseInsensitive);
00662                 QStringList result;
00663                 for (int x = 0; x < handler->validextensions.size(); x++)
00664                 {
00665                     QString extension = handler->validextensions.at(x);
00666                     if (extension.contains(r))
00667                         result.append(extension);
00668                 }
00669 
00670                 if (result.isEmpty())
00671                     continue;
00672             }
00673 
00674             m_GameMap[RomName] = GameScan(RomName,Info.filePath(),inFileSystem,
00675                                  GameName, Info.absoluteDir().path());
00676 
00677             LOG(VB_GENERAL, LOG_INFO, LOC + QString("Found ROM : (%1) - %2")
00678                     .arg(handler->SystemName()).arg(RomName));
00679 
00680             *filecount = *filecount + 1;
00681             if (m_progressDlg)
00682                 m_progressDlg->SetProgress(*filecount);
00683 
00684         }
00685     }
00686 }
00687 
00688 void GameHandler::processGames(GameHandler *handler)
00689 {
00690     QString thequery;
00691     int maxcount = 0;
00692     MSqlQuery query(MSqlQuery::InitCon());
00693 
00694     if ((!handler->SystemRomPath().isEmpty()) && (handler->GameType() != "PC"))
00695     {
00696         QDir d(handler->SystemRomPath());
00697         if (d.exists())
00698             maxcount = buildFileCount(handler->SystemRomPath(),handler);
00699         else
00700         {
00701             LOG(VB_GENERAL, LOG_ERR, LOC +
00702                 QString("ROM Path does not exist: %1")
00703                     .arg(handler->SystemRomPath()));
00704             return;
00705         }
00706     }
00707     else
00708         maxcount = 100;
00709 
00710     if (handler->GameType() == "PC")
00711     {
00712         MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00713 
00714         QString message = QObject::tr("Scanning for %1 games...")
00715                                                 .arg(handler->SystemName());
00716         MythUIBusyDialog *busyDialog = new MythUIBusyDialog(message, popupStack,
00717                                                 "gamescanbusy");
00718 
00719         if (busyDialog->Create())
00720             popupStack->AddScreen(busyDialog, false);
00721         else
00722         {
00723             delete busyDialog;
00724             busyDialog = NULL;
00725         }
00726 
00727         m_GameMap[handler->SystemCmdLine()] =
00728                 GameScan(handler->SystemCmdLine(),
00729                     handler->SystemCmdLine(),
00730                     inFileSystem,
00731                     handler->SystemName(),
00732                     handler->SystemCmdLine().left(handler->SystemCmdLine().lastIndexOf(QRegExp("/"))));
00733 
00734         if (busyDialog)
00735             busyDialog->Close();
00736 
00737         LOG(VB_GENERAL, LOG_INFO, LOC +
00738             QString("PC Game %1").arg(handler->SystemName()));
00739     }
00740     else
00741     {
00742         QString message = QObject::tr("Scanning for %1 games...")
00743                                                 .arg(handler->SystemName());
00744         CreateProgress(message);
00745 
00746         if (m_progressDlg)
00747             m_progressDlg->SetTotal(maxcount);
00748 
00749         int filecount = 0;
00750         buildFileList(handler->SystemRomPath(), handler, &filecount);
00751 
00752         if (m_progressDlg)
00753         {
00754             m_progressDlg->Close();
00755             m_progressDlg = NULL;
00756         }
00757     }
00758 
00759     VerifyGameDB(handler);
00760 
00761     // If we still have some games in the list then update the database
00762     if (!m_GameMap.empty())
00763     {
00764         InitMetaDataMap(handler->GameType());
00765 
00766         UpdateGameDB(handler);
00767 
00768         romDB.clear();
00769         handler->setRebuild(true);
00770     }
00771     else
00772         handler->setRebuild(false);
00773 }
00774 
00775 void GameHandler::processAllGames(void)
00776 {
00777     checkHandlers();
00778     QStringList updatelist;
00779 
00780     for (int x = 0; x < handlers->size(); x++)
00781     {
00782         GameHandler *handler = handlers->at(x);
00783 
00784         if (handler)
00785         {
00786             updateSettings(handler);
00787             handler->processGames(handler);
00788 
00789             if (handler->needRebuild())
00790                 updatelist.append(handler->GameType());
00791         }
00792     }
00793 
00794     if (!updatelist.isEmpty())
00795         UpdateGameCounts(updatelist);
00796 }
00797 
00798 GameHandler* GameHandler::GetHandler(RomInfo *rominfo)
00799 {
00800     if (!rominfo)
00801         return NULL;
00802 
00803     for (int x = 0; x < handlers->size(); x++)
00804     {
00805         GameHandler *handler = handlers->at(x);
00806         if (handler)
00807         {
00808             if (rominfo->System() == handler->SystemName())
00809                 return handler;
00810         }
00811     }
00812 
00813     return NULL;
00814 }
00815 
00816 GameHandler* GameHandler::GetHandlerByName(QString systemname)
00817 {
00818     if (systemname.isEmpty() || systemname.isNull())
00819         return NULL;
00820 
00821     for (int x = 0; x < handlers->size(); x++)
00822     {
00823         GameHandler *handler = handlers->at(x);
00824 
00825         if (handler)
00826         {
00827             if (handler->SystemName() == systemname)
00828                 return handler;
00829         }
00830     }
00831 
00832     return NULL;
00833 }
00834 
00835 void GameHandler::Launchgame(RomInfo *romdata, QString systemname)
00836 {
00837     GameHandler *handler;
00838 
00839     if (!systemname.isEmpty() && !systemname.isNull())
00840     {
00841         handler = GetHandlerByName(systemname);
00842     }
00843     else if (!(handler = GetHandler(romdata)))
00844     {
00845         // Couldn't get handler so abort.
00846         return;
00847     }
00848     QString exec = handler->SystemCmdLine();
00849 
00850     if (exec.isEmpty())
00851         return;
00852 
00853     if (handler->GameType() != "PC")
00854     {
00855         QString arg = "\"" + romdata->Rompath() +
00856                       "/" + romdata->Romname() + "\"";
00857 
00858         // If they specified a %s in the commandline place the romname
00859         // in that location, otherwise tack it on to the end of
00860         // the command.
00861         if (exec.contains("%s") || handler->SpanDisks())
00862         {
00863             exec = exec.replace(QRegExp("%s"),arg);
00864 
00865             if (handler->SpanDisks())
00866             {
00867                 QRegExp rxp = QRegExp( "%d[0-4]", Qt::CaseSensitive, QRegExp::RegExp);
00868 
00869                 if (exec.contains(rxp))
00870                 {
00871                     if (romdata->DiskCount() > 1)
00872                     {
00873                         // Chop off the extension, .  and last character of the name which we are assuming is the disk #
00874                         QString basename = romdata->Romname().left(romdata->Romname().length() - (romdata->getExtension().length() + 2));
00875                         QString extension = romdata->getExtension();
00876                         QString rom;
00877                         QString diskid[] = { "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6" };
00878 
00879                         for (int disk = 1; disk <= romdata->DiskCount(); disk++)
00880                         {
00881                             rom = QString("\"%1/%2%3.%4\"")
00882                                           .arg(romdata->Rompath())
00883                                           .arg(basename)
00884                                           .arg(disk)
00885                                           .arg(extension);
00886                             exec = exec.replace(QRegExp(diskid[disk]),rom);
00887                         }
00888                     } else
00889                     {   // If there is only one disk make sure we replace %d1 just like %s
00890                         exec = exec.replace(QRegExp("%d1"),arg);
00891                     }
00892                 }
00893             }
00894         }
00895         else
00896         {
00897             exec = exec + " \"" +
00898                    romdata->Rompath() + "/" +
00899                    romdata->Romname() + "\"";
00900         }
00901     }
00902 
00903     QString savedir = QDir::current().path();
00904     QDir d;
00905     if (!handler->SystemWorkingPath().isEmpty())
00906     {
00907         if (!d.cd(handler->SystemWorkingPath()))
00908         {
00909             LOG(VB_GENERAL, LOG_ERR, LOC +
00910                 QString("Failed to change to specified Working Directory: %1")
00911                     .arg(handler->SystemWorkingPath()));
00912         }
00913     }
00914     LOG(VB_GENERAL, LOG_INFO, LOC + QString("Launching Game : %1 : %2")
00915            .arg(handler->SystemName())
00916            .arg(exec));
00917 
00918     GetMythUI()->AddCurrentLocation(QString("MythGame %1 ( %2 )").arg(handler->SystemName()).arg(exec));
00919 
00920     QStringList cmdlist = exec.split(";");
00921     if (cmdlist.count() > 0)
00922     {
00923         for (QStringList::Iterator cmd = cmdlist.begin(); cmd != cmdlist.end();
00924              ++cmd )
00925         {
00926             LOG(VB_GENERAL, LOG_INFO, LOC +
00927                 QString("Executing : %1").arg(*cmd));
00928             myth_system(*cmd, kMSProcessEvents);
00929         }
00930     }
00931     else
00932     {
00933         LOG(VB_GENERAL, LOG_INFO, LOC + QString("Executing : %1").arg(exec));
00934         myth_system(exec, kMSProcessEvents);
00935     }
00936 
00937     GetMythUI()->RemoveCurrentLocation();
00938 
00939     (void)d.cd(savedir);
00940 }
00941 
00942 RomInfo *GameHandler::CreateRomInfo(RomInfo *parent)
00943 {
00944     if (!parent || !GetHandler(parent))
00945         return NULL;
00946 
00947     return new RomInfo(*parent);
00948 }
00949 
00950 void GameHandler::registerHandler(GameHandler *handler)
00951 {
00952     handlers->append(handler);
00953 }
00954 
00955 void GameHandler::customEvent(QEvent *event)
00956 {
00957     if (event->type() == DialogCompletionEvent::kEventType)
00958     {
00959         DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00960 
00961         QString resultid   = dce->GetId();
00962         QString resulttext = dce->GetResultText();
00963 
00964         if (resultid == "removalPopup")
00965         {
00966             int buttonNum = dce->GetResult();
00967             GameScan scan = qVariantValue<GameScan>(dce->GetData());
00968             switch (buttonNum)
00969             {
00970                 case 1:
00971                     m_KeepAll = true;
00972                     break;
00973                 case 2:
00974                     purgeGameDB(scan.Rom() , scan.RomFullPath());
00975                     break;
00976                 case 3:
00977                     m_RemoveAll = true;
00978                     purgeGameDB(scan.Rom() , scan.RomFullPath());
00979                     break;
00980                 default:
00981                     break;
00982             };
00983         }
00984         else if (resultid == "clearAllPopup")
00985         {
00986             int buttonNum = dce->GetResult();
00987             switch (buttonNum)
00988             {
00989                 case 1:
00990                     clearAllMetadata();
00991                     break;
00992                 default:
00993                     break;
00994             }
00995         }
00996     }
00997 }
00998 
00999 void GameHandler::clearAllMetadata(void)
01000 {
01001      MSqlQuery query(MSqlQuery::InitCon());
01002      if (!query.exec("DELETE FROM gamemetadata;"))
01003          MythDB::DBError("GameHandler::clearAllGameData - "
01004                           "delete gamemetadata", query);
01005 }
01006 
01007 void GameHandler::CreateProgress(QString message)
01008 {
01009     if (m_progressDlg)
01010         return;
01011 
01012     MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
01013 
01014     m_progressDlg = new MythUIProgressDialog(message, popupStack,
01015                                              "gameprogress");
01016 
01017     if (m_progressDlg->Create())
01018     {
01019         popupStack->AddScreen(m_progressDlg, false);
01020     }
01021     else
01022     {
01023         delete m_progressDlg;
01024         m_progressDlg = NULL;
01025     }
01026 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends