diff --git a/Core/MovieManager.cpp b/Core/MovieManager.cpp index 690de968..a4cbd3e8 100644 --- a/Core/MovieManager.cpp +++ b/Core/MovieManager.cpp @@ -10,10 +10,10 @@ shared_ptr MovieManager::_player; shared_ptr MovieManager::_recorder; -void MovieManager::Record(string filename, bool reset) +void MovieManager::Record(RecordMovieOptions options) { shared_ptr recorder(new MovieRecorder()); - if(recorder->Record(filename, reset)) { + if(recorder->Record(options)) { _recorder = recorder; } } diff --git a/Core/MovieManager.h b/Core/MovieManager.h index d9af470b..f26c3384 100644 --- a/Core/MovieManager.h +++ b/Core/MovieManager.h @@ -3,6 +3,7 @@ #include "MessageManager.h" #include "EmulationSettings.h" #include "IInputProvider.h" +#include "Types.h" class MovieRecorder; class VirtualFile; @@ -31,7 +32,7 @@ private: static shared_ptr _recorder; public: - static void Record(string filename, bool reset); + static void Record(RecordMovieOptions options); static void Play(VirtualFile file); static void Stop(); static bool Playing(); diff --git a/Core/MovieRecorder.cpp b/Core/MovieRecorder.cpp index be96e46f..46bd6469 100644 --- a/Core/MovieRecorder.cpp +++ b/Core/MovieRecorder.cpp @@ -18,9 +18,11 @@ MovieRecorder::~MovieRecorder() { } -bool MovieRecorder::Record(string filename, bool reset) +bool MovieRecorder::Record(RecordMovieOptions options) { - _filename = filename; + _filename = options.Filename; + _author = options.Author; + _description = options.Description; _writer.reset(new ZipWriter()); _inputData = stringstream(); _saveStateData = stringstream(); @@ -31,18 +33,21 @@ bool MovieRecorder::Record(string filename, bool reset) return false; } else { Console::Pause(); - - //TODO: Prevent game from loading battery from disk when not recording battery files - BatteryManager::SetBatteryProvider(shared_from_this()); + + if(options.RecordFrom == RecordMovieFrom::StartWithoutSaveData) { + BatteryManager::SetBatteryProvider(shared_from_this()); + } //Save existing battery files - BatteryManager::SetBatteryRecorder(shared_from_this()); + if(options.RecordFrom == RecordMovieFrom::StartWithSaveData) { + BatteryManager::SetBatteryRecorder(shared_from_this()); + } ControlManager::RegisterInputRecorder(this); - if(reset) { - Console::GetInstance()->PowerCycle(); - } else { + if(options.RecordFrom == RecordMovieFrom::CurrentState) { SaveStateManager::SaveState(_saveStateData); _hasSaveState = true; + } else { + Console::GetInstance()->PowerCycle(); } BatteryManager::SetBatteryRecorder(nullptr); Console::Resume(); @@ -159,6 +164,13 @@ bool MovieRecorder::Stop() GetGameSettings(out); _writer->AddFile(out, "GameSettings.txt"); + if(!_author.empty() || !_description.empty()) { + stringstream movieInfo; + WriteString(movieInfo, "Author", _author); + movieInfo << "Description\n" << _description; + _writer->AddFile(movieInfo, "MovieInfo.txt"); + } + VirtualFile patchFile = Console::GetPatchFile(); vector patchData; if(patchFile.IsValid() && patchFile.ReadFile(patchData)) { diff --git a/Core/MovieRecorder.h b/Core/MovieRecorder.h index b72bbd33..59425f9b 100644 --- a/Core/MovieRecorder.h +++ b/Core/MovieRecorder.h @@ -4,6 +4,7 @@ #include "IInputRecorder.h" #include "CheatManager.h" #include "BatteryManager.h" +#include "Types.h" class ZipWriter; @@ -12,6 +13,8 @@ class MovieRecorder : public IInputRecorder, public IBatteryRecorder, public IBa private: static const uint32_t MovieFormatVersion = 1; string _filename; + string _author; + string _description; unique_ptr _writer; std::unordered_map> _batteryData; stringstream _inputData; @@ -28,7 +31,7 @@ public: MovieRecorder(); ~MovieRecorder(); - bool Record(string filename, bool reset); + bool Record(RecordMovieOptions options); bool Stop(); void RecordInput(vector> devices) override; diff --git a/Core/RecordedRomTest.cpp b/Core/RecordedRomTest.cpp index 12eba0a7..af6f7a14 100644 --- a/Core/RecordedRomTest.cpp +++ b/Core/RecordedRomTest.cpp @@ -124,7 +124,11 @@ void RecordedRomTest::Record(string filename, bool reset) _recording = true; //Start recording movie alongside with screenshots - MovieManager::Record(FolderUtilities::CombinePath(FolderUtilities::GetFolderName(filename), FolderUtilities::GetFilename(filename, false) + ".mmo"), reset); + RecordMovieOptions options; + string movieFilename = FolderUtilities::CombinePath(FolderUtilities::GetFolderName(filename), FolderUtilities::GetFilename(filename, false) + ".mmo"); + memcpy(options.Filename, movieFilename.c_str(), std::max(1000, (int)movieFilename.size())); + options.RecordFrom = reset ? RecordMovieFrom::StartWithSaveData : RecordMovieFrom::CurrentState; + MovieManager::Record(options); Console::Resume(); } diff --git a/Core/Types.h b/Core/Types.h index 7606fc43..6db92259 100644 --- a/Core/Types.h +++ b/Core/Types.h @@ -252,3 +252,20 @@ enum class ConsoleFeatures BarcodeReader = 8, TapeRecorder = 16, }; + +enum class RecordMovieFrom +{ + StartWithoutSaveData = 0, + StartWithSaveData, + CurrentState +}; + +struct RecordMovieOptions +{ +public: + char Filename[2000] = {}; + char Author[250] = {}; + char Description[10000] = {}; + + RecordMovieFrom RecordFrom = RecordMovieFrom::StartWithoutSaveData; +}; \ No newline at end of file diff --git a/GUI.NET/Config/Configuration.cs b/GUI.NET/Config/Configuration.cs index 15ae2dbb..f2759d9c 100644 --- a/GUI.NET/Config/Configuration.cs +++ b/GUI.NET/Config/Configuration.cs @@ -31,6 +31,7 @@ namespace Mesen.GUI.Config public PlayerProfile Profile; public DebugInfo DebugInfo; public AviRecordInfo AviRecordInfo; + public MovieRecordInfo MovieRecordInfo; public Point? WindowLocation; public Size? WindowSize; @@ -49,6 +50,7 @@ namespace Mesen.GUI.Config VsConfig = new List(); DebugInfo = new DebugInfo(); AviRecordInfo = new AviRecordInfo(); + MovieRecordInfo = new MovieRecordInfo(); } ~Configuration() diff --git a/GUI.NET/Config/MovieRecordInfo.cs b/GUI.NET/Config/MovieRecordInfo.cs new file mode 100644 index 00000000..838ccd92 --- /dev/null +++ b/GUI.NET/Config/MovieRecordInfo.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Mesen.GUI.Config +{ + public class MovieRecordInfo + { + public RecordMovieFrom RecordFrom; + public string Author; + public string Description; + } +} diff --git a/GUI.NET/Dependencies/resources.ca.xml b/GUI.NET/Dependencies/resources.ca.xml index c866dd69..5cd338ac 100644 --- a/GUI.NET/Dependencies/resources.ca.xml +++ b/GUI.NET/Dependencies/resources.ca.xml @@ -71,9 +71,7 @@ Configura el teu perfil Pel·lícules Reprodueix... - Enregistra des... - Del principi - D'ara + Enregistra... Atura Enregistrador de so Enregistra... @@ -568,6 +566,16 @@ Això iniciarà Mesen en mode de pantalla completa i amb la rom "MyGame.nes" carregada. A més, farà servir el filtre NTSC ajustat a una escala de 2x i configurarà les opcions de sobreescaneig. El paràmetre "DoNotSaveSettings" s'utilitza per evitar que els canvis efectuats des de la línia d'ordres es desin permanentment a la configuració de Mesen. /fullscreen - Inicia Mesen en pantalla completa /DoNotSaveSettings - Evita que els canvis es desin (útil per a evitar que les opcions de la línia d'ordres es converteixin en la configuració per defecte) +
+ Save to: + Record from: + Movie Information (optional) + Author: + Description: + Navega... + D'acord + Cancel·la +
Codi de barres: D'acord @@ -932,5 +940,10 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) + + Power on + Power on, with save data + Current state + diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml index e968aaf8..09068290 100644 --- a/GUI.NET/Dependencies/resources.en.xml +++ b/GUI.NET/Dependencies/resources.en.xml @@ -285,7 +285,12 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) - + + Power on + Power on, with save data + Current state + + Hexadecimal diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml index 8eced96c..1bbbfcaf 100644 --- a/GUI.NET/Dependencies/resources.es.xml +++ b/GUI.NET/Dependencies/resources.es.xml @@ -70,9 +70,7 @@ Configurar tu perfil Videos Reproducir... - Grabar a partir... - Del inicio del juego - Del estado actual + Grabar... Detener Grabar sonido Grabar... @@ -586,6 +584,16 @@ CONFIRMAR Cancelar +
+ Save to: + Record from: + Movie Information (optional) + Author: + Description: + Buscar... + OK + Cancelar +
Barcode: OK @@ -950,5 +958,10 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) + + Power on + Power on, with save data + Current state + diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml index d21922a1..2789c8ba 100644 --- a/GUI.NET/Dependencies/resources.fr.xml +++ b/GUI.NET/Dependencies/resources.fr.xml @@ -71,9 +71,7 @@ Configurer votre profil Films Jouer... - Enregistrer à partir... - Du début du jeu - De maintenant + Enregistrer... Arrêter Enregistreur audio Enregistrer... @@ -597,12 +595,21 @@ CONFIRMER Annuler
+
+ Sauvegarder sous : + Enregistrer à partir: + Information sur le film (optionel) + Auteur : + Description : + Parcourir... + OK + Annuler +
Code-barres : OK Annuler
-
Les tabs sans icône sont vides. Chaque bouton peut être mappé à 4 boutons différents sur votre clavier et/ou votre manette. Mappage #1 @@ -964,5 +971,10 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) + + Du début + Du début (en incluant les sauvegardes) + De maintenant + diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml index 19cce15e..b45a198c 100644 --- a/GUI.NET/Dependencies/resources.ja.xml +++ b/GUI.NET/Dependencies/resources.ja.xml @@ -72,9 +72,7 @@ プロファイル設定 動画 再生 - 録画 - 最初から - この時点から + 録画 停止 サウンドレコーダー 録音 @@ -581,6 +579,16 @@ 確認 キャンセル
+
+ 保存先: + 録画開始時点: + 映画情報 (任意) + 作者: + 説明: + 参照... + OK + キャンセル +
バーコード: 入力 @@ -947,5 +955,10 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) + + パワーオンから + パワーオンから (セーブデータ付き) + 今から + diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml index 047fbc5b..fa91f9a5 100644 --- a/GUI.NET/Dependencies/resources.pt.xml +++ b/GUI.NET/Dependencies/resources.pt.xml @@ -70,9 +70,7 @@ Configurar perfil Vídeos Reproduzir... - Gravar a partir de... - Do início do jogo - Do estado atual + Gravar... Parar Gravador de vídeo Gravar... @@ -584,6 +582,16 @@ CONFIRMAR Cancelar
+
+ Save to: + Record from: + Movie Information (optional) + Author: + Description: + Procurar... + OK + Cancelar +
Barcode: OK @@ -948,5 +956,10 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) + + Power on + Power on, with save data + Current state + diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml index 6238971a..5c0455e0 100644 --- a/GUI.NET/Dependencies/resources.ru.xml +++ b/GUI.NET/Dependencies/resources.ru.xml @@ -70,9 +70,7 @@ Настроить профиль Записи Проиграть - Записать - Сначала - Немедленно + Записать Остановить запись Запись звука Начать @@ -586,6 +584,16 @@ CONFIRM Cancel
+
+ Save to: + Record from: + Movie Information (optional) + Author: + Description: + Browse... + OK + Отмена +
Barcode: OK @@ -952,5 +960,10 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) + + Power on + Power on, with save data + Current state + diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml index 9c01f32a..d40c4e5b 100644 --- a/GUI.NET/Dependencies/resources.uk.xml +++ b/GUI.NET/Dependencies/resources.uk.xml @@ -70,9 +70,7 @@ Налаштувати профіль Записи Програти - Записати - Спочатку - Негайно + Записати Зупинити запис Запис звуку Почати @@ -586,6 +584,16 @@ ПIДТВЕРДИТИ Скасувати
+
+ Save to: + Record from: + Movie Information (optional) + Author: + Description: + Огляд... + OK + Вiдмiна +
Barcode: OK @@ -952,5 +960,10 @@ Zip Motion Block Video (ZMBV) Camstudio (CSCD) + + Power on + Power on, with save data + Current state + diff --git a/GUI.NET/Forms/EntityBinder.cs b/GUI.NET/Forms/EntityBinder.cs index 59bc20da..005b20c9 100644 --- a/GUI.NET/Forms/EntityBinder.cs +++ b/GUI.NET/Forms/EntityBinder.cs @@ -68,7 +68,7 @@ namespace Mesen.GUI.Forms if(value is IFormattable) { kvp.Value.Text = ((IFormattable)value).ToString(format == eNumberFormat.Decimal ? "" : "X", System.Globalization.CultureInfo.InvariantCulture); } else { - kvp.Value.Text = (string)value; + kvp.Value.Text = ((string)value).Replace(Environment.NewLine, "\n").Replace("\n", Environment.NewLine); } } else if(kvp.Value is ctrlPathSelection) { kvp.Value.Text = (string)value; diff --git a/GUI.NET/Forms/frmMain.Designer.cs b/GUI.NET/Forms/frmMain.Designer.cs index 96c91a5b..32dc7369 100644 --- a/GUI.NET/Forms/frmMain.Designer.cs +++ b/GUI.NET/Forms/frmMain.Designer.cs @@ -156,9 +156,7 @@ namespace Mesen.GUI.Forms this.mnuProfile = new System.Windows.Forms.ToolStripMenuItem(); this.mnuMovies = new System.Windows.Forms.ToolStripMenuItem(); this.mnuPlayMovie = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuRecordFrom = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuRecordFromStart = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuRecordFromNow = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuRecordMovie = new System.Windows.Forms.ToolStripMenuItem(); this.mnuStopMovie = new System.Windows.Forms.ToolStripMenuItem(); this.mnuCheats = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem22 = new System.Windows.Forms.ToolStripSeparator(); @@ -1215,7 +1213,7 @@ namespace Mesen.GUI.Forms // this.mnuMovies.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.mnuPlayMovie, - this.mnuRecordFrom, + this.mnuRecordMovie, this.mnuStopMovie}); this.mnuMovies.Image = global::Mesen.GUI.Properties.Resources.Movie; this.mnuMovies.Name = "mnuMovies"; @@ -1226,39 +1224,23 @@ namespace Mesen.GUI.Forms // this.mnuPlayMovie.Image = global::Mesen.GUI.Properties.Resources.Play; this.mnuPlayMovie.Name = "mnuPlayMovie"; - this.mnuPlayMovie.Size = new System.Drawing.Size(149, 22); + this.mnuPlayMovie.Size = new System.Drawing.Size(152, 22); this.mnuPlayMovie.Text = "Play..."; this.mnuPlayMovie.Click += new System.EventHandler(this.mnuPlayMovie_Click); // - // mnuRecordFrom + // mnuRecordMovie // - this.mnuRecordFrom.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuRecordFromStart, - this.mnuRecordFromNow}); - this.mnuRecordFrom.Image = global::Mesen.GUI.Properties.Resources.Record; - this.mnuRecordFrom.Name = "mnuRecordFrom"; - this.mnuRecordFrom.Size = new System.Drawing.Size(149, 22); - this.mnuRecordFrom.Text = "Record from..."; - // - // mnuRecordFromStart - // - this.mnuRecordFromStart.Name = "mnuRecordFromStart"; - this.mnuRecordFromStart.Size = new System.Drawing.Size(99, 22); - this.mnuRecordFromStart.Text = "Start"; - this.mnuRecordFromStart.Click += new System.EventHandler(this.mnuRecordFromStart_Click); - // - // mnuRecordFromNow - // - this.mnuRecordFromNow.Name = "mnuRecordFromNow"; - this.mnuRecordFromNow.Size = new System.Drawing.Size(99, 22); - this.mnuRecordFromNow.Text = "Now"; - this.mnuRecordFromNow.Click += new System.EventHandler(this.mnuRecordFromNow_Click); + this.mnuRecordMovie.Image = global::Mesen.GUI.Properties.Resources.Record; + this.mnuRecordMovie.Name = "mnuRecordMovie"; + this.mnuRecordMovie.Size = new System.Drawing.Size(152, 22); + this.mnuRecordMovie.Text = "Record..."; + this.mnuRecordMovie.Click += new System.EventHandler(this.mnuRecordMovie_Click); // // mnuStopMovie // this.mnuStopMovie.Image = global::Mesen.GUI.Properties.Resources.Stop; this.mnuStopMovie.Name = "mnuStopMovie"; - this.mnuStopMovie.Size = new System.Drawing.Size(149, 22); + this.mnuStopMovie.Size = new System.Drawing.Size(152, 22); this.mnuStopMovie.Text = "Stop"; this.mnuStopMovie.Click += new System.EventHandler(this.mnuStopMovie_Click); // @@ -1654,9 +1636,7 @@ namespace Mesen.GUI.Forms private System.Windows.Forms.ToolStripMenuItem mnuPlayMovie; private System.Windows.Forms.ToolStripMenuItem mnuDebugger; private System.Windows.Forms.ToolStripMenuItem mnuTakeScreenshot; - private System.Windows.Forms.ToolStripMenuItem mnuRecordFrom; - private System.Windows.Forms.ToolStripMenuItem mnuRecordFromStart; - private System.Windows.Forms.ToolStripMenuItem mnuRecordFromNow; + private System.Windows.Forms.ToolStripMenuItem mnuRecordMovie; private System.Windows.Forms.ToolStripMenuItem mnuStopMovie; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; private System.Windows.Forms.ToolStripMenuItem mnuExit; diff --git a/GUI.NET/Forms/frmMain.Tools.cs b/GUI.NET/Forms/frmMain.Tools.cs index 0c329cee..97795987 100644 --- a/GUI.NET/Forms/frmMain.Tools.cs +++ b/GUI.NET/Forms/frmMain.Tools.cs @@ -27,18 +27,6 @@ namespace Mesen.GUI.Forms } } - private void RecordMovie(bool resetEmu) - { - using(SaveFileDialog sfd = new SaveFileDialog()) { - sfd.SetFilter(ResourceHelper.GetMessage("FilterMovie")); - sfd.InitialDirectory = ConfigManager.MovieFolder; - sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mmo"; - if(sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { - InteropEmu.MovieRecord(sfd.FileName, resetEmu); - } - } - } - private void mnuPlayMovie_Click(object sender, EventArgs e) { using(OpenFileDialog ofd = new OpenFileDialog()) { @@ -54,15 +42,12 @@ namespace Mesen.GUI.Forms { InteropEmu.MovieStop(); } - - private void mnuRecordFromStart_Click(object sender, EventArgs e) + + private void mnuRecordMovie_Click(object sender, EventArgs e) { - RecordMovie(true); - } - - private void mnuRecordFromNow_Click(object sender, EventArgs e) - { - RecordMovie(false); + using(frmRecordMovie frm = new frmRecordMovie()) { + frm.ShowDialog(mnuMovies, this); + } } private void mnuWaveRecord_Click(object sender, EventArgs e) diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index d743ea22..e54e9697 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -880,10 +880,8 @@ namespace Mesen.GUI.Forms bool movieRecording = InteropEmu.MovieRecording(); mnuPlayMovie.Enabled = !netPlay && !moviePlaying && !movieRecording; mnuStopMovie.Enabled = running && !netPlay && (moviePlaying || movieRecording); - mnuRecordFrom.Enabled = running && !moviePlaying && !movieRecording; - mnuRecordFromStart.Enabled = running && !isNetPlayClient && !moviePlaying && !movieRecording; - mnuRecordFromNow.Enabled = running && !moviePlaying && !movieRecording; - + mnuRecordMovie.Enabled = running && !moviePlaying && !movieRecording && !isNetPlayClient; + bool waveRecording = InteropEmu.WaveIsRecording(); mnuWaveRecord.Enabled = running && !waveRecording; mnuWaveStop.Enabled = running && waveRecording; @@ -914,7 +912,7 @@ namespace Mesen.GUI.Forms mnuNetPlay.Enabled = !InteropEmu.IsNsf(); if(running && InteropEmu.IsNsf()) { mnuPowerCycle.Enabled = false; - mnuMovies.Enabled = mnuPlayMovie.Enabled = mnuStopMovie.Enabled = mnuRecordFrom.Enabled = mnuRecordFromStart.Enabled = mnuRecordFromNow.Enabled = false; + mnuMovies.Enabled = mnuPlayMovie.Enabled = mnuStopMovie.Enabled = mnuRecordMovie.Enabled = false; } mnuRegionAuto.Checked = ConfigManager.Config.Region == NesModel.Auto; diff --git a/GUI.NET/Forms/frmRecordMovie.Designer.cs b/GUI.NET/Forms/frmRecordMovie.Designer.cs new file mode 100644 index 00000000..ae567858 --- /dev/null +++ b/GUI.NET/Forms/frmRecordMovie.Designer.cs @@ -0,0 +1,219 @@ +namespace Mesen.GUI.Forms +{ + partial class frmRecordMovie + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if(disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.lblSaveTo = new System.Windows.Forms.Label(); + this.txtFilename = new System.Windows.Forms.TextBox(); + this.btnBrowse = new System.Windows.Forms.Button(); + this.txtAuthor = new System.Windows.Forms.TextBox(); + this.lblRecordFrom = new System.Windows.Forms.Label(); + this.lblAuthor = new System.Windows.Forms.Label(); + this.lblDescription = new System.Windows.Forms.Label(); + this.cboRecordFrom = new System.Windows.Forms.ComboBox(); + this.txtDescription = new System.Windows.Forms.TextBox(); + this.lblMovieInformation = new System.Windows.Forms.Label(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // baseConfigPanel + // + this.baseConfigPanel.Location = new System.Drawing.Point(0, 202); + this.baseConfigPanel.Size = new System.Drawing.Size(397, 29); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 3; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.Controls.Add(this.lblSaveTo, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.txtFilename, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.btnBrowse, 2, 0); + this.tableLayoutPanel1.Controls.Add(this.txtAuthor, 1, 3); + this.tableLayoutPanel1.Controls.Add(this.lblRecordFrom, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.lblAuthor, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.lblDescription, 0, 4); + this.tableLayoutPanel1.Controls.Add(this.cboRecordFrom, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.txtDescription, 1, 4); + this.tableLayoutPanel1.Controls.Add(this.lblMovieInformation, 0, 2); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 6; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(397, 231); + this.tableLayoutPanel1.TabIndex = 0; + // + // lblSaveTo + // + this.lblSaveTo.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblSaveTo.AutoSize = true; + this.lblSaveTo.Location = new System.Drawing.Point(3, 8); + this.lblSaveTo.Name = "lblSaveTo"; + this.lblSaveTo.Size = new System.Drawing.Size(47, 13); + this.lblSaveTo.TabIndex = 0; + this.lblSaveTo.Text = "Save to:"; + // + // txtFilename + // + this.txtFilename.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtFilename.Location = new System.Drawing.Point(82, 3); + this.txtFilename.MaxLength = 1999; + this.txtFilename.Name = "txtFilename"; + this.txtFilename.ReadOnly = true; + this.txtFilename.Size = new System.Drawing.Size(231, 20); + this.txtFilename.TabIndex = 1; + // + // btnBrowse + // + this.btnBrowse.Location = new System.Drawing.Point(319, 3); + this.btnBrowse.Name = "btnBrowse"; + this.btnBrowse.Size = new System.Drawing.Size(75, 23); + this.btnBrowse.TabIndex = 2; + this.btnBrowse.Text = "Browse..."; + this.btnBrowse.UseVisualStyleBackColor = true; + this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click); + // + // txtAuthor + // + this.tableLayoutPanel1.SetColumnSpan(this.txtAuthor, 2); + this.txtAuthor.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtAuthor.Location = new System.Drawing.Point(82, 84); + this.txtAuthor.MaxLength = 249; + this.txtAuthor.Name = "txtAuthor"; + this.txtAuthor.Size = new System.Drawing.Size(312, 20); + this.txtAuthor.TabIndex = 12; + // + // lblRecordFrom + // + this.lblRecordFrom.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblRecordFrom.AutoSize = true; + this.lblRecordFrom.Location = new System.Drawing.Point(3, 36); + this.lblRecordFrom.Name = "lblRecordFrom"; + this.lblRecordFrom.Size = new System.Drawing.Size(68, 13); + this.lblRecordFrom.TabIndex = 6; + this.lblRecordFrom.Text = "Record from:"; + // + // lblAuthor + // + this.lblAuthor.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblAuthor.AutoSize = true; + this.lblAuthor.Location = new System.Drawing.Point(13, 87); + this.lblAuthor.Margin = new System.Windows.Forms.Padding(13, 0, 3, 0); + this.lblAuthor.Name = "lblAuthor"; + this.lblAuthor.Size = new System.Drawing.Size(41, 13); + this.lblAuthor.TabIndex = 5; + this.lblAuthor.Text = "Author:"; + // + // lblDescription + // + this.lblDescription.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblDescription.AutoSize = true; + this.lblDescription.Location = new System.Drawing.Point(13, 146); + this.lblDescription.Margin = new System.Windows.Forms.Padding(13, 0, 3, 0); + this.lblDescription.Name = "lblDescription"; + this.lblDescription.Size = new System.Drawing.Size(63, 13); + this.lblDescription.TabIndex = 11; + this.lblDescription.Text = "Description:"; + // + // cboRecordFrom + // + this.cboRecordFrom.Dock = System.Windows.Forms.DockStyle.Fill; + this.cboRecordFrom.FormattingEnabled = true; + this.cboRecordFrom.Location = new System.Drawing.Point(82, 32); + this.cboRecordFrom.Name = "cboRecordFrom"; + this.cboRecordFrom.Size = new System.Drawing.Size(231, 21); + this.cboRecordFrom.TabIndex = 13; + // + // txtDescription + // + this.txtDescription.AcceptsReturn = true; + this.tableLayoutPanel1.SetColumnSpan(this.txtDescription, 2); + this.txtDescription.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtDescription.Location = new System.Drawing.Point(82, 110); + this.txtDescription.MaxLength = 9999; + this.txtDescription.Multiline = true; + this.txtDescription.Name = "txtDescription"; + this.txtDescription.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.txtDescription.Size = new System.Drawing.Size(312, 86); + this.txtDescription.TabIndex = 10; + // + // lblMovieInformation + // + this.lblMovieInformation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.lblMovieInformation.AutoSize = true; + this.tableLayoutPanel1.SetColumnSpan(this.lblMovieInformation, 2); + this.lblMovieInformation.ForeColor = System.Drawing.SystemColors.GrayText; + this.lblMovieInformation.Location = new System.Drawing.Point(3, 65); + this.lblMovieInformation.Name = "lblMovieInformation"; + this.lblMovieInformation.Padding = new System.Windows.Forms.Padding(0, 0, 0, 3); + this.lblMovieInformation.Size = new System.Drawing.Size(139, 16); + this.lblMovieInformation.TabIndex = 24; + this.lblMovieInformation.Text = "Movie Information (Optional)"; + // + // frmRecordMovie + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(397, 231); + this.Controls.Add(this.tableLayoutPanel1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "frmRecordMovie"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Movie Recording Options"; + this.Controls.SetChildIndex(this.tableLayoutPanel1, 0); + this.Controls.SetChildIndex(this.baseConfigPanel, 0); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Label lblSaveTo; + private System.Windows.Forms.TextBox txtFilename; + private System.Windows.Forms.Button btnBrowse; + private System.Windows.Forms.Label lblAuthor; + private System.Windows.Forms.Label lblRecordFrom; + private System.Windows.Forms.TextBox txtDescription; + private System.Windows.Forms.Label lblDescription; + private System.Windows.Forms.TextBox txtAuthor; + private System.Windows.Forms.ComboBox cboRecordFrom; + private System.Windows.Forms.Label lblMovieInformation; + } +} \ No newline at end of file diff --git a/GUI.NET/Forms/frmRecordMovie.cs b/GUI.NET/Forms/frmRecordMovie.cs new file mode 100644 index 00000000..0c34c51e --- /dev/null +++ b/GUI.NET/Forms/frmRecordMovie.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Mesen.GUI.Config; + +namespace Mesen.GUI.Forms +{ + public partial class frmRecordMovie : BaseConfigForm + { + public frmRecordMovie() + { + InitializeComponent(); + + Entity = ConfigManager.Config.MovieRecordInfo; + AddBinding("Author", txtAuthor); + AddBinding("Description", txtDescription); + AddBinding("RecordFrom", cboRecordFrom); + } + + protected override bool ValidateInput() + { + return !string.IsNullOrWhiteSpace(txtFilename.Text); + } + + protected override void OnFormClosed(FormClosedEventArgs e) + { + base.OnFormClosed(e); + if(this.DialogResult == DialogResult.OK) { + InteropEmu.MovieRecord(new RecordMovieOptions( + this.txtFilename.Text, + this.txtAuthor.Text, + this.txtDescription.Text, + this.cboRecordFrom.GetEnumValue() + )); + } + } + + private void btnBrowse_Click(object sender, EventArgs e) + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.SetFilter(ResourceHelper.GetMessage("FilterMovie")); + sfd.InitialDirectory = ConfigManager.MovieFolder; + sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".mmo"; + if(sfd.ShowDialog() == DialogResult.OK) { + txtFilename.Text = sfd.FileName; + } + } + } +} diff --git a/GUI.NET/Forms/frmRecordMovie.resx b/GUI.NET/Forms/frmRecordMovie.resx new file mode 100644 index 00000000..8766f298 --- /dev/null +++ b/GUI.NET/Forms/frmRecordMovie.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/GUI.NET/GUI.NET.csproj b/GUI.NET/GUI.NET.csproj index eaa5ce2e..8dd6df30 100644 --- a/GUI.NET/GUI.NET.csproj +++ b/GUI.NET/GUI.NET.csproj @@ -211,6 +211,7 @@ + @@ -898,6 +899,12 @@ frmMain.cs Form + + Form + + + frmRecordMovie.cs + Form @@ -1277,6 +1284,9 @@ frmMain.cs + + frmRecordMovie.cs + frmRecordAvi.cs diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 1928ad2c..d93b97fc 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -98,7 +98,7 @@ namespace Mesen.GUI [DllImport(DLLPath, EntryPoint = "GetLog")] private static extern IntPtr GetLogWrapper(); [DllImport(DLLPath)] public static extern void MoviePlay([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename); - [DllImport(DLLPath)] public static extern void MovieRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string filename, [MarshalAs(UnmanagedType.I1)]bool reset); + [DllImport(DLLPath)] public static extern void MovieRecord(RecordMovieOptions options); [DllImport(DLLPath)] public static extern void MovieStop(); [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MoviePlaying(); [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool MovieRecording(); @@ -1720,6 +1720,48 @@ namespace Mesen.GUI } } + public enum RecordMovieFrom + { + StartWithoutSaveData, + StartWithSaveData, + CurrentState + } + + public struct RecordMovieOptions + { + private const int AuthorMaxSize = 250; + private const int DescriptionMaxSize = 10000; + private const int FilenameMaxSize = 2000; + + public RecordMovieOptions(string filename, string author, string description, RecordMovieFrom recordFrom) + { + Author = Encoding.UTF8.GetBytes(author); + Array.Resize(ref Author, AuthorMaxSize); + Author[AuthorMaxSize-1] = 0; + + Description = Encoding.UTF8.GetBytes(description.Replace("\r", "")); + Array.Resize(ref Description, DescriptionMaxSize); + Description[DescriptionMaxSize-1] = 0; + + Filename = Encoding.UTF8.GetBytes(filename); + Array.Resize(ref Filename, FilenameMaxSize); + Filename[FilenameMaxSize-1] = 0; + + RecordFrom = recordFrom; + } + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = FilenameMaxSize)] + public byte[] Filename; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = AuthorMaxSize)] + public byte[] Author; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = DescriptionMaxSize)] + public byte[] Description; + + public RecordMovieFrom RecordFrom; + } + [Flags] public enum BreakpointType { diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp index f2db7f01..ffc09893 100644 --- a/InteropDLL/ConsoleWrapper.cpp +++ b/InteropDLL/ConsoleWrapper.cpp @@ -356,7 +356,7 @@ namespace InteropEmu { DllExport int64_t __stdcall GetStateInfo(uint32_t stateIndex) { return SaveStateManager::GetStateInfo(stateIndex); } DllExport void __stdcall MoviePlay(char* filename) { MovieManager::Play(string(filename)); } - DllExport void __stdcall MovieRecord(char* filename, bool reset) { MovieManager::Record(filename, reset); } + DllExport void __stdcall MovieRecord(RecordMovieOptions options) { MovieManager::Record(options); } DllExport void __stdcall MovieStop() { MovieManager::Stop(); } DllExport bool __stdcall MoviePlaying() { return MovieManager::Playing(); } DllExport bool __stdcall MovieRecording() { return MovieManager::Recording(); }