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
00032
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
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
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
00199
00200
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
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
00530 m_GameMap.erase(iter);
00531 }
00532 else
00533 {
00534
00535
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
00552
00553 int GameHandler::buildFileCount(QString directory, GameHandler *handler)
00554 {
00555 int filecount = 0;
00556 QDir RomDir(directory);
00557
00558
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
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
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
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
00859
00860
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
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 {
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 }