History Viewer: Added option to export a save state

This commit is contained in:
Sour 2019-02-01 13:05:25 -05:00
parent accd3e7a0a
commit 10a7928f52
15 changed files with 99 additions and 26 deletions

View file

@ -7,6 +7,7 @@
#include "NotificationManager.h"
#include "RomData.h"
#include "MovieRecorder.h"
#include "SaveStateManager.h"
HistoryViewer::HistoryViewer(shared_ptr<Console> console)
{
@ -80,6 +81,23 @@ void HistoryViewer::SeekTo(uint32_t seekPosition)
}
}
bool HistoryViewer::CreateSaveState(string outputFile, uint32_t position)
{
if(position < _history.size()) {
std::stringstream stateData;
_console->GetSaveStateManager()->GetSaveStateHeader(stateData);
_history[position].GetStateData(stateData);
ofstream output(outputFile, ios::binary);
if(output) {
output << stateData.rdbuf();
output.close();
return true;
}
}
return false;
}
bool HistoryViewer::SaveMovie(string movieFile, uint32_t startPosition, uint32_t endPosition)
{
//Take a savestate to be able to restore it after generating the movie file

View file

@ -27,6 +27,7 @@ public:
uint32_t GetPosition();
void SeekTo(uint32_t seekPosition);
bool CreateSaveState(string outputFile, uint32_t position);
bool SaveMovie(string movieFile, uint32_t startPosition, uint32_t endPosition);
void ResumeGameplay(shared_ptr<Console> console, uint32_t resumePosition);

View file

@ -607,6 +607,7 @@
<Control ID="mnuFile">File</Control>
<Control ID="mnuImportMovie">Import Movie</Control>
<Control ID="mnuExportMovie">Export Movie</Control>
<Control ID="mnuCreateSaveState">Create Save State</Control>
<Control ID="mnuResumeGameplay">Resume Gameplay</Control>
<Control ID="mnuClose">Close</Control>
</Form>
@ -734,6 +735,7 @@
<Message ID="MovieSegment">Segment #{0}</Message>
<Message ID="MovieSaveError">An error occurred while trying to save the movie file.</Message>
<Message ID="FileSaveError">An error occurred while trying to save the file.</Message>
<Message ID="ClearHistory">Esborra el registre</Message>
<Message ID="LastFolderUsed">Darrera carpeta utilitzada</Message>

View file

@ -617,6 +617,7 @@
<Control ID="mnuFile">File</Control>
<Control ID="mnuImportMovie">Import Movie</Control>
<Control ID="mnuExportMovie">Export Movie</Control>
<Control ID="mnuCreateSaveState">Create Save State</Control>
<Control ID="mnuResumeGameplay">Resume Gameplay</Control>
<Control ID="mnuClose">Close</Control>
</Form>
@ -764,6 +765,7 @@
<Message ID="MovieSegment">Segment #{0}</Message>
<Message ID="MovieSaveError">An error occurred while trying to save the movie file.</Message>
<Message ID="FileSaveError">An error occurred while trying to save the file.</Message>
<Message ID="ClearHistory">Clear History</Message>
<Message ID="LastFolderUsed">Last Folder Used</Message>

View file

@ -605,6 +605,7 @@
<Control ID="mnuFile">Archivo</Control>
<Control ID="mnuImportMovie">Importar película</Control>
<Control ID="mnuExportMovie">Exportar película</Control>
<Control ID="mnuCreateSaveState">Create Save State</Control>
<Control ID="mnuResumeGameplay">Continuar el juego</Control>
<Control ID="mnuClose">Cerrar</Control>
</Form>
@ -751,6 +752,7 @@
<Message ID="MovieSegment">Parte #{0}</Message>
<Message ID="MovieSaveError">Se produjo un error al intentar guardar el archivo de película.</Message>
<Message ID="FileSaveError">An error occurred while trying to save the file.</Message>
<Message ID="ClearHistory">Limpiar historial</Message>
<Message ID="LastFolderUsed">Última carpeta usada</Message>

View file

@ -617,6 +617,7 @@
<Control ID="mnuFile">Fichier</Control>
<Control ID="mnuImportMovie">Importer un film</Control>
<Control ID="mnuExportMovie">Exporter un film</Control>
<Control ID="mnuCreateSaveState">Créer une sauvegarde d'état</Control>
<Control ID="mnuResumeGameplay">Reprendre le jeu</Control>
<Control ID="mnuClose">Fermer</Control>
</Form>
@ -764,6 +765,7 @@
<Message ID="MovieSegment">Segment #{0}</Message>
<Message ID="MovieSaveError">Une erreur est survenue pendant la sauvegarde du film.</Message>
<Message ID="FileSaveError">Une erreur est survenue pendant la sauvegarde du fichier.</Message>
<Message ID="ClearHistory">Effacer l'historique</Message>
<Message ID="LastFolderUsed">Dernier dossier utilisé</Message>

View file

@ -607,6 +607,7 @@
<Control ID="mnuFile">ファイル</Control>
<Control ID="mnuImportMovie">動画をインポートする</Control>
<Control ID="mnuExportMovie">動画をエクスポートする</Control>
<Control ID="mnuCreateSaveState">クイックセーブを作る</Control>
<Control ID="mnuResumeGameplay">ここからゲームを再開する</Control>
<Control ID="mnuClose">終了</Control>
</Form>
@ -754,6 +755,7 @@
<Message ID="MovieSegment">パート {0}</Message>
<Message ID="MovieSaveError">動画エクスポートは失敗しました。</Message>
<Message ID="FileSaveError">ファイルの保存に失敗しました。</Message>
<Message ID="ClearHistory">履歴を消去</Message>
<Message ID="LastFolderUsed">最後に使用したフォルダ</Message>

View file

@ -617,6 +617,7 @@
<Control ID="mnuFile">Arquivo</Control>
<Control ID="mnuImportMovie">Importar vídeo</Control>
<Control ID="mnuExportMovie">Exportar vídeo</Control>
<Control ID="mnuCreateSaveState">Create Save State</Control>
<Control ID="mnuResumeGameplay">Continuar jogo</Control>
<Control ID="mnuClose">Fechar</Control>
</Form>
@ -764,7 +765,8 @@
<Message ID="MovieSegment">Segmento #{0}</Message>
<Message ID="MovieSaveError">Ocorreu um erro ao tentar salvar o vídeo.</Message>
<Message ID="FileSaveError">An error occurred while trying to save the file.</Message>
<Message ID="ClearHistory">Limpar histórico</Message>
<Message ID="LastFolderUsed">Última pasta usada</Message>

View file

@ -605,6 +605,7 @@
<Control ID="mnuFile">File</Control>
<Control ID="mnuImportMovie">Import Movie</Control>
<Control ID="mnuExportMovie">Export Movie</Control>
<Control ID="mnuCreateSaveState">Create Save State</Control>
<Control ID="mnuResumeGameplay">Resume Gameplay</Control>
<Control ID="mnuClose">Close</Control>
</Form>
@ -752,6 +753,7 @@
<Message ID="MovieSegment">Segment #{0}</Message>
<Message ID="MovieSaveError">An error occurred while trying to save the movie file.</Message>
<Message ID="FileSaveError">An error occurred while trying to save the file.</Message>
<Message ID="ClearHistory">Clear History</Message>
<Message ID="LastFolderUsed">Last Folder Used</Message>

View file

@ -605,6 +605,7 @@
<Control ID="mnuFile">Файл</Control>
<Control ID="mnuImportMovie">Імпортувати відео</Control>
<Control ID="mnuExportMovie">Експортувати вiдео</Control>
<Control ID="mnuCreateSaveState">Create Save State</Control>
<Control ID="mnuResumeGameplay">Відновити геймплей</Control>
<Control ID="mnuClose">Закрити</Control>
</Form>
@ -752,6 +753,7 @@
<Message ID="MovieSegment">Сегмент #{0}</Message>
<Message ID="MovieSaveError">Сталася помилка під час спроби зберегти відео файл.</Message>
<Message ID="FileSaveError">An error occurred while trying to save the file.</Message>
<Message ID="ClearHistory">Очистити історію</Message>
<Message ID="LastFolderUsed">Використовувана остання папка</Message>

View file

@ -609,6 +609,7 @@
<Control ID="mnuFile">文件</Control>
<Control ID="mnuImportMovie">导入影片</Control>
<Control ID="mnuExportMovie">导出影片</Control>
<Control ID="mnuCreateSaveState">Create Save State</Control>
<Control ID="mnuResumeGameplay">继续播放</Control>
<Control ID="mnuClose">关闭</Control>
</Form>
@ -755,6 +756,8 @@
<Message ID="SaveToFile">保存到文件...</Message>
<Message ID="MovieSegment">第 #{0} 段</Message>
<Message ID="MovieSaveError">尝试保存电影文件时发生错误.</Message>
<Message ID="FileSaveError">An error occurred while trying to save the file.</Message>
<Message ID="ClearHistory">清除历史</Message>
<Message ID="LastFolderUsed">上次使用的文件夹</Message>

View file

@ -33,6 +33,7 @@
this.btnPausePlay = new System.Windows.Forms.Button();
this.lblPosition = new System.Windows.Forms.Label();
this.pnlRenderer = new System.Windows.Forms.Panel();
this.picNsfIcon = new System.Windows.Forms.PictureBox();
this.tlpRenderer = new System.Windows.Forms.TableLayoutPanel();
this.ctrlRenderer = new System.Windows.Forms.Panel();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
@ -44,18 +45,18 @@
this.mnuImportMovie = new System.Windows.Forms.ToolStripMenuItem();
this.mnuExportMovie = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuCreateSaveState = new System.Windows.Forms.ToolStripMenuItem();
this.mnuResumeGameplay = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
this.picNsfIcon = new System.Windows.Forms.PictureBox();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trkPosition)).BeginInit();
this.pnlRenderer.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picNsfIcon)).BeginInit();
this.tlpRenderer.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trkVolume)).BeginInit();
this.menuStrip2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picNsfIcon)).BeginInit();
this.SuspendLayout();
//
// tableLayoutPanel1
@ -126,6 +127,19 @@
this.pnlRenderer.Size = new System.Drawing.Size(551, 397);
this.pnlRenderer.TabIndex = 0;
//
// picNsfIcon
//
this.picNsfIcon.Anchor = System.Windows.Forms.AnchorStyles.None;
this.picNsfIcon.BackgroundImage = global::Mesen.GUI.Properties.Resources.NsfBackground;
this.picNsfIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.picNsfIcon.Location = new System.Drawing.Point(199, 152);
this.picNsfIcon.Margin = new System.Windows.Forms.Padding(0);
this.picNsfIcon.MaximumSize = new System.Drawing.Size(500, 90);
this.picNsfIcon.Name = "picNsfIcon";
this.picNsfIcon.Size = new System.Drawing.Size(150, 90);
this.picNsfIcon.TabIndex = 6;
this.picNsfIcon.TabStop = false;
//
// tlpRenderer
//
this.tlpRenderer.ColumnCount = 1;
@ -212,13 +226,14 @@
this.mnuImportMovie,
this.mnuExportMovie,
this.toolStripMenuItem1,
this.mnuCreateSaveState,
this.mnuResumeGameplay,
this.toolStripMenuItem2,
this.mnuClose});
this.mnuFile.Name = "mnuFile";
this.mnuFile.Size = new System.Drawing.Size(37, 20);
this.mnuFile.Text = "File";
this.mnuFile.DropDownOpening += new System.EventHandler(this.fileToolStripMenuItem_DropDownOpening);
this.mnuFile.DropDownOpening += new System.EventHandler(this.mnuFile_DropDownOpening);
//
// mnuImportMovie
//
@ -239,6 +254,14 @@
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(168, 6);
//
// mnuCreateSaveState
//
this.mnuCreateSaveState.Image = global::Mesen.GUI.Properties.Resources.Floppy;
this.mnuCreateSaveState.Name = "mnuCreateSaveState";
this.mnuCreateSaveState.Size = new System.Drawing.Size(171, 22);
this.mnuCreateSaveState.Text = "Create Save State";
this.mnuCreateSaveState.Click += new System.EventHandler(this.mnuCreateSaveState_Click);
//
// mnuResumeGameplay
//
this.mnuResumeGameplay.Image = global::Mesen.GUI.Properties.Resources.Play;
@ -260,19 +283,6 @@
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
// picNsfIcon
//
this.picNsfIcon.Anchor = System.Windows.Forms.AnchorStyles.None;
this.picNsfIcon.BackgroundImage = global::Mesen.GUI.Properties.Resources.NsfBackground;
this.picNsfIcon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.picNsfIcon.Location = new System.Drawing.Point(199, 152);
this.picNsfIcon.Margin = new System.Windows.Forms.Padding(0);
this.picNsfIcon.MaximumSize = new System.Drawing.Size(500, 90);
this.picNsfIcon.Name = "picNsfIcon";
this.picNsfIcon.Size = new System.Drawing.Size(150, 90);
this.picNsfIcon.TabIndex = 6;
this.picNsfIcon.TabStop = false;
//
// frmHistoryViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -287,13 +297,13 @@
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trkPosition)).EndInit();
this.pnlRenderer.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.picNsfIcon)).EndInit();
this.tlpRenderer.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trkVolume)).EndInit();
this.menuStrip2.ResumeLayout(false);
this.menuStrip2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picNsfIcon)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@ -321,5 +331,6 @@
private System.Windows.Forms.Label lblVolume;
private System.Windows.Forms.TrackBar trkVolume;
private System.Windows.Forms.PictureBox picNsfIcon;
private System.Windows.Forms.ToolStripMenuItem mnuCreateSaveState;
}
}

View file

@ -167,7 +167,7 @@ namespace Mesen.GUI.Forms
InteropEmu.HistoryViewerResumeGameplay(InteropEmu.HistoryViewerGetPosition());
}
private void fileToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
private void mnuFile_DropDownOpening(object sender, EventArgs e)
{
mnuExportMovie.DropDownItems.Clear();
@ -186,13 +186,14 @@ namespace Mesen.GUI.Forms
string segmentName = ResourceHelper.GetMessage("MovieSegment", (mnuExportMovie.DropDownItems.Count + 1).ToString());
ToolStripMenuItem item = new ToolStripMenuItem(segmentName + ", " + start.ToString() + " - " + end.ToString());
item.Click += (s, evt) => {
SaveFileDialog sfd = new SaveFileDialog();
sfd.SetFilter(ResourceHelper.GetMessage("FilterMovie"));
sfd.InitialDirectory = ConfigManager.MovieFolder;
sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mmo";
if(sfd.ShowDialog() == DialogResult.OK) {
if(!InteropEmu.HistoryViewerSaveMovie(sfd.FileName, segStart, segEnd)) {
MesenMsgBox.Show("MovieSaveError", MessageBoxButtons.OK, MessageBoxIcon.Error);
using(SaveFileDialog sfd = new SaveFileDialog()) {
sfd.SetFilter(ResourceHelper.GetMessage("FilterMovie"));
sfd.InitialDirectory = ConfigManager.MovieFolder;
sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mmo";
if(sfd.ShowDialog() == DialogResult.OK) {
if(!InteropEmu.HistoryViewerSaveMovie(sfd.FileName, segStart, segEnd)) {
MesenMsgBox.Show("MovieSaveError", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
};
@ -204,6 +205,20 @@ namespace Mesen.GUI.Forms
mnuImportMovie.Visible = false;
mnuExportMovie.Enabled = mnuExportMovie.HasDropDownItems && !_isNsf;
}
private void mnuCreateSaveState_Click(object sender, EventArgs e)
{
using(SaveFileDialog sfd = new SaveFileDialog()) {
sfd.SetFilter(ResourceHelper.GetMessage("FilterSavestate"));
sfd.InitialDirectory = ConfigManager.SaveStateFolder;
sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mst";
if(sfd.ShowDialog() == DialogResult.OK) {
if(!InteropEmu.HistoryViewerCreateSaveState(sfd.FileName, InteropEmu.HistoryViewerGetPosition())) {
MesenMsgBox.Show("FileSaveError", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void btnPausePlay_Click(object sender, EventArgs e)
{

View file

@ -33,6 +33,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void HistoryViewerStop();
[DllImport(DLLPath)] public static extern UInt32 HistoryViewerGetHistoryLength();
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool HistoryViewerSaveMovie([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string movieFile, UInt32 startPosition, UInt32 endPosition);
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool HistoryViewerCreateSaveState([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string outfileFile, UInt32 position);
[DllImport(DLLPath)] public static extern void HistoryViewerSetPosition(UInt32 seekPosition);
[DllImport(DLLPath)] public static extern void HistoryViewerResumeGameplay(UInt32 seekPosition);
[DllImport(DLLPath)] public static extern UInt32 HistoryViewerGetPosition();

View file

@ -250,6 +250,14 @@ namespace InteropEmu {
}
}
DllExport bool __stdcall HistoryViewerCreateSaveState(const char* outputFile, uint32_t position)
{
if(_historyConsole) {
return _historyConsole->GetHistoryViewer()->CreateSaveState(outputFile, position);
}
return false;
}
DllExport bool __stdcall HistoryViewerSaveMovie(const char* movieFile, uint32_t startPosition, uint32_t endPosition)
{
if(_historyConsole) {