From bd9ec3c57d9a6db952f69f8f5528a7c1f424c3a4 Mon Sep 17 00:00:00 2001
From: YoshiRulz <OSSYoshiRulz@gmail.com>
Date: Thu, 8 Apr 2021 16:10:18 +1000
Subject: [PATCH] Convert static class QuickBmpFile to (empty) struct with
 interface

---
 src/BizHawk.Client.Common/IQuickBmpFile.cs     | 17 +++++++++++++++++
 src/BizHawk.Client.Common/QuickBmpFile.cs      |  8 +++++++-
 .../movie/MovieSession.cs                      |  6 +++++-
 .../movie/tasproj/TasBranch.cs                 | 14 +++++++++-----
 .../movie/tasproj/TasMovie.cs                  |  5 +++--
 .../savestates/SavestateFile.cs                | 18 +++++++++++++-----
 .../IMainFormForTools.cs                       |  3 +++
 src/BizHawk.Client.EmuHawk/MainForm.cs         |  7 +++++--
 .../tools/TAStudio/BookmarksBranchesBox.cs     |  2 +-
 9 files changed, 63 insertions(+), 17 deletions(-)
 create mode 100644 src/BizHawk.Client.Common/IQuickBmpFile.cs

diff --git a/src/BizHawk.Client.Common/IQuickBmpFile.cs b/src/BizHawk.Client.Common/IQuickBmpFile.cs
new file mode 100644
index 0000000000..c85494d0ca
--- /dev/null
+++ b/src/BizHawk.Client.Common/IQuickBmpFile.cs
@@ -0,0 +1,17 @@
+using System.IO;
+
+using BizHawk.Emulation.Common;
+
+namespace BizHawk.Client.Common
+{
+	public interface IQuickBmpFile
+	{
+		void Copy(IVideoProvider src, IVideoProvider dst);
+
+		bool Load(IVideoProvider v, Stream s);
+
+		bool LoadAuto(Stream s, out IVideoProvider vp);
+
+		void Save(IVideoProvider v, Stream s, int w, int h);
+	}
+}
diff --git a/src/BizHawk.Client.Common/QuickBmpFile.cs b/src/BizHawk.Client.Common/QuickBmpFile.cs
index 602451f3c4..c9d323dd67 100644
--- a/src/BizHawk.Client.Common/QuickBmpFile.cs
+++ b/src/BizHawk.Client.Common/QuickBmpFile.cs
@@ -12,7 +12,7 @@ using BizHawk.Emulation.Common;
 // ReSharper disable StyleCop.SA1401
 namespace BizHawk.Client.Common
 {
-	public static class QuickBmpFile
+	public readonly struct QuickBmpFile : IQuickBmpFile
 	{
 		[StructLayout(LayoutKind.Sequential, Pack = 1)]
 		private class BITMAPFILEHEADER
@@ -334,6 +334,12 @@ namespace BizHawk.Client.Common
 			s.Write(dst, 0, dst.Length);
 		}
 
+		readonly void IQuickBmpFile.Copy(IVideoProvider src, IVideoProvider dst) => Copy(src, dst);
+
+		readonly bool IQuickBmpFile.Load(IVideoProvider v, Stream s) => Load(v, s);
+
 		public readonly bool LoadAuto(Stream s, out IVideoProvider vp) => Load(vp = new LoadedBMP(), s);
+
+		readonly void IQuickBmpFile.Save(IVideoProvider v, Stream s, int w, int h) => Save(v, s, w, h);
 	}
 }
diff --git a/src/BizHawk.Client.Common/movie/MovieSession.cs b/src/BizHawk.Client.Common/movie/MovieSession.cs
index 7829c7ce78..d32ef14380 100644
--- a/src/BizHawk.Client.Common/movie/MovieSession.cs
+++ b/src/BizHawk.Client.Common/movie/MovieSession.cs
@@ -20,10 +20,13 @@ namespace BizHawk.Client.Common
 
 		private IMovie _queuedMovie;
 
+		private readonly IQuickBmpFile _quickBmpFile;
+
 		public MovieSession(
 			IMovieConfig settings,
 			string backDirectory,
 			IDialogParent dialogParent,
+			IQuickBmpFile quickBmpFile,
 			Action<string> messageCallback,
 			Action pauseCallback,
 			Action modeChangedCallback)
@@ -32,6 +35,7 @@ namespace BizHawk.Client.Common
 			BackupDirectory = backDirectory;
 			_messageCallback = messageCallback;
 			_dialogParent = dialogParent;
+			_quickBmpFile = quickBmpFile;
 			_pauseCallback = pauseCallback
 				?? throw new ArgumentNullException($"{nameof(pauseCallback)} cannot be null.");
 			_modeChangedCallback = modeChangedCallback
@@ -311,7 +315,7 @@ namespace BizHawk.Client.Common
 			// TODO: change IMovies to take HawkFiles only and not path
 			if (Path.GetExtension(path)?.EndsWith("tasproj") ?? false)
 			{
-				return new TasMovie(this, path);
+				return new TasMovie(this, path, _quickBmpFile);
 			}
 
 			return new Bk2Movie(this, path);
diff --git a/src/BizHawk.Client.Common/movie/tasproj/TasBranch.cs b/src/BizHawk.Client.Common/movie/tasproj/TasBranch.cs
index 5d3195bfb1..22984e6d68 100644
--- a/src/BizHawk.Client.Common/movie/tasproj/TasBranch.cs
+++ b/src/BizHawk.Client.Common/movie/tasproj/TasBranch.cs
@@ -38,9 +38,13 @@ namespace BizHawk.Client.Common
 	public class TasBranchCollection : List<TasBranch>, ITasBranchCollection
 	{
 		private readonly ITasMovie _movie;
-		public TasBranchCollection(ITasMovie movie)
+
+		private readonly IQuickBmpFile _quickBmpFile;
+
+		public TasBranchCollection(ITasMovie movie, IQuickBmpFile quickBmpFile)
 		{
 			_movie = movie;
+			_quickBmpFile = quickBmpFile;
 		}
 
 		public int Current { get; set; } = -1;
@@ -147,13 +151,13 @@ namespace BizHawk.Client.Common
 				bs.PutLump(nframebuffer, delegate(Stream s)
 				{
 					var vp = new BitmapBufferVideoProvider(b.OSDFrameBuffer);
-					QuickBmpFile.Save(vp, s, b.OSDFrameBuffer.Width, b.OSDFrameBuffer.Height);
+					_quickBmpFile.Save(vp, s, b.OSDFrameBuffer.Width, b.OSDFrameBuffer.Height);
 				});
 
 				bs.PutLump(ncoreframebuffer, delegate(Stream s)
 				{
 					var vp = new BitmapBufferVideoProvider(b.CoreFrameBuffer);
-					QuickBmpFile.Save(vp, s, b.CoreFrameBuffer.Width, b.CoreFrameBuffer.Height);
+					_quickBmpFile.Save(vp, s, b.CoreFrameBuffer.Width, b.CoreFrameBuffer.Height);
 				});
 
 				bs.PutLump(nmarkers, delegate(TextWriter tw)
@@ -240,13 +244,13 @@ namespace BizHawk.Client.Common
 
 				bl.GetLump(nframebuffer, true, delegate(Stream s, long length)
 				{
-					QuickBmpFile.LoadAuto(s, out var vp);
+					_quickBmpFile.LoadAuto(s, out var vp);
 					b.OSDFrameBuffer = new BitmapBuffer(vp.BufferWidth, vp.BufferHeight, vp.GetVideoBuffer());
 				});
 
 				bl.GetLump(ncoreframebuffer, false, delegate(Stream s, long length)
 				{
-					QuickBmpFile.LoadAuto(s, out var vp);
+					_quickBmpFile.LoadAuto(s, out var vp);
 					b.CoreFrameBuffer = new BitmapBuffer(vp.BufferWidth, vp.BufferHeight, vp.GetVideoBuffer());
 				});
 
diff --git a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.cs b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.cs
index 76dec72e5e..d542d940e7 100644
--- a/src/BizHawk.Client.Common/movie/tasproj/TasMovie.cs
+++ b/src/BizHawk.Client.Common/movie/tasproj/TasMovie.cs
@@ -16,9 +16,10 @@ namespace BizHawk.Client.Common
 		public const double CurrentVersion = 1.1;
 
 		/// <exception cref="InvalidOperationException">loaded core does not implement <see cref="IStatable"/></exception>
-		internal TasMovie(IMovieSession session, string path) : base(session, path)
+		internal TasMovie(IMovieSession session, string path, IQuickBmpFile quickBmpFile)
+			: base(session, path)
 		{
-			Branches = new TasBranchCollection(this);
+			Branches = new TasBranchCollection(this, quickBmpFile);
 			ChangeLog = new TasMovieChangeLog(this);
 			Header[HeaderKeys.MovieVersion] = $"BizHawk v2.0 Tasproj v{CurrentVersion.ToString(CultureInfo.InvariantCulture)}";
 			Markers = new TasMovieMarkerList(this);
diff --git a/src/BizHawk.Client.Common/savestates/SavestateFile.cs b/src/BizHawk.Client.Common/savestates/SavestateFile.cs
index b73708f882..a2bdd6da3e 100644
--- a/src/BizHawk.Client.Common/savestates/SavestateFile.cs
+++ b/src/BizHawk.Client.Common/savestates/SavestateFile.cs
@@ -17,9 +17,16 @@ namespace BizHawk.Client.Common
 		private readonly IStatable _statable;
 		private readonly IVideoProvider _videoProvider;
 		private readonly IMovieSession _movieSession;
+
+		private readonly IQuickBmpFile _quickBmpFile;
+
 		private readonly IDictionary<string, object> _userBag;
 
-		public SavestateFile(IEmulator emulator, IMovieSession movieSession, IDictionary<string, object> userBag)
+		public SavestateFile(
+			IEmulator emulator,
+			IMovieSession movieSession,
+			IQuickBmpFile quickBmpFile,
+			IDictionary<string, object> userBag)
 		{
 			if (!emulator.HasSavestates())
 			{
@@ -34,6 +41,7 @@ namespace BizHawk.Client.Common
 			}
 
 			_movieSession = movieSession;
+			_quickBmpFile = quickBmpFile;
 			_userBag = userBag;
 		}
 
@@ -81,7 +89,7 @@ namespace BizHawk.Client.Common
 
 					using (new SimpleTime("Save Framebuffer"))
 					{
-						bs.PutLump(BinaryStateLump.Framebuffer, s => QuickBmpFile.Save(_videoProvider, s, outWidth, outHeight));
+						bs.PutLump(BinaryStateLump.Framebuffer, s => _quickBmpFile.Save(_videoProvider, s, outWidth, outHeight));
 					}
 				}
 			}
@@ -154,7 +162,7 @@ namespace BizHawk.Client.Common
 
 					if (_videoProvider != null)
 					{
-						bl.GetLump(BinaryStateLump.Framebuffer, false, br => PopulateFramebuffer(br, _videoProvider));
+						bl.GetLump(BinaryStateLump.Framebuffer, false, br => PopulateFramebuffer(br, _videoProvider, _quickBmpFile));
 					}
 
 					string userData = "";
@@ -199,13 +207,13 @@ namespace BizHawk.Client.Common
 			return false;
 		}
 
-		private static void PopulateFramebuffer(BinaryReader br, IVideoProvider videoProvider)
+		private static void PopulateFramebuffer(BinaryReader br, IVideoProvider videoProvider, IQuickBmpFile quickBmpFile)
 		{
 			try
 			{
 				using (new SimpleTime("Load Framebuffer"))
 				{
-					QuickBmpFile.Load(videoProvider, br.BaseStream);
+					quickBmpFile.Load(videoProvider, br.BaseStream);
 				}
 			}
 			catch
diff --git a/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs b/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs
index 8013c9cfca..a5b7c86f7e 100644
--- a/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs
+++ b/src/BizHawk.Client.EmuHawk/IMainFormForTools.cs
@@ -41,6 +41,9 @@ namespace BizHawk.Client.EmuHawk
 		/// <remarks>only referenced from <see cref="PlaybackBox"/></remarks>
 		bool PressRewind { set; }
 
+		/// <remarks>only referenced from <see cref="TAStudio"/></remarks>
+		IQuickBmpFile QuickBmpFile { get; }
+
 		/// <remarks>only referenced from <see cref="GenericDebugger"/></remarks>
 		event Action<bool> OnPauseChanged;
 
diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs
index f0b64cded2..dbb6e025e9 100644
--- a/src/BizHawk.Client.EmuHawk/MainForm.cs
+++ b/src/BizHawk.Client.EmuHawk/MainForm.cs
@@ -319,6 +319,7 @@ namespace BizHawk.Client.EmuHawk
 				Config.Movies,
 				Config.PathEntries.MovieBackupsAbsolutePath(),
 				this,
+				QuickBmpFile,
 				AddOnScreenMessage,
 				PauseEmulator,
 				SetMainformMovieInfo);
@@ -4091,7 +4092,7 @@ namespace BizHawk.Client.EmuHawk
 				return;
 			}
 
-			if (new SavestateFile(Emulator, MovieSession, MovieSession.UserBag).Load(path))
+			if (new SavestateFile(Emulator, MovieSession, QuickBmpFile, MovieSession.UserBag).Load(path))
 			{
 				OSD.ClearGuiText();
 				EmuClient.OnStateLoaded(this, userFriendlyStateName);
@@ -4170,7 +4171,7 @@ namespace BizHawk.Client.EmuHawk
 
 			try
 			{
-				new SavestateFile(Emulator, MovieSession, MovieSession.UserBag).Create(path, Config.Savestates);
+				new SavestateFile(Emulator, MovieSession, QuickBmpFile, MovieSession.UserBag).Create(path, Config.Savestates);
 
 				EmuClient.OnStateSaved(this, userFriendlyStateName);
 
@@ -4737,5 +4738,7 @@ namespace BizHawk.Client.EmuHawk
 			//BANZAIIIIIIIIIIIIIIIIIIIIIIIIIII
 			LoadRom(args[0]);
 		}
+
+		public IQuickBmpFile QuickBmpFile { get; } = new QuickBmpFile();
 	}
 }
diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/BookmarksBranchesBox.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/BookmarksBranchesBox.cs
index 2e5ed655d2..2c5f9b8db8 100644
--- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/BookmarksBranchesBox.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/BookmarksBranchesBox.cs
@@ -201,7 +201,7 @@ namespace BizHawk.Client.EmuHawk
 			Movie.LoadBranch(branch);
 			Tastudio.LoadState(new KeyValuePair<int, Stream>(branch.Frame, new MemoryStream(branch.CoreData, false)));
 			Movie.TasStateManager.Capture(Tastudio.Emulator.Frame, Tastudio.Emulator.AsStatable());
-			QuickBmpFile.Copy(new BitmapBufferVideoProvider(branch.CoreFrameBuffer), Tastudio.VideoProvider);
+			Tastudio.MainForm.QuickBmpFile.Copy(new BitmapBufferVideoProvider(branch.CoreFrameBuffer), Tastudio.VideoProvider);
 
 			if (Tastudio.Settings.OldControlSchemeForBranches && Tastudio.TasPlaybackBox.RecordingMode)
 				Movie.Truncate(branch.Frame);