|
MythTV
0.26-pre
|
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 }
1.7.6.1