-Made ImportMMV more functional.
-Seemingly programmed the header handling for ImportFMV correctly. TODO: -ImportFMV frame data handling.
This commit is contained in:
parent
0b69b4c17c
commit
c4029509fc
|
@ -49,9 +49,11 @@ namespace BizHawk.MultiClient
|
|||
m = ImportVBM(path, out errorMsg, out warningMsg);
|
||||
break;
|
||||
}
|
||||
m.Header.SetHeaderLine(MovieHeader.MOVIEVERSION, MovieHeader.MovieVersion);
|
||||
if (errorMsg == "")
|
||||
{
|
||||
m.Header.SetHeaderLine(MovieHeader.MOVIEVERSION, MovieHeader.MovieVersion);
|
||||
m.WriteMovie();
|
||||
}
|
||||
}
|
||||
catch (Exception except)
|
||||
{
|
||||
|
@ -70,6 +72,20 @@ namespace BizHawk.MultiClient
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Read bytes from a BinaryReader and translate them into a string for either the hexidecimal representation of the
|
||||
binary numbers or the UTF-8 string they represent.
|
||||
*/
|
||||
private static string BytesToString(BinaryReader r, int size, bool hexadecimal = false)
|
||||
{
|
||||
byte[] bytes = new byte[size];
|
||||
for (int b = 0; b < size; b++)
|
||||
bytes[b] = r.ReadByte();
|
||||
if (hexadecimal)
|
||||
return string.Concat(bytes.Select(b => string.Format("{0:x2}", b)));
|
||||
return System.Text.Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
|
||||
// Import a text-based movie format. This works for .FM2 and .MC2.
|
||||
private static Movie ImportText(string path, out string errorMsg, out string warningMsg)
|
||||
{
|
||||
|
@ -99,69 +115,69 @@ namespace BizHawk.MultiClient
|
|||
m.Header.SetHeaderLine(MovieHeader.PLATFORM, platform);
|
||||
using (StreamReader sr = file.OpenText())
|
||||
{
|
||||
int line = 0;
|
||||
string str = "";
|
||||
string rerecordStr = "";
|
||||
while ((str = sr.ReadLine()) != null)
|
||||
int lineNum = 0;
|
||||
string line = "";
|
||||
string rerecordCount = "";
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
line++;
|
||||
if (str == "")
|
||||
lineNum++;
|
||||
if (line == "")
|
||||
continue;
|
||||
if (str.Contains("rerecordCount"))
|
||||
if (line.Contains("rerecordCount"))
|
||||
{
|
||||
rerecordStr = ParseHeader(str, "rerecordCount");
|
||||
rerecordCount = ParseHeader(line, "rerecordCount");
|
||||
// Try to parse the Re-record count as an integer, defaulting to 0 if it fails.
|
||||
try
|
||||
{
|
||||
m.SetRerecords(int.Parse(rerecordStr));
|
||||
m.SetRerecords(int.Parse(rerecordCount));
|
||||
}
|
||||
catch
|
||||
{
|
||||
m.SetRerecords(0);
|
||||
}
|
||||
}
|
||||
else if (str.Contains("StartsFromSavestate"))
|
||||
else if (line.Contains("StartsFromSavestate"))
|
||||
{
|
||||
str = ParseHeader(str, "StartsFromSavestate");
|
||||
line = ParseHeader(line, "StartsFromSavestate");
|
||||
// If this movie starts from a savestate, we can't support it.
|
||||
if (str == "1")
|
||||
if (line == "1")
|
||||
{
|
||||
warningMsg = "Movies that begin with a savestate are not supported.";
|
||||
errorMsg = "Movies that begin with a savestate are not supported.";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (str.StartsWith("emuVersion"))
|
||||
m.Header.Comments.Add("emuOrigin " + emulator + " version " + ParseHeader(str, "emuVersion"));
|
||||
else if (str.StartsWith("version"))
|
||||
if (line.StartsWith("emuVersion"))
|
||||
m.Header.Comments.Add("emuOrigin " + emulator + " version " + ParseHeader(line, "emuVersion"));
|
||||
else if (line.StartsWith("version"))
|
||||
m.Header.Comments.Add(
|
||||
"MovieOrigin " + Path.GetExtension(path) + " version " + ParseHeader(str, "version")
|
||||
"MovieOrigin " + Path.GetExtension(path) + " version " + ParseHeader(line, "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("sub"))
|
||||
else if (line.StartsWith("romFilename"))
|
||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, ParseHeader(line, "romFilename"));
|
||||
else if (line.StartsWith("comment author"))
|
||||
m.Header.SetHeaderLine(MovieHeader.AUTHOR, ParseHeader(line, "comment author"));
|
||||
else if (line.StartsWith("guid"))
|
||||
m.Header.SetHeaderLine(MovieHeader.GUID, ParseHeader(line, "GUID"));
|
||||
else if (line.StartsWith("sub"))
|
||||
{
|
||||
Subtitle s = new Subtitle();
|
||||
// The header name, frame, and message are separated by a space.
|
||||
int first = str.IndexOf(' ');
|
||||
int second = str.IndexOf(' ', first + 1);
|
||||
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.
|
||||
string frame = str.Substring(first + 1, second - first - 1);
|
||||
string message = str.Substring(second + 1, str.Length - second - 1);
|
||||
string frame = line.Substring(first + 1, second - first - 1);
|
||||
string message = line.Substring(second + 1, line.Length - second - 1);
|
||||
m.Subtitles.AddSubtitle("subtitle " + frame + " 0 0 200 FFFFFFFF " + message);
|
||||
}
|
||||
}
|
||||
else if (str[0] == '|')
|
||||
else if (line[0] == '|')
|
||||
{
|
||||
// Handle a frame of input.
|
||||
ArrayList frame = new ArrayList();
|
||||
// Split up the sections of the frame.
|
||||
string[] sections = str.Split('|');
|
||||
string[] sections = line.Split('|');
|
||||
// Start building the data for the controllers.
|
||||
SimpleController controllers = new SimpleController();
|
||||
controllers.Type = new ControllerDefinition();
|
||||
|
@ -193,7 +209,7 @@ namespace BizHawk.MultiClient
|
|||
break;
|
||||
}
|
||||
if (warningMsg != "")
|
||||
warningMsg = "Unable to import " + warningMsg + " command on line " + line;
|
||||
warningMsg = "Unable to import " + warningMsg + " command on line " + lineNum + ".";
|
||||
}
|
||||
/*
|
||||
Skip the first two sections of the split, which consist of everything before the starting | and the
|
||||
|
@ -221,7 +237,7 @@ namespace BizHawk.MultiClient
|
|||
}
|
||||
else
|
||||
// Everything not explicitly defined is treated as a comment.
|
||||
m.Header.Comments.Add(str);
|
||||
m.Header.Comments.Add(line);
|
||||
}
|
||||
}
|
||||
return m;
|
||||
|
@ -236,6 +252,7 @@ namespace BizHawk.MultiClient
|
|||
return str;
|
||||
}
|
||||
|
||||
// Remove the NULL characters from a string.
|
||||
private static string RemoveNull(string original)
|
||||
{
|
||||
string translated = "";
|
||||
|
@ -260,7 +277,7 @@ namespace BizHawk.MultiClient
|
|||
string signature = System.Text.Encoding.UTF8.GetString(signatureBytes);
|
||||
if (signature.Substring(0, 3) != "FCM")
|
||||
{
|
||||
errorMsg = "This is not a valid FCM file!";
|
||||
errorMsg = "This is not a valid .FCM file.";
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -282,8 +299,8 @@ namespace BizHawk.MultiClient
|
|||
byte[] romCheckSum = r.ReadBytes(16);
|
||||
//TODO: ROM checksum movie header line (MD5)
|
||||
|
||||
uint EmuVersion = r.ReadUInt32();
|
||||
m.Header.Comments.Add("emuOrigin FCEU " + EmuVersion.ToString());
|
||||
uint emuVersion = r.ReadUInt32();
|
||||
m.Header.Comments.Add("emuOrigin FCEU " + emuVersion.ToString());
|
||||
|
||||
List<byte> romBytes = new List<byte>();
|
||||
while (true)
|
||||
|
@ -374,6 +391,73 @@ namespace BizHawk.MultiClient
|
|||
errorMsg = "";
|
||||
warningMsg = "";
|
||||
Movie m = new Movie(Path.ChangeExtension(path, ".tas"), MOVIEMODE.PLAY);
|
||||
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader r = new BinaryReader(fs);
|
||||
// 000 4-byte signature: 46 4D 56 1A "FMV\x1A"
|
||||
string signature = BytesToString(r, 4);
|
||||
if (signature != "FMV\x1A")
|
||||
{
|
||||
errorMsg = "This is not a valid .FMV file.";
|
||||
return null;
|
||||
}
|
||||
// 004 1-byte flags:
|
||||
byte flags = r.ReadByte();
|
||||
/*
|
||||
* bit 7: 0=reset-based, 1=savestate-based
|
||||
* other bits: unknown, set to 0
|
||||
*/
|
||||
if ((int)(flags & 0x80) != 0)
|
||||
{
|
||||
errorMsg = "Movies that begin with a savestate are not supported.";
|
||||
return null;
|
||||
}
|
||||
// 005 1-byte flags:
|
||||
flags = r.ReadByte();
|
||||
/*
|
||||
* bit 5: is a FDS recording
|
||||
* bit 6: uses controller 2
|
||||
* bit 7: uses controller 1
|
||||
* other bits: unknown, set to 0
|
||||
*/
|
||||
bool FDS;
|
||||
if ((int)(flags & 0x20) != 0)
|
||||
{
|
||||
FDS = true;
|
||||
m.Header.SetHeaderLine(MovieHeader.PLATFORM, "FDS");
|
||||
}
|
||||
else
|
||||
{
|
||||
FDS = false;
|
||||
m.Header.SetHeaderLine(MovieHeader.PLATFORM, "NES");
|
||||
}
|
||||
bool controller2 = false;
|
||||
if ((int)(flags & 0x40) != 0)
|
||||
{
|
||||
controller2 = true;
|
||||
}
|
||||
bool controller1 = false;
|
||||
if ((int)(flags & 0x80) != 0)
|
||||
{
|
||||
controller1 = true;
|
||||
}
|
||||
// 006 4-byte little-endian unsigned int: unknown, set to 00000000
|
||||
r.ReadInt32();
|
||||
// 00A 4-byte little-endian unsigned int: rerecord count minus 1
|
||||
uint rerecordCount = r.ReadUInt32();
|
||||
m.SetRerecords(((int)rerecordCount) - 1);
|
||||
// 00E 2-byte little-endian unsigned int: unknown, set to 0000
|
||||
r.ReadInt16();
|
||||
// 010 64-byte zero-terminated emulator identifier string
|
||||
string emuVersion = RemoveNull(BytesToString(r, 64));
|
||||
m.Header.Comments.Add("emuOrigin Famtasia version " + emuVersion);
|
||||
// 050 64-byte zero-terminated movie title string
|
||||
string gameName = RemoveNull(BytesToString(r, 64));
|
||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, gameName);
|
||||
// 090 frame data begins here
|
||||
if (controller1 || controller2 || FDS)
|
||||
{
|
||||
// TODO: Frame data handling.
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -414,24 +498,23 @@ namespace BizHawk.MultiClient
|
|||
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader r = new BinaryReader(fs);
|
||||
// 0000: 4-byte signature: "MMV\0"
|
||||
byte[] signatureBytes = new byte[4];
|
||||
for (int character = 0; character < 4; character++)
|
||||
signatureBytes[character] = r.ReadByte();
|
||||
string signature = System.Text.Encoding.UTF8.GetString(signatureBytes);
|
||||
string signature = BytesToString(r, 4);
|
||||
if (signature != "MMV\0")
|
||||
{
|
||||
errorMsg = "This is not a valid MMV file.";
|
||||
errorMsg = "This is not a valid .MMV file.";
|
||||
return null;
|
||||
}
|
||||
// 0004: 4-byte little endian unsigned int: dega version
|
||||
uint version = r.ReadUInt32();
|
||||
m.Header.Comments.Add("emuOrigin Dega version " + version.ToString());
|
||||
uint emuVersion = r.ReadUInt32();
|
||||
m.Header.Comments.Add("emuOrigin Dega version " + emuVersion.ToString());
|
||||
// 0008: 4-byte little endian unsigned int: frame count
|
||||
uint framecount = r.ReadUInt32();
|
||||
// 000c: 4-byte little endian unsigned int: rerecord count
|
||||
m.SetRerecords((int)r.ReadUInt32());
|
||||
uint rerecordCount = r.ReadUInt32();
|
||||
m.SetRerecords((int)rerecordCount);
|
||||
// 0010: 4-byte little endian flag: begin from reset?
|
||||
if (r.ReadUInt32() == 0)
|
||||
uint reset = r.ReadUInt32();
|
||||
if (reset == 0)
|
||||
{
|
||||
errorMsg = "Movies that begin with a savestate are not supported.";
|
||||
return null;
|
||||
|
@ -443,11 +526,7 @@ namespace BizHawk.MultiClient
|
|||
// 001c: 4-byte little endian unsigned int: size of input packet
|
||||
r.ReadUInt32();
|
||||
// 0020-005f: string: author info (UTF-8)
|
||||
byte[] authorBytes = new byte[64];
|
||||
for (int character = 0; character < 64; character++)
|
||||
authorBytes[character] = r.ReadByte();
|
||||
string author = System.Text.Encoding.UTF8.GetString(authorBytes);
|
||||
author = RemoveNull(author);
|
||||
string author = RemoveNull(BytesToString(r, 64));
|
||||
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author);
|
||||
// 0060: 4-byte little endian flags
|
||||
byte flags = r.ReadByte();
|
||||
|
@ -479,17 +558,10 @@ namespace BizHawk.MultiClient
|
|||
// bits 4-31: unused
|
||||
r.ReadBytes(3);
|
||||
// 0064-00e3: string: rom name (ASCII)
|
||||
byte[] romnameBytes = new byte[128];
|
||||
for (int character = 0; character < 128; character++)
|
||||
romnameBytes[character] = r.ReadByte();
|
||||
string romname = System.Text.Encoding.UTF8.GetString(romnameBytes);
|
||||
romname = RemoveNull(romname);
|
||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, romname);
|
||||
string gameName = RemoveNull(BytesToString(r, 128));
|
||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, gameName);
|
||||
// 00e4-00f3: binary: rom MD5 digest
|
||||
byte[] MD5Bytes = new byte[16];
|
||||
for (int item = 0; item < 16; item++)
|
||||
MD5Bytes[item] = r.ReadByte();
|
||||
string MD5 = string.Concat(MD5Bytes.Select(b => string.Format("{0:x2}", b)));
|
||||
string MD5 = BytesToString(r, 16, true);
|
||||
m.Header.SetHeaderLine("MD5", MD5);
|
||||
/*
|
||||
* 76543210
|
||||
|
@ -502,7 +574,7 @@ namespace BizHawk.MultiClient
|
|||
* bit 6 (0x40): start (Master System)
|
||||
* bit 7 (0x80): start (Game Gear)
|
||||
*/
|
||||
for (int x = 0; x < (framecount); x++)
|
||||
for (int frame = 0; frame < framecount; frame++)
|
||||
{
|
||||
byte controllerstate;
|
||||
SimpleController controllers = new SimpleController();
|
||||
|
@ -544,7 +616,7 @@ namespace BizHawk.MultiClient
|
|||
string signature = System.Text.Encoding.UTF8.GetString(signatureBytes);
|
||||
if (signature.Substring(0, 3) != "SMV")
|
||||
{
|
||||
errorMsg = "This is not a valid SMV file.";
|
||||
errorMsg = "This is not a valid .SMV file.";
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -560,7 +632,7 @@ namespace BizHawk.MultiClient
|
|||
return ImportSMV152(r, path);
|
||||
default:
|
||||
{
|
||||
errorMsg = "SMV version not recognized, 143, 151, and 152 are currently supported";
|
||||
errorMsg = "SMV version not recognized, 143, 151, and 152 are currently supported.";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -652,7 +724,7 @@ namespace BizHawk.MultiClient
|
|||
uint signature = r.ReadUInt32(); //always 56 42 4D 1A (VBM\x1A)
|
||||
if (signature != 0x56424D1A)
|
||||
{
|
||||
errorMsg = "This is not a valid VBM file.";
|
||||
errorMsg = "This is not a valid .VBM file.";
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -662,8 +734,8 @@ namespace BizHawk.MultiClient
|
|||
uint framecount = r.ReadUInt32();
|
||||
|
||||
//0x10
|
||||
uint rerecordcount = r.ReadUInt32();
|
||||
m.SetRerecords((int)rerecordcount);
|
||||
uint rerecordCount = r.ReadUInt32();
|
||||
m.SetRerecords((int)rerecordCount);
|
||||
m.Header.SetHeaderLine(MovieHeader.RERECORDS, m.Rerecords.ToString());
|
||||
Byte moviestartflags = r.ReadByte();
|
||||
|
||||
|
@ -704,7 +776,7 @@ namespace BizHawk.MultiClient
|
|||
|
||||
if (is_gb & is_gbc & is_gba & is_sgb)
|
||||
{
|
||||
errorMsg = "Not a valid VBM platform type.";
|
||||
errorMsg = "Not a valid .VBM platform type.";
|
||||
return null;
|
||||
}
|
||||
//TODO: set platform in header
|
||||
|
@ -726,7 +798,7 @@ namespace BizHawk.MultiClient
|
|||
if ((flags & 0x10) > 0) lagreduction = true;
|
||||
if ((flags & 0x08) > 0)
|
||||
{
|
||||
errorMsg = "Invalid VBM file";
|
||||
errorMsg = "Invalid .VBM file.";
|
||||
return null;
|
||||
}
|
||||
if ((flags & 0x04) > 0) rtcenable = true;
|
||||
|
|
Loading…
Reference in New Issue