Core: Add option to allow preloading the entire ROM before running

This commit is contained in:
Vicki Pfau 2017-04-13 00:28:28 -07:00
parent 58c9bcf67a
commit 959f66a1a0
8 changed files with 79 additions and 14 deletions

View File

@ -13,6 +13,7 @@ Features:
- Qt: German translation (by Lothar Serra Mari) - Qt: German translation (by Lothar Serra Mari)
- Savestates now contain any RTC override data - Savestates now contain any RTC override data
- Command line ability to override configuration values - Command line ability to override configuration values
- Add option to allow preloading the entire ROM before running
Bugfixes: Bugfixes:
- LR35902: Fix core never exiting with certain event patterns - LR35902: Fix core never exiting with certain event patterns
- GB Timer: Improve DIV reset behavior - GB Timer: Improve DIV reset behavior

View File

@ -151,6 +151,9 @@ struct mCore {
struct mCore* mCoreFind(const char* path); struct mCore* mCoreFind(const char* path);
bool mCoreLoadFile(struct mCore* core, const char* path); bool mCoreLoadFile(struct mCore* core, const char* path);
bool mCorePreloadVF(struct mCore* core, struct VFile* vf);
bool mCorePreloadFile(struct mCore* core, const char* path);
bool mCoreAutoloadSave(struct mCore* core); bool mCoreAutoloadSave(struct mCore* core);
bool mCoreAutoloadPatch(struct mCore* core); bool mCoreAutoloadPatch(struct mCore* core);

View File

@ -115,6 +115,35 @@ bool mCoreLoadFile(struct mCore* core, const char* path) {
return ret; return ret;
} }
bool mCorePreloadVF(struct mCore* core, struct VFile* vf) {
struct VFile* vfm = VFileMemChunk(NULL, vf->size(vf));
uint8_t buffer[2048];
ssize_t read;
vf->seek(vf, 0, SEEK_SET);
while ((read = vf->read(vf, buffer, sizeof(buffer))) > 0) {
vfm->write(vfm, buffer, read);
}
vf->close(vf);
bool ret = core->loadROM(core, vfm);
if (!ret) {
vfm->close(vfm);
}
return ret;
}
bool mCorePreloadFile(struct mCore* core, const char* path) {
struct VFile* rom = mDirectorySetOpenPath(&core->dirs, path, core->isROM);
if (!rom) {
return false;
}
bool ret = mCorePreloadVF(core, rom);
if (!ret) {
rom->close(rom);
}
return ret;
}
bool mCoreAutoloadSave(struct mCore* core) { bool mCoreAutoloadSave(struct mCore* core) {
return core->loadSave(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.save, ".sav", O_CREAT | O_RDWR)); return core->loadSave(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.save, ".sav", O_CREAT | O_RDWR));
} }

View File

@ -69,6 +69,7 @@ GameController::GameController(QObject* parent)
, m_backupSaveState(nullptr) , m_backupSaveState(nullptr)
, m_saveStateFlags(SAVESTATE_SCREENSHOT | SAVESTATE_SAVEDATA | SAVESTATE_CHEATS | SAVESTATE_RTC) , m_saveStateFlags(SAVESTATE_SCREENSHOT | SAVESTATE_SAVEDATA | SAVESTATE_CHEATS | SAVESTATE_RTC)
, m_loadStateFlags(SAVESTATE_SCREENSHOT | SAVESTATE_RTC) , m_loadStateFlags(SAVESTATE_SCREENSHOT | SAVESTATE_RTC)
, m_preload(false)
, m_override(nullptr) , m_override(nullptr)
{ {
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
@ -458,11 +459,20 @@ void GameController::openGame(bool biosOnly) {
QByteArray bytes; QByteArray bytes;
if (!biosOnly) { if (!biosOnly) {
bytes = m_fname.toUtf8(); bytes = m_fname.toUtf8();
if (m_vf) { if (m_preload) {
m_threadContext.core->loadROM(m_threadContext.core, m_vf); if (m_vf) {
mCorePreloadVF(m_threadContext.core, m_vf);
} else {
mCorePreloadFile(m_threadContext.core, bytes.constData());
mDirectorySetDetachBase(&m_threadContext.core->dirs);
}
} else { } else {
mCoreLoadFile(m_threadContext.core, bytes.constData()); if (m_vf) {
mDirectorySetDetachBase(&m_threadContext.core->dirs); m_threadContext.core->loadROM(m_threadContext.core, m_vf);
} else {
mCoreLoadFile(m_threadContext.core, bytes.constData());
mDirectorySetDetachBase(&m_threadContext.core->dirs);
}
} }
} else { } else {
bytes = m_bios.toUtf8(); bytes = m_bios.toUtf8();
@ -1107,6 +1117,10 @@ void GameController::setLoadStateExtdata(int flags) {
m_loadStateFlags = flags; m_loadStateFlags = flags;
} }
void GameController::setPreload(bool preload) {
m_preload = preload;
}
void GameController::setLuminanceValue(uint8_t value) { void GameController::setLuminanceValue(uint8_t value) {
m_luxValue = value; m_luxValue = value;
value = std::max<int>(value - 0x16, 0); value = std::max<int>(value - 0x16, 0);

View File

@ -154,6 +154,7 @@ public slots:
void reloadAudioDriver(); void reloadAudioDriver();
void setSaveStateExtdata(int flags); void setSaveStateExtdata(int flags);
void setLoadStateExtdata(int flags); void setLoadStateExtdata(int flags);
void setPreload(bool);
#ifdef USE_PNG #ifdef USE_PNG
void screenshot(); void screenshot();
@ -234,6 +235,8 @@ private:
int m_saveStateFlags; int m_saveStateFlags;
int m_loadStateFlags; int m_loadStateFlags;
bool m_preload;
InputController* m_inputController; InputController* m_inputController;
MultiplayerController* m_multiplayer; MultiplayerController* m_multiplayer;

View File

@ -204,6 +204,7 @@ void SettingsView::updateConfig() {
saveSetting("screenshotPath", m_ui.screenshotPath); saveSetting("screenshotPath", m_ui.screenshotPath);
saveSetting("patchPath", m_ui.patchPath); saveSetting("patchPath", m_ui.patchPath);
saveSetting("showLibrary", m_ui.showLibrary); saveSetting("showLibrary", m_ui.showLibrary);
saveSetting("preload", m_ui.preload);
if (m_ui.fastForwardUnbounded->isChecked()) { if (m_ui.fastForwardUnbounded->isChecked()) {
saveSetting("fastForwardRatio", "-1"); saveSetting("fastForwardRatio", "-1");
@ -283,6 +284,7 @@ void SettingsView::reloadConfig() {
loadSetting("screenshotPath", m_ui.screenshotPath); loadSetting("screenshotPath", m_ui.screenshotPath);
loadSetting("patchPath", m_ui.patchPath); loadSetting("patchPath", m_ui.patchPath);
loadSetting("showLibrary", m_ui.showLibrary); loadSetting("showLibrary", m_ui.showLibrary);
loadSetting("preload", m_ui.preload);
double fastForwardRatio = loadSetting("fastForwardRatio").toDouble(); double fastForwardRatio = loadSetting("fastForwardRatio").toDouble();
if (fastForwardRatio <= 0) { if (fastForwardRatio <= 0) {

View File

@ -568,21 +568,21 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="7" column="0" colspan="2"> <item row="8" column="0" colspan="2">
<widget class="Line" name="line_2"> <widget class="Line" name="line_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="0"> <item row="9" column="0">
<widget class="QLabel" name="label_24"> <widget class="QLabel" name="label_24">
<property name="text"> <property name="text">
<string>Savestate extra data:</string> <string>Savestate extra data:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="9" column="1">
<widget class="QCheckBox" name="saveStateScreenshot"> <widget class="QCheckBox" name="saveStateScreenshot">
<property name="text"> <property name="text">
<string>Screenshot</string> <string>Screenshot</string>
@ -592,7 +592,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="1"> <item row="10" column="1">
<widget class="QCheckBox" name="saveStateSave"> <widget class="QCheckBox" name="saveStateSave">
<property name="text"> <property name="text">
<string>Save data</string> <string>Save data</string>
@ -602,7 +602,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="1"> <item row="11" column="1">
<widget class="QCheckBox" name="saveStateCheats"> <widget class="QCheckBox" name="saveStateCheats">
<property name="text"> <property name="text">
<string>Cheat codes</string> <string>Cheat codes</string>
@ -612,14 +612,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="0"> <item row="13" column="0">
<widget class="QLabel" name="label_25"> <widget class="QLabel" name="label_25">
<property name="text"> <property name="text">
<string>Load extra data:</string> <string>Load extra data:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="1"> <item row="13" column="1">
<widget class="QCheckBox" name="loadStateScreenshot"> <widget class="QCheckBox" name="loadStateScreenshot">
<property name="text"> <property name="text">
<string>Screenshot</string> <string>Screenshot</string>
@ -629,21 +629,21 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="1"> <item row="14" column="1">
<widget class="QCheckBox" name="loadStateSave"> <widget class="QCheckBox" name="loadStateSave">
<property name="text"> <property name="text">
<string>Save data</string> <string>Save data</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="14" column="1"> <item row="15" column="1">
<widget class="QCheckBox" name="loadStateCheats"> <widget class="QCheckBox" name="loadStateCheats">
<property name="text"> <property name="text">
<string>Cheat codes</string> <string>Cheat codes</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="0" colspan="2"> <item row="12" column="0" colspan="2">
<widget class="Line" name="line_9"> <widget class="Line" name="line_9">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -660,6 +660,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1">
<widget class="QCheckBox" name="preload">
<property name="text">
<string>Preload entire ROM into memory</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="bios"> <widget class="QWidget" name="bios">

View File

@ -1476,6 +1476,12 @@ void Window::setupMenu(QMenuBar* menubar) {
m_controller->setLoadStateExtdata(value.toInt()); m_controller->setLoadStateExtdata(value.toInt());
}, this); }, this);
ConfigOption* preload = m_config->addOption("preload");
preload->connect([this](const QVariant& value) {
m_controller->setPreload(value.toBool());
}, this);
m_config->updateOption("preload");
QAction* exitFullScreen = new QAction(tr("Exit fullscreen"), frameMenu); QAction* exitFullScreen = new QAction(tr("Exit fullscreen"), frameMenu);
connect(exitFullScreen, SIGNAL(triggered()), this, SLOT(exitFullScreen())); connect(exitFullScreen, SIGNAL(triggered()), this, SLOT(exitFullScreen()));
exitFullScreen->setShortcut(QKeySequence("Esc")); exitFullScreen->setShortcut(QKeySequence("Esc"));