diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
index 5246ade05f..e08b916a9d 100644
--- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj
+++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
@@ -156,6 +156,7 @@
+
diff --git a/BizHawk.Client.Common/movie/import/Mc2Import.cs b/BizHawk.Client.Common/movie/import/Mc2Import.cs
new file mode 100644
index 0000000000..3df4b4f798
--- /dev/null
+++ b/BizHawk.Client.Common/movie/import/Mc2Import.cs
@@ -0,0 +1,184 @@
+using BizHawk.Emulation.Cores.PCEngine;
+
+namespace BizHawk.Client.Common.movie.import
+{
+ // MC2 file format: http://code.google.com/p/pcejin/wiki/MC2
+ // ReSharper disable once UnusedMember.Global
+ [ImportExtension(".mc2")]
+ public class Mc2Import : MovieImporter
+ {
+ private PceControllerDeck _deck;
+
+ protected override void RunImport()
+ {
+ var ss = new PCEngine.PCESyncSettings
+ {
+ Port1 = PceControllerType.Unplugged,
+ Port2 = PceControllerType.Unplugged,
+ Port3 = PceControllerType.Unplugged,
+ Port4 = PceControllerType.Unplugged,
+ Port5 = PceControllerType.Unplugged
+ };
+
+ _deck = new PceControllerDeck(
+ ss.Port1,
+ ss.Port2,
+ ss.Port3,
+ ss.Port4,
+ ss.Port5);
+
+ Result.Movie.HeaderEntries[HeaderKeys.PLATFORM] = "PCE";
+ 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("ports"))
+ {
+ var portNumStr = ParseHeader(line, "ports");
+ if (int.TryParse(portNumStr, out int ports))
+ {
+ // Ugh
+ if (ports > 0)
+ {
+ ss.Port1 = PceControllerType.GamePad;
+ }
+
+ if (ports > 1)
+ {
+ ss.Port2 = PceControllerType.GamePad;
+ }
+
+ if (ports > 2)
+ {
+ ss.Port3 = PceControllerType.GamePad;
+ }
+
+ if (ports > 3)
+ {
+ ss.Port4 = PceControllerType.GamePad;
+ }
+
+ if (ports > 4)
+ {
+ ss.Port5 = PceControllerType.GamePad;
+ }
+
+ _deck = new PceControllerDeck(
+ ss.Port1,
+ ss.Port2,
+ ss.Port3,
+ ss.Port4,
+ ss.Port5);
+ }
+ }
+ else if (line.ToLower().StartsWith("pcecd"))
+ {
+ Result.Movie.HeaderEntries[HeaderKeys.PLATFORM] = "PCECD";
+ }
+ else if (line.ToLower().StartsWith("emuversion"))
+ {
+ Result.Movie.Comments.Add($"{EmulationOrigin} Mednafen/PCEjin version {ParseHeader(line, "emuVersion")}");
+ }
+ else if (line.ToLower().StartsWith("version"))
+ {
+ string version = ParseHeader(line, "version");
+ Result.Movie.Comments.Add($"{MovieOrigin} .mc2 version {version}");
+ }
+ else if (line.ToLower().StartsWith("romfilename"))
+ {
+ Result.Movie.HeaderEntries[HeaderKeys.GAMENAME] = ParseHeader(line, "romFilename");
+ }
+ else if (line.ToLower().StartsWith("cdgamename"))
+ {
+ Result.Movie.HeaderEntries[HeaderKeys.GAMENAME] = ParseHeader(line, "cdGameName");
+ }
+ else if (line.ToLower().StartsWith("comment author"))
+ {
+ Result.Movie.HeaderEntries[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;
+ }
+
+ 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
+ {
+ // Everything not explicitly defined is treated as a comment.
+ Result.Movie.Comments.Add(line);
+ }
+ }
+
+ Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(ss);
+ }
+
+ // Import a frame from a text-based format.
+ private void ImportTextFrame(string line)
+ {
+ var buttons = new[] { "Up", "Down", "Left", "Right", "B1", "B2", "Run", "Select" };
+
+ var controllers = new SimpleController { Definition = _deck.Definition };
+
+ // Split up the sections of the frame.
+ string[] sections = line.Split('|');
+
+ /*
+ Skip the first two sections of the split, which consist of everything before the starting | and the command.
+ Do not use the section after the last |. In other words, get the sections for the players.
+ */
+ int start = 2;
+ int end = sections.Length - 1;
+ int playerOffset = -1;
+
+ for (int section = start; section < end; section++)
+ {
+ // The player number is one less than the section number for the reasons explained above.
+ int player = section + playerOffset;
+ string prefix = $"P{player} ";
+
+ // Only count lines with that have the right number of buttons and are for valid players.
+ if (
+ sections[section].Length == buttons.Length)
+ {
+ for (int button = 0; button < buttons.Length; button++)
+ {
+ // Consider the button pressed so long as its spot is not occupied by a ".".
+ controllers[prefix + buttons[button]] = sections[section][button] != '.';
+ }
+ }
+ }
+
+ // Convert the data for the controllers to a mnemonic and add it as a frame.
+ Result.Movie.AppendFrame(controllers);
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/movie/import/MovieImport.cs b/BizHawk.Client.Common/movie/import/MovieImport.cs
index cb307bb317..63ec1cb4d5 100644
--- a/BizHawk.Client.Common/movie/import/MovieImport.cs
+++ b/BizHawk.Client.Common/movie/import/MovieImport.cs
@@ -145,9 +145,6 @@ namespace BizHawk.Client.Common
case ".GMV":
m = ImportGmv(path, out errorMsg, out warningMsg);
break;
- case ".MC2":
- m = ImportMc2(path, out errorMsg, out warningMsg);
- break;
case ".MMV":
m = ImportMmv(path, out errorMsg, out warningMsg);
break;
@@ -205,40 +202,11 @@ namespace BizHawk.Client.Common
return extensions.Any(ext => extension.ToUpper() == $".{ext}");
}
- // Reduce all whitespace to single spaces.
- private static string SingleSpaces(string line)
- {
- line = line.Replace("\t", " ");
- line = line.Replace("\n", " ");
- line = line.Replace("\r", " ");
- line = line.Replace("\r\n", " ");
- string prev;
- do
- {
- prev = line;
- line = line.Replace(" ", " ");
- }
- while (prev != line);
- return line;
- }
-
// Import a frame from a text-based format.
private static BkmMovie ImportTextFrame(string line, int lineNum, BkmMovie m, string path, string platform, ref string warningMsg)
{
- string[] buttons = { };
- var controller = "";
- var ext = path != null ? Path.GetExtension(path).ToUpper() : "";
- switch (ext)
- {
- case ".MC2":
- buttons = new[] { "Up", "Down", "Left", "Right", "B1", "B2", "Run", "Select" };
- controller = "PC Engine Controller";
- break;
- case ".YMV":
- buttons = new[] { "Left", "Right", "Up", "Down", "Start", "A", "B", "C", "X", "Y", "Z", "L", "R" };
- controller = "Saturn Controller";
- break;
- }
+ var buttons = new[] { "Left", "Right", "Up", "Down", "Start", "A", "B", "C", "X", "Y", "Z", "L", "R" };
+ var controller = "Saturn Controller";
var controllers = new SimpleController { Definition = new ControllerDefinition { Name = controller } };
@@ -258,12 +226,6 @@ namespace BizHawk.Client.Common
// The player number is one less than the section number for the reasons explained above.
int player = section + playerOffset;
string prefix = $"P{player} ";
-
- // Gameboy doesn't currently have a prefix saying which player the input is for.
- if (controllers.Definition.Name == "Gameboy Controller")
- {
- prefix = "";
- }
// Only count lines with that have the right number of buttons and are for valid players.
if (
@@ -283,47 +245,16 @@ namespace BizHawk.Client.Common
return m;
}
- // Import a subtitle from a text-based format.
- private static BkmMovie ImportTextSubtitle(string line, BkmMovie m, string path)
- {
- line = SingleSpaces(line);
-
- // The header name, frame, and message are separated by whitespace.
- int first = line.IndexOf(' ');
- int second = line.IndexOf(' ', first + 1);
- if (first != -1 && second != -1)
- {
- // Concatenate the frame and message with default values for the additional fields.
- var frame = line.Substring(0, first);
- var length = line.Substring(first + 1, second - first - 1);
-
- string message = line.Substring(second + 1).Trim();
- m.Subtitles.AddFromString($"subtitle {frame} 0 0 {length} FFFFFFFF {message}");
- }
-
- return m;
- }
-
- // Import a text-based movie format. This works for .MC2 and .YMV.
- private static BkmMovie ImportText(string path, out string errorMsg, out string warningMsg)
+ // 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 = "";
- var platform = "";
- switch (Path.GetExtension(path).ToUpper())
- {
- case ".MC2":
- emulator = "Mednafen/PCEjin";
- platform = "PCE";
- break;
- case ".YMV":
- emulator = "Yabause";
- platform = "Sega Saturn";
- break;
- }
+
+ var emulator = "Yabause";
+ var platform = "Sega Saturn";
m.Header[HeaderKeys.PLATFORM] = platform;
int lineNum = 0;
@@ -345,10 +276,6 @@ namespace BizHawk.Client.Common
return null;
}
}
- else if (line.ToLower().StartsWith("sub"))
- {
- m = ImportTextSubtitle(line, m, path);
- }
else if (line.ToLower().StartsWith("emuversion"))
{
m.Comments.Add($"{EMULATIONORIGIN} {emulator} version {ParseHeader(line, "emuVersion")}");
@@ -362,10 +289,6 @@ namespace BizHawk.Client.Common
{
m.Header[HeaderKeys.GAMENAME] = ParseHeader(line, "romFilename");
}
- else if (line.ToLower().StartsWith("cdgamename"))
- {
- m.Header[HeaderKeys.GAMENAME] = ParseHeader(line, "cdGameName");
- }
else if (line.ToLower().StartsWith("comment author"))
{
m.Header[HeaderKeys.AUTHOR] = ParseHeader(line, "comment author");
@@ -396,11 +319,6 @@ namespace BizHawk.Client.Common
return null;
}
}
- else if (line.ToLower().StartsWith("palflag"))
- {
- bool pal = ParseHeader(line, "palFlag") == "1";
- m.Header[HeaderKeys.PAL] = pal.ToString();
- }
else if (line.ToLower().StartsWith("ispal"))
{
bool pal = ParseHeader(line, "isPal") == "1";
@@ -739,12 +657,6 @@ namespace BizHawk.Client.Common
return m;
}
- // MC2 file format: http://code.google.com/p/pcejin/wiki/MC2
- private static BkmMovie ImportMc2(string path, out string errorMsg, out string warningMsg)
- {
- return ImportText(path, out errorMsg, out warningMsg);
- }
-
// MMV file format: http://tasvideos.org/MMV.html
private static BkmMovie ImportMmv(string path, out string errorMsg, out string warningMsg)
{
@@ -1471,11 +1383,5 @@ namespace BizHawk.Client.Common
fs.Close();
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)
- {
- return ImportText(path, out errorMsg, out warningMsg);
- }
}
}