00001 #include "gamehandler.h"
00002 #include "rominfo.h"
00003 #include "rom_metadata.h"
00004
00005 #include <qobject.h>
00006 #include <qptrlist.h>
00007 #include <qstringlist.h>
00008 #include <iostream>
00009 #include <qdir.h>
00010 #include <qregexp.h>
00011
00012 #include <mythtv/mythcontext.h>
00013 #include <mythtv/mythdbcon.h>
00014 #include <mythtv/mythdialogs.h>
00015 #include <mythtv/util.h>
00016
00017 #define LOC_ERR QString("MythGame:GAMEHANDLER Error: ")
00018 #define LOC QString("MythGame:GAMEHANDLER: ")
00019
00020 using namespace std;
00021
00022 static QPtrList<GameHandler> *handlers = 0;
00023
00024 bool existsHandler(const QString name)
00025 {
00026 GameHandler *handler = handlers->first();
00027 while(handler)
00028 {
00029 if (handler->SystemName() == name)
00030 {
00031 return TRUE;
00032 }
00033
00034 handler = handlers->next();
00035 }
00036
00037 return FALSE;
00038 }
00039
00040 static void checkHandlers(void)
00041 {
00042
00043
00044 if (! handlers)
00045 {
00046 handlers = new QPtrList<GameHandler>;
00047 }
00048 else {
00049 handlers->clear();
00050 }
00051
00052 MSqlQuery query(MSqlQuery::InitCon());
00053 query.exec("SELECT DISTINCT playername FROM gameplayers WHERE playername <> '';");
00054
00055 while (query.next())
00056 {
00057 QString name = query.value(0).toString();
00058 GameHandler::registerHandler(GameHandler::newHandler(name));
00059 }
00060
00061 }
00062
00063 GameHandler* GameHandler::getHandler(uint i)
00064 {
00065 return handlers->at(i);
00066 }
00067
00068 void GameHandler::updateSettings(GameHandler *handler)
00069 {
00070 MSqlQuery query(MSqlQuery::InitCon());
00071
00072 query.prepare("SELECT rompath, workingpath, commandline, screenshots, "
00073 "gameplayerid, gametype, extensions, spandisks "
00074 "FROM gameplayers WHERE playername = :SYSTEM ");
00075
00076 query.bindValue(":SYSTEM", handler->SystemName());
00077
00078 query.exec();
00079
00080 query.next();
00081 handler->rompath = query.value(0).toString();
00082 handler->workingpath = query.value(1).toString();
00083 handler->commandline = query.value(2).toString();
00084 handler->screenshots = query.value(3).toString();
00085 handler->gameplayerid = query.value(4).toInt();
00086 handler->gametype = query.value(5).toString();
00087 handler->validextensions = QStringList::split(",", query.value(6).toString().stripWhiteSpace().remove(" "));
00088 handler->spandisks = query.value(7).toInt();
00089
00090 }
00091
00092 GameHandler* GameHandler::newInstance = 0;
00093
00094 GameHandler* GameHandler::newHandler(QString name)
00095 {
00096 newInstance = new GameHandler();
00097 newInstance->systemname = name;
00098
00099 updateSettings(newInstance);
00100
00101 return newInstance;
00102 }
00103
00104
00105 uint GameHandler::count(void)
00106 {
00107 checkHandlers();
00108 return handlers->count();
00109 }
00110
00111 void GameHandler::InitMetaDataMap(QString GameType)
00112 {
00113 QString key;
00114
00115 MSqlQuery query(MSqlQuery::InitCon());
00116 query.prepare("SELECT crc, category, year, country, name, "
00117 "description, publisher, platform, version, "
00118 "binfile FROM romdb WHERE platform = :GAMETYPE;");
00119
00120 query.bindValue(":GAMETYPE",GameType);
00121 query.exec();
00122
00123 if (query.isActive() && query.size() > 0)
00124 {
00125 while (query.next())
00126 {
00127 key = QString("%1:%2")
00128 .arg(query.value(0).toString())
00129 .arg(query.value(9).toString());
00130 romDB[key] = RomData(
00131 query.value(1).toString(),
00132 query.value(2).toString(),
00133 query.value(3).toString(),
00134 query.value(4).toString(),
00135 query.value(5).toString(),
00136 query.value(6).toString(),
00137 query.value(7).toString(),
00138 query.value(8).toString());
00139 }
00140 }
00141
00142 if (romDB.count() == 0)
00143 VERBOSE(VB_GENERAL, LOC_ERR + QString("No romDB data read from database. Not imported?"));
00144 else
00145 VERBOSE(VB_GENERAL, LOC + QString("Loaded %1 items from romDB Database")
00146 .arg(romDB.count()));
00147
00148 }
00149
00150 void GameHandler::GetMetadata(GameHandler *handler, QString rom, QString* Genre, QString* Year,
00151 QString* Country, QString* CRC32, QString* GameName,
00152 QString *Publisher, QString *Version)
00153 {
00154 QString key;
00155 QString tmpcrc;
00156
00157 *CRC32 = crcinfo(rom, handler->GameType(), &key, &romDB);
00158
00159
00160
00161
00162 *Year = QObject::tr("19xx");
00163 *Country = QObject::tr("Unknown");
00164 *GameName = QObject::tr("Unknown");
00165 *Genre = QObject::tr("Unknown");
00166 *Publisher = QObject::tr("Unknown");
00167 *Version = QObject::tr("0");
00168
00169 if (*CRC32 != "")
00170 {
00171 if (romDB.contains(key))
00172 {
00173 VERBOSE(VB_GENERAL, LOC + QString("ROMDB FOUND for %1 - %2")
00174 .arg(romDB[key].GameName())
00175 .arg(key));
00176 *Year = romDB[key].Year();
00177 *Country = romDB[key].Country();
00178 *Genre = romDB[key].Genre();
00179 *Publisher = romDB[key].Publisher();
00180 *GameName = romDB[key].GameName();
00181 *Version = romDB[key].Version();
00182 }
00183 else VERBOSE(VB_GENERAL, LOC + QString("NO ROMDB FOUND for %1").arg(rom));
00184
00185 };
00186
00187 if ((*Genre == "Unknown") || (*Genre == ""))
00188 *Genre = QString("Unknown%1").arg( handler->GameType() );
00189
00190 }
00191
00192 void purgeGameDB(QString filename, QString RomPath)
00193 {
00194 VERBOSE(VB_GENERAL, LOC + QString("Purging %1 - %2")
00195 .arg(RomPath)
00196 .arg(filename));
00197
00198 MSqlQuery query(MSqlQuery::InitCon());
00199
00200
00201
00202
00203 query.prepare("DELETE FROM gamemetadata WHERE "
00204 "romname = :ROMNAME AND "
00205 "rompath = :ROMPATH ");
00206
00207 query.bindValue(":ROMNAME",filename);
00208 query.bindValue(":ROMPATH",RomPath);
00209
00210 query.exec();
00211
00212 }
00213
00214 void GameHandler::promptForRemoval(QString filename, QString RomPath)
00215 {
00216 if (m_RemoveAll)
00217 purgeGameDB(filename , RomPath);
00218
00219 if (m_KeepAll || m_RemoveAll)
00220 return;
00221
00222 QStringList buttonText;
00223 buttonText += QObject::tr("No");
00224 buttonText += QObject::tr("No to all");
00225 buttonText += QObject::tr("Yes");
00226 buttonText += QObject::tr("Yes to all");
00227
00228
00229 DialogCode result = MythPopupBox::ShowButtonPopup(
00230 gContext->GetMainWindow(),
00231 QObject::tr("File Missing"),
00232 QString(QObject::tr("%1 appears to be missing.\nRemove it"
00233 " from the database?")).arg(filename),
00234 buttonText, kDialogCodeButton0);
00235
00236 switch (result)
00237 {
00238 case kDialogCodeButton0:
00239 case kDialogCodeRejected:
00240 default:
00241 break;
00242 case kDialogCodeButton1:
00243 m_KeepAll = true;
00244 break;
00245 case kDialogCodeButton2:
00246 purgeGameDB(filename , RomPath);
00247 break;
00248 case kDialogCodeButton3:
00249 m_RemoveAll = true;
00250 purgeGameDB(filename , RomPath);
00251 break;
00252 };
00253
00254 }
00255
00256 void updateDisplayRom(QString romname, int display, QString Systemname)
00257 {
00258 MSqlQuery query(MSqlQuery::InitCon());
00259 query.prepare("UPDATE gamemetadata SET display = :DISPLAY "
00260 "WHERE romname = :ROMNAME AND system = :SYSTEM");
00261
00262 query.bindValue(":DISPLAY", display);
00263 query.bindValue(":ROMNAME", romname);
00264 query.bindValue(":SYSTEM", Systemname);
00265
00266 query.exec();
00267
00268 }
00269
00270 void updateDiskCount(QString romname, int diskcount, QString GameType)
00271 {
00272 MSqlQuery query(MSqlQuery::InitCon());
00273 query.prepare("UPDATE gamemetadata SET diskcount = :DISKCOUNT "
00274 "WHERE romname = :ROMNAME AND gametype = :GAMETYPE ");
00275
00276 query.bindValue(":DISKCOUNT",diskcount);
00277 query.bindValue(":ROMNAME", romname);
00278 query.bindValue(":GAMETYPE",GameType);
00279
00280 query.exec();
00281
00282 }
00283
00284 void updateGameName(QString romname, QString GameName, QString Systemname)
00285 {
00286 MSqlQuery query(MSqlQuery::InitCon());
00287 query.prepare("UPDATE gamemetadata SET GameName = :GAMENAME "
00288 "WHERE romname = :ROMNAME AND system = :SYSTEM ");
00289
00290 query.bindValue(":GAMENAME", GameName);
00291 query.bindValue(":ROMNAME", romname);
00292 query.bindValue(":SYSTEM", Systemname);
00293
00294 query.exec();
00295
00296 }
00297
00298
00299 static void UpdateGameCounts(QStringList updatelist)
00300 {
00301 MSqlQuery query(MSqlQuery::InitCon());
00302
00303 QRegExp multiDiskRGXP = QRegExp( "[0-4]$", TRUE, FALSE );
00304 int diskcount = 0;
00305 int pos = 0;
00306
00307 QString lastrom = "";
00308 QString firstname = "";
00309 QString basename = "";
00310
00311 for ( QStringList::Iterator it = updatelist.begin(); it != updatelist.end(); ++it )
00312 {
00313 diskcount = 0;
00314 QString GameType = *it;
00315 VERBOSE(VB_GENERAL, LOC + QString("Update gametype %1").arg(GameType));
00316
00317 query.prepare("SELECT romname,system,spandisks,gamename FROM "
00318 "gamemetadata,gameplayers WHERE "
00319 "gamemetadata.gametype = :GAMETYPE AND "
00320 "playername = system ORDER BY romname");
00321
00322 query.bindValue(":GAMETYPE",GameType);
00323
00324 query.exec();
00325
00326 if (query.isActive() && query.size() > 0)
00327 {
00328 while (query.next())
00329 {
00330 QString RomName = query.value(0).toString();
00331 QString System = query.value(1).toString();
00332 int spandisks = query.value(2).toInt();
00333 QString GameName = query.value(3).toString();
00334 int extlength = 0;
00335
00336 basename = RomName;
00337
00338 if (spandisks)
00339 {
00340 {
00341
00342 pos = RomName.findRev(".");
00343 if (pos > 1)
00344 {
00345 extlength = RomName.length() - pos;
00346 pos--;
00347
00348 basename = RomName.mid(pos,1);
00349 }
00350
00351 if (basename.contains(multiDiskRGXP))
00352 {
00353 pos = (RomName.length() - extlength) - 1;
00354 basename = RomName.left(pos);
00355
00356 if (basename.right(1) == ".")
00357 basename = RomName.left(pos - 1);
00358 }
00359 else
00360 basename = GameName;
00361
00362 if (basename == lastrom)
00363 {
00364 updateDisplayRom(RomName,0,System);
00365 diskcount++;
00366 if (diskcount > 1)
00367 updateDiskCount(firstname,diskcount,GameType);
00368 }
00369 else
00370 {
00371 firstname = RomName;
00372 lastrom = basename;
00373 diskcount = 1;
00374 }
00375 if (basename != GameName)
00376 updateGameName(RomName,basename,System);
00377 }
00378 }
00379 else
00380 {
00381 if (basename == lastrom)
00382 updateDisplayRom(RomName,0,System);
00383 else
00384 lastrom = basename;
00385
00386 }
00387 }
00388 }
00389 }
00390 }
00391
00392 void GameHandler::UpdateGameDB(GameHandler *handler)
00393 {
00394 int counter = 0;
00395 MSqlQuery query(MSqlQuery::InitCon());
00396
00397 MythProgressDialog *progressDlg =
00398 new MythProgressDialog(
00399 QObject::tr("Updating %1(%2) ROM database")
00400 .arg(handler->SystemName()).arg(handler->GameType()),
00401 m_GameMap.size());
00402
00403 GameScanMap::Iterator iter;
00404
00405 QString GameName;
00406 QString Genre;
00407 QString Country;
00408 QString CRC32;
00409 QString thequery;
00410 QString queryvalues;
00411 QString Year;
00412 QString Publisher;
00413 QString Version;
00414
00415 int removalprompt = gContext->GetSetting("GameRemovalPrompt").toInt();
00416 int indepth = gContext->GetSetting("GameDeepScan").toInt();
00417
00418 for (iter = m_GameMap.begin(); iter != m_GameMap.end(); iter++)
00419 {
00420
00421 if (iter.data().FoundLoc() == inFileSystem)
00422 {
00423 if (indepth)
00424 {
00425 GetMetadata(handler, iter.data().RomFullPath(), &Genre, &Year, &Country, &CRC32, &GameName,
00426 &Publisher, &Version);
00427 }
00428 else
00429 {
00430 Genre = QObject::tr( QString("Unknown%1").arg( handler->GameType() ));
00431 Country = QObject::tr("Unknown");
00432 CRC32 = "";
00433 Year = QObject::tr("19xx");
00434 GameName = QObject::tr("Unknown");
00435 Publisher = QObject::tr("Unknown");
00436 Version = QObject::tr("0");
00437 }
00438
00439 if (GameName == QObject::tr("Unknown"))
00440 GameName = iter.data().GameName();
00441
00442
00443
00444
00445 VERBOSE(VB_GENERAL, QString("file %1 - genre %2 ").arg(iter.data().Rom()).arg(Genre));
00446 query.prepare("INSERT INTO gamemetadata "
00447 "(system, romname, gamename, genre, year, gametype, "
00448 "rompath, country, crc_value, diskcount, display, "
00449 "publisher, version) "
00450 "VALUES (:SYSTEM, :ROMNAME, :GAMENAME, :GENRE, :YEAR, "
00451 ":GAMETYPE, :ROMPATH, :COUNTRY, :CRC32, '1', '1', :PUBLISHER, :VERSION)");
00452
00453
00454
00455 query.bindValue(":SYSTEM",handler->SystemName());
00456 query.bindValue(":ROMNAME",iter.data().Rom());
00457 query.bindValue(":GAMENAME",GameName);
00458 query.bindValue(":GENRE",Genre);
00459 query.bindValue(":YEAR",Year);
00460 query.bindValue(":GAMETYPE",handler->GameType());
00461 query.bindValue(":ROMPATH",iter.data().RomPath());
00462 query.bindValue(":COUNTRY",Country);
00463 query.bindValue(":CRC32", CRC32);
00464 query.bindValue(":PUBLISHER", Publisher);
00465 query.bindValue(":VERSION", Version);
00466
00467 query.exec();
00468 }
00469 else if ((iter.data().FoundLoc() == inDatabase) && (removalprompt))
00470 {
00471
00472 promptForRemoval( iter.data().Rom() , iter.data().RomPath() );
00473 }
00474
00475 progressDlg->setProgress(++counter);
00476 }
00477
00478 progressDlg->Close();
00479 progressDlg->deleteLater();
00480 }
00481
00482 void GameHandler::VerifyGameDB(GameHandler *handler)
00483 {
00484 int counter = 0;
00485 GameScanMap::Iterator iter;
00486
00487 MSqlQuery query(MSqlQuery::InitCon());
00488 query.prepare("SELECT romname,rompath,gamename FROM gamemetadata "
00489 "WHERE system = :SYSTEM");
00490
00491 query.bindValue(":SYSTEM",handler->SystemName());
00492
00493 query.exec();
00494
00495 MythProgressDialog *progressDlg = new MythProgressDialog(
00496 QObject::tr("Verifying %1 files").arg(handler->SystemName()),
00497 query.numRowsAffected());
00498
00499
00500 if (query.isActive() && query.size() > 0)
00501 {
00502 while (query.next())
00503 {
00504 QString RomName = QString::fromUtf8(query.value(0).toString());
00505 QString RomPath = query.value(1).toString();
00506 QString GameName = query.value(2).toString();
00507 if (RomName != QString::null)
00508 {
00509 if ((iter = m_GameMap.find(RomName)) != m_GameMap.end())
00510 {
00511
00512 m_GameMap.remove(iter);
00513 }
00514 else
00515 {
00516
00517
00518 m_GameMap[RomName] = GameScan(RomName,RomPath + "/" + RomName,inDatabase,
00519 GameName,RomPath);
00520 }
00521 }
00522 progressDlg->setProgress(++counter);
00523 }
00524 }
00525 progressDlg->Close();
00526 progressDlg->deleteLater();
00527 }
00528
00529
00530
00531 int GameHandler::buildFileCount(QString directory, GameHandler *handler)
00532 {
00533 int filecount = 0;
00534 QDir RomDir(directory);
00535
00536
00537 if (!RomDir.isReadable())
00538 return 0;
00539
00540 const QFileInfoList* List = RomDir.entryInfoList();
00541 for (QFileInfoListIterator it(*List); it; ++it)
00542 {
00543 QFileInfo Info(*it.current());
00544 QString RomName = Info.fileName();
00545
00546 if (RomName == "." ||
00547 RomName == "..")
00548 {
00549 continue;
00550 }
00551
00552 if (Info.isDir())
00553 {
00554 filecount += buildFileCount(Info.filePath(), handler);
00555 continue;
00556 }
00557 else
00558 {
00559 if (handler->validextensions.count() > 0)
00560 {
00561 QRegExp r;
00562
00563 r.setPattern("^" + Info.extension( FALSE ) + "$");
00564 r.setCaseSensitive(false);
00565 QStringList result = handler->validextensions.grep(r);
00566 if (result.isEmpty()) {
00567 continue;
00568 }
00569 }
00570 filecount++;
00571
00572 }
00573 }
00574
00575 return filecount;
00576 }
00577
00578 void GameHandler::clearAllGameData(void)
00579 {
00580 QStringList buttonText;
00581 buttonText += QObject::tr("No");
00582 buttonText += QObject::tr("Yes");
00583
00584 DialogCode result = MythPopupBox::ShowButtonPopup(
00585 gContext->GetMainWindow(),
00586 QObject::tr("Are you sure?"),
00587 QString(QObject::tr("This will clear all Game Meta Data\n"
00588 "from the database. Are you sure you\n"
00589 "want to do this?" )),
00590 buttonText, kDialogCodeButton0);
00591
00592 switch (result)
00593 {
00594 case kDialogCodeRejected:
00595 case kDialogCodeButton0:
00596 default:
00597
00598 break;
00599 case kDialogCodeButton1:
00600 MSqlQuery query(MSqlQuery::InitCon());
00601 query.exec("DELETE FROM gamemetadata;");
00602 break;
00603 };
00604 }
00605
00606 void GameHandler::buildFileList(QString directory, GameHandler *handler,
00607 MythProgressDialog *pdial, int* filecount)
00608 {
00609 QDir RomDir(directory);
00610
00611
00612 if (!RomDir.isReadable())
00613 return;
00614
00615 RomDir.setSorting( QDir:: DirsFirst | QDir::Name );
00616 const QFileInfoList* List = RomDir.entryInfoList();
00617 for (QFileInfoListIterator it(*List); it; ++it)
00618 {
00619 QFileInfo Info(*it.current());
00620 QString RomName = Info.fileName();
00621 QString GameName = Info.baseName(TRUE);
00622
00623 if (RomName == "." ||
00624 RomName == "..")
00625 {
00626 continue;
00627 }
00628
00629 if (Info.isDir())
00630 {
00631 buildFileList(Info.filePath(), handler, pdial, filecount);
00632 continue;
00633 }
00634 else
00635 {
00636
00637 if (handler->validextensions.count() > 0)
00638 {
00639 QRegExp r;
00640
00641 r.setPattern("^" + Info.extension( FALSE ) + "$");
00642 r.setCaseSensitive(false);
00643 QStringList result = handler->validextensions.grep(r);
00644 if (result.isEmpty()) {
00645 continue;
00646 }
00647 }
00648
00649 m_GameMap[RomName] = GameScan(RomName,Info.filePath(),inFileSystem,
00650 GameName,Info.dirPath());
00651
00652 VERBOSE(VB_GENERAL, LOC + QString("Found Rom : (%1) - %2")
00653 .arg(handler->SystemName())
00654 .arg(RomName));
00655
00656 *filecount = *filecount + 1;
00657 pdial->setProgress(*filecount);
00658
00659 }
00660 }
00661 }
00662
00663 void GameHandler::processGames(GameHandler *handler)
00664 {
00665 QString thequery;
00666 int maxcount = 0;
00667 MSqlQuery query(MSqlQuery::InitCon());
00668
00669 if ((handler->SystemRomPath()) && (handler->GameType() != "PC"))
00670 {
00671 QDir d(handler->SystemRomPath());
00672 if (d.exists())
00673 maxcount = buildFileCount(handler->SystemRomPath(),handler);
00674 else
00675 {
00676 VERBOSE(VB_GENERAL, LOC_ERR + QString("Rom Path does not exist: %1")
00677 .arg(handler->SystemRomPath()));
00678 return;
00679 }
00680 }
00681 else
00682 maxcount = 100;
00683
00684 MythProgressDialog *pdial = new MythProgressDialog(
00685 QObject::tr("Scanning for %1 game(s)...").arg(handler->SystemName()),
00686 maxcount);
00687 pdial->setProgress(0);
00688
00689 if (handler->GameType() == "PC")
00690 {
00691 m_GameMap[handler->SystemCmdLine()] = GameScan(handler->SystemCmdLine(),
00692 handler->SystemCmdLine(),
00693 inFileSystem,
00694 handler->SystemName(),
00695 handler->SystemCmdLine().left(handler->SystemCmdLine().findRev(QRegExp("/"))));
00696
00697
00698 pdial->setProgress(maxcount);
00699 VERBOSE(VB_GENERAL, LOC + QString("PC Game %1").arg(handler->SystemName()));
00700
00701 }
00702 else
00703 {
00704 int filecount = 0;
00705 buildFileList(handler->SystemRomPath(), handler, pdial, &filecount);
00706 }
00707
00708 VerifyGameDB(handler);
00709
00710
00711 if (!m_GameMap.empty())
00712 {
00713 InitMetaDataMap(handler->GameType());
00714
00715 UpdateGameDB(handler);
00716
00717 romDB.clear();
00718 handler->setRebuild(true);
00719 }
00720 else
00721 handler->setRebuild(false);
00722
00723
00724 pdial->Close();
00725 pdial->deleteLater();
00726 }
00727
00728 void GameHandler::processAllGames(void)
00729 {
00730 checkHandlers();
00731 QStringList updatelist;
00732
00733 GameHandler *handler = handlers->first();
00734
00735 while(handler)
00736 {
00737 updateSettings(handler);
00738 handler->processGames(handler);
00739
00740 if (handler->needRebuild())
00741 updatelist.append(handler->GameType());
00742
00743 handler = handlers->next();
00744 }
00745
00746 if (!updatelist.isEmpty())
00747 UpdateGameCounts(updatelist);
00748 }
00749
00750 GameHandler* GameHandler::GetHandler(RomInfo *rominfo)
00751 {
00752 if (!rominfo)
00753 return NULL;
00754
00755 GameHandler *handler = handlers->first();
00756 while(handler)
00757 {
00758 if(rominfo->System() == handler->SystemName())
00759 {
00760 return handler;
00761 }
00762 handler = handlers->next();
00763 }
00764 return handler;
00765 }
00766
00767 GameHandler* GameHandler::GetHandlerByName(QString systemname)
00768 {
00769 if (!systemname)
00770 return NULL;
00771
00772 GameHandler *handler = handlers->first();
00773 while(handler)
00774 {
00775 if(handler->SystemName() == systemname)
00776 {
00777 return handler;
00778 }
00779 handler = handlers->next();
00780 }
00781 return handler;
00782 }
00783
00784 void GameHandler::Launchgame(RomInfo *romdata, QString systemname)
00785 {
00786 GameHandler *handler;
00787 if (systemname)
00788 {
00789 handler = GetHandlerByName(systemname);
00790 }
00791 else if (!(handler = GetHandler(romdata)))
00792 {
00793
00794 return;
00795 }
00796 QString exec = handler->SystemCmdLine();
00797
00798 if (handler->GameType() != "PC")
00799 {
00800 QString arg = "\"" + romdata->Rompath() +
00801 "/" + romdata->Romname() + "\"";
00802
00803
00804
00805
00806 if (exec.contains("%s") || handler->SpanDisks())
00807 {
00808 exec = exec.replace(QRegExp("%s"),arg);
00809
00810 if (handler->SpanDisks())
00811 {
00812 QRegExp rxp = QRegExp( "%d[0-4]", TRUE, FALSE );
00813
00814 if (exec.contains(rxp))
00815 {
00816 if (romdata->DiskCount() > 1)
00817 {
00818
00819 QString basename = romdata->Romname().left(romdata->Romname().length() - (romdata->getExtension().length() + 2));
00820 QString extension = romdata->getExtension();
00821 QString rom;
00822 QString diskid[] = { "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6" };
00823
00824 for (int disk = 1; disk <= romdata->DiskCount(); disk++)
00825 {
00826 rom = QString("\"%1/%2%3.%4\"")
00827 .arg(romdata->Rompath())
00828 .arg(basename)
00829 .arg(disk)
00830 .arg(extension);
00831 exec = exec.replace(QRegExp(diskid[disk]),rom);
00832 }
00833 } else
00834 {
00835 exec = exec.replace(QRegExp("%d1"),arg);
00836 }
00837 }
00838 }
00839 }
00840 else
00841 {
00842 exec = exec + " \"" +
00843 romdata->Rompath() + "/" +
00844 romdata->Romname() + "\"";
00845 }
00846 }
00847
00848 QString savedir = QDir::currentDirPath ();
00849 QDir d;
00850 if (handler->SystemWorkingPath()) {
00851 if (!d.cd(handler->SystemWorkingPath()))
00852 {
00853 VERBOSE(VB_GENERAL, LOC_ERR + QString("Failed to change to specified Working Directory: %1")
00854 .arg(handler->SystemWorkingPath()));
00855 }
00856 }
00857 VERBOSE(VB_GENERAL, LOC + QString("Launching Game : %1 : %2")
00858 .arg(handler->SystemName())
00859 .arg(exec));
00860
00861
00862 QStringList cmdlist = QStringList::split(";", exec);
00863 if (cmdlist.count() > 0) {
00864 for ( QStringList::Iterator cmd = cmdlist.begin(); cmd != cmdlist.end(); ++cmd ) {
00865 VERBOSE(VB_GENERAL, LOC + QString("Executing : %1").arg(*cmd));
00866 myth_system(*cmd);
00867 }
00868 }
00869 else {
00870 VERBOSE(VB_GENERAL, LOC + QString("Executing : %1").arg(exec));
00871 myth_system(exec);
00872 }
00873
00874 (void)d.cd(savedir);
00875 }
00876
00877 RomInfo* GameHandler::CreateRomInfo(RomInfo* parent)
00878 {
00879 GameHandler *handler;
00880 if((handler = GetHandler(parent)))
00881 return new RomInfo(*parent);
00882 return NULL;
00883 }
00884
00885 void GameHandler::registerHandler(GameHandler *handler)
00886 {
00887 handlers->append(handler);
00888 }
00889