From 7d135a5d6241f7274236e5a62f445b5e34bb6fd3 Mon Sep 17 00:00:00 2001 From: "andres.delikat" Date: Wed, 11 May 2011 01:47:28 +0000 Subject: [PATCH] Lot's of fix ups to the Play Movie dialog and the Movie class. Cleaned up behavior of main form to allow for a user movie and an input log when the user movie is not active. Currently selecting a movie for playback crashes though. --- BizHawk.MultiClient/MainForm.MenuItems.cs | 4 +- BizHawk.MultiClient/MainForm.cs | 38 +++++++----- BizHawk.MultiClient/PlayMovie.Designer.cs | 68 ++++++++++++++------- BizHawk.MultiClient/PlayMovie.cs | 57 ++++++++++++++++- BizHawk.MultiClient/RenderPanel.cs | 2 +- BizHawk.MultiClient/movie/Movie.cs | 74 ++++++++++++++++++++++- 6 files changed, 199 insertions(+), 44 deletions(-) diff --git a/BizHawk.MultiClient/MainForm.MenuItems.cs b/BizHawk.MultiClient/MainForm.MenuItems.cs index df26627316..43a01f3d68 100644 --- a/BizHawk.MultiClient/MainForm.MenuItems.cs +++ b/BizHawk.MultiClient/MainForm.MenuItems.cs @@ -127,7 +127,9 @@ namespace BizHawk.MultiClient private void playMovieToolStripMenuItem_Click(object sender, EventArgs e) { PlayMovie p = new PlayMovie(); - p.ShowDialog(); + DialogResult d = p.ShowDialog(); + if (d == DialogResult.OK) + LoadRom(CurrentlyOpenRom); } private void stopMovieToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index c5c9072f71..9720abacec 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -19,10 +19,11 @@ namespace BizHawk.MultiClient { private Control renderTarget; private RetainedViewportPanel retainedPanel; - private string CurrentlyOpenRom; + public string CurrentlyOpenRom; //TODO: adelikat: can this be the official file extension? public Movie InputLog = new Movie("log.tas", MOVIEMODE.RECORD); //This movie is always recording while user is playing + public Movie UserMovie = new Movie("", MOVIEMODE.INACTIVE); //the currently selected savestate slot private int SaveSlot = 0; @@ -65,7 +66,6 @@ namespace BizHawk.MultiClient using (HawkFile NesCartFile = new HawkFile("NesCarts.7z").BindFirst()) return Util.ReadAllBytes(NesCartFile.GetStream()); }; - //InputLog.StartPlayback(); //Debug switch this on to play back log.tas Global.MainForm = this; Database.LoadDatabase("gamedb.txt"); @@ -83,6 +83,7 @@ namespace BizHawk.MultiClient { CloseGame(); InputLog.StopMovie(); + UserMovie.StopMovie(); SaveConfig(); }; @@ -99,7 +100,6 @@ namespace BizHawk.MultiClient InitControls(); Global.Emulator = new NullEmulator(); - //InputLog.StopMovie(); Global.ActiveController = Global.NullControls; Global.Sound = new Sound(Handle, Global.DSound); Global.Sound.StartSound(); @@ -541,7 +541,7 @@ namespace BizHawk.MultiClient Global.ActiveController.MovieMode = false; } - private bool LoadRom(string path) + public bool LoadRom(string path) { using (var file = new HawkFile(path)) { @@ -636,16 +636,15 @@ namespace BizHawk.MultiClient { new BizHawk.Emulation.Consoles.Gameboy.Debugger(Global.Emulator as Gameboy).Show(); } - - if (InputLog.GetMovieMode() == MOVIEMODE.RECORD) - InputLog.StartNewRecording(); //TODO: Uncomment and check for a user movie selected? - - else if (InputLog.GetMovieMode() == MOVIEMODE.PLAY) - { - InputLog.LoadMovie(); //TODO: Debug - InputLog.StartPlayback(); //TODO: Debug - } + //Remove this block once movie selection is more polished, input log should only be playback through the same mechanism as any other movie file + if (InputLog.GetMovieMode() == MOVIEMODE.PLAY) + { + InputLog.LoadMovie(); //TODO: Debug + InputLog.StartPlayback(); //TODO: Debug + } + else + InputLog.StartNewRecording(); //(Keep this line) //setup the throttle based on platform's specifications //(one day later for some systems we will need to modify it at runtime as the display mode changes) @@ -697,8 +696,9 @@ namespace BizHawk.MultiClient writer.Close(); } Global.Emulator = new NullEmulator(); - //InputLog.StopMovie(); Global.ActiveController = Global.NullControls; + UserMovie.StopMovie(); + InputLog.StopMovie(); } [System.Security.SuppressUnmanagedCodeSecurity, DllImport("User32.dll", CharSet = CharSet.Auto)] @@ -976,7 +976,11 @@ namespace BizHawk.MultiClient if (!runloop_frameadvance) genSound = true; else if (!Global.Config.MuteFrameAdvance) genSound = true; - if (InputLog.GetMovieMode() == MOVIEMODE.PLAY) + + //TODO: clean up this movie code, use a function or an object to manage the togglign of two movies + if (UserMovie.GetMovieMode() == MOVIEMODE.PLAY) + Global.ActiveController.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame) + 1); + else if (InputLog.GetMovieMode() == MOVIEMODE.PLAY) Global.ActiveController.SetControllersAsMnemonic(InputLog.GetInputFrame(Global.Emulator.Frame) + 1); Global.Emulator.FrameAdvance(!throttle.skipnextframe); RamWatch1.UpdateValues(); @@ -984,7 +988,9 @@ namespace BizHawk.MultiClient HexEditor1.UpdateValues(); NESNameTableViewer1.UpdateValues(); NESPPU1.UpdateValues(); - if (InputLog.GetMovieMode() == MOVIEMODE.RECORD) + if (UserMovie.GetMovieMode() == MOVIEMODE.RECORD) + UserMovie.GetMnemonic(); + else if (InputLog.GetMovieMode() == MOVIEMODE.RECORD) InputLog.GetMnemonic(); } diff --git a/BizHawk.MultiClient/PlayMovie.Designer.cs b/BizHawk.MultiClient/PlayMovie.Designer.cs index 9e79194924..8b16a98960 100644 --- a/BizHawk.MultiClient/PlayMovie.Designer.cs +++ b/BizHawk.MultiClient/PlayMovie.Designer.cs @@ -32,7 +32,7 @@ this.Cancel = new System.Windows.Forms.Button(); this.OK = new System.Windows.Forms.Button(); this.BrowseMovies = new System.Windows.Forms.Button(); - this.MovieView = new System.Windows.Forms.ListView(); + this.MovieView = new BizHawk.VirtualListView(); this.columnHeader1 = new System.Windows.Forms.ColumnHeader(); this.columnHeader2 = new System.Windows.Forms.ColumnHeader(); this.columnHeader3 = new System.Windows.Forms.ColumnHeader(); @@ -41,8 +41,9 @@ this.columnHeader5 = new System.Windows.Forms.ColumnHeader(); this.columnHeader6 = new System.Windows.Forms.ColumnHeader(); this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); + this.button1 = new System.Windows.Forms.Button(); + this.MovieCount = new System.Windows.Forms.Label(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // @@ -50,7 +51,7 @@ // this.Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.Cancel.Location = new System.Drawing.Point(595, 353); + this.Cancel.Location = new System.Drawing.Point(628, 361); this.Cancel.Name = "Cancel"; this.Cancel.Size = new System.Drawing.Size(75, 23); this.Cancel.TabIndex = 0; @@ -61,7 +62,7 @@ // OK // this.OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.OK.Location = new System.Drawing.Point(504, 353); + this.OK.Location = new System.Drawing.Point(537, 361); this.OK.Name = "OK"; this.OK.Size = new System.Drawing.Size(75, 23); this.OK.TabIndex = 1; @@ -71,7 +72,7 @@ // // BrowseMovies // - this.BrowseMovies.Location = new System.Drawing.Point(12, 353); + this.BrowseMovies.Location = new System.Drawing.Point(12, 366); this.BrowseMovies.Name = "BrowseMovies"; this.BrowseMovies.Size = new System.Drawing.Size(75, 23); this.BrowseMovies.TabIndex = 2; @@ -81,15 +82,23 @@ // // MovieView // + this.MovieView.AllowDrop = true; + this.MovieView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.MovieView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.columnHeader1, this.columnHeader2, this.columnHeader3, this.columnHeader4}); this.MovieView.GridLines = true; + this.MovieView.HideSelection = false; + this.MovieView.ItemCount = 0; this.MovieView.Location = new System.Drawing.Point(12, 28); + this.MovieView.MultiSelect = false; this.MovieView.Name = "MovieView"; - this.MovieView.Size = new System.Drawing.Size(346, 303); + this.MovieView.selectedItem = -1; + this.MovieView.Size = new System.Drawing.Size(413, 303); this.MovieView.TabIndex = 3; this.MovieView.UseCompatibleStateImageBehavior = false; this.MovieView.View = System.Windows.Forms.View.Details; @@ -97,22 +106,22 @@ // columnHeader1 // this.columnHeader1.Text = "File"; - this.columnHeader1.Width = 129; + this.columnHeader1.Width = 120; // // columnHeader2 // - this.columnHeader2.Text = "System"; - this.columnHeader2.Width = 46; + this.columnHeader2.Text = "SysID"; + this.columnHeader2.Width = 42; // // columnHeader3 // this.columnHeader3.Text = "Game"; - this.columnHeader3.Width = 75; + this.columnHeader3.Width = 149; // // columnHeader4 // this.columnHeader4.Text = "Author"; - this.columnHeader4.Width = 92; + this.columnHeader4.Width = 97; // // DetailsView // @@ -142,22 +151,13 @@ this.groupBox1.Controls.Add(this.button2); this.groupBox1.Controls.Add(this.button1); this.groupBox1.Controls.Add(this.DetailsView); - this.groupBox1.Location = new System.Drawing.Point(379, 28); + this.groupBox1.Location = new System.Drawing.Point(444, 28); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(259, 303); this.groupBox1.TabIndex = 6; this.groupBox1.TabStop = false; this.groupBox1.Text = "Details"; // - // button1 - // - this.button1.Location = new System.Drawing.Point(15, 251); - this.button1.Name = "button1"; - this.button1.Size = new System.Drawing.Size(75, 23); - this.button1.TabIndex = 5; - this.button1.Text = "Comments"; - this.button1.UseVisualStyleBackColor = true; - // // button2 // this.button2.Location = new System.Drawing.Point(125, 251); @@ -167,13 +167,32 @@ this.button2.Text = "Subtitles"; this.button2.UseVisualStyleBackColor = true; // + // button1 + // + this.button1.Location = new System.Drawing.Point(15, 251); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 5; + this.button1.Text = "Comments"; + this.button1.UseVisualStyleBackColor = true; + // + // MovieCount + // + this.MovieCount.AutoSize = true; + this.MovieCount.Location = new System.Drawing.Point(13, 338); + this.MovieCount.Name = "MovieCount"; + this.MovieCount.Size = new System.Drawing.Size(31, 13); + this.MovieCount.TabIndex = 7; + this.MovieCount.Text = " "; + // // PlayMovie // this.AcceptButton = this.OK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.Cancel; - this.ClientSize = new System.Drawing.Size(682, 393); + this.ClientSize = new System.Drawing.Size(715, 401); + this.Controls.Add(this.MovieCount); this.Controls.Add(this.groupBox1); this.Controls.Add(this.MovieView); this.Controls.Add(this.BrowseMovies); @@ -184,8 +203,10 @@ this.MinimizeBox = false; this.Name = "PlayMovie"; this.Text = "Play Movie"; + this.Load += new System.EventHandler(this.PlayMovie_Load); this.groupBox1.ResumeLayout(false); this.ResumeLayout(false); + this.PerformLayout(); } @@ -194,7 +215,7 @@ private System.Windows.Forms.Button Cancel; private System.Windows.Forms.Button OK; private System.Windows.Forms.Button BrowseMovies; - private System.Windows.Forms.ListView MovieView; + private VirtualListView MovieView; private System.Windows.Forms.ColumnHeader columnHeader1; private System.Windows.Forms.ColumnHeader columnHeader2; private System.Windows.Forms.ColumnHeader columnHeader3; @@ -205,5 +226,6 @@ private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label MovieCount; } } \ No newline at end of file diff --git a/BizHawk.MultiClient/PlayMovie.cs b/BizHawk.MultiClient/PlayMovie.cs index dbdbd921eb..a0f76074a8 100644 --- a/BizHawk.MultiClient/PlayMovie.cs +++ b/BizHawk.MultiClient/PlayMovie.cs @@ -15,12 +15,35 @@ namespace BizHawk.MultiClient //TODO: Think about this: .\Movies is the default folder, when shoudl this be created? On load (no platform specific folders do this) //Upon open file dialog? that's weird, record movie? more often people will use play movie first //Never? then the path default must be .\ not .\movies + //TODO: after browse & update, focus on the movie just added + //Make MovieView not allow multiselect + //This is a modal dialog, implement it as modeless + // In order to do this, this dialog will have to restart the rom List MovieList = new List(); public PlayMovie() { InitializeComponent(); + MovieView.QueryItemText += new QueryItemTextHandler(MovieView_QueryItemText); + MovieView.QueryItemBkColor += new QueryItemBkColorHandler(MovieView_QueryItemBkColor); + MovieView.VirtualMode = true; + } + + void MovieView_QueryItemText(int index, int column, out string text) + { + text = ""; + if (column == 0) //File + text = Path.GetFileName(MovieList[index].GetFilePath()); + if (column == 1) //System + text = MovieList[index].GetSysID(); + if (column == 2) //Game + text = MovieList[index].GetGameName(); + } + + private void MovieView_QueryItemBkColor(int index, int column, ref Color color) + { + } private void Cancel_Click(object sender, EventArgs e) @@ -30,6 +53,10 @@ namespace BizHawk.MultiClient private void OK_Click(object sender, EventArgs e) { + Global.MainForm.UserMovie = MovieList[MovieView.SelectedIndices[0]]; + Global.MainForm.LoadRom(Global.MainForm.CurrentlyOpenRom); + Global.MainForm.UserMovie.LoadMovie(); + Global.MainForm.UserMovie.StartPlayback(); this.Close(); } @@ -48,15 +75,41 @@ namespace BizHawk.MultiClient if (!file.Exists) return; else + { PreLoadMovieFile(file); - - + MovieView.ItemCount = MovieList.Count; + UpdateList(); + MovieView.SelectedIndices.Clear(); + MovieView.setSelection(MovieList.Count-1); + } } } private void PreLoadMovieFile(FileInfo path) { + Movie m = new Movie(path.FullName, MOVIEMODE.INACTIVE); + m.PreLoadText(); + MovieList.Add(m); + } + private void UpdateList() + { + MovieView.Refresh(); + UpdateMovieCount(); + } + + private void UpdateMovieCount() + { + int x = MovieList.Count; + if (x == 1) + MovieCount.Text = x.ToString() + " movie"; + else + MovieCount.Text = x.ToString() + " movies"; + } + + private void PlayMovie_Load(object sender, EventArgs e) + { + } } } diff --git a/BizHawk.MultiClient/RenderPanel.cs b/BizHawk.MultiClient/RenderPanel.cs index c1385e4542..30911db188 100644 --- a/BizHawk.MultiClient/RenderPanel.cs +++ b/BizHawk.MultiClient/RenderPanel.cs @@ -303,7 +303,7 @@ namespace BizHawk.MultiClient private string MakeFrameCounter() { - if (Global.MainForm.InputLog.GetMovieMode() == MOVIEMODE.PLAY) //TODO: use user movie not input log (input log will never be allowed to be played back) + if (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY) { return Global.Emulator.Frame.ToString() + " " + Global.MainForm.InputLog.lastLog.ToString() + "/" + Global.MainForm.InputLog.GetMovieLength().ToString(); diff --git a/BizHawk.MultiClient/movie/Movie.cs b/BizHawk.MultiClient/movie/Movie.cs index 8d3431bb27..466c4016e9 100644 --- a/BizHawk.MultiClient/movie/Movie.cs +++ b/BizHawk.MultiClient/movie/Movie.cs @@ -21,7 +21,6 @@ namespace BizHawk.MultiClient //TODO: //Author field, needs to be passed in by a record or play dialog - //A PreLoad() function that will read just header info of the file public Movie(string filename, MOVIEMODE m) { @@ -30,6 +29,21 @@ namespace BizHawk.MultiClient lastLog = 0; } + public string GetFilePath() + { + return Filename; + } + + public string GetSysID() + { + return Header.GetHeaderLine(MovieHeader.PLATFORM); + } + + public string GetGameName() + { + return Header.GetHeaderLine(MovieHeader.GAMENAME); + } + public void StopMovie() { MovieMode = MOVIEMODE.INACTIVE; @@ -85,6 +99,7 @@ namespace BizHawk.MultiClient private void WriteText() { + if (Filename.Length == 0) return; //Nothing to write int length = Log.GetMovieLength(); using (StreamWriter sw = new StreamWriter(Filename)) @@ -173,6 +188,63 @@ namespace BizHawk.MultiClient } + public bool PreLoadText() + { + var file = new FileInfo(Filename); + + if (file.Exists == false) + return false; + else + { + Header.Clear(); + Log.Clear(); + } + + using (StreamReader sr = file.OpenText()) + { + string str = ""; + + while ((str = sr.ReadLine()) != null) + { + if (str == "") + { + continue; + } + else if (str.Contains(MovieHeader.EMULATIONVERSION)) + { + str = ParseHeader(str, MovieHeader.EMULATIONVERSION); + Header.AddHeaderLine(MovieHeader.EMULATIONVERSION, str); + } + else if (str.Contains(MovieHeader.MOVIEVERSION)) + { + str = ParseHeader(str, MovieHeader.MOVIEVERSION); + Header.AddHeaderLine(MovieHeader.MOVIEVERSION, str); + } + else if (str.Contains(MovieHeader.PLATFORM)) + { + str = ParseHeader(str, MovieHeader.PLATFORM); + Header.AddHeaderLine(MovieHeader.PLATFORM, str); + } + else if (str.Contains(MovieHeader.GAMENAME)) + { + str = ParseHeader(str, MovieHeader.GAMENAME); + Header.AddHeaderLine(MovieHeader.GAMENAME, str); + } + else if (str[0] == '|') + { + break; + } + else + { + Header.Comments.Add(str); + } + + } + } + + return true; + } + private bool LoadBinary() { return true;