-Added the beginning of ImportNMV and ImportVMV.
-Added PAL handling to ImportText. -Finished the header and metadata of ImportFCM. TODO: -Input handling for ImportFCM. -Find out what the format for the FDS data is on FMV, as it occurs to me that I already handle FDS data in ImportText by giving warnings, so I might as well do the same thing in this case. -Figure out whether or not I should be using "using" for the BinaryReader objects, as it seems like they do in fact have .Close() methods.
This commit is contained in:
parent
a60698c03e
commit
39246b2ca5
|
@ -33,6 +33,9 @@ namespace BizHawk.MultiClient
|
|||
case ".GMV":
|
||||
m = ImportGMV(path, out errorMsg, out warningMsg);
|
||||
break;
|
||||
case ".NMV":
|
||||
m = ImportNMV(path, out errorMsg, out warningMsg);
|
||||
break;
|
||||
case ".MCM":
|
||||
m = ImportMCM(path, out errorMsg, out warningMsg);
|
||||
break;
|
||||
|
@ -48,6 +51,9 @@ namespace BizHawk.MultiClient
|
|||
case ".VBM":
|
||||
m = ImportVBM(path, out errorMsg, out warningMsg);
|
||||
break;
|
||||
case ".VMV":
|
||||
m = ImportVMV(path, out errorMsg, out warningMsg);
|
||||
break;
|
||||
}
|
||||
if (errorMsg == "")
|
||||
{
|
||||
|
@ -65,7 +71,9 @@ namespace BizHawk.MultiClient
|
|||
// Return whether or not the type of file provided can currently be imported.
|
||||
public static bool IsValidMovieExtension(string extension)
|
||||
{
|
||||
string[] extensions = new string[9] { "FCM", "FM2", "FMV", "GMV", "MC2", "MMV", "SMV", "TAS", "VBM" };
|
||||
string[] extensions = new string[11] {
|
||||
"FCM", "FM2", "FMV", "GMV", "NMV", "MCM", "MC2", "MMV", "SMV", "VBM", "VMV"
|
||||
};
|
||||
foreach (string ext in extensions)
|
||||
if (extension.ToUpper() == "." + ext)
|
||||
return true;
|
||||
|
@ -117,35 +125,11 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
int lineNum = 0;
|
||||
string line = "";
|
||||
string rerecordCount = "";
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
lineNum++;
|
||||
if (line == "")
|
||||
continue;
|
||||
if (line.Contains("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(rerecordCount));
|
||||
}
|
||||
catch
|
||||
{
|
||||
m.SetRerecords(0);
|
||||
}
|
||||
}
|
||||
else if (line.Contains("StartsFromSavestate"))
|
||||
{
|
||||
line = ParseHeader(line, "StartsFromSavestate");
|
||||
// If this movie starts from a savestate, we can't support it.
|
||||
if (line == "1")
|
||||
{
|
||||
errorMsg = "Movies that begin with a savestate are not supported.";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (line.StartsWith("emuVersion"))
|
||||
m.Header.Comments.Add("emuOrigin " + emulator + " version " + ParseHeader(line, "emuVersion"));
|
||||
else if (line.StartsWith("version"))
|
||||
|
@ -156,8 +140,45 @@ namespace BizHawk.MultiClient
|
|||
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("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.SetRerecords(rerecordCount);
|
||||
}
|
||||
else if (line.StartsWith("guid"))
|
||||
m.Header.SetHeaderLine(MovieHeader.GUID, ParseHeader(line, "GUID"));
|
||||
else if (line.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.";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if (line.StartsWith("palFlag"))
|
||||
{
|
||||
bool pal;
|
||||
// Try to parse the PAL setting as a bool, defaulting to false if it fails.
|
||||
try
|
||||
{
|
||||
pal = Convert.ToBoolean(int.Parse(ParseHeader(line, "palFlag")));
|
||||
}
|
||||
catch
|
||||
{
|
||||
pal = false;
|
||||
}
|
||||
m.Header.SetHeaderLine("PAL", pal.ToString());
|
||||
}
|
||||
else if (line.StartsWith("sub"))
|
||||
{
|
||||
Subtitle s = new Subtitle();
|
||||
|
@ -270,108 +291,110 @@ namespace BizHawk.MultiClient
|
|||
Movie m = new Movie(Path.ChangeExtension(path, ".tas"), MOVIEMODE.PLAY);
|
||||
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader r = new BinaryReader(fs);
|
||||
|
||||
byte[] signatureBytes = new byte[4];
|
||||
for (int x = 0; x < 4; x++)
|
||||
signatureBytes[x] = r.ReadByte();
|
||||
string signature = System.Text.Encoding.UTF8.GetString(signatureBytes);
|
||||
if (signature.Substring(0, 3) != "FCM")
|
||||
// 000 4-byte signature: 46 43 4D 1A "FCM\x1A"
|
||||
string signature = BytesToString(r, 4);
|
||||
if (signature != "FCM\x1A")
|
||||
{
|
||||
errorMsg = "This is not a valid .FCM file.";
|
||||
return null;
|
||||
}
|
||||
|
||||
// 004 4-byte little-endian unsigned int: version number, must be 2
|
||||
uint version = r.ReadUInt32();
|
||||
m.Header.SetHeaderLine(MovieHeader.MovieVersion, "FCEU movie version " + version.ToString() + " (.fcm)");
|
||||
|
||||
byte[] flags = new byte[4];
|
||||
for (int x = 0; x < 4; x++)
|
||||
flags[x] = r.ReadByte();
|
||||
|
||||
m.Header.Comments.Add("MovieOrigin .FCM version " + version);
|
||||
// 008 1-byte flags
|
||||
byte flags = r.ReadByte();
|
||||
/*
|
||||
* bit 0: reserved, set to 0
|
||||
* bit 1:
|
||||
** if "0", movie begins from an embedded "quicksave" snapshot
|
||||
** if "1", movie begins from reset or power-on[1]
|
||||
* bit 2:
|
||||
** if "0", NTSC timing
|
||||
** if "1", PAL timing
|
||||
** see notes below
|
||||
* other: reserved, set to 0
|
||||
*/
|
||||
if ((int)(flags & 2) == 0)
|
||||
{
|
||||
errorMsg = "Movies that begin with a savestate are not supported.";
|
||||
return null;
|
||||
}
|
||||
bool pal = false;
|
||||
if ((int)(flags & 4) != 0)
|
||||
pal = true;
|
||||
m.Header.SetHeaderLine("PAL", pal.ToString());
|
||||
bool movieSyncHackOn = true;
|
||||
if ((int)(flags & 16) != 0)
|
||||
movieSyncHackOn = false;
|
||||
m.Header.SetHeaderLine("SyncHack", movieSyncHackOn.ToString());
|
||||
/*
|
||||
009 1-byte flags: reserved, set to 0
|
||||
00A 1-byte flags: reserved, set to 0
|
||||
00B 1-byte flags: reserved, set to 0
|
||||
*/
|
||||
r.ReadBytes(3);
|
||||
// 00C 4-byte little-endian unsigned int: number of frames
|
||||
uint frameCount = r.ReadUInt32();
|
||||
|
||||
m.SetRerecords((int)r.ReadUInt32());
|
||||
|
||||
// 010 4-byte little-endian unsigned int: rerecord count
|
||||
uint rerecordCount = r.ReadUInt32();
|
||||
m.SetRerecords((int)rerecordCount);
|
||||
// 014 4-byte little-endian unsigned int: length of controller data in bytes
|
||||
uint movieDataSize = r.ReadUInt32();
|
||||
// 018 4-byte little-endian unsigned int: offset to the savestate inside file
|
||||
uint savestateOffset = r.ReadUInt32();
|
||||
// 01C 4-byte little-endian unsigned int: offset to the controller data inside file
|
||||
uint firstFrameOffset = r.ReadUInt32();
|
||||
|
||||
byte[] romCheckSum = r.ReadBytes(16);
|
||||
//TODO: ROM checksum movie header line (MD5)
|
||||
|
||||
// 020 16-byte md5sum of the ROM used
|
||||
string MD5 = BytesToString(r, 16, true);
|
||||
m.Header.SetHeaderLine("MD5", MD5);
|
||||
// 030 4-byte little-endian unsigned int: version of the emulator used
|
||||
uint emuVersion = r.ReadUInt32();
|
||||
m.Header.Comments.Add("emuOrigin FCEU " + emuVersion.ToString());
|
||||
|
||||
List<byte> romBytes = new List<byte>();
|
||||
while (true)
|
||||
// 034 name of the ROM used - UTF8 encoded nul-terminated string.
|
||||
List<byte> gameBytes = new List<byte>();
|
||||
while (r.PeekChar() != 0)
|
||||
{
|
||||
if (r.PeekChar() == 0)
|
||||
break;
|
||||
else
|
||||
romBytes.Add(r.ReadByte());
|
||||
gameBytes.Add(r.ReadByte());
|
||||
}
|
||||
string rom = System.Text.Encoding.UTF8.GetString(romBytes.ToArray());
|
||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, rom);
|
||||
|
||||
r.ReadByte(); //Advance past null byte
|
||||
|
||||
// Advance past null byte.
|
||||
r.ReadByte();
|
||||
string gameName = System.Text.Encoding.UTF8.GetString(gameBytes.ToArray());
|
||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, gameName);
|
||||
/*
|
||||
After the header comes "metadata", which is UTF8-coded movie title string. The metadata begins after the ROM name
|
||||
and ends at the savestate offset. This string is displayed as "Author Info" in the Windows version of the
|
||||
emulator.
|
||||
*/
|
||||
List<byte> authorBytes = new List<byte>();
|
||||
while (true)
|
||||
while (r.PeekChar() != 0)
|
||||
{
|
||||
if (r.PeekChar() == 0)
|
||||
break;
|
||||
else
|
||||
authorBytes.Add(r.ReadByte());
|
||||
authorBytes.Add(r.ReadByte());
|
||||
}
|
||||
// Advance past null byte.
|
||||
r.ReadByte();
|
||||
string author = System.Text.Encoding.UTF8.GetString(authorBytes.ToArray());
|
||||
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author);
|
||||
|
||||
r.ReadByte(); //Advance past null byte
|
||||
|
||||
bool movieSyncHackOn = true;
|
||||
if ((int)(flags[0] & 16) > 0)
|
||||
movieSyncHackOn = false;
|
||||
|
||||
bool pal = false;
|
||||
if ((int)(flags[0] & 4) > 0)
|
||||
pal = true;
|
||||
|
||||
m.Header.SetHeaderLine("SyncHack", movieSyncHackOn.ToString());
|
||||
m.Header.SetHeaderLine("PAL", pal.ToString());
|
||||
|
||||
//Power on vs reset
|
||||
if ((int)(flags[0] & 8) > 0)
|
||||
{ } //Power-on = default
|
||||
else if ((int)(flags[0] & 2) > 0)
|
||||
{ } //we don't support start from reset, do some kind of notification here
|
||||
else
|
||||
{ } //this movie starts from savestate, freak out here
|
||||
|
||||
//Advance to first byte of input data
|
||||
//byte[] throwaway = new byte[firstFrameOffset];
|
||||
//r.Read(throwaway, 0, (int)firstFrameOffset);
|
||||
// Advance to first byte of input data
|
||||
// byte[] throwaway = new byte[firstFrameOffset];
|
||||
// r.Read(throwaway, 0, (int)firstFrameOffset);
|
||||
r.BaseStream.Position = firstFrameOffset;
|
||||
//moviedatasize stuff
|
||||
|
||||
//read frame data
|
||||
//TODO: special commands like fds disk switch, etc, and power/reset
|
||||
|
||||
//TODO: use stringbuilder class for speed
|
||||
//string ButtonLookup = "RLDUSsBARLDUSsBARLDUSsBARLDUSsBA"; //TODO: This assumes input data is the same in fcm as bizhawk, which it isn't
|
||||
string frame = "|0|"; //TODO: read reset command rather than hard code it off
|
||||
for (int x = 0; x < frameCount; x++)
|
||||
// moviedatasize stuff
|
||||
// read frame data
|
||||
// TODO: special commands like fds disk switch, etc, and power/reset
|
||||
// TODO: use stringbuilder class for speed
|
||||
// string ButtonLookup = "RLDUSsBARLDUSsBARLDUSsBARLDUSsBA"; //TODO: This assumes input data is the same in fcm as bizhawk, which it isn't
|
||||
// string frame = "|0|"; //TODO: read reset command rather than hard code it off
|
||||
for (int frame = 0; frame < frameCount; frame++)
|
||||
{
|
||||
/*
|
||||
byte joy = r.ReadByte();
|
||||
|
||||
//Read each byte of controller one data
|
||||
|
||||
// Read each byte of controller one data
|
||||
frame += "|";
|
||||
|
||||
r.ReadBytes(3); //Lose remaining controllers for now
|
||||
m.AppendFrame(frame);
|
||||
m.AppendFrame("Test");
|
||||
*/
|
||||
}
|
||||
|
||||
//set 4 score flag if necessary
|
||||
// set 4 score flag if necessary
|
||||
r.Close();
|
||||
return m;
|
||||
}
|
||||
|
@ -466,7 +489,7 @@ namespace BizHawk.MultiClient
|
|||
The file format has no means of identifying NTSC/PAL. It is always assumed that the game is NTSC - that is, 60
|
||||
fps.
|
||||
*/
|
||||
m.Header.SetHeaderLine("NTSC", "True");
|
||||
m.Header.SetHeaderLine("PAL", "False");
|
||||
/*
|
||||
090 frame data begins here
|
||||
The file has no terminator byte or frame count. The number of frames is the <filesize minus 144> divided by
|
||||
|
@ -515,7 +538,7 @@ namespace BizHawk.MultiClient
|
|||
byte and = 0x1;
|
||||
for (int button = 0; button < buttons.Length; button++)
|
||||
{
|
||||
controllers["P" + player + " " + buttons[button]] = ((int)(controllerstate & and) > 0);
|
||||
controllers["P" + player + " " + buttons[button]] = ((int)(controllerstate & and) != 0);
|
||||
and <<= 1;
|
||||
}
|
||||
}
|
||||
|
@ -541,6 +564,24 @@ namespace BizHawk.MultiClient
|
|||
return m;
|
||||
}
|
||||
|
||||
// NMV file format: http://tasvideos.org/NMV.html
|
||||
private static Movie ImportNMV(string path, out string errorMsg, out string warningMsg)
|
||||
{
|
||||
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: 4E 53 53 1A "NSS\x1A"
|
||||
string signature = BytesToString(r, 4);
|
||||
if (signature != "NSS\x1A")
|
||||
{
|
||||
errorMsg = "This is not a valid .NMV file.";
|
||||
return null;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
// MCM file format: http://code.google.com/p/mednafen-rr/wiki/MCM
|
||||
private static Movie ImportMCM(string path, out string errorMsg, out string warningMsg)
|
||||
{
|
||||
|
@ -579,7 +620,7 @@ namespace BizHawk.MultiClient
|
|||
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();
|
||||
uint frameCount = r.ReadUInt32();
|
||||
// 000c: 4-byte little endian unsigned int: rerecord count
|
||||
uint rerecordCount = r.ReadUInt32();
|
||||
m.SetRerecords((int)rerecordCount);
|
||||
|
@ -608,15 +649,15 @@ namespace BizHawk.MultiClient
|
|||
* bit 3: Game Gear (version 1.16+)
|
||||
*/
|
||||
bool pal = false;
|
||||
if ((int)(flags & 2) > 0)
|
||||
if ((int)(flags & 2) != 0)
|
||||
pal = true;
|
||||
m.Header.SetHeaderLine("PAL", pal.ToString());
|
||||
bool japan = false;
|
||||
if ((int)(flags & 4) > 0)
|
||||
if ((int)(flags & 4) != 0)
|
||||
japan = true;
|
||||
m.Header.SetHeaderLine("Japan", japan.ToString());
|
||||
bool gamegear;
|
||||
if ((int)(flags & 8) > 0)
|
||||
if ((int)(flags & 8) != 0)
|
||||
{
|
||||
gamegear = true;
|
||||
m.Header.SetHeaderLine(MovieHeader.PLATFORM, "GG");
|
||||
|
@ -634,14 +675,14 @@ namespace BizHawk.MultiClient
|
|||
// 00e4-00f3: binary: rom MD5 digest
|
||||
string MD5 = BytesToString(r, 16, true);
|
||||
m.Header.SetHeaderLine("MD5", MD5);
|
||||
for (int frame = 0; frame < framecount; frame++)
|
||||
for (int frame = 0; frame < frameCount; frame++)
|
||||
{
|
||||
byte controllerstate;
|
||||
SimpleController controllers = new SimpleController();
|
||||
controllers.Type = new ControllerDefinition();
|
||||
controllers.Type.Name = "SMS Controller";
|
||||
/*
|
||||
* 76543210
|
||||
76543210
|
||||
* bit 0 (0x01): up
|
||||
* bit 1 (0x02): down
|
||||
* bit 2 (0x04): left
|
||||
|
@ -660,16 +701,16 @@ namespace BizHawk.MultiClient
|
|||
for (int player = 1; player <= 2; player++)
|
||||
{
|
||||
controllerstate = r.ReadByte();
|
||||
byte and = 0x1;
|
||||
byte and = 1;
|
||||
for (int button = 0; button < buttons.Length; button++)
|
||||
{
|
||||
controllers["P" + player + " " + buttons[button]] = ((int)(controllerstate & and) > 0);
|
||||
controllers["P" + player + " " + buttons[button]] = ((int)(controllerstate & and) != 0);
|
||||
and <<= 1;
|
||||
}
|
||||
if (player == 1)
|
||||
controllers["Pause"] = (
|
||||
((int)(controllerstate & 0x40) > 0 && (!gamegear)) ||
|
||||
((int)(controllerstate & 0x80) > 0 && gamegear)
|
||||
((int)(controllerstate & 0x40) != 0 && (!gamegear)) ||
|
||||
((int)(controllerstate & 0x80) != 0 && gamegear)
|
||||
);
|
||||
}
|
||||
MnemonicsGenerator mg = new MnemonicsGenerator();
|
||||
|
@ -723,17 +764,17 @@ namespace BizHawk.MultiClient
|
|||
m.Header.SetHeaderLine(MovieHeader.GUID, GUID.ToString()); //TODO: format to hex string
|
||||
m.SetRerecords((int)r.ReadUInt32());
|
||||
|
||||
uint framecount = r.ReadUInt32();
|
||||
uint frameCount = r.ReadUInt32();
|
||||
byte ControllerFlags = r.ReadByte();
|
||||
|
||||
int numControllers;
|
||||
if ((int)(ControllerFlags & 16) > 0)
|
||||
if ((int)(ControllerFlags & 16) != 0)
|
||||
numControllers = 5;
|
||||
else if ((int)(ControllerFlags & 8) > 0)
|
||||
else if ((int)(ControllerFlags & 8) != 0)
|
||||
numControllers = 4;
|
||||
else if ((int)(ControllerFlags & 4) > 0)
|
||||
else if ((int)(ControllerFlags & 4) != 0)
|
||||
numControllers = 3;
|
||||
else if ((int)(ControllerFlags & 2) > 0)
|
||||
else if ((int)(ControllerFlags & 2) != 0)
|
||||
numControllers = 2;
|
||||
else
|
||||
numControllers = 1;
|
||||
|
@ -743,7 +784,7 @@ namespace BizHawk.MultiClient
|
|||
if ((int)(MovieFlags & 1) == 0)
|
||||
return null; //TODO: Savestate movies not supported error
|
||||
|
||||
if ((int)(MovieFlags & 2) > 0)
|
||||
if ((int)(MovieFlags & 2) != 0)
|
||||
{
|
||||
m.Header.SetHeaderLine("PAL", "True");
|
||||
}
|
||||
|
@ -758,7 +799,7 @@ namespace BizHawk.MultiClient
|
|||
//TODO: get extra rom info
|
||||
|
||||
r.BaseStream.Position = FrameDataOffset;
|
||||
for (int x = 0; x < framecount; x++)
|
||||
for (int x = 0; x < frameCount; x++)
|
||||
{
|
||||
//TODO: FF FF for all controllers = Reset
|
||||
//string frame = "|0|";
|
||||
|
@ -807,7 +848,7 @@ namespace BizHawk.MultiClient
|
|||
uint versionno = r.ReadUInt32(); //always 1
|
||||
uint uid = r.ReadUInt32(); //time of recording
|
||||
m.Header.SetHeaderLine(MovieHeader.GUID, uid.ToString());
|
||||
uint framecount = r.ReadUInt32();
|
||||
uint frameCount = r.ReadUInt32();
|
||||
|
||||
//0x10
|
||||
uint rerecordCount = r.ReadUInt32();
|
||||
|
@ -818,8 +859,8 @@ namespace BizHawk.MultiClient
|
|||
bool startfromquicksave = false;
|
||||
bool startfromsram = false;
|
||||
|
||||
if ((moviestartflags & 0x01) > 0) startfromquicksave = true;
|
||||
if ((moviestartflags & 0x02) > 0) startfromsram = true;
|
||||
if ((moviestartflags & 0x01) != 0) startfromquicksave = true;
|
||||
if ((moviestartflags & 0x02) != 0) startfromsram = true;
|
||||
|
||||
if (startfromquicksave & startfromsram)
|
||||
{
|
||||
|
@ -832,9 +873,9 @@ namespace BizHawk.MultiClient
|
|||
|
||||
int numControllers; //number of controllers changes for SGB
|
||||
|
||||
if ((controllerflags & 0x08) > 0) numControllers = 4;
|
||||
else if ((controllerflags & 0x04) > 0) numControllers = 3;
|
||||
else if ((controllerflags & 0x02) > 0) numControllers = 2;
|
||||
if ((controllerflags & 0x08) != 0) numControllers = 4;
|
||||
else if ((controllerflags & 0x04) != 0) numControllers = 3;
|
||||
else if ((controllerflags & 0x02) != 0) numControllers = 2;
|
||||
else numControllers = 1;
|
||||
|
||||
//0x16
|
||||
|
@ -845,9 +886,9 @@ namespace BizHawk.MultiClient
|
|||
bool is_sgb = false;
|
||||
bool is_gb = false;
|
||||
|
||||
if ((systemflags & 0x04) > 0) is_sgb = true;
|
||||
if ((systemflags & 0x02) > 0) is_gbc = true;
|
||||
if ((systemflags & 0x01) > 0) is_gba = true;
|
||||
if ((systemflags & 0x04) != 0) is_sgb = true;
|
||||
if ((systemflags & 0x02) != 0) is_gbc = true;
|
||||
if ((systemflags & 0x01) != 0) is_gba = true;
|
||||
else is_gb = true;
|
||||
|
||||
if (is_gb & is_gbc & is_gba & is_sgb)
|
||||
|
@ -869,17 +910,17 @@ namespace BizHawk.MultiClient
|
|||
bool skipbiosfile = false;
|
||||
bool usebiosfile = false;
|
||||
|
||||
if ((flags & 0x40) > 0) echoramfix = true;
|
||||
if ((flags & 0x20) > 0) gbchdma5fix = true;
|
||||
if ((flags & 0x10) > 0) lagreduction = true;
|
||||
if ((flags & 0x08) > 0)
|
||||
if ((flags & 0x40) != 0) echoramfix = true;
|
||||
if ((flags & 0x20) != 0) gbchdma5fix = true;
|
||||
if ((flags & 0x10) != 0) lagreduction = true;
|
||||
if ((flags & 0x08) != 0)
|
||||
{
|
||||
errorMsg = "Invalid .VBM file.";
|
||||
return null;
|
||||
}
|
||||
if ((flags & 0x04) > 0) rtcenable = true;
|
||||
if ((flags & 0x02) > 0) skipbiosfile = true;
|
||||
if ((flags & 0x01) > 0) usebiosfile = true;
|
||||
if ((flags & 0x04) != 0) rtcenable = true;
|
||||
if ((flags & 0x02) != 0) skipbiosfile = true;
|
||||
if ((flags & 0x01) != 0) usebiosfile = true;
|
||||
|
||||
//0x18
|
||||
uint winsavetype = r.ReadUInt32();
|
||||
|
@ -917,7 +958,7 @@ namespace BizHawk.MultiClient
|
|||
//TODO: implement start data. There are no specifics on the googlecode page as to how long
|
||||
//the SRAM or savestate should be.
|
||||
|
||||
uint framesleft = framecount;
|
||||
uint framesleft = frameCount;
|
||||
|
||||
r.BaseStream.Position = controllerdataoffset; //advances to controller data.
|
||||
|
||||
|
@ -928,14 +969,14 @@ namespace BizHawk.MultiClient
|
|||
controllers.Type.Name = "Gameboy Controller";
|
||||
string[] buttons = new string[8] {"A", "B", "Select", "Start", "Right", "Left", "Up", "Down"};
|
||||
|
||||
for (int frame = 1; frame <= framecount; frame++)
|
||||
for (int frame = 1; frame <= frameCount; frame++)
|
||||
{
|
||||
ushort controllerstate = r.ReadUInt16();
|
||||
// TODO: reset, GBA buttons go here
|
||||
byte and = 0x1;
|
||||
for (int button = 0; button < buttons.Length; button++)
|
||||
{
|
||||
controllers["P1 " + buttons[button]] = ((int)(controllerstate & and) > 0);
|
||||
controllers["P1 " + buttons[button]] = ((int)(controllerstate & and) != 0);
|
||||
and <<= 1;
|
||||
}
|
||||
}
|
||||
|
@ -944,5 +985,23 @@ namespace BizHawk.MultiClient
|
|||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||
return m;
|
||||
}
|
||||
|
||||
// VMV file format: http://tasvideos.org/VMV.html
|
||||
private static Movie ImportVMV(string path, out string errorMsg, out string warningMsg)
|
||||
{
|
||||
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 12-byte signature: "VirtuaNES MV"
|
||||
string signature = BytesToString(r, 12);
|
||||
if (signature != "VirtuaNES MV")
|
||||
{
|
||||
errorMsg = "This is not a valid .VMV file.";
|
||||
return null;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue