diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
index e08b916a9d..a3a65fead3 100644
--- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj
+++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
@@ -158,6 +158,7 @@
+
diff --git a/BizHawk.Client.Common/movie/import/MovieImport.cs b/BizHawk.Client.Common/movie/import/MovieImport.cs
index 63ec1cb4d5..013716bf20 100644
--- a/BizHawk.Client.Common/movie/import/MovieImport.cs
+++ b/BizHawk.Client.Common/movie/import/MovieImport.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
-using BizHawk.Common;
using BizHawk.Common.BufferExtensions;
using BizHawk.Common.IOExtensions;
@@ -154,9 +153,6 @@ namespace BizHawk.Client.Common
case ".VBM":
m = ImportVbm(path, out errorMsg, out warningMsg);
break;
- case ".YMV":
- m = ImportYmv(path, out errorMsg, out warningMsg);
- break;
case ".BKM":
m.Filename = path;
m.Load(false);
@@ -197,7 +193,7 @@ namespace BizHawk.Client.Common
{
string[] extensions =
{
- "BKM", "FMV", "GMV", "MMV", "SMV", "VBM", "YMV"
+ "BKM", "FMV", "GMV", "MMV", "SMV", "VBM"
};
return extensions.Any(ext => extension.ToUpper() == $".{ext}");
}
@@ -245,96 +241,6 @@ namespace BizHawk.Client.Common
return m;
}
- // YMV file format: https://code.google.com/p/yabause-rr/wiki/YMVfileformat
- private static BkmMovie ImportYmv(string path, out string errorMsg, out string warningMsg)
- {
- errorMsg = warningMsg = "";
- var m = new BkmMovie(path);
- var file = new FileInfo(path);
- var sr = file.OpenText();
-
- var emulator = "Yabause";
- var platform = "Sega Saturn";
-
- m.Header[HeaderKeys.PLATFORM] = platform;
- int lineNum = 0;
- string line;
- while ((line = sr.ReadLine()) != null)
- {
- lineNum++;
- if (line == "")
- {
- continue;
- }
-
- if (line[0] == '|')
- {
- m = ImportTextFrame(line, lineNum, m, path, platform, ref warningMsg);
- if (errorMsg != "")
- {
- sr.Close();
- return null;
- }
- }
- else if (line.ToLower().StartsWith("emuversion"))
- {
- m.Comments.Add($"{EMULATIONORIGIN} {emulator} version {ParseHeader(line, "emuVersion")}");
- }
- else if (line.ToLower().StartsWith("version"))
- {
- string version = ParseHeader(line, "version");
- m.Comments.Add($"{MOVIEORIGIN} {Path.GetExtension(path)} version {version}");
- }
- else if (line.ToLower().StartsWith("romfilename"))
- {
- m.Header[HeaderKeys.GAMENAME] = ParseHeader(line, "romFilename");
- }
- else if (line.ToLower().StartsWith("comment author"))
- {
- m.Header[HeaderKeys.AUTHOR] = ParseHeader(line, "comment author");
- }
- else if (line.ToLower().StartsWith("rerecordcount"))
- {
- int rerecordCount;
-
- // Try to parse the re-record count as an integer, defaulting to 0 if it fails.
- try
- {
- rerecordCount = int.Parse(ParseHeader(line, "rerecordCount"));
- }
- catch
- {
- rerecordCount = 0;
- }
-
- m.Rerecords = (ulong)rerecordCount;
- }
- else if (line.ToLower().StartsWith("startsfromsavestate"))
- {
- // If this movie starts from a savestate, we can't support it.
- if (ParseHeader(line, "StartsFromSavestate") == "1")
- {
- errorMsg = "Movies that begin with a savestate are not supported.";
- sr.Close();
- return null;
- }
- }
- else if (line.ToLower().StartsWith("ispal"))
- {
- bool pal = ParseHeader(line, "isPal") == "1";
- m.Header[HeaderKeys.PAL] = pal.ToString();
- }
- else
- {
- // Everything not explicitly defined is treated as a comment.
- m.Comments.Add(line);
- }
- }
-
- sr.Close();
- return m;
- }
-
// Get the content for a particular header.
private static string ParseHeader(string line, string headerName)
{
diff --git a/BizHawk.Client.Common/movie/import/YmvImport.cs b/BizHawk.Client.Common/movie/import/YmvImport.cs
new file mode 100644
index 0000000000..cf768f8a48
--- /dev/null
+++ b/BizHawk.Client.Common/movie/import/YmvImport.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using BizHawk.Emulation.Common;
+using BizHawk.Emulation.Cores.Consoles.Sega.Saturn;
+
+namespace BizHawk.Client.Common.movie.import
+{
+ // https://code.google.com/archive/p/yabause-rr/wikis/YMVfileformat.wiki
+ // ReSharper disable once UnusedMember.Global
+ [ImportExtension(".ymv")]
+ public class YmvImport : MovieImporter
+ {
+ protected override void RunImport()
+ {
+ Result.Movie.HeaderEntries[HeaderKeys.PLATFORM] = "SAT";
+ var ss = new Saturnus.SyncSettings
+ {
+ Port1 = SaturnusControllerDeck.Device.Gamepad,
+ Port2 = SaturnusControllerDeck.Device.None
+ };
+
+ using var sr = SourceFile.OpenText();
+ string line;
+ while ((line = sr.ReadLine()) != null)
+ {
+ if (string.IsNullOrWhiteSpace(line))
+ {
+ continue;
+ }
+
+ if (line[0] == '|')
+ {
+ ImportTextFrame(line);
+ }
+ else if (line.ToLower().StartsWith("emuversion"))
+ {
+ Result.Movie.Comments.Add($"{EmulationOrigin} Yabause version {ParseHeader(line, "emuVersion")}");
+ }
+ else if (line.ToLower().StartsWith("version"))
+ {
+ string version = ParseHeader(line, "version");
+ Result.Movie.Comments.Add($"{MovieOrigin} .ymv version {version}");
+ }
+ else if (line.ToLower().StartsWith("cdGameName"))
+ {
+ Result.Movie.HeaderEntries[HeaderKeys.GAMENAME] = ParseHeader(line, "romFilename");
+ }
+ else if (line.ToLower().StartsWith("rerecordcount"))
+ {
+ int rerecordCount;
+
+ // Try to parse the re-record count as an integer, defaulting to 0 if it fails.
+ try
+ {
+ rerecordCount = int.Parse(ParseHeader(line, "rerecordCount"));
+ }
+ catch
+ {
+ rerecordCount = 0;
+ }
+
+ Result.Movie.Rerecords = (ulong)rerecordCount;
+ }
+ else if (line.ToLower().StartsWith("startsfromsavestate"))
+ {
+ // If this movie starts from a savestate, we can't support it.
+ if (ParseHeader(line, "StartsFromSavestate") == "1")
+ {
+ Result.Errors.Add("Movies that begin with a savestate are not supported.");
+ }
+ }
+ else if (line.ToLower().StartsWith("ispal"))
+ {
+ bool pal = ParseHeader(line, "isPal") == "1";
+ Result.Movie.HeaderEntries[HeaderKeys.PAL] = pal.ToString();
+ }
+ else
+ {
+ // Everything not explicitly defined is treated as a comment.
+ Result.Movie.Comments.Add(line);
+ }
+ }
+
+ Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(ss);
+ }
+
+ private void ImportTextFrame(string line)
+ {
+ // Yabause only supported 1 controller
+ var controllers = new SimpleController
+ {
+ Definition = new ControllerDefinition
+ {
+ Name = "Saturn Controller",
+ BoolButtons = new List
+ {
+ "Reset", "Power", "Previous Disk", "Next Disk", "P1 Left", "P1 Right", "P1 Up", "P1 Down", "P1 Start", "P1 A", "P1 B", "P1 C", "P1 X", "P1 Y", "P1 Z", "P1 L", "P1 R"
+ }
+ }
+ };
+
+ // Split up the sections of the frame.
+ string[] sections = line.Split(new [] { "|" }, StringSplitOptions.RemoveEmptyEntries);
+ if (sections.Length != 2)
+ {
+ Result.Errors.Add("Unsupported input configuration");
+ return;
+ }
+
+ if (sections[0][0] == '1')
+ {
+ controllers["Reset"] = true;
+ }
+
+ var buttonNames = controllers.Definition.ControlsOrdered.Skip(1).First().ToList();
+
+ // Only count lines with that have the right number of buttons and are for valid players.
+ if (sections[1].Length == buttonNames.Count)
+ {
+ for (int button = 0; button < buttonNames.Count; button++)
+ {
+ // Consider the button pressed so long as its spot is not occupied by a ".".
+ controllers[buttonNames[button]] = sections[1][button] != '.';
+ }
+ }
+
+ // Convert the data for the controllers to a mnemonic and add it as a frame.
+ Result.Movie.AppendFrame(controllers);
+ }
+
+ }
+}
diff --git a/BizHawk.sln.DotSettings b/BizHawk.sln.DotSettings
index 1148d786bc..9f8d3b93a4 100644
--- a/BizHawk.sln.DotSettings
+++ b/BizHawk.sln.DotSettings
@@ -270,6 +270,7 @@
True
True
True
+ True
True
True
True