Auto quick saves - allow automatic save states to be taken and saved to slot #6 (read-only) every X minutes

This commit is contained in:
Souryo 2016-08-31 20:54:38 -04:00
parent c4a3b6594e
commit 1ddb980be9
18 changed files with 320 additions and 41 deletions

32
Core/AutoSaveManager.cpp Normal file
View file

@ -0,0 +1,32 @@
#include "stdafx.h"
#include "AutoSaveManager.h"
#include "Console.h"
#include "EmulationSettings.h"
#include "SaveStateManager.h"
AutoSaveManager::AutoSaveManager()
{
_stopThread = false;
_timer.Reset();
_autoSaveThread = std::thread([=]() {
while(!_stopThread) {
bool showMessage = false;
uint32_t autoSaveDelay = EmulationSettings::GetAutoSaveDelay(showMessage) * 60 * 1000;
if(autoSaveDelay > 0) {
if(_timer.GetElapsedMS() > autoSaveDelay) {
SaveStateManager::SaveState(_autoSaveSlot, showMessage);
_timer.Reset();
}
} else {
_timer.Reset();
}
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(1000));
}
});
}
AutoSaveManager::~AutoSaveManager()
{
_stopThread = true;
_autoSaveThread.join();
}

17
Core/AutoSaveManager.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include "stdafx.h"
#include <thread>
#include "../Utilities/Timer.h"
class AutoSaveManager
{
private:
const uint32_t _autoSaveSlot = 6;
std::thread _autoSaveThread;
atomic<bool> _stopThread;
Timer _timer;
public:
AutoSaveManager();
~AutoSaveManager();
};

View file

@ -54,6 +54,7 @@ void Console::Initialize(string romFilename, stringstream *filestream, string ip
if(mapper) {
_romFilepath = romFilename;
_autoSaveManager.reset(new AutoSaveManager());
VideoDecoder::GetInstance()->StopThread();
_mapper = mapper;
@ -210,7 +211,7 @@ void Console::ResetComponents(bool softReset)
_controlManager->Reset(softReset);
_lagCounter = 0;
SoundMixer::StopAudio(true);
if(softReset) {
@ -262,6 +263,8 @@ void Console::Run()
Timer clockTimer;
double targetTime;
uint32_t lastFrameNumber = -1;
_autoSaveManager.reset(new AutoSaveManager());
_runLock.Acquire();
_stopLock.Acquire();
@ -348,6 +351,8 @@ void Console::Run()
SoundMixer::StopRecording();
PlatformUtilities::EnableScreensaver();
_autoSaveManager.reset();
VideoDecoder::GetInstance()->StopThread();
_initialized = false;

View file

@ -7,6 +7,7 @@
#include "MemoryManager.h"
#include "ControlManager.h"
#include "../Utilities/SimpleLock.h"
#include "AutoSaveManager.h"
class Debugger;
class BaseMapper;
@ -28,6 +29,8 @@ class Console
unique_ptr<ControlManager> _controlManager;
shared_ptr<MemoryManager> _memoryManager;
unique_ptr<AutoSaveManager> _autoSaveManager;
NesModel _model;
string _romFilepath;

View file

@ -404,6 +404,7 @@
<ClInclude Include="APU.h" />
<ClInclude Include="ArkanoidController.h" />
<ClInclude Include="AutoRomTest.h" />
<ClInclude Include="AutoSaveManager.h" />
<ClInclude Include="Bandai74161_7432.h" />
<ClInclude Include="BandaiFcg.h" />
<ClInclude Include="BandaiKaraoke.h" />
@ -683,6 +684,7 @@
<ClCompile Include="ApuLengthCounter.cpp" />
<ClCompile Include="ArkanoidController.cpp" />
<ClCompile Include="AutoRomTest.cpp" />
<ClCompile Include="AutoSaveManager.cpp" />
<ClCompile Include="BaseControlDevice.cpp" />
<ClCompile Include="BaseMapper.cpp" />
<ClCompile Include="BaseSoundFilter.cpp" />

View file

@ -925,6 +925,9 @@
<ClInclude Include="MMC3_219.h">
<Filter>Nes\Mappers\MMC</Filter>
</ClInclude>
<ClInclude Include="AutoSaveManager.h">
<Filter>Misc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -1095,5 +1098,8 @@
<ClCompile Include="OekaKidsTablet.cpp">
<Filter>Nes\Controllers</Filter>
</ClCompile>
<ClCompile Include="AutoSaveManager.cpp">
<Filter>Misc</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -38,6 +38,9 @@ int32_t EmulationSettings::_nsfAutoDetectSilenceDelay = 3000;
int32_t EmulationSettings::_nsfMoveToNextTrackTime = 120;
bool EmulationSettings::_nsfDisableApuIrqs = true;
uint32_t EmulationSettings::_autoSaveDelay = 5;
bool EmulationSettings::_autoSaveNotify = false;
RamPowerOnState EmulationSettings::_ramPowerOnState = RamPowerOnState::AllZeros;
InputDisplaySettings EmulationSettings::_inputDisplaySettings = { 0, InputDisplayPosition::TopLeft, false };

View file

@ -305,6 +305,9 @@ private:
static InputDisplaySettings _inputDisplaySettings;
static uint32_t _autoSaveDelay;
static bool _autoSaveNotify;
static RamPowerOnState _ramPowerOnState;
public:
@ -777,4 +780,16 @@ public:
{
return _ramPowerOnState;
}
static void SetAutoSaveOptions(uint32_t delayInMinutes, bool showMessage)
{
_autoSaveDelay = delayInMinutes;
_autoSaveNotify = showMessage;
}
static uint32_t GetAutoSaveDelay(bool &showMessage)
{
showMessage = _autoSaveNotify;
return _autoSaveDelay;
}
};

View file

@ -27,7 +27,7 @@ uint64_t SaveStateManager::GetStateInfo(int stateIndex)
return 0;
}
void SaveStateManager::SaveState(int stateIndex)
void SaveStateManager::SaveState(int stateIndex, bool displayMessage)
{
string filepath = SaveStateManager::GetStateFilepath(stateIndex);
ofstream file(filepath, ios::out | ios::binary);
@ -43,7 +43,10 @@ void SaveStateManager::SaveState(int stateIndex)
Console::SaveState(file);
Console::Resume();
file.close();
MessageManager::DisplayMessage("SaveStates", "SaveStateSaved" , std::to_string(stateIndex));
if(displayMessage) {
MessageManager::DisplayMessage("SaveStates", "SaveStateSaved", std::to_string(stateIndex));
}
}
}

View file

@ -11,7 +11,6 @@ public:
static const uint32_t FileFormatVersion = 5;
static uint64_t GetStateInfo(int stateIndex);
static void SaveState(int stateIndex);
static void SaveState(int stateIndex, bool displayMessage = true);
static bool LoadState(int stateIndex);
};

View file

@ -23,6 +23,10 @@ namespace Mesen.GUI.Config
public bool AllowInvalidInput = false;
public bool RemoveSpriteLimit = false;
public bool AutoSave = true;
public Int32 AutoSaveDelay = 5;
public bool AutoSaveNotify = false;
public bool FdsAutoLoadDisk = true;
public bool FdsFastForwardOnLoad = false;
@ -92,6 +96,7 @@ namespace Mesen.GUI.Config
InteropEmu.SetFlag(EmulationFlags.DisableGameDatabase, preferenceInfo.DisableGameDatabase);
InteropEmu.NsfSetNsfConfig(preferenceInfo.NsfAutoDetectSilence ? preferenceInfo.NsfAutoDetectSilenceDelay : 0, preferenceInfo.NsfMoveToNextTrackAfterTime ? preferenceInfo.NsfMoveToNextTrackTime : -1, preferenceInfo.NsfDisableApuIrqs);
InteropEmu.SetAutoSaveOptions(preferenceInfo.AutoSave ? (uint)preferenceInfo.AutoSaveDelay : 0, preferenceInfo.AutoSaveNotify);
}
}
}

View file

@ -279,7 +279,13 @@
<Control ID="chkFdsAutoLoadDisk">Insérer le côté A du disque 1 lors du chargement d'un jeu de FDS</Control>
<Control ID="chkFdsFastForwardOnLoad">Augmenter la vitesse d'émulation pendant le chargement des jeux FDS</Control>
<Control ID="tpgCloudSave">Sauvegarde en ligne</Control>
<Control ID="tpgSaveData">Sauvegardes</Control>
<Control ID="grpAutomaticSaves">Sauvegarde d'état automatique</Control>
<Control ID="chkAutoSave">Créer une sauvegarde d'état à chaque</Control>
<Control ID="lblAutoSave">minutes (Appuyer sur F6 pour charger)</Control>
<Control ID="chkAutoSaveNotify">Afficher une notification à l'écran au moment de la sauvegarde automatique</Control>
<Control ID="grpCloudSaves">Sauvegarde en ligne</Control>
<Control ID="lblGoogleDriveIntegration">Mesen peut utiliser Google Drive pour mettre vos sauvegardes dans votre compte Google Drive. Lorsque l'intégration est activée, toutes les données de sauvegarde de vos jeux (fichiers .sav et sauvegardes rapides) sont facilement accessibles à partir de n'importe quel ordinateur.</Control>
<Control ID="lblIntegrationOK">L'intégration avec Google Drive est active.</Control>
<Control ID="btnDisableIntegration">Désactiver l'intégration Google Drive</Control>
@ -295,6 +301,7 @@
<Control ID="chkNsfMoveToNextTrackAfterTime">Limiter la durée des pistes à</Control>
<Control ID="lblNsfSeconds">secondes</Control>
<Control ID="chkNsfDisableApuIrqs">Désactiver les IRQs du APU (Recommandé)</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Annuler</Control>

View file

@ -278,7 +278,13 @@
<Control ID="chkFdsAutoLoadDisk">ファミコンディスクシステムのゲームをロードする時に自動的にディスクのA面を入れる</Control>
<Control ID="chkFdsFastForwardOnLoad">ファミコンディスクシステムのゲームをディスクからロードする時に自動的に最高速度にする</Control>
<Control ID="tpgCloudSave">クラウドバックアップ</Control>
<Control ID="tpgSaveData">セーブデータ</Control>
<Control ID="grpAutomaticSaves">オートクイックセーブ</Control>
<Control ID="chkAutoSave">オートクイックセーブを</Control>
<Control ID="lblAutoSave">分おきにするF6でクイックロード</Control>
<Control ID="chkAutoSaveNotify">オートクイックセーブする際、通信を表示する</Control>
<Control ID="grpCloudSaves">クラウドバックアップ</Control>
<Control ID="lblGoogleDriveIntegration">MesenはGoogle Driveを利用することでクラウドバックアップが出来ます。 Google Drive同期を有効にすれば、ゲームのセーブデータはGoogle Driveにバックアップされ、どんなパソコンからでもアクセスが可能になります。</Control>
<Control ID="lblIntegrationOK">Google Drive同期は有効です。</Control>
<Control ID="btnDisableIntegration">Google Drive同期を無効にする</Control>

View file

@ -43,7 +43,7 @@
this.cboDisplayLanguage = new System.Windows.Forms.ComboBox();
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgGeneral = new System.Windows.Forms.TabPage();
this.tpgCloudSave = new System.Windows.Forms.TabPage();
this.tpgSaveData = new System.Windows.Forms.TabPage();
this.tlpCloudSaves = new System.Windows.Forms.TableLayoutPanel();
this.tlpCloudSaveDesc = new System.Windows.Forms.TableLayoutPanel();
this.lblGoogleDriveIntegration = new System.Windows.Forms.Label();
@ -84,11 +84,20 @@
this.chkFdsAutoLoadDisk = new System.Windows.Forms.CheckBox();
this.chkFdsFastForwardOnLoad = new System.Windows.Forms.CheckBox();
this.tmrSyncDateTime = new System.Windows.Forms.Timer(this.components);
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.grpCloudSaves = new System.Windows.Forms.GroupBox();
this.grpAutomaticSaves = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.flpAutoSave = new System.Windows.Forms.FlowLayoutPanel();
this.chkAutoSave = new System.Windows.Forms.CheckBox();
this.nudAutoSave = new System.Windows.Forms.NumericUpDown();
this.lblAutoSave = new System.Windows.Forms.Label();
this.chkAutoSaveNotify = new System.Windows.Forms.CheckBox();
this.tlpMain.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout();
this.tabMain.SuspendLayout();
this.tpgGeneral.SuspendLayout();
this.tpgCloudSave.SuspendLayout();
this.tpgSaveData.SuspendLayout();
this.tlpCloudSaves.SuspendLayout();
this.tlpCloudSaveDesc.SuspendLayout();
this.tlpCloudSaveEnabled.SuspendLayout();
@ -106,11 +115,17 @@
this.tlpFileFormat.SuspendLayout();
this.tpgAdvanced.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.grpCloudSaves.SuspendLayout();
this.grpAutomaticSaves.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.flpAutoSave.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudAutoSave)).BeginInit();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 282);
this.baseConfigPanel.Location = new System.Drawing.Point(0, 369);
this.baseConfigPanel.Size = new System.Drawing.Size(487, 29);
//
// tlpMain
@ -140,7 +155,7 @@
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.Size = new System.Drawing.Size(473, 250);
this.tlpMain.Size = new System.Drawing.Size(473, 223);
this.tlpMain.TabIndex = 1;
//
// chkSingleInstance
@ -217,7 +232,7 @@
// btnOpenMesenFolder
//
this.btnOpenMesenFolder.AutoSize = true;
this.btnOpenMesenFolder.Location = new System.Drawing.Point(3, 224);
this.btnOpenMesenFolder.Location = new System.Drawing.Point(3, 197);
this.btnOpenMesenFolder.Name = "btnOpenMesenFolder";
this.btnOpenMesenFolder.Size = new System.Drawing.Size(117, 23);
this.btnOpenMesenFolder.TabIndex = 16;
@ -257,7 +272,7 @@
// tabMain
//
this.tabMain.Controls.Add(this.tpgGeneral);
this.tabMain.Controls.Add(this.tpgCloudSave);
this.tabMain.Controls.Add(this.tpgSaveData);
this.tabMain.Controls.Add(this.tpgNsf);
this.tabMain.Controls.Add(this.tpgFileAssociations);
this.tabMain.Controls.Add(this.tpgAdvanced);
@ -265,7 +280,7 @@
this.tabMain.Location = new System.Drawing.Point(0, 0);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(487, 282);
this.tabMain.Size = new System.Drawing.Size(487, 369);
this.tabMain.TabIndex = 2;
//
// tpgGeneral
@ -274,21 +289,21 @@
this.tpgGeneral.Location = new System.Drawing.Point(4, 22);
this.tpgGeneral.Name = "tpgGeneral";
this.tpgGeneral.Padding = new System.Windows.Forms.Padding(3);
this.tpgGeneral.Size = new System.Drawing.Size(479, 256);
this.tpgGeneral.Size = new System.Drawing.Size(479, 229);
this.tpgGeneral.TabIndex = 0;
this.tpgGeneral.Text = "General";
this.tpgGeneral.UseVisualStyleBackColor = true;
//
// tpgCloudSave
// tpgSaveData
//
this.tpgCloudSave.Controls.Add(this.tlpCloudSaves);
this.tpgCloudSave.Location = new System.Drawing.Point(4, 22);
this.tpgCloudSave.Name = "tpgCloudSave";
this.tpgCloudSave.Padding = new System.Windows.Forms.Padding(3);
this.tpgCloudSave.Size = new System.Drawing.Size(479, 256);
this.tpgCloudSave.TabIndex = 3;
this.tpgCloudSave.Text = "Cloud Saves";
this.tpgCloudSave.UseVisualStyleBackColor = true;
this.tpgSaveData.Controls.Add(this.tableLayoutPanel3);
this.tpgSaveData.Location = new System.Drawing.Point(4, 22);
this.tpgSaveData.Name = "tpgSaveData";
this.tpgSaveData.Padding = new System.Windows.Forms.Padding(3);
this.tpgSaveData.Size = new System.Drawing.Size(479, 343);
this.tpgSaveData.TabIndex = 3;
this.tpgSaveData.Text = "Save Data";
this.tpgSaveData.UseVisualStyleBackColor = true;
//
// tlpCloudSaves
//
@ -297,12 +312,12 @@
this.tlpCloudSaves.Controls.Add(this.tlpCloudSaveDesc, 0, 0);
this.tlpCloudSaves.Controls.Add(this.tlpCloudSaveEnabled, 0, 1);
this.tlpCloudSaves.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpCloudSaves.Location = new System.Drawing.Point(3, 3);
this.tlpCloudSaves.Location = new System.Drawing.Point(3, 16);
this.tlpCloudSaves.Name = "tlpCloudSaves";
this.tlpCloudSaves.RowCount = 2;
this.tlpCloudSaves.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpCloudSaves.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpCloudSaves.Size = new System.Drawing.Size(473, 250);
this.tlpCloudSaves.Size = new System.Drawing.Size(461, 239);
this.tlpCloudSaves.TabIndex = 0;
//
// tlpCloudSaveDesc
@ -318,7 +333,7 @@
this.tlpCloudSaveDesc.RowCount = 2;
this.tlpCloudSaveDesc.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpCloudSaveDesc.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpCloudSaveDesc.Size = new System.Drawing.Size(473, 100);
this.tlpCloudSaveDesc.Size = new System.Drawing.Size(461, 100);
this.tlpCloudSaveDesc.TabIndex = 0;
//
// lblGoogleDriveIntegration
@ -326,7 +341,7 @@
this.lblGoogleDriveIntegration.AutoSize = true;
this.lblGoogleDriveIntegration.Location = new System.Drawing.Point(3, 0);
this.lblGoogleDriveIntegration.Name = "lblGoogleDriveIntegration";
this.lblGoogleDriveIntegration.Size = new System.Drawing.Size(467, 52);
this.lblGoogleDriveIntegration.Size = new System.Drawing.Size(455, 52);
this.lblGoogleDriveIntegration.TabIndex = 0;
this.lblGoogleDriveIntegration.Text = resources.GetString("lblGoogleDriveIntegration.Text");
this.lblGoogleDriveIntegration.UseWaitCursor = true;
@ -355,9 +370,9 @@
this.tlpCloudSaveEnabled.RowCount = 4;
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpCloudSaveEnabled.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tlpCloudSaveEnabled.Size = new System.Drawing.Size(473, 150);
this.tlpCloudSaveEnabled.Size = new System.Drawing.Size(461, 139);
this.tlpCloudSaveEnabled.TabIndex = 1;
//
// btnDisableIntegration
@ -378,7 +393,7 @@
this.flowLayoutPanel3.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
this.flowLayoutPanel3.Size = new System.Drawing.Size(473, 22);
this.flowLayoutPanel3.Size = new System.Drawing.Size(461, 22);
this.flowLayoutPanel3.TabIndex = 1;
//
// picOK
@ -453,7 +468,7 @@
this.tpgNsf.Location = new System.Drawing.Point(4, 22);
this.tpgNsf.Name = "tpgNsf";
this.tpgNsf.Padding = new System.Windows.Forms.Padding(3);
this.tpgNsf.Size = new System.Drawing.Size(479, 256);
this.tpgNsf.Size = new System.Drawing.Size(479, 259);
this.tpgNsf.TabIndex = 4;
this.tpgNsf.Text = "NSF / NSFe";
this.tpgNsf.UseVisualStyleBackColor = true;
@ -472,7 +487,7 @@
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(473, 250);
this.tableLayoutPanel2.Size = new System.Drawing.Size(473, 253);
this.tableLayoutPanel2.TabIndex = 0;
//
// flowLayoutPanel7
@ -596,7 +611,7 @@
this.tpgFileAssociations.Location = new System.Drawing.Point(4, 22);
this.tpgFileAssociations.Name = "tpgFileAssociations";
this.tpgFileAssociations.Padding = new System.Windows.Forms.Padding(3);
this.tpgFileAssociations.Size = new System.Drawing.Size(479, 256);
this.tpgFileAssociations.Size = new System.Drawing.Size(479, 259);
this.tpgFileAssociations.TabIndex = 2;
this.tpgFileAssociations.Text = "File Associations";
this.tpgFileAssociations.UseVisualStyleBackColor = true;
@ -607,7 +622,7 @@
this.grpFileAssociations.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpFileAssociations.Location = new System.Drawing.Point(3, 3);
this.grpFileAssociations.Name = "grpFileAssociations";
this.grpFileAssociations.Size = new System.Drawing.Size(473, 250);
this.grpFileAssociations.Size = new System.Drawing.Size(473, 253);
this.grpFileAssociations.TabIndex = 12;
this.grpFileAssociations.TabStop = false;
this.grpFileAssociations.Text = "File Associations";
@ -633,7 +648,7 @@
this.tlpFileFormat.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpFileFormat.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpFileFormat.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpFileFormat.Size = new System.Drawing.Size(467, 231);
this.tlpFileFormat.Size = new System.Drawing.Size(467, 234);
this.tlpFileFormat.TabIndex = 0;
//
// chkNsfeFormat
@ -713,7 +728,7 @@
this.tpgAdvanced.Location = new System.Drawing.Point(4, 22);
this.tpgAdvanced.Name = "tpgAdvanced";
this.tpgAdvanced.Padding = new System.Windows.Forms.Padding(3);
this.tpgAdvanced.Size = new System.Drawing.Size(479, 256);
this.tpgAdvanced.Size = new System.Drawing.Size(479, 259);
this.tpgAdvanced.TabIndex = 1;
this.tpgAdvanced.Text = "Advanced";
this.tpgAdvanced.UseVisualStyleBackColor = true;
@ -773,11 +788,132 @@
this.tmrSyncDateTime.Enabled = true;
this.tmrSyncDateTime.Tick += new System.EventHandler(this.tmrSyncDateTime_Tick);
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 1;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Controls.Add(this.grpCloudSaves, 0, 1);
this.tableLayoutPanel3.Controls.Add(this.grpAutomaticSaves, 0, 0);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 2;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(473, 337);
this.tableLayoutPanel3.TabIndex = 1;
//
// grpCloudSaves
//
this.grpCloudSaves.Controls.Add(this.tlpCloudSaves);
this.grpCloudSaves.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpCloudSaves.Location = new System.Drawing.Point(3, 76);
this.grpCloudSaves.Name = "grpCloudSaves";
this.grpCloudSaves.Size = new System.Drawing.Size(467, 258);
this.grpCloudSaves.TabIndex = 2;
this.grpCloudSaves.TabStop = false;
this.grpCloudSaves.Text = "Cloud Saves";
//
// grpAutomaticSaves
//
this.grpAutomaticSaves.Controls.Add(this.tableLayoutPanel4);
this.grpAutomaticSaves.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpAutomaticSaves.Location = new System.Drawing.Point(3, 3);
this.grpAutomaticSaves.Name = "grpAutomaticSaves";
this.grpAutomaticSaves.Size = new System.Drawing.Size(467, 67);
this.grpAutomaticSaves.TabIndex = 3;
this.grpAutomaticSaves.TabStop = false;
this.grpAutomaticSaves.Text = "Automatic Save States";
//
// tableLayoutPanel4
//
this.tableLayoutPanel4.ColumnCount = 1;
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Controls.Add(this.chkAutoSaveNotify, 0, 2);
this.tableLayoutPanel4.Controls.Add(this.flpAutoSave, 0, 0);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 3;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(461, 48);
this.tableLayoutPanel4.TabIndex = 0;
//
// flpAutoSave
//
this.flpAutoSave.Controls.Add(this.chkAutoSave);
this.flpAutoSave.Controls.Add(this.nudAutoSave);
this.flpAutoSave.Controls.Add(this.lblAutoSave);
this.flpAutoSave.Dock = System.Windows.Forms.DockStyle.Fill;
this.flpAutoSave.Location = new System.Drawing.Point(0, 0);
this.flpAutoSave.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.flpAutoSave.Name = "flpAutoSave";
this.flpAutoSave.Size = new System.Drawing.Size(461, 23);
this.flpAutoSave.TabIndex = 0;
//
// chkAutoSave
//
this.chkAutoSave.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkAutoSave.AutoSize = true;
this.chkAutoSave.Location = new System.Drawing.Point(3, 4);
this.chkAutoSave.Name = "chkAutoSave";
this.chkAutoSave.Size = new System.Drawing.Size(211, 17);
this.chkAutoSave.TabIndex = 0;
this.chkAutoSave.Text = "Automatically create a save state every";
this.chkAutoSave.UseVisualStyleBackColor = true;
this.chkAutoSave.CheckedChanged += new System.EventHandler(this.chkAutoSave_CheckedChanged);
//
// nudAutoSave
//
this.nudAutoSave.Location = new System.Drawing.Point(220, 3);
this.nudAutoSave.Maximum = new decimal(new int[] {
600,
0,
0,
0});
this.nudAutoSave.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudAutoSave.Name = "nudAutoSave";
this.nudAutoSave.Size = new System.Drawing.Size(42, 20);
this.nudAutoSave.TabIndex = 1;
this.nudAutoSave.Value = new decimal(new int[] {
5,
0,
0,
0});
//
// lblAutoSave
//
this.lblAutoSave.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAutoSave.AutoSize = true;
this.lblAutoSave.Location = new System.Drawing.Point(268, 6);
this.lblAutoSave.Name = "lblAutoSave";
this.lblAutoSave.Size = new System.Drawing.Size(99, 13);
this.lblAutoSave.TabIndex = 2;
this.lblAutoSave.Text = "minutes (F6 to load)";
//
// chkAutoSaveNotify
//
this.chkAutoSaveNotify.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.chkAutoSaveNotify.AutoSize = true;
this.chkAutoSaveNotify.Location = new System.Drawing.Point(15, 27);
this.chkAutoSaveNotify.Margin = new System.Windows.Forms.Padding(15, 3, 3, 3);
this.chkAutoSaveNotify.Name = "chkAutoSaveNotify";
this.chkAutoSaveNotify.Size = new System.Drawing.Size(240, 17);
this.chkAutoSaveNotify.TabIndex = 1;
this.chkAutoSaveNotify.Text = "Notify when an automatic save state is saved";
this.chkAutoSaveNotify.UseVisualStyleBackColor = true;
//
// frmPreferences
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(487, 311);
this.ClientSize = new System.Drawing.Size(487, 398);
this.Controls.Add(this.tabMain);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
@ -794,7 +930,7 @@
this.flowLayoutPanel2.PerformLayout();
this.tabMain.ResumeLayout(false);
this.tpgGeneral.ResumeLayout(false);
this.tpgCloudSave.ResumeLayout(false);
this.tpgSaveData.ResumeLayout(false);
this.tlpCloudSaves.ResumeLayout(false);
this.tlpCloudSaveDesc.ResumeLayout(false);
this.tlpCloudSaveDesc.PerformLayout();
@ -820,6 +956,14 @@
this.tpgAdvanced.ResumeLayout(false);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.tableLayoutPanel3.ResumeLayout(false);
this.grpCloudSaves.ResumeLayout(false);
this.grpAutomaticSaves.ResumeLayout(false);
this.tableLayoutPanel4.ResumeLayout(false);
this.tableLayoutPanel4.PerformLayout();
this.flpAutoSave.ResumeLayout(false);
this.flpAutoSave.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudAutoSave)).EndInit();
this.ResumeLayout(false);
}
@ -847,7 +991,7 @@
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.Label lblDisplayLanguage;
private System.Windows.Forms.ComboBox cboDisplayLanguage;
private System.Windows.Forms.TabPage tpgCloudSave;
private System.Windows.Forms.TabPage tpgSaveData;
private System.Windows.Forms.TableLayoutPanel tlpCloudSaves;
private System.Windows.Forms.TableLayoutPanel tlpCloudSaveDesc;
private System.Windows.Forms.Label lblGoogleDriveIntegration;
@ -881,5 +1025,14 @@
private System.Windows.Forms.Label lblNsfMillisecondsOfSilence;
private System.Windows.Forms.CheckBox chkNsfDisableApuIrqs;
private System.Windows.Forms.CheckBox chkUnfFormat;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.GroupBox grpCloudSaves;
private System.Windows.Forms.GroupBox grpAutomaticSaves;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.FlowLayoutPanel flpAutoSave;
private System.Windows.Forms.CheckBox chkAutoSave;
private System.Windows.Forms.NumericUpDown nudAutoSave;
private System.Windows.Forms.Label lblAutoSave;
private System.Windows.Forms.CheckBox chkAutoSaveNotify;
}
}

View file

@ -49,6 +49,10 @@ namespace Mesen.GUI.Forms.Config
AddBinding("DisableGameDatabase", chkDisableGameDatabase);
AddBinding("AutoSave", chkAutoSave);
AddBinding("AutoSaveDelay", nudAutoSave);
AddBinding("AutoSaveNotify", chkAutoSaveNotify);
UpdateCloudDisplay();
}
@ -129,5 +133,11 @@ namespace Mesen.GUI.Forms.Config
{
Task.Run(() => CloudSyncHelper.Sync());
}
private void chkAutoSave_CheckedChanged(object sender, EventArgs e)
{
nudAutoSave.Enabled = chkAutoSave.Checked;
chkAutoSaveNotify.Enabled = chkAutoSave.Checked;
}
}
}

View file

@ -755,7 +755,8 @@ namespace Mesen.GUI.Forms
this.BeginInvoke((MethodInvoker)(() => this.InitializeStateMenu(menu, forSave)));
} else {
menu.DropDownItems.Clear();
for(uint i = 1; i <= frmMain.NumberOfSaveSlots; i++) {
Action<uint> addSaveStateInfo = (i) => {
Int64 fileTime = InteropEmu.GetStateInfo(i);
string label;
if(fileTime == 0) {
@ -778,10 +779,20 @@ namespace Mesen.GUI.Forms
}
}
};
item.ShortcutKeys = (Keys)((int)Keys.F1 + i - 1);
if(forSave) {
item.ShortcutKeys |= Keys.Shift;
}
};
for(uint i = 1; i <= frmMain.NumberOfSaveSlots; i++) {
addSaveStateInfo(i);
}
if(!forSave) {
menu.DropDownItems.Add("-");
addSaveStateInfo(6);
}
}
}

View file

@ -146,6 +146,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetPictureSettings(double brightness, double contrast, double saturation, double hue, double scanlineIntensity);
[DllImport(DLLPath)] public static extern void SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, [MarshalAs(UnmanagedType.I1)]bool mergeFields);
[DllImport(DLLPath)] public static extern void SetInputDisplaySettings(byte visiblePorts, InputDisplayPosition displayPosition, [MarshalAs(UnmanagedType.I1)]bool displayHorizontally);
[DllImport(DLLPath)] public static extern void SetAutoSaveOptions(UInt32 delayInMinutes, [MarshalAs(UnmanagedType.I1)]bool showMessage);
[DllImport(DLLPath, EntryPoint="GetRgbPalette")] private static extern void GetRgbPaletteWrapper(IntPtr paletteBuffer);

View file

@ -347,6 +347,7 @@ namespace InteropEmu {
DllExport void __stdcall SetNtscFilterSettings(double artifacts, double bleed, double fringing, double gamma, double resolution, double sharpness, bool mergeFields) { EmulationSettings::SetNtscFilterSettings(artifacts, bleed, fringing, gamma, resolution, sharpness, mergeFields); }
DllExport void __stdcall SetInputDisplaySettings(uint8_t visiblePorts, InputDisplayPosition displayPosition, bool displayHorizontally) { EmulationSettings::SetInputDisplaySettings(visiblePorts, displayPosition, displayHorizontally); }
DllExport void __stdcall SetAutoSaveOptions(uint32_t delayInMinutes, bool showMessage) { EmulationSettings::SetAutoSaveOptions(delayInMinutes, showMessage); }
DllExport const char* __stdcall GetAudioDevices()
{