-Began working on the importer.

--Created ImportFile to decide what function to use for each filetype.
---It currently automatically writes to a .TAS file, but that option will eventually only be applied when specified in the GUI, hopefully completely external from this class.
--Made IsValidMovieExtension work.
--Created LoadText to do the majority of the work that both .FM2 and .MC2 need to be done.
--.MC2 seems to work perfectly, not that it was a hard conversion!
--.FM2 seems to convert most headers correct, except for subtitles, which replaces the beginning portions of each subtitle's text with 0 0 120 4294967295. Not sure what that's about, though this sure feels like deja vu...
--I still need to switch around the order of the buttons the frames are added, but I need to find out what way I can do this without reinventing the wheel.
-Added the FixMnemonic function to Movie.cs. It currently does nothing, but my goal is to have it correct the mnemonic for all frames in a movie file based on the position of the characters.
--As of right now, ImportFile uses this.
-MainForm.IsValidMovieExtension only checks whether or not its .TAS or not now.

TODO:
-Fix the FM2 subtitles.
-Shift around the FM2 buttons.
--After completed, test a .FM2 file that should sync and see if it works, with and without FixMnemonic being used.
-Make FixMnemonic actually do something.
-Refactor code? I originally thought it'd be best to treat Movie.LoadText just like any other importer, but I think at this point it might just be best to keep these things completely separate.
-Consider the possibility of working with the binary file importers.
--Yes adelikat, I am somewhat interested, especially considering how useful it would be to have a working .FCM importer so I can compare old runs when TASing. I already was hoping to learn about .VBM and .SMV for my ButtonCount.lua script. By the way, might this be bundled with bizhawk as it is with FCEUX 2.1.6? :)
This commit is contained in:
brandman211 2012-02-15 06:54:09 +00:00
parent a45a98f773
commit 145830d5a4
3 changed files with 173 additions and 41 deletions

View File

@ -722,14 +722,7 @@ namespace BizHawk.MultiClient
private bool IsValidMovieExtension(string ext)
{
switch (ext.ToUpper())
{
case ".TAS": //Bizhawk
case ".MC2": //PCEjin
return true;
default:
return false;
}
return (ext.ToUpper() == ".TAS");
}
private void FormDragDrop(object sender, DragEventArgs e)

View File

@ -65,6 +65,7 @@ namespace BizHawk.MultiClient
{
return Header.GetHeaderLine(MovieHeader.GAMENAME);
}
public int Length()
{
if (Loaded)
@ -328,6 +329,15 @@ namespace BizHawk.MultiClient
return LoadText();
}
public void FixMnemonic()
{
int frame = 0;
while (frame < Log.Length())
{
// TODO: Correct mnemonics, using Log.GetFrame(frame))?
}
lastLog = frame;
}
public void DumpLogIntoSavestateText(TextWriter writer)
{
@ -764,7 +774,7 @@ namespace BizHawk.MultiClient
return 0;
}
private string ParseHeader(string line, string headerName)
private static string ParseHeader(string line, string headerName)
{
string str;
int x = line.LastIndexOf(headerName) + headerName.Length;
@ -778,4 +788,4 @@ namespace BizHawk.MultiClient
Header.AddHeaderLine(MovieHeader.STARTSFROMSAVESTATE, "1");
}
}
}
}

View File

@ -12,30 +12,139 @@ namespace BizHawk.MultiClient
{
public static Movie ImportFile(string path, out string errorMsg)
{
//TODO: This function will receive a file, parse the file extension,
//then decide which import function to call, call it, and return a movie object
//the multiclient should only call this and not the import members (make them private)
Movie mov;
errorMsg = "";
return new Movie();
switch (Path.GetExtension(path).ToUpper())
{
case ".FCM":
mov = ImportFCM(path, out errorMsg);
break;
case ".FM2":
mov = ImportFM2(path, out errorMsg);
break;
case ".GMV":
mov = ImportGMV(path, out errorMsg);
break;
case ".MCM":
mov = ImportMCM(path, out errorMsg);
break;
case ".MC2":
mov = ImportMC2(path, out errorMsg);
break;
case ".MMV":
mov = ImportMMV(path, out errorMsg);
break;
case ".SMV":
// TODO: Decide which SMV parser to use. Perhaps have one parent function that decides.
mov = new Movie();
break;
case ".VBM":
mov = ImportVBM(path, out errorMsg);
break;
default:
mov = new Movie();
break;
}
mov.FixMnemonic();
mov.WriteMovie();
return mov;
}
public static bool IsValidMovieExtension(string extension)
{
switch (extension.ToUpper())
string[] extensions = {"FCM", "FM2", "GMV", "MC2", "MMV", "TAS", "VBM"};
foreach (string ext in extensions)
{
case "TAS":
case "FM2":
case "FCM":
case "MMV":
case "GMV":
case "MC2":
case "VBM":
if (extension.ToUpper() == "." + ext)
{
return true;
default:
return false;
}
}
return false;
}
private static string ParseHeader(string line, string headerName)
{
string str;
int x = line.LastIndexOf(headerName) + headerName.Length;
str = line.Substring(x + 1, line.Length - x - 1);
return str;
}
private static Movie ImportText(string path, out string errorMsg, string emulator)
{
errorMsg = "";
Movie m = new Movie(Path.ChangeExtension(path, ".tas"), MOVIEMODE.PLAY);
var file = new FileInfo(path);
using (StreamReader sr = file.OpenText())
{
string str = "";
string rerecordStr = "";
while ((str = sr.ReadLine()) != null)
{
if (str == "")
{
continue;
}
if (str.Contains("rerecordCount"))
{
rerecordStr = ParseHeader(str, "rerecordCount");
try
{
m.SetRerecords(int.Parse(rerecordStr));
}
catch
{
m.SetRerecords(0);
}
}
else if (str.Contains("StartsFromSavestate"))
{
str = ParseHeader(str, "StartsFromSavestate");
if (str == "1")
{
errorMsg = "Movies that begin with a savestate are not supported.";
return null;
}
}
if (str.StartsWith("emuVersion"))
{
m.Header.SetHeaderLine(MovieHeader.EMULATIONVERSION, emulator + " version " + ParseHeader(str, "emuVersion"));
}
else if (str.StartsWith("version"))
{
m.Header.SetHeaderLine(MovieHeader.MOVIEVERSION, ParseHeader(str, "version"));
}
else if (str.StartsWith("romFilename"))
{
m.Header.SetHeaderLine(MovieHeader.GAMENAME, ParseHeader(str, "romFilename"));
}
else if (str.StartsWith("comment author"))
{
m.Header.SetHeaderLine(MovieHeader.AUTHOR, ParseHeader(str, "comment author"));
}
else if (str.StartsWith("guid"))
{
m.Header.SetHeaderLine(MovieHeader.GUID, ParseHeader(str, "GUID"));
}
else if (str.StartsWith("subtitle") || str.StartsWith("sub"))
{
m.Subtitles.AddSubtitle(str);
}
else if (str[0] == '|')
{
m.AppendFrame(str);
}
else
{
m.Header.Comments.Add(str);
}
}
}
return m;
}
private static Movie ImportFCM(string path, out string errorMsg)
{
errorMsg = "";
@ -158,6 +267,41 @@ namespace BizHawk.MultiClient
}
}
private static Movie ImportFM2(string path, out string errorMsg)
{
errorMsg = "";
Movie m = ImportText(path, out errorMsg, "FCEUX");
m.Header.SetHeaderLine(MovieHeader.PLATFORM, "NES");
// TODO: Mnemonic switches.
// FM2 file format: http://www.fceux.com/web/FM2.html
return m;
}
private static Movie ImportGMV(string path, out string errorMsg)
{
errorMsg = "";
Movie m = new Movie(Path.ChangeExtension(path, ".tas"), MOVIEMODE.PLAY);
return m;
}
private static Movie ImportMCM(string path, out string errorMsg)
{
errorMsg = "";
Movie m = new Movie(Path.ChangeExtension(path, ".tas"), MOVIEMODE.PLAY);
return m;
}
private static Movie ImportMC2(string path, out string errorMsg)
{
errorMsg = "";
Movie m = ImportText(path, out errorMsg, "Mednafen/PCEjin");
m.Header.SetHeaderLine(MovieHeader.PLATFORM, "MC2");
// TODO: PCECD equivalent.
// MC2 file format: http://code.google.com/p/pcejin/wiki/MC2
return m;
}
private static Movie ImportMMV(string path, out string errorMsg)
{
errorMsg = "";
@ -284,13 +428,6 @@ namespace BizHawk.MultiClient
return m;
}
private static string ImportMCM(string path)
{
string converted = Path.ChangeExtension(path, ".tas");
return converted;
}
private static Movie ImportSMV(string path, out string errorMSG)
{
errorMSG = "";
@ -400,14 +537,6 @@ namespace BizHawk.MultiClient
return m;
}
private static Movie ImportGMV(string path, out string errorMsg)
{
errorMsg = "";
Movie m = new Movie(Path.ChangeExtension(path, ".tas"), MOVIEMODE.PLAY);
return m;
}
private static Movie ImportVBM(string path, out string errorMsg)
{
errorMsg = "";
@ -576,4 +705,4 @@ namespace BizHawk.MultiClient
return m;
}
}
}
}