Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Attempt Mode #80

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
31 changes: 22 additions & 9 deletions gambatte_qt/src/gambattemenuhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,17 +491,25 @@ GambatteMenuHandler::GambatteMenuHandler(MainWindow &mw,
cycleBasedAction_->setCheckable(true);
cycleBasedAction_->setChecked(QSettings().value("rtc-mode", true).toBool());
rtcModeActions->addAction(cycleBasedAction_);
#ifdef ENABLE_REAL_TIME_RTC
realTimeAction_ = rtcModeMenu->addAction(tr("&Real-time"));
realTimeAction_->setCheckable(true);
realTimeAction_->setChecked(!cycleBasedAction_->isChecked());
rtcModeActions->addAction(realTimeAction_);
#endif
connect(rtcModeActions, SIGNAL(triggered(QAction *)), this, SLOT(setRtcMode()));
}

trueColorsAction_ = settingsm->addAction(tr("True &Colors"));
trueColorsAction_->setCheckable(true);
trueColorsAction_->setChecked(QSettings().value("true-colors", false).toBool());
connect(trueColorsAction_, SIGNAL(toggled(bool)), &source, SLOT(setTrueColors(bool)));

settingsm->addSeparator();
attemptModeAction_ = settingsm->addAction(tr("Attempt &Mode"));
attemptModeAction_->setCheckable(true);
attemptModeAction_->setChecked(QSettings().value("attempt-mode", true).toBool());
connect(attemptModeAction_, SIGNAL(toggled(bool)), &source, SLOT(setAttemptMode(bool)));

settingsm->addSeparator();
fsAct_ = settingsm->addAction(tr("&Full Screen"), this, SLOT(toggleFullScreen()), tr("Ctrl+F"));
Expand Down Expand Up @@ -549,6 +557,7 @@ GambatteMenuHandler::GambatteMenuHandler(MainWindow &mw,
connect(&mw, SIGNAL(dwmCompositionChange()), this, SLOT(reconsiderSyncFrameRateActionEnable()));
connect(this, SIGNAL(romLoaded(bool)), romLoadedActions, SLOT(setEnabled(bool)));
connect(this, SIGNAL(romLoaded(bool)), gambattePlatformMenu_.group(), SLOT(setDisabled(bool)));
connect(this, SIGNAL(romLoaded(bool)), attemptModeAction_, SLOT(setDisabled(bool)));
connect(this, SIGNAL(romLoaded(bool)), stateSlotGroup_->actions().at(0), SLOT(setChecked(bool)));

mw.setAspectRatio(QSize(160, 144));
Expand Down Expand Up @@ -590,6 +599,7 @@ GambatteMenuHandler::~GambatteMenuHandler() {
QSettings settings;
settings.setValue("rtc-mode", cycleBasedAction_->isChecked());
settings.setValue("true-colors", trueColorsAction_->isChecked());
settings.setValue("attempt-mode", attemptModeAction_->isChecked());
}

void GambatteMenuHandler::setWindowPrefix(QString const &windowPrefix) {
Expand Down Expand Up @@ -697,8 +707,9 @@ void GambatteMenuHandler::loadFile(QString const &fileName) {
//setDmgPaletteColors();
}

source_.setTrueColors(trueColorsAction_->isChecked());
source_.setTimeMode(cycleBasedAction_->isChecked());
source_.setTrueColors(trueColorsAction_->isChecked());
source_.setAttemptMode(attemptModeAction_->isChecked());

gambatte::PakInfo const &pak = source_.pakInfo();
std::cout << romTitle.toStdString() << '\n'
Expand All @@ -711,23 +722,25 @@ void GambatteMenuHandler::loadFile(QString const &fileName) {
// Basic good rom testing for PSR only. Fail doesn't mean it's a bad ROM for anything except English Gen1-2 games!!!
QString label;
for (GambatteGoodromInfo good : gambatte_goodroms) {
if (romTitle.toStdString() == good.title && pak.crc() == good.crc) {
if (romTitle.toStdString() == good.title && pak.crc() == good.crc && platformId == DEFAULT_GAMBATTE_PLATFORM) {
if (!good.label.empty())
label = " " + QString::fromStdString(good.label);

source_.setBreakpoint(good.savBreakpoint);
break;
}
}

setWindowPrefix(strippedName(fileName) + label);
setWindowPrefix(strippedName(fileName) + label + (attemptModeAction_->isChecked() ? " AM" : ""));
setCurrentFile(fileName);

emit romLoaded(true);
emit dmgRomLoaded(!source_.isCgb());

mw_.resetAudio();
mw_.run();

if (attemptModeAction_->isChecked())
reset(); // Force reset fadeout for loading ROMs; prevents avoiding the fadeout from closing and re-opening the ROM
}

void GambatteMenuHandler::open() {
Expand Down Expand Up @@ -1064,7 +1077,7 @@ void GambatteMenuHandler::saveState() {
}

void GambatteMenuHandler::loadState() {
if (isResetting_)
if (attemptModeAction_->isChecked() || isResetting_)
return;
LoadStateFun fun = { source_ };
mw_.callInWorkerThread(fun);
Expand All @@ -1086,7 +1099,7 @@ void GambatteMenuHandler::saveStateAs() {
}

void GambatteMenuHandler::loadStateFrom() {
if (isResetting_)
if (attemptModeAction_->isChecked() || isResetting_)
return;
TmpPauser tmpPauser(mw_, 4);
mw_.waitUntilPaused();
Expand Down Expand Up @@ -1131,7 +1144,7 @@ void GambatteMenuHandler::setResetting(bool state) {
}

void GambatteMenuHandler::pauseChange() {
if (isResetting_) {
if (attemptModeAction_->isChecked() || isResetting_) {
pauseAction_->setChecked(false);
return;
}
Expand All @@ -1142,12 +1155,12 @@ void GambatteMenuHandler::pauseChange() {
}

void GambatteMenuHandler::frameStep() {
if (isResetting_)
if (attemptModeAction_->isChecked() || isResetting_)
return;
if (pauseAction_->isChecked()) {
mw_.frameStep();

if (isResetting_) {
if (attemptModeAction_->isChecked() || isResetting_) {
pauseAction_->setChecked(false);
mw_.unpause();
}
Expand Down
1 change: 1 addition & 0 deletions gambatte_qt/src/gambattemenuhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ class GambatteMenuHandler : public QObject {
QAction *cycleBasedAction_;
QAction *realTimeAction_;
QAction *trueColorsAction_;
QAction *attemptModeAction_;
QAction *fsAct_;
QMenu *recentMenu_;
PaletteDialog *globalPaletteDialog_;
Expand Down
21 changes: 13 additions & 8 deletions gambatte_qt/src/gambattesource.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,12 @@ class GambatteSource : public QObject, public MediaSource {
virtual void generateVideoFrame(PixelBuffer const &fb);

public slots:
void setTrueColors(bool trueColors) { gb_.setTrueColors(trueColors); }
void setTimeMode(bool useCycles) { gb_.setTimeMode(useCycles); }
void setTrueColors(bool trueColors) { gb_.setTrueColors(trueColors); }
void setAttemptMode(bool attemptMode) {
gb_.setAttemptMode(attemptMode);
attemptMode_ = attemptMode;
}

signals:
void setTurbo(bool on);
Expand Down Expand Up @@ -181,6 +185,7 @@ public slots:
signed resetCounter_;
unsigned resetFade_;
unsigned resetStall_;
bool attemptMode_;

std::mt19937 rng_;
std::uniform_int_distribution<std::mt19937::result_type> dist35112_;
Expand All @@ -197,16 +202,16 @@ public slots:
void enableBreakpoint(bool enable) { gb_.setInterruptAddresses(breakpoint_, enable ? 1 : 0); }
int getHitAddress() { return gb_.getHitInterruptAddress(); }

void emitSetTurbo(bool on) { if(!isResetting_) { emit setTurbo(on);} }
void emitPause() { if(!isResetting_) { emit togglePause();} }
void emitFrameStep() { if(!isResetting_) { emit frameStep();} }
void emitDecFrameRate() { if(!isResetting_) { emit decFrameRate();} }
void emitIncFrameRate() { if(!isResetting_) { emit incFrameRate();} }
void emitResetFrameRate() { if(!isResetting_) { emit resetFrameRate();} }
void emitSetTurbo(bool on) { if(!isResetting_ && !attemptMode_) { emit setTurbo(on);} }
void emitPause() { if(!isResetting_ && !attemptMode_) { emit togglePause();} }
void emitFrameStep() { if(!isResetting_ && !attemptMode_) { emit frameStep();} }
void emitDecFrameRate() { if(!isResetting_ && !attemptMode_) { emit decFrameRate();} }
void emitIncFrameRate() { if(!isResetting_ && !attemptMode_) { emit incFrameRate();} }
void emitResetFrameRate() { if(!isResetting_ && !attemptMode_) { emit resetFrameRate();} }
void emitPrevStateSlot() { if(!isResetting_) { emit prevStateSlot();} }
void emitNextStateSlot() { if(!isResetting_) { emit nextStateSlot();} }
void emitSaveState() { if(!isResetting_) { emit saveStateSignal();} }
void emitLoadState() { if(!isResetting_) { emit loadStateSignal();} }
void emitLoadState() { if(!isResetting_ && !attemptMode_) { emit loadStateSignal();} }
void emitReset() { emit resetSignal(); }
void emitQuit() { emit quit(); }
};
Expand Down
11 changes: 8 additions & 3 deletions libgambatte/include/gambatte.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,15 @@ class GB {
*/
void setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32);

/** Use GBP color conversion instead of GBC-screen approximation. */
void setTrueColors(bool trueColors);

/** Use cycle-based RTC instead of real-time. */
void setTimeMode(bool useCycles);

/** Use GBP color conversion instead of GBC-screen approximation. */
void setTrueColors(bool trueColors);

/** Disable unwanted emulator functions for speedrunning attempts. */
void setAttemptMode(bool attemptMode) { attemptMode_ = attemptMode; }

/** Sets the callback used for getting input state. */
void setInputGetter(InputGetter *getInput, void *p);

Expand Down Expand Up @@ -283,6 +286,8 @@ class GB {

GB(GB const &);
GB & operator=(GB const &);

bool attemptMode_;
};

}
Expand Down
2 changes: 1 addition & 1 deletion libgambatte/src/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ class CPU {
mem_.setDmgPaletteColor(palNum, colorNum, rgb32);
}

void setTrueColors(bool trueColors) { mem_.setTrueColors(trueColors); }
void setTimeMode(bool useCycles) { mem_.setTimeMode(useCycles, cycleCounter_); }
void setTrueColors(bool trueColors) { mem_.setTrueColors(trueColors); }
void setRtcDivisorOffset(long const rtcDivisorOffset) { mem_.setRtcDivisorOffset(rtcDivisorOffset); }

void setGameGenie(std::string const &codes) { mem_.setGameGenie(codes); }
Expand Down
11 changes: 6 additions & 5 deletions libgambatte/src/gambatte.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void GB::reset(std::size_t samplesToStall, std::string const &build) {
p_->cpu.stall(samplesToStall * 2);

if (!build.empty())
p_->cpu.setOsdElement(newResetElement(build, GB::pakInfo().crc()));
p_->cpu.setOsdElement(newResetElement(build, GB::pakInfo().crc(), attemptMode_));
}
}

Expand Down Expand Up @@ -130,6 +130,7 @@ LoadRes GB::load(std::string const &romfile, unsigned const flags) {
setInitState(state, flags & CGB_MODE, flags & SGB_MODE);
setInitStateCart(state);
p_->cpu.loadState(state);
if (!attemptMode_)
p_->cpu.loadSavedata();

p_->stateNo = 1;
Expand Down Expand Up @@ -186,14 +187,14 @@ void GB::setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32) {
p_->cpu.setDmgPaletteColor(palNum, colorNum, rgb32);
}

void GB::setTrueColors(bool trueColors) {
p_->cpu.setTrueColors(trueColors);
}

void GB::setTimeMode(bool useCycles) {
p_->cpu.setTimeMode(useCycles);
}

void GB::setTrueColors(bool trueColors) {
p_->cpu.setTrueColors(trueColors);
}

bool GB::loadState(std::string const &filepath) {
if (p_->cpu.loaded()) {
if (p_->implicitSave())
Expand Down
11 changes: 10 additions & 1 deletion libgambatte/src/state_osd_elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ transfer_ptr<OsdElement> newStateSavedOsdElement(unsigned stateNo) {
return transfer_ptr<OsdElement>(new ShadedTextOsdElment(text::stateSavedWidth, txt));
}

transfer_ptr<OsdElement> newResetElement(std::string const &build, unsigned checksum) {
transfer_ptr<OsdElement> newResetElement(std::string const &build, unsigned checksum, bool attemptMode) {
unsigned checksumPart;
char txt[sizeof text::reset];
std::memcpy(txt, text::reset, sizeof txt);
Expand Down Expand Up @@ -199,6 +199,15 @@ transfer_ptr<OsdElement> newResetElement(std::string const &build, unsigned chec
txt[idx] = (char) (bitmapfont::A + (checksumPart - 0x0A));
}
}

// Put AM into char array if attempt mode is active
// AM -> Attempt Mode
if (attemptMode) {
int idx = p_len + p_off + 1; // 1 space in between CRC and AM
txt[idx] = bitmapfont::A;
txt[idx + 1] = bitmapfont::M;
}


return transfer_ptr<OsdElement>(new ShadedTextOsdElment(bitmapfont::getWidth(txt), txt));
}
Expand Down
2 changes: 1 addition & 1 deletion libgambatte/src/state_osd_elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace gambatte {
transfer_ptr<OsdElement> newStateLoadedOsdElement(unsigned stateNo);
transfer_ptr<OsdElement> newStateSavedOsdElement(unsigned stateNo);
transfer_ptr<OsdElement> newSaveStateOsdElement(const std::string &fileName, unsigned stateNo);
transfer_ptr<OsdElement> newResetElement(std::string const &build, unsigned checksum);
transfer_ptr<OsdElement> newResetElement(std::string const &build, unsigned checksum, bool attemptMode);
}

#endif