123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- //
- // Copyright (C) 2007 by sinamas <sinamas at users.sourceforge.net>
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License version 2 as
- // published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License version 2 for more details.
- //
- // You should have received a copy of the GNU General Public License
- // version 2 along with this program; if not, write to the
- // Free Software Foundation, Inc.,
- // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- //
- #include "gambattemenuhandler.h"
- #include "blitterconf.h"
- #include "cheatdialog.h"
- #include "gambattesource.h"
- #include "mainwindow.h"
- #include "miscdialog.h"
- #include "palettedialog.h"
- #include "sounddialog.h"
- #include "videodialog.h"
- #include <QActionGroup>
- #include <QFileInfo>
- #include <QSettings>
- #include <QtGui>
- #include <iostream>
- namespace {
- static QString const strippedName(QString const &fullFileName) {
- return QFileInfo(fullFileName).fileName();
- }
- struct TmpPauser : private Uncopyable {
- MainWindow &mw;
- int const inc;
- explicit TmpPauser(MainWindow &mw, int inc = 4)
- : mw(mw), inc(inc)
- {
- mw.incPause(inc);
- }
- ~TmpPauser() {
- mw.decPause(inc);
- }
- };
- }
- FrameRateAdjuster::FrameTime::FrameTime(unsigned baseNum, unsigned baseDenom)
- : index_(num_steps)
- {
- setBaseFrameTime(baseNum, baseDenom);
- }
- void FrameRateAdjuster::FrameTime::setBaseFrameTime(unsigned const baseNum, unsigned const baseDenom) {
- frameTimes_[num_steps] = Rational(baseNum, baseDenom);
- unsigned const bnum = baseNum * 0x10000ul / baseDenom;
- for (std::size_t i = num_steps, num = bnum; i < num_steps * 2; ++i)
- frameTimes_[i + 1] = Rational(num = num * 11 / 10, 0x10000);
- for (std::size_t i = num_steps, num = bnum; i; --i)
- frameTimes_[i - 1] = Rational(num = num * 10 / 11, 0x10000);
- }
- FrameRateAdjuster::FrameRateAdjuster(MiscDialog const &miscDialog, MainWindow &mw, QObject *parent)
- : QObject(parent)
- , frameTime_(miscDialog.baseFps().height(), miscDialog.baseFps().width())
- , miscDialog_(miscDialog)
- , mw_(mw)
- , decFrameRateAction_(new QAction(tr("&Decrease Frame Rate"), &mw))
- , incFrameRateAction_(new QAction(tr("&Increase Frame Rate"), &mw))
- , resetFrameRateAction_(new QAction(tr("&Reset Frame Rate"), &mw))
- , enabled_(true)
- {
- decFrameRateAction_->setShortcut(QString("Ctrl+D"));
- incFrameRateAction_->setShortcut(QString("Ctrl+I"));
- resetFrameRateAction_->setShortcut(QString("Ctrl+U"));
- connect(decFrameRateAction_, SIGNAL(triggered()), this, SLOT(decFrameRate()));
- connect(incFrameRateAction_, SIGNAL(triggered()), this, SLOT(incFrameRate()));
- connect(resetFrameRateAction_, SIGNAL(triggered()), this, SLOT(resetFrameRate()));
- connect(&miscDialog, SIGNAL(accepted()), this, SLOT(miscDialogChange()));
- changed();
- }
- QList<QAction *> const FrameRateAdjuster::actions() {
- QList<QAction *> l;
- l.append(decFrameRateAction_);
- l.append(incFrameRateAction_);
- l.append(resetFrameRateAction_);
- return l;
- }
- void FrameRateAdjuster::miscDialogChange() {
- QSize const &baseFps = miscDialog_.baseFps();
- frameTime_.setBaseFrameTime(baseFps.height(), baseFps.width());
- changed();
- }
- void FrameRateAdjuster::setDisabled(bool disabled) {
- enabled_ = !disabled;
- changed();
- }
- void FrameRateAdjuster::decFrameRate() {
- if (enabled_) {
- frameTime_.inc();
- changed();
- }
- }
- void FrameRateAdjuster::incFrameRate() {
- if (enabled_) {
- frameTime_.dec();
- changed();
- }
- }
- void FrameRateAdjuster::resetFrameRate() {
- if (enabled_) {
- frameTime_.reset();
- changed();
- }
- }
- void FrameRateAdjuster::changed() {
- incFrameRateAction_->setEnabled(enabled_ && frameTime_.decPossible());
- decFrameRateAction_->setEnabled(enabled_ && frameTime_.incPossible());
- resetFrameRateAction_->setEnabled(enabled_ && frameTime_.resetPossible());
- FrameTime::Rational const &ft = enabled_ ? frameTime_.get() : frameTime_.base();
- mw_.setFrameTime(ft.num, ft.denom);
- }
- WindowSizeMenu::WindowSizeMenu(MainWindow &mw, VideoDialog const &vd)
- : mw_(mw)
- , menu_(new QMenu(tr("&Window Size"), &mw))
- , group_(new QActionGroup(menu_))
- , maxSize_(QApplication::desktop()->screen()->size())
- {
- fillMenu(vd.sourceSize(), vd.scalingMethod());
- setCheckedSize(QSettings().value("video/windowSize", QSize()).toSize());
- connect(group_, SIGNAL(triggered(QAction *)), this, SLOT(triggered()));
- QSize const &size = checkedSize();
- mw_.setWindowSize(size);
- if (size.isEmpty())
- mw_.resize(QSettings().value("mainwindow/size", QSize(160, 144)).toSize());
- }
- WindowSizeMenu::~WindowSizeMenu() {
- QSettings settings;
- settings.setValue("video/windowSize", checkedSize());
- }
- void WindowSizeMenu::videoDialogChange(VideoDialog const &vd) {
- QSize const &oldSize = checkedSize();
- disconnect(group_, SIGNAL(triggered(QAction *)), this, SLOT(triggered()));
- menu_->clear();
- delete group_;
- group_ = new QActionGroup(menu_);
- fillMenu(vd.sourceSize(), vd.scalingMethod());
- setCheckedSize(oldSize);
- connect(group_, SIGNAL(triggered(QAction *)), this, SLOT(triggered()));
- QSize const &newSize = checkedSize();
- if (newSize != oldSize)
- mw_.setWindowSize(newSize);
- }
- void WindowSizeMenu::triggered() {
- mw_.setWindowSize(checkedSize());
- }
- void WindowSizeMenu::fillMenu(QSize const &sourceSize, ScalingMethod const scalingMethod) {
- QSize const aspectRatio(160, 144);
- QSize const basesz(scalingMethod == scaling_integer ? sourceSize : aspectRatio);
- QSize sz(basesz);
- while (sz.width() <= maxSize_.width() && sz.height() <= maxSize_.height()) {
- if (sz.width() >= sourceSize.width() && sz.height() >= sourceSize.height()) {
- QAction *a = menu_->addAction(
- '&' + QString::number(sz.width()) + 'x' + QString::number(sz.height()));
- a->setData(sz);
- a->setCheckable(true);
- group_->addAction(a);
- }
- sz += basesz;
- }
- QAction *a = menu_->addAction(tr("&Variable"));
- a->setData(QSize());
- a->setCheckable(true);
- group_->addAction(a);
- }
- void WindowSizeMenu::setCheckedSize(QSize const &size) {
- QList<QAction *> const &actions = group_->actions();
- foreach (QAction *a, actions) {
- if (a->data() == size) {
- a->setChecked(true);
- return;
- }
- }
- if (!group_->checkedAction())
- actions.front()->setChecked(true);
- }
- QSize const WindowSizeMenu::checkedSize() const {
- return group_->checkedAction() ? group_->checkedAction()->data().toSize() : QSize();
- }
- static QString const settingsPath() {
- QString path = QSettings(QSettings::IniFormat, QSettings::UserScope,
- QCoreApplication::organizationName(), QCoreApplication::applicationName()).fileName();
- path.truncate(path.lastIndexOf('/'));
- return path;
- }
- static QString const toCmdString(QAction const *a) {
- QString text = a->text().toLower();
- text.replace('&', QString());
- text.replace(' ', '-');
- return text;
- }
- static char toCmdChar(QAction const *a) {
- return a->shortcut().count() == 1
- ? (a->shortcut()[0] - Qt::Key_A + 'a') & 0xff
- : 0;
- }
- static QAction * findCmdStringAction(QList<QAction *> const &l, QString const &cmdstr) {
- foreach (QAction *a, l) {
- if (cmdstr == toCmdString(a))
- return a;
- }
- return 0;
- }
- static QAction * findCmdCharAction(QList<QAction *> const &l, char const c) {
- foreach (QAction *a, l) {
- if (c == toCmdChar(a))
- return a;
- }
- return 0;
- }
- static void printUsage(char const *const arg0, QList<QAction *> const &actions) {
- std::cout << "Usage: " << arg0 << " [OPTION]... [romfile]\n";
- foreach (QAction const *const a, actions) {
- if (a->isCheckable() && a->isEnabled()) {
- std::string const &text = toCmdString(a).toStdString();
- char const c = toCmdChar(a);
- std::cout << " "
- << (c ? '-' + std::string(1, c) + ", " : std::string(" "))
- << "--" << text << "[=0]\n";
- }
- }
- }
- GambatteMenuHandler::GambatteMenuHandler(MainWindow &mw,
- GambatteSource &source,
- int const argc,
- char const *const argv[])
- : mw_(mw)
- , source_(source)
- , soundDialog_(new SoundDialog(mw, &mw))
- , videoDialog_(new VideoDialog(mw, source.generateVideoSourceInfos(),
- QString("Video filter:"), &mw))
- , miscDialog_(new MiscDialog(settingsPath() + "/saves", &mw))
- , cheatDialog_(new CheatDialog(settingsPath() + "/cheats.ini", &mw))
- , recentFileActs_()
- , pauseAction_()
- , syncFrameRateAction_()
- , gbaCgbAction_()
- , forceDmgAction_()
- , fsAct_()
- , recentMenu_()
- , globalPaletteDialog_()
- , romPaletteDialog_()
- , stateSlotGroup_(new QActionGroup(&mw))
- , windowSizeMenu_(mw, *videoDialog_)
- , pauseInc_(4)
- {
- mw.setWindowTitle("Gambatte");
- source.inputDialog()->setParent(&mw, source.inputDialog()->windowFlags());
- {
- QString const &settingspath = settingsPath();
- QString const &palpath = settingspath + "/palettes";
- QDir::root().mkpath(settingspath + "/saves");
- QDir::root().mkpath(palpath);
- globalPaletteDialog_ = new PaletteDialog(palpath, 0, &mw);
- romPaletteDialog_ = new PaletteDialog(palpath, globalPaletteDialog_, &mw);
- connect(globalPaletteDialog_, SIGNAL(accepted()), this, SLOT(globalPaletteChange()));
- connect(romPaletteDialog_, SIGNAL(accepted()), this, SLOT(romPaletteChange()));
- }
- QActionGroup *const romLoadedActions = new QActionGroup(&mw);
- romLoadedActions->setExclusive(false);
- {
- for (int i = 0; i < max_recent_files; ++i) {
- recentFileActs_[i] = new QAction(&mw);
- recentFileActs_[i]->setVisible(false);
- connect(recentFileActs_[i], SIGNAL(triggered()), this, SLOT(openRecentFile()));
- }
- QMenu *fileMenu = mw.menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(tr("&Open..."), this, SLOT(open()), tr("Ctrl+O"));
- recentMenu_ = fileMenu->addMenu(tr("Open Re¢"));
- for (int i = 0; i < max_recent_files; ++i)
- recentMenu_->addAction(recentFileActs_[i]);
- fileMenu->addSeparator();
- romLoadedActions->addAction(fileMenu->addAction(tr("&Reset"), this, SLOT(reset()), tr("Ctrl+R")));
- fileMenu->addSeparator();
- romLoadedActions->addAction(fileMenu->addAction(tr("Save State &As..."), this, SLOT(saveStateAs())));
- romLoadedActions->addAction(fileMenu->addAction(tr("Load State &From..."), this, SLOT(loadStateFrom())));
- fileMenu->addSeparator();
- romLoadedActions->addAction(fileMenu->addAction(tr("&Save State"),
- this, SLOT(saveState()), QString("Ctrl+S")));
- romLoadedActions->addAction(fileMenu->addAction(tr("&Load State"),
- this, SLOT(loadState()), QString("Ctrl+L")));
- {
- QMenu *const stateSlotMenu = fileMenu->addMenu(tr("S&elect State Slot"));
- stateSlotMenu->setEnabled(false);
- stateSlotMenu->addAction(tr("&Previous"), this, SLOT(prevStateSlot()), QString("Ctrl+Z"));
- stateSlotMenu->addAction(tr("&Next"), this, SLOT(nextStateSlot()), QString("Ctrl+X"));
- stateSlotMenu->addSeparator();
- for (int i = 0; i < 10; ++i) {
- int const no = i == 9 ? 0 : i + 1;
- QString const &strno = QString::number(no);
- QAction *action = stateSlotMenu->addAction(
- "Slot &" + strno, this, SLOT(selectStateSlot()), strno);
- action->setCheckable(true);
- action->setData(no);
- stateSlotGroup_->addAction(action);
- }
- connect(this, SIGNAL(romLoaded(bool)), stateSlotMenu, SLOT(setEnabled(bool)));
- }
- fileMenu->addSeparator();
- fileMenu->addAction(tr("&Quit"), qApp, SLOT(closeAllWindows()), tr("Ctrl+Q"));
- updateRecentFileActions();
- }
- FrameRateAdjuster *const frameRateAdjuster = new FrameRateAdjuster(*miscDialog_, mw, this);
- QList<QAction *> cmdactions;
- {
- QMenu *const playm = mw.menuBar()->addMenu(tr("&Play"));
- romLoadedActions->addAction(pauseAction_ = playm->addAction(
- tr("&Pause"), this, SLOT(pauseChange()), QString("Ctrl+P")));
- pauseAction_->setCheckable(true);
- romLoadedActions->addAction(playm->addAction(tr("Frame &Step"),
- this, SLOT(frameStep()), QString("Ctrl+.")));
- playm->addSeparator();
- syncFrameRateAction_ = playm->addAction(tr("&Sync Frame Rate to Refresh Rate"));
- syncFrameRateAction_->setCheckable(true);
- connect(syncFrameRateAction_, SIGNAL(triggered(bool)),
- frameRateAdjuster, SLOT(setDisabled(bool)));
- connect(syncFrameRateAction_, SIGNAL(triggered(bool)),
- &mw, SLOT(setSyncToRefreshRate(bool)));
- foreach (QAction *action, frameRateAdjuster->actions())
- playm->addAction(romLoadedActions->addAction(action));
- cmdactions += playm->actions();
- }
- QMenu *const settingsm = mw.menuBar()->addMenu(tr("&Settings"));
- settingsm->addAction(tr("&Input..."), this, SLOT(execInputDialog()));
- settingsm->addAction(tr("&Miscellaneous..."), this, SLOT(execMiscDialog()));
- settingsm->addAction(tr("&Sound..."), this, SLOT(execSoundDialog()));
- settingsm->addAction(tr("&Video..."), this, SLOT(execVideoDialog()));
- settingsm->addSeparator();
- settingsm->addMenu(windowSizeMenu_.menu());
- settingsm->addSeparator();
- gbaCgbAction_ = settingsm->addAction(tr("GB&A CGB Mode"));
- gbaCgbAction_->setCheckable(true);
- gbaCgbAction_->setChecked(QSettings().value("gbacgb", false).toBool());
- forceDmgAction_ = settingsm->addAction(tr("Force &DMG Mode"));
- forceDmgAction_->setCheckable(true);
- {
- QMenu *const palm = settingsm->addMenu(tr("DMG &Palette"));
- palm->addAction(tr("&Global..."), this, SLOT(execGlobalPaletteDialog()));
- QAction *romPaletteAct = palm->addAction(tr("Current &ROM..."), this, SLOT(execRomPaletteDialog()));
- romPaletteAct->setEnabled(false);
- connect(this, SIGNAL(dmgRomLoaded(bool)), romPaletteAct, SLOT(setEnabled(bool)));
- }
- settingsm->addSeparator();
- fsAct_ = settingsm->addAction(tr("&Full Screen"), this, SLOT(toggleFullScreen()), tr("Ctrl+F"));
- fsAct_->setCheckable(true);
- cmdactions += settingsm->actions();
- romLoadedActions->addAction(mw.menuBar()->addMenu(tr("&Tools"))->addAction(tr("&Cheats..."),
- cheatDialog_, SLOT(exec())));
- romLoadedActions->setEnabled(false);
- mw.menuBar()->addSeparator();
- QMenu *const helpMenu = mw.menuBar()->addMenu(tr("&Help"));
- helpMenu->addAction(tr("&About"), this, SLOT(about()));
- mw.addActions(mw.menuBar()->actions());
- {
- QAction *escAct = new QAction(&mw);
- escAct->setShortcut(tr("Esc"));
- connect(escAct, SIGNAL(triggered()), this, SLOT(escPressed()));
- mw.addAction(escAct);
- }
- mw.setSamplesPerFrame(35112);
- connect(&source, SIGNAL(setTurbo(bool)), &mw, SLOT(setFastForward(bool)));
- connect(&source, SIGNAL(togglePause()), pauseAction_, SLOT(trigger()));
- connect(&source, SIGNAL(frameStep()), this, SLOT(frameStep()));
- connect(&source, SIGNAL(decFrameRate()), frameRateAdjuster, SLOT(decFrameRate()));
- connect(&source, SIGNAL(incFrameRate()), frameRateAdjuster, SLOT(incFrameRate()));
- connect(&source, SIGNAL(resetFrameRate()), frameRateAdjuster, SLOT(resetFrameRate()));
- connect(&source, SIGNAL(prevStateSlot()), this, SLOT(prevStateSlot()));
- connect(&source, SIGNAL(nextStateSlot()), this, SLOT(nextStateSlot()));
- connect(&source, SIGNAL(saveStateSignal()), this, SLOT(saveState()));
- connect(&source, SIGNAL(loadStateSignal()), this, SLOT(loadState()));
- connect(&source, SIGNAL(quit()), qApp, SLOT(closeAllWindows()));
- connect(videoDialog_, SIGNAL(accepted()), this, SLOT(videoDialogChange()));
- connect(soundDialog_, SIGNAL(accepted()), this, SLOT(soundDialogChange()));
- connect(miscDialog_, SIGNAL(accepted()), this, SLOT(miscDialogChange()));
- connect(cheatDialog_, SIGNAL(accepted()), this, SLOT(cheatDialogChange()));
- connect(&mw, SIGNAL(videoBlitterFailure()), this, SLOT(videoBlitterFailure()));
- connect(&mw, SIGNAL(audioEngineFailure()), this, SLOT(audioEngineFailure()));
- connect(&mw, SIGNAL(closing()), this, SLOT(saveWindowSizeIfNotFullScreen()));
- connect(&mw, SIGNAL(dwmCompositionChange()), this, SLOT(reconsiderSyncFrameRateActionEnable()));
- connect(this, SIGNAL(romLoaded(bool)), romLoadedActions, SLOT(setEnabled(bool)));
- connect(this, SIGNAL(romLoaded(bool)), stateSlotGroup_->actions().at(0), SLOT(setChecked(bool)));
- mw.setAspectRatio(QSize(160, 144));
- videoDialogChange();
- soundDialogChange();
- miscDialogChange();
- bool unknownCmd = false;
- for (int i = 1; i < argc; ++i) {
- if (argv[i][0] == '-' && argv[i][1]) {
- QString const argstr(argv[i] + 2);
- if (QAction *a = argv[i][1] == '-'
- ? findCmdStringAction(cmdactions, argstr.left(argstr.lastIndexOf('=')))
- : findCmdCharAction(cmdactions, argv[i][1])) {
- if (argstr.endsWith("=0") == a->isChecked() && a->isEnabled())
- a->trigger();
- } else
- unknownCmd = true;
- }
- }
- if (unknownCmd)
- printUsage(argv[0], cmdactions);
- for (int i = 1; i < argc; ++i) {
- if (argv[i][0] != '-') {
- if (fsAct_->isChecked())
- mw.menuBar()->hide();
- loadFile(QFileInfo(QString(argv[i])).absoluteFilePath());
- break;
- }
- }
- }
- GambatteMenuHandler::~GambatteMenuHandler() {
- QSettings settings;
- settings.setValue("gbacgb", gbaCgbAction_->isChecked());
- }
- void GambatteMenuHandler::updateRecentFileActions() {
- QSettings settings;
- QStringList files = settings.value("recentFileList").toStringList();
- int const numRecentFiles = qMin(files.size(), static_cast<int>(max_recent_files));
- for (int i = 0; i < numRecentFiles; ++i) {
- QString const &text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i]));
- recentFileActs_[i]->setText(text);
- recentFileActs_[i]->setData(files[i]);
- recentFileActs_[i]->setVisible(true);
- }
- for (int j = numRecentFiles; j < max_recent_files; ++j)
- recentFileActs_[j]->setVisible(false);
- recentMenu_->setEnabled(numRecentFiles > 0);
- }
- void GambatteMenuHandler::setCurrentFile(QString const &fileName) {
- QSettings settings;
- QStringList files = settings.value("recentFileList").toStringList();
- files.removeAll(fileName);
- files.prepend(fileName);
- while (files.size() > max_recent_files)
- files.removeLast();
- settings.setValue("recentFileList", files);
- updateRecentFileActions();
- }
- void GambatteMenuHandler::loadFile(QString const &fileName) {
- TmpPauser tmpPauser(mw_, 4);
- pauseAction_->setChecked(false);
- pauseChange();
- mw_.waitUntilPaused();
- if (gambatte::LoadRes const error =
- source_.load(fileName.toLocal8Bit().constData(),
- gbaCgbAction_->isChecked() * gambatte::GB::GBA_CGB
- + forceDmgAction_->isChecked() * gambatte::GB::FORCE_DMG
- + miscDialog_->multicartCompat() * gambatte::GB::MULTICART_COMPAT)) {
- mw_.stop();
- emit dmgRomLoaded(false);
- emit romLoaded(false);
- QMessageBox::critical(
- &mw_,
- tr("File Load Error"),
- (tr("Failed to load file\n")
- + fileName + ".\n\n"
- + gambatte::to_string(error).c_str() + '.'));
- return;
- }
- QString const &romTitle = QString::fromStdString(source_.romTitle()).trimmed();
- cheatDialog_->setGameName(romTitle.isEmpty() ? QFileInfo(fileName).completeBaseName() : romTitle);
- cheatDialogChange();
- if (!source_.isCgb()) {
- romPaletteDialog_->setSettingsFile(
- QFileInfo(fileName).completeBaseName() + ".pal",
- romTitle);
- setDmgPaletteColors();
- }
- gambatte::PakInfo const &pak = source_.pakInfo();
- std::cout << romTitle.toStdString() << '\n'
- << "GamePak type: " << pak.mbc()
- << " rambanks: " << pak.rambanks()
- << " rombanks: " << pak.rombanks() << '\n'
- << "header checksum: " << (pak.headerChecksumOk() ? "ok" : "bad") << '\n'
- << "cgb: " << source_.isCgb() << std::endl;
- mw_.setWindowTitle(strippedName(fileName) + (pak.headerChecksumOk() ? "" : " [bad]") + " - Gambatte");
- setCurrentFile(fileName);
- emit romLoaded(true);
- emit dmgRomLoaded(!source_.isCgb());
- mw_.resetAudio();
- mw_.run();
- }
- void GambatteMenuHandler::open() {
- TmpPauser tmpPauser(mw_, 4);
- mw_.waitUntilPaused();
- QString const &fileName = QFileDialog::getOpenFileName(
- &mw_, tr("Open"), recentFileActs_[0]->data().toString(),
- tr("Game Boy ROM Images (*.dmg *.gb *.gbc *.sgb *.zip *.gz);;All Files (*)"));
- if (!fileName.isEmpty())
- loadFile(fileName);
- // giving back focus after getOpenFileName seems to fail at times, which
- // can be problematic with current exclusive mode handling.
- mw_.setFocus();
- }
- void GambatteMenuHandler::openRecentFile() {
- if (QAction const *action = qobject_cast<QAction *>(sender()))
- loadFile(action->data().toString());
- }
- void GambatteMenuHandler::about() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- QMessageBox::about(
- &mw_,
- "About Gambatte",
- "<h3>Gambatte Qt"
- #ifdef GAMBATTE_QT_VERSION_STR
- " (" GAMBATTE_QT_VERSION_STR ")"
- #endif
- "</h3>"
- "<p>"
- "<b>Homepage:</b> "
- "<a href=\"https://github.com/sinamas/gambatte\">"
- "https://github.com/sinamas/gambatte"
- "</a>"
- "</p>"
- "<p>"
- "A portable, open-source Game Boy Color emulator."
- "</p>"
- );
- }
- void GambatteMenuHandler::globalPaletteChange() {
- romPaletteDialog_->externalChange();
- setDmgPaletteColors();
- }
- void GambatteMenuHandler::romPaletteChange() {
- globalPaletteDialog_->externalChange();
- setDmgPaletteColors();
- }
- namespace {
- struct SetDmgPaletteColorFun {
- GambatteSource &source; int palnum; int colornum; unsigned long rgb32;
- void operator()() const { source.setDmgPaletteColor(palnum, colornum, rgb32); }
- };
- struct SetVideoSourceFun {
- GambatteSource &source; std::size_t sourceIndex;
- void operator()() const { source.setVideoSource(sourceIndex); }
- };
- struct SetSaveDirFun {
- GambatteSource &source; QString path;
- void operator()() const { source.setSavedir(path.toLocal8Bit().constData()); }
- };
- } // anon ns
- void GambatteMenuHandler::setDmgPaletteColors() {
- for (int palnum = 0; palnum < 3; ++palnum)
- for (int colornum = 0; colornum < 4; ++colornum) {
- SetDmgPaletteColorFun fun = { source_, palnum, colornum,
- romPaletteDialog_->color(palnum, colornum) };
- mw_.callInWorkerThread(fun);
- }
- }
- void GambatteMenuHandler::videoDialogChange() {
- {
- SetVideoSourceFun fun = { source_, videoDialog_->sourceIndex() };
- mw_.callInWorkerThread(fun);
- }
- applySettings(mw_, *videoDialog_);
- windowSizeMenu_.videoDialogChange(*videoDialog_);
- reconsiderSyncFrameRateActionEnable();
- }
- void GambatteMenuHandler::soundDialogChange() {
- applySettings(mw_, *soundDialog_);
- }
- void GambatteMenuHandler::miscDialogChange() {
- SetSaveDirFun const setSaveDirFun = { source_, miscDialog_->savePath() };
- mw_.callInWorkerThread(setSaveDirFun);
- mw_.setDwmTripleBuffer(miscDialog_->dwmTripleBuf());
- mw_.setFastForwardSpeed(miscDialog_->turboSpeed());
- mw_.setPauseOnFocusOut(miscDialog_->pauseOnFocusOut() ? 2 : 0);
- pauseInc_ = miscDialog_->pauseOnDialogs() ? 4 : 0;
- }
- void GambatteMenuHandler::cheatDialogChange() {
- std::string gameGenieCodes;
- std::string gameSharkCodes;
- foreach (QString const &s, cheatDialog_->cheats().split(';', QString::SkipEmptyParts)) {
- if (s.contains('-')) {
- gameGenieCodes += s.toStdString() + ';';
- } else
- gameSharkCodes += s.toStdString() + ';';
- }
- source_.setGameGenie(gameGenieCodes);
- source_.setGameShark(gameSharkCodes);
- }
- void GambatteMenuHandler::reconsiderSyncFrameRateActionEnable() {
- if (mw_.blitterConf(videoDialog_->blitterNo()).maxSwapInterval()
- && !MainWindow::isDwmCompositionEnabled()) {
- syncFrameRateAction_->setEnabled(true);
- } else {
- if (syncFrameRateAction_->isChecked())
- syncFrameRateAction_->trigger();
- syncFrameRateAction_->setEnabled(false);
- }
- }
- void GambatteMenuHandler::execGlobalPaletteDialog() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- globalPaletteDialog_->exec();
- }
- void GambatteMenuHandler::execRomPaletteDialog() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- romPaletteDialog_->exec();
- }
- void GambatteMenuHandler::execInputDialog() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- source_.inputDialog()->exec();
- }
- void GambatteMenuHandler::execSoundDialog() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- soundDialog_->exec();
- }
- void GambatteMenuHandler::execVideoDialog() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- videoDialog_->exec();
- }
- void GambatteMenuHandler::execMiscDialog() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- miscDialog_->exec();
- }
- void GambatteMenuHandler::prevStateSlot() {
- stateSlotGroup_->actions().at(source_.currentState() < 2
- ? source_.currentState() + 8
- : source_.currentState() - 2)->trigger();
- }
- void GambatteMenuHandler::nextStateSlot() {
- stateSlotGroup_->actions().at(source_.currentState())->trigger();
- }
- namespace {
- struct SelectStateFun {
- GambatteSource &source; int i;
- void operator()() const { source.selectState(i); }
- };
- struct SaveStateFun {
- GambatteSource &source;
- MainWindow::FrameBuffer fb;
- void operator()() const {
- source.saveState(MainWindow::FrameBuffer::Locked(fb).get());
- }
- };
- struct LoadStateFun {
- GambatteSource &source;
- void operator()() const { source.loadState(); }
- };
- struct SaveStateAsFun {
- GambatteSource &source;
- MainWindow::FrameBuffer fb;
- QString fileName;
- void operator()() const {
- source.saveState(MainWindow::FrameBuffer::Locked(fb).get(),
- fileName.toLocal8Bit().constData());
- }
- };
- struct LoadStateFromFun {
- GambatteSource &source;
- QString fileName;
- void operator()() const {
- source.loadState(fileName.toLocal8Bit().constData());
- }
- };
- struct ResetFun {
- GambatteSource &source;
- void operator()() const { source.reset(); }
- };
- } // anon ns
- void GambatteMenuHandler::selectStateSlot() {
- if (QAction *action = stateSlotGroup_->checkedAction()) {
- SelectStateFun fun = { source_, action->data().toInt() };
- mw_.callInWorkerThread(fun);
- }
- }
- void GambatteMenuHandler::saveState() {
- SaveStateFun fun = { source_, MainWindow::FrameBuffer(mw_) };
- mw_.callInWorkerThread(fun);
- }
- void GambatteMenuHandler::loadState() {
- LoadStateFun fun = { source_ };
- mw_.callInWorkerThread(fun);
- }
- void GambatteMenuHandler::saveStateAs() {
- TmpPauser tmpPauser(mw_, 4);
- mw_.waitUntilPaused();
- QString const &fileName = QFileDialog::getSaveFileName(
- &mw_, tr("Save State"), QString(),
- tr("Gambatte Quick Save Files (*.gqs);;All Files (*)"));
- if (!fileName.isEmpty()) {
- SaveStateAsFun fun = { source_, MainWindow::FrameBuffer(mw_), fileName };
- mw_.callInWorkerThread(fun);
- }
- }
- void GambatteMenuHandler::loadStateFrom() {
- TmpPauser tmpPauser(mw_, 4);
- mw_.waitUntilPaused();
- QString const &fileName = QFileDialog::getOpenFileName(
- &mw_, tr("Load State"), QString(),
- tr("Gambatte Quick Save Files (*.gqs);;All Files (*)"));
- if (!fileName.isEmpty()) {
- LoadStateFromFun fun = { source_, fileName };
- mw_.callInWorkerThread(fun);
- }
- }
- void GambatteMenuHandler::reset() {
- ResetFun fun = { source_ };
- mw_.callInWorkerThread(fun);
- }
- void GambatteMenuHandler::pauseChange() {
- if (pauseAction_->isChecked())
- mw_.pause();
- else
- mw_.unpause();
- }
- void GambatteMenuHandler::frameStep() {
- if (pauseAction_->isChecked())
- mw_.frameStep();
- else
- pauseAction_->trigger();
- }
- void GambatteMenuHandler::escPressed() {
- #ifdef Q_WS_MAC
- if (fsAct_->isChecked())
- fsAct_->trigger();
- #else
- mw_.menuBar()->setVisible(!mw_.menuBar()->isVisible());
- if (!mw_.menuBar()->isVisible())
- mw_.hideCursor();
- #endif
- }
- void GambatteMenuHandler::videoBlitterFailure() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- QMessageBox::critical(&mw_, tr("Video engine failure"),
- tr("Failed to update video output. This may be fixed by changing the video engine settings."));
- videoDialog_->exec();
- }
- void GambatteMenuHandler::audioEngineFailure() {
- TmpPauser tmpPauser(mw_, pauseInc_);
- QMessageBox::critical(&mw_, tr("Sound engine failure"),
- tr("Failed to output audio. This may be fixed by changing the sound settings."));
- soundDialog_->exec();
- }
- void GambatteMenuHandler::toggleFullScreen() {
- saveWindowSizeIfNotFullScreen();
- mw_.toggleFullScreen();
- }
- void GambatteMenuHandler::saveWindowSizeIfNotFullScreen() {
- if (!mw_.isFullScreen()) {
- QSettings settings;
- settings.setValue("mainwindow/size", mw_.size());
- }
- }
|