-Controller type for GBA.
-Cleanup (adelikat inspired me to always use braces).
This commit is contained in:
parent
e449ab34fd
commit
a346389c2f
|
@ -62,7 +62,7 @@ namespace BizHawk.MultiClient
|
||||||
"GBA Controller", new Dictionary<string, string>()
|
"GBA Controller", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{"Up", "U"}, {"Down", "D"}, {"Left", "L"}, {"Right", "R"}, {"Select", "s"}, {"Start", "S"}, {"B", "B"},
|
{"Up", "U"}, {"Down", "D"}, {"Left", "L"}, {"Right", "R"}, {"Select", "s"}, {"Start", "S"}, {"B", "B"},
|
||||||
{"A", "A"}, {"L", "L"}, {"R", "R"},
|
{"A", "A"}, {"L", "L"}, {"R", "R"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -83,7 +83,7 @@ namespace BizHawk.MultiClient
|
||||||
"SNES Controller", new Dictionary<string, string>()
|
"SNES Controller", new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{"Up", "U"}, {"Down", "D"}, {"Left", "L"}, {"Right", "R"}, {"Select", "s"}, {"Start", "S"}, {"B", "B"},
|
{"Up", "U"}, {"Down", "D"}, {"Left", "L"}, {"Right", "R"}, {"Select", "s"}, {"Start", "S"}, {"B", "B"},
|
||||||
{"A", "A"}, {"X", "X"}, {"Y", "Y"}, {"L", "L"}, {"R", "R"},
|
{"A", "A"}, {"X", "X"}, {"Y", "Y"}, {"L", "L"}, {"R", "R"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -160,9 +160,8 @@ namespace BizHawk.MultiClient
|
||||||
|
|
||||||
public static readonly Dictionary<string, int> PLAYERS = new Dictionary<string, int>()
|
public static readonly Dictionary<string, int> PLAYERS = new Dictionary<string, int>()
|
||||||
{
|
{
|
||||||
{"Gameboy Controller", 1}, {"Genesis 3-Button Controller", 2}, {"NES Controller", 4},
|
{"Gameboy Controller", 1}, {"GBA Controller", 1}, {"Genesis 3-Button Controller", 2}, {"NES Controller", 4},
|
||||||
{"SNES Controller", 4},
|
{"SNES Controller", 4}, {"PC Engine Controller", 5}, {"SMS Controller", 2}, {"TI83 Controller", 1}, {"Atari 2600 Basic Controller", 2},
|
||||||
{"PC Engine Controller", 5}, {"SMS Controller", 2}, {"TI83 Controller", 1}, {"Atari 2600 Basic Controller", 2},
|
|
||||||
{"ColecoVision Basic Controller", 2}, {"Commodore 64 Controller", 2}
|
{"ColecoVision Basic Controller", 2}, {"Commodore 64 Controller", 2}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,12 @@ namespace BizHawk.MultiClient
|
||||||
"FCM", "FM2", "FMV", "GMV", "MCM", "MC2", "MMV", "NMV", "LSMV", "SMV", "VBM", "VMV", "ZMV"
|
"FCM", "FM2", "FMV", "GMV", "MCM", "MC2", "MMV", "NMV", "LSMV", "SMV", "VBM", "VMV", "ZMV"
|
||||||
};
|
};
|
||||||
foreach (string ext in extensions)
|
foreach (string ext in extensions)
|
||||||
|
{
|
||||||
if (extension.ToUpper() == "." + ext)
|
if (extension.ToUpper() == "." + ext)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +174,9 @@ namespace BizHawk.MultiClient
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
if (m.Frames != 0)
|
if (m.Frames != 0)
|
||||||
|
{
|
||||||
warningMsg = "hard reset";
|
warningMsg = "hard reset";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '4':
|
case '4':
|
||||||
warningMsg = "FDS Insert";
|
warningMsg = "FDS Insert";
|
||||||
|
@ -183,7 +189,9 @@ namespace BizHawk.MultiClient
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (warningMsg != "")
|
if (warningMsg != "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to import " + warningMsg + " command on line " + lineNum + ".";
|
warningMsg = "Unable to import " + warningMsg + " command on line " + lineNum + ".";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Path.GetExtension(path).ToUpper() == ".LSMV" && sections.Length != 0)
|
if (Path.GetExtension(path).ToUpper() == ".LSMV" && sections.Length != 0)
|
||||||
|
@ -201,7 +209,9 @@ namespace BizHawk.MultiClient
|
||||||
if (reset && ((flags.Length >= 2 && flags[1] != '0') || (flags.Length >= 4 && flags[3] != '0')))
|
if (reset && ((flags.Length >= 2 && flags[1] != '0') || (flags.Length >= 4 && flags[3] != '0')))
|
||||||
{
|
{
|
||||||
if (warningMsg == "")
|
if (warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to import delayed reset.";
|
warningMsg = "Unable to import delayed reset.";
|
||||||
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
controllers["Reset"] = reset;
|
controllers["Reset"] = reset;
|
||||||
|
@ -227,15 +237,21 @@ namespace BizHawk.MultiClient
|
||||||
string prefix = "P" + (player).ToString() + " ";
|
string prefix = "P" + (player).ToString() + " ";
|
||||||
// Gameboy doesn't currently have a prefix saying which player the input is for.
|
// Gameboy doesn't currently have a prefix saying which player the input is for.
|
||||||
if (controllers.Type.Name == "Gameboy Controller")
|
if (controllers.Type.Name == "Gameboy Controller")
|
||||||
|
{
|
||||||
prefix = "";
|
prefix = "";
|
||||||
|
}
|
||||||
// Only count lines with that have the right number of buttons and are for valid players.
|
// Only count lines with that have the right number of buttons and are for valid players.
|
||||||
if (
|
if (
|
||||||
sections[section].Length == buttons.Length &&
|
sections[section].Length == buttons.Length &&
|
||||||
player <= Global.PLAYERS[controllers.Type.Name]
|
player <= Global.PLAYERS[controllers.Type.Name]
|
||||||
)
|
)
|
||||||
|
{
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
// Consider the button pressed so long as its spot is not occupied by a ".".
|
// Consider the button pressed so long as its spot is not occupied by a ".".
|
||||||
controllers[prefix + buttons[button]] = (sections[section][button] != '.');
|
controllers[prefix + buttons[button]] = (sections[section][button] != '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Convert the data for the controllers to a mnemonic and add it as a frame.
|
// Convert the data for the controllers to a mnemonic and add it as a frame.
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
|
@ -300,7 +316,9 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
lineNum++;
|
lineNum++;
|
||||||
if (line == "")
|
if (line == "")
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
else if (line[0] == '|')
|
else if (line[0] == '|')
|
||||||
{
|
{
|
||||||
m = ImportTextFrame(line, lineNum, m, path, platform, ref warningMsg, ref errorMsg);
|
m = ImportTextFrame(line, lineNum, m, path, platform, ref warningMsg, ref errorMsg);
|
||||||
|
@ -311,11 +329,15 @@ namespace BizHawk.MultiClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (line.ToLower().StartsWith("sub"))
|
else if (line.ToLower().StartsWith("sub"))
|
||||||
|
{
|
||||||
m = ImportTextSubtitle(line, m, path);
|
m = ImportTextSubtitle(line, m, path);
|
||||||
|
}
|
||||||
else if (line.ToLower().StartsWith("emuversion"))
|
else if (line.ToLower().StartsWith("emuversion"))
|
||||||
|
{
|
||||||
m.Header.Comments.Add(
|
m.Header.Comments.Add(
|
||||||
EMULATIONORIGIN + " " + emulator + " version " + ParseHeader(line, "emuVersion")
|
EMULATIONORIGIN + " " + emulator + " version " + ParseHeader(line, "emuVersion")
|
||||||
);
|
);
|
||||||
|
}
|
||||||
else if (line.ToLower().StartsWith("version"))
|
else if (line.ToLower().StartsWith("version"))
|
||||||
{
|
{
|
||||||
string version = ParseHeader(line, "version");
|
string version = ParseHeader(line, "version");
|
||||||
|
@ -330,18 +352,26 @@ namespace BizHawk.MultiClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (line.ToLower().StartsWith("romfilename"))
|
else if (line.ToLower().StartsWith("romfilename"))
|
||||||
|
{
|
||||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, ParseHeader(line, "romFilename"));
|
m.Header.SetHeaderLine(MovieHeader.GAMENAME, ParseHeader(line, "romFilename"));
|
||||||
|
}
|
||||||
else if (line.ToLower().StartsWith("romchecksum"))
|
else if (line.ToLower().StartsWith("romchecksum"))
|
||||||
{
|
{
|
||||||
string blob = ParseHeader(line, "romChecksum");
|
string blob = ParseHeader(line, "romChecksum");
|
||||||
byte[] md5 = DecodeBlob(blob);
|
byte[] md5 = DecodeBlob(blob);
|
||||||
if (md5 != null && md5.Length == 16)
|
if (md5 != null && md5.Length == 16)
|
||||||
|
{
|
||||||
m.Header.SetHeaderLine(MD5, BizHawk.Util.BytesToHexString(md5).ToLower());
|
m.Header.SetHeaderLine(MD5, BizHawk.Util.BytesToHexString(md5).ToLower());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
warningMsg = "Bad ROM checksum.";
|
warningMsg = "Bad ROM checksum.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (line.ToLower().StartsWith("comment author"))
|
else if (line.ToLower().StartsWith("comment author"))
|
||||||
|
{
|
||||||
m.Header.SetHeaderLine(MovieHeader.AUTHOR, ParseHeader(line, "comment author"));
|
m.Header.SetHeaderLine(MovieHeader.AUTHOR, ParseHeader(line, "comment author"));
|
||||||
|
}
|
||||||
else if (line.ToLower().StartsWith("rerecordcount"))
|
else if (line.ToLower().StartsWith("rerecordcount"))
|
||||||
{
|
{
|
||||||
int rerecordCount;
|
int rerecordCount;
|
||||||
|
@ -357,7 +387,9 @@ namespace BizHawk.MultiClient
|
||||||
m.Rerecords = rerecordCount;
|
m.Rerecords = rerecordCount;
|
||||||
}
|
}
|
||||||
else if (line.ToLower().StartsWith("guid"))
|
else if (line.ToLower().StartsWith("guid"))
|
||||||
|
{
|
||||||
m.Header.SetHeaderLine(MovieHeader.GUID, ParseHeader(line, "guid"));
|
m.Header.SetHeaderLine(MovieHeader.GUID, ParseHeader(line, "guid"));
|
||||||
|
}
|
||||||
else if (line.ToLower().StartsWith("startsfromsavestate"))
|
else if (line.ToLower().StartsWith("startsfromsavestate"))
|
||||||
{
|
{
|
||||||
// If this movie starts from a savestate, we can't support it.
|
// If this movie starts from a savestate, we can't support it.
|
||||||
|
@ -371,7 +403,7 @@ namespace BizHawk.MultiClient
|
||||||
else if (line.ToLower().StartsWith("palflag"))
|
else if (line.ToLower().StartsWith("palflag"))
|
||||||
{
|
{
|
||||||
bool pal = (ParseHeader(line, "palFlag") == "1");
|
bool pal = (ParseHeader(line, "palFlag") == "1");
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
}
|
}
|
||||||
else if (line.ToLower().StartsWith("fourscore"))
|
else if (line.ToLower().StartsWith("fourscore"))
|
||||||
{
|
{
|
||||||
|
@ -402,14 +434,21 @@ namespace BizHawk.MultiClient
|
||||||
private static byte[] DecodeBlob(string blob)
|
private static byte[] DecodeBlob(string blob)
|
||||||
{
|
{
|
||||||
if (blob.Length < 2)
|
if (blob.Length < 2)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
if (blob[0] == '0' && (blob[1] == 'x' || blob[1] == 'X'))
|
if (blob[0] == '0' && (blob[1] == 'x' || blob[1] == 'X'))
|
||||||
|
{
|
||||||
// hex
|
// hex
|
||||||
return BizHawk.Util.HexStringToBytes(blob.Substring(2));
|
return BizHawk.Util.HexStringToBytes(blob.Substring(2));
|
||||||
else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// base64
|
// base64
|
||||||
if(!blob.ToLower().StartsWith("base64:"))
|
if (!blob.ToLower().StartsWith("base64:"))
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Convert.FromBase64String(blob.Substring(7));
|
return Convert.FromBase64String(blob.Substring(7));
|
||||||
|
@ -426,7 +465,9 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
int pos = str.IndexOf('\0');
|
int pos = str.IndexOf('\0');
|
||||||
if (pos != -1)
|
if (pos != -1)
|
||||||
|
{
|
||||||
str = str.Substring(0, pos);
|
str = str.Substring(0, pos);
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,7 +522,7 @@ namespace BizHawk.MultiClient
|
||||||
preference. This means that this site cannot calculate movie lengths reliably.
|
preference. This means that this site cannot calculate movie lengths reliably.
|
||||||
*/
|
*/
|
||||||
bool pal = (((flags >> 2) & 0x1) != 0);
|
bool pal = (((flags >> 2) & 0x1) != 0);
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
// other: reserved, set to 0
|
// other: reserved, set to 0
|
||||||
bool syncHack = (((flags >> 4) & 0x1) != 0);
|
bool syncHack = (((flags >> 4) & 0x1) != 0);
|
||||||
m.Header.Comments.Add(SYNCHACK + " " + syncHack.ToString());
|
m.Header.Comments.Add(SYNCHACK + " " + syncHack.ToString());
|
||||||
|
@ -561,7 +602,9 @@ namespace BizHawk.MultiClient
|
||||||
65536-(2^24-1) 3
|
65536-(2^24-1) 3
|
||||||
*/
|
*/
|
||||||
for (int b = 0; b < delta; b++)
|
for (int b = 0; b < delta; b++)
|
||||||
|
{
|
||||||
frames += r.ReadByte() * (int)Math.Pow(2, b * 8);
|
frames += r.ReadByte() * (int)Math.Pow(2, b * 8);
|
||||||
|
}
|
||||||
frame += frames;
|
frame += frames;
|
||||||
while (frames > 0)
|
while (frames > 0)
|
||||||
{
|
{
|
||||||
|
@ -595,7 +638,9 @@ namespace BizHawk.MultiClient
|
||||||
case 2:
|
case 2:
|
||||||
reset = true;
|
reset = true;
|
||||||
if (frame != 1)
|
if (frame != 1)
|
||||||
|
{
|
||||||
warningMsg = "hard reset";
|
warningMsg = "hard reset";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// VS System Insert Coin
|
// VS System Insert Coin
|
||||||
case 7:
|
case 7:
|
||||||
|
@ -625,7 +670,9 @@ namespace BizHawk.MultiClient
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (warningMsg != "")
|
if (warningMsg != "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to import " + warningMsg + " command at frame " + frame + ".";
|
warningMsg = "Unable to import " + warningMsg + " command at frame " + frame + ".";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
1 Even if the header says "movie begins from reset", the file still contains a quicksave, and the
|
1 Even if the header says "movie begins from reset", the file still contains a quicksave, and the
|
||||||
|
@ -649,7 +696,9 @@ namespace BizHawk.MultiClient
|
||||||
*/
|
*/
|
||||||
int player = ((update >> 3) & 0x3) + 1;
|
int player = ((update >> 3) & 0x3) + 1;
|
||||||
if (player > 2)
|
if (player > 2)
|
||||||
|
{
|
||||||
fourscore = true;
|
fourscore = true;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
ccc:
|
ccc:
|
||||||
* 0 A
|
* 0 A
|
||||||
|
@ -762,7 +811,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,
|
The file format has no means of identifying NTSC/"PAL". It is always assumed that the game is NTSC - that is,
|
||||||
60 fps.
|
60 fps.
|
||||||
*/
|
*/
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, "False");
|
m.Header.SetHeaderLine(MovieHeader.PAL, "False");
|
||||||
// 090 frame data begins here
|
// 090 frame data begins here
|
||||||
SimpleController controllers = new SimpleController();
|
SimpleController controllers = new SimpleController();
|
||||||
controllers.Type = new ControllerDefinition();
|
controllers.Type = new ControllerDefinition();
|
||||||
|
@ -786,8 +835,12 @@ namespace BizHawk.MultiClient
|
||||||
*/
|
*/
|
||||||
int bytesPerFrame = 0;
|
int bytesPerFrame = 0;
|
||||||
for (int player = 1; player <= masks.Length; player++)
|
for (int player = 1; player <= masks.Length; player++)
|
||||||
|
{
|
||||||
if (masks[player - 1])
|
if (masks[player - 1])
|
||||||
|
{
|
||||||
bytesPerFrame++;
|
bytesPerFrame++;
|
||||||
|
}
|
||||||
|
}
|
||||||
long frameCount = (fs.Length - 144) / bytesPerFrame;
|
long frameCount = (fs.Length - 144) / bytesPerFrame;
|
||||||
for (long frame = 1; frame <= frameCount; frame++)
|
for (long frame = 1; frame <= frameCount; frame++)
|
||||||
{
|
{
|
||||||
|
@ -799,13 +852,21 @@ namespace BizHawk.MultiClient
|
||||||
for (int player = 1; player <= masks.Length; player++)
|
for (int player = 1; player <= masks.Length; player++)
|
||||||
{
|
{
|
||||||
if (!masks[player - 1])
|
if (!masks[player - 1])
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
byte controllerState = r.ReadByte();
|
byte controllerState = r.ReadByte();
|
||||||
if (player != 3)
|
if (player != 3)
|
||||||
|
{
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
warningMsg = "FDS commands are not properly supported.";
|
warningMsg = "FDS commands are not properly supported.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
|
@ -845,7 +906,9 @@ namespace BizHawk.MultiClient
|
||||||
// 015 ASCII-encoded controller config for player 2. '3' or '6'.
|
// 015 ASCII-encoded controller config for player 2. '3' or '6'.
|
||||||
string player2Config = r.ReadStringFixedAscii(1);
|
string player2Config = r.ReadStringFixedAscii(1);
|
||||||
if (player1Config == "6" || player2Config == "6")
|
if (player1Config == "6" || player2Config == "6")
|
||||||
|
{
|
||||||
warningMsg = "6 button controllers are not properly supported.";
|
warningMsg = "6 button controllers are not properly supported.";
|
||||||
|
}
|
||||||
// 016 special flags (Version A and up only)
|
// 016 special flags (Version A and up only)
|
||||||
byte flags = r.ReadByte();
|
byte flags = r.ReadByte();
|
||||||
/*
|
/*
|
||||||
|
@ -854,7 +917,7 @@ namespace BizHawk.MultiClient
|
||||||
header.
|
header.
|
||||||
*/
|
*/
|
||||||
bool pal = (((flags >> 7) & 0x1) != 0);
|
bool pal = (((flags >> 7) & 0x1) != 0);
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
// bit 6: if "1", movie requires a savestate.
|
// bit 6: if "1", movie requires a savestate.
|
||||||
if (((flags >> 6) & 0x1) != 0)
|
if (((flags >> 6) & 0x1) != 0)
|
||||||
{
|
{
|
||||||
|
@ -911,16 +974,26 @@ namespace BizHawk.MultiClient
|
||||||
byte controllerState = r.ReadByte();
|
byte controllerState = r.ReadByte();
|
||||||
// * is controller 3 if a 3-player movie, or XYZ-mode if a 2-player movie.
|
// * is controller 3 if a 3-player movie, or XYZ-mode if a 2-player movie.
|
||||||
if (player != 3 || threePlayers)
|
if (player != 3 || threePlayers)
|
||||||
|
{
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) == 0);
|
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
for (int button = 0; button < other.Length; button++)
|
for (int button = 0; button < other.Length; button++)
|
||||||
{
|
{
|
||||||
if (player1Config == "6")
|
if (player1Config == "6")
|
||||||
|
{
|
||||||
controllers["P1 " + other[button]] = (((controllerState >> button) & 0x1) == 0);
|
controllers["P1 " + other[button]] = (((controllerState >> button) & 0x1) == 0);
|
||||||
|
}
|
||||||
if (player2Config == "6")
|
if (player2Config == "6")
|
||||||
|
{
|
||||||
controllers["P2 " + other[button]] = (((controllerState >> (button + 4)) & 0x1) == 0);
|
controllers["P2 " + other[button]] = (((controllerState >> (button + 4)) & 0x1) == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
|
@ -961,15 +1034,21 @@ namespace BizHawk.MultiClient
|
||||||
if (author != "")
|
if (author != "")
|
||||||
{
|
{
|
||||||
if (author_last != "")
|
if (author_last != "")
|
||||||
|
{
|
||||||
author_list += author_last + ", ";
|
author_list += author_last + ", ";
|
||||||
|
}
|
||||||
author_last = author;
|
author_last = author;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (author_list != "")
|
if (author_list != "")
|
||||||
|
{
|
||||||
author_list += "and ";
|
author_list += "and ";
|
||||||
|
}
|
||||||
if (author_last != "")
|
if (author_last != "")
|
||||||
|
{
|
||||||
author_list += author_last;
|
author_list += author_last;
|
||||||
|
}
|
||||||
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author_list);
|
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author_list);
|
||||||
hf.Unbind();
|
hf.Unbind();
|
||||||
}
|
}
|
||||||
|
@ -1011,7 +1090,7 @@ namespace BizHawk.MultiClient
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bool pal = (gametype == "snes_pal" || gametype == "sgb_pal");
|
bool pal = (gametype == "snes_pal" || gametype == "sgb_pal");
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
hf.Unbind();
|
hf.Unbind();
|
||||||
}
|
}
|
||||||
else if (item.name == "input")
|
else if (item.name == "input")
|
||||||
|
@ -1027,7 +1106,9 @@ namespace BizHawk.MultiClient
|
||||||
while ((line = reader.ReadLine()) != null)
|
while ((line = reader.ReadLine()) != null)
|
||||||
{
|
{
|
||||||
if (line == "")
|
if (line == "")
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
m = ImportTextFrame(line, lineNum, m, path, platform, ref warningMsg, ref errorMsg);
|
m = ImportTextFrame(line, lineNum, m, path, platform, ref warningMsg, ref errorMsg);
|
||||||
if (errorMsg != "")
|
if (errorMsg != "")
|
||||||
{
|
{
|
||||||
|
@ -1161,7 +1242,7 @@ namespace BizHawk.MultiClient
|
||||||
Movie m = new Movie(path + "." + Global.Config.MovieExtension);
|
Movie m = new Movie(path + "." + Global.Config.MovieExtension);
|
||||||
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||||
BinaryReader r = new BinaryReader(fs);
|
BinaryReader r = new BinaryReader(fs);
|
||||||
// 000 8-byte "MDFNMOVI" signature
|
// 000 8-byte "MDFNMOVI" signature
|
||||||
string signature = r.ReadStringFixedAscii(8);
|
string signature = r.ReadStringFixedAscii(8);
|
||||||
if (signature != "MDFNMOVI")
|
if (signature != "MDFNMOVI")
|
||||||
{
|
{
|
||||||
|
@ -1170,24 +1251,24 @@ namespace BizHawk.MultiClient
|
||||||
fs.Close();
|
fs.Close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// 008 uint32 Mednafen Version (Current is 0A 08)
|
// 008 uint32 Mednafen Version (Current is 0A 08)
|
||||||
uint emuVersion = r.ReadUInt32();
|
uint emuVersion = r.ReadUInt32();
|
||||||
m.Header.Comments.Add(EMULATIONORIGIN + " Mednafen " + emuVersion.ToString());
|
m.Header.Comments.Add(EMULATIONORIGIN + " Mednafen " + emuVersion.ToString());
|
||||||
// 00C uint32 Movie Format Version (Current is 01)
|
// 00C uint32 Movie Format Version (Current is 01)
|
||||||
uint version = r.ReadUInt32();
|
uint version = r.ReadUInt32();
|
||||||
m.Header.Comments.Add(MOVIEORIGIN + " .MCM version " + version);
|
m.Header.Comments.Add(MOVIEORIGIN + " .MCM version " + version);
|
||||||
// 010 32-byte MD5 of the ROM used
|
// 010 32-byte MD5 of the ROM used
|
||||||
byte[] md5 = r.ReadBytes(16);
|
byte[] md5 = r.ReadBytes(16);
|
||||||
// Discard the second 16 bytes.
|
// Discard the second 16 bytes.
|
||||||
r.ReadBytes(16);
|
r.ReadBytes(16);
|
||||||
m.Header.SetHeaderLine(MD5, BizHawk.Util.BytesToHexString(md5).ToLower());
|
m.Header.SetHeaderLine(MD5, BizHawk.Util.BytesToHexString(md5).ToLower());
|
||||||
// 030 64-byte Filename of the ROM used (with extension)
|
// 030 64-byte Filename of the ROM used (with extension)
|
||||||
string gameName = NullTerminated(r.ReadStringFixedAscii(64));
|
string gameName = NullTerminated(r.ReadStringFixedAscii(64));
|
||||||
m.Header.SetHeaderLine(MovieHeader.GAMENAME, gameName);
|
m.Header.SetHeaderLine(MovieHeader.GAMENAME, gameName);
|
||||||
// 070 uint32 Re-record Count
|
// 070 uint32 Re-record Count
|
||||||
uint rerecordCount = r.ReadUInt32();
|
uint rerecordCount = r.ReadUInt32();
|
||||||
m.Rerecords = (int)rerecordCount;
|
m.Rerecords = (int)rerecordCount;
|
||||||
// 074 5-byte Console indicator (pce, ngp, pcfx, wswan)
|
// 074 5-byte Console indicator (pce, ngp, pcfx, wswan)
|
||||||
string platform = NullTerminated(r.ReadStringFixedAscii(5));
|
string platform = NullTerminated(r.ReadStringFixedAscii(5));
|
||||||
Dictionary<string, Dictionary<string, object>> platforms = new Dictionary<string, Dictionary<string, object>>()
|
Dictionary<string, Dictionary<string, object>> platforms = new Dictionary<string, Dictionary<string, object>>()
|
||||||
{
|
{
|
||||||
|
@ -1220,7 +1301,7 @@ namespace BizHawk.MultiClient
|
||||||
}
|
}
|
||||||
string name = (string)platforms[platform]["name"];
|
string name = (string)platforms[platform]["name"];
|
||||||
m.Header.SetHeaderLine(MovieHeader.PLATFORM, name);
|
m.Header.SetHeaderLine(MovieHeader.PLATFORM, name);
|
||||||
// 079 32-byte Author name
|
// 079 32-byte Author name
|
||||||
string author = NullTerminated(r.ReadStringFixedAscii(32));
|
string author = NullTerminated(r.ReadStringFixedAscii(32));
|
||||||
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author);
|
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author);
|
||||||
// 099 103-byte Padding 0s
|
// 099 103-byte Padding 0s
|
||||||
|
@ -1250,15 +1331,21 @@ namespace BizHawk.MultiClient
|
||||||
for (int player = 1; player <= ports; player++)
|
for (int player = 1; player <= ports; player++)
|
||||||
{
|
{
|
||||||
if (bytesPerPort == 2)
|
if (bytesPerPort == 2)
|
||||||
|
{
|
||||||
// Discard the first byte.
|
// Discard the first byte.
|
||||||
r.ReadByte();
|
r.ReadByte();
|
||||||
|
}
|
||||||
ushort controllerState = r.ReadByte();
|
ushort controllerState = r.ReadByte();
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
r.ReadByte();
|
r.ReadByte();
|
||||||
if (platform == "nes" && warningMsg == "")
|
if (platform == "nes" && warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Control commands are not properly supported.";
|
warningMsg = "Control commands are not properly supported.";
|
||||||
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
}
|
}
|
||||||
|
@ -1325,7 +1412,7 @@ namespace BizHawk.MultiClient
|
||||||
// bit 0: unused
|
// bit 0: unused
|
||||||
// bit 1: "PAL"
|
// bit 1: "PAL"
|
||||||
bool pal = (((flags >> 1) & 0x1) != 0);
|
bool pal = (((flags >> 1) & 0x1) != 0);
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
// bit 2: Japan
|
// bit 2: Japan
|
||||||
bool japan = (((flags >> 2) & 0x1) != 0);
|
bool japan = (((flags >> 2) & 0x1) != 0);
|
||||||
m.Header.SetHeaderLine(JAPAN, japan.ToString());
|
m.Header.SetHeaderLine(JAPAN, japan.ToString());
|
||||||
|
@ -1376,12 +1463,16 @@ namespace BizHawk.MultiClient
|
||||||
{
|
{
|
||||||
byte controllerState = r.ReadByte();
|
byte controllerState = r.ReadByte();
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
||||||
|
}
|
||||||
if (player == 1)
|
if (player == 1)
|
||||||
|
{
|
||||||
controllers["Pause"] = (
|
controllers["Pause"] = (
|
||||||
(((controllerState >> 6) & 0x1) != 0 && (!gamegear)) ||
|
(((controllerState >> 6) & 0x1) != 0 && (!gamegear)) ||
|
||||||
(((controllerState >> 7) & 0x1) != 0 && gamegear)
|
(((controllerState >> 7) & 0x1) != 0 && gamegear)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
|
@ -1469,7 +1560,9 @@ namespace BizHawk.MultiClient
|
||||||
per frame. Nintendulator's Four-Score recording is seemingly broken.
|
per frame. Nintendulator's Four-Score recording is seemingly broken.
|
||||||
*/
|
*/
|
||||||
for (int controller = 1; controller < masks.Length; controller++)
|
for (int controller = 1; controller < masks.Length; controller++)
|
||||||
|
{
|
||||||
masks[controller - 1] = (((controller2 >> (controller - 1)) & 0x1) != 0);
|
masks[controller - 1] = (((controller2 >> (controller - 1)) & 0x1) != 0);
|
||||||
|
}
|
||||||
warningMsg = "Nintendulator's Four Score recording is seemingly broken.";
|
warningMsg = "Nintendulator's Four Score recording is seemingly broken.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1505,7 +1598,9 @@ namespace BizHawk.MultiClient
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (warningMsg != "")
|
if (warningMsg != "")
|
||||||
|
{
|
||||||
warningMsg = warningMsg + " is not properly supported.";
|
warningMsg = warningMsg + " is not properly supported.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1527,14 +1622,20 @@ namespace BizHawk.MultiClient
|
||||||
"Alternate keyboard layout", "Family Trainer", "Oeka Kids writing tablet"
|
"Alternate keyboard layout", "Family Trainer", "Oeka Kids writing tablet"
|
||||||
};
|
};
|
||||||
if (expansion != 0 && warningMsg == "")
|
if (expansion != 0 && warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Expansion port is not properly supported. This movie uses " + expansions[expansion] + ".";
|
warningMsg = "Expansion port is not properly supported. This movie uses " + expansions[expansion] + ".";
|
||||||
|
}
|
||||||
// 003 1-byte number of bytes per frame, plus flags
|
// 003 1-byte number of bytes per frame, plus flags
|
||||||
byte data = r.ReadByte();
|
byte data = r.ReadByte();
|
||||||
int bytesPerFrame = data & 0xF;
|
int bytesPerFrame = data & 0xF;
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
for (int controller = 1; controller < masks.Length; controller++)
|
for (int controller = 1; controller < masks.Length; controller++)
|
||||||
|
{
|
||||||
if (masks[controller - 1])
|
if (masks[controller - 1])
|
||||||
|
{
|
||||||
bytes++;
|
bytes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Depending on the mapper used by the game in question, an additional byte of data may be stored during each
|
Depending on the mapper used by the game in question, an additional byte of data may be stored during each
|
||||||
frame. This is most frequently used for FDS games (storing either the disk number or 0xFF to eject) or VS
|
frame. This is most frequently used for FDS games (storing either the disk number or 0xFF to eject) or VS
|
||||||
|
@ -1542,7 +1643,9 @@ namespace BizHawk.MultiClient
|
||||||
not match up with the amount of bytes the controllers take up.
|
not match up with the amount of bytes the controllers take up.
|
||||||
*/
|
*/
|
||||||
if (bytes != bytesPerFrame)
|
if (bytes != bytesPerFrame)
|
||||||
|
{
|
||||||
masks[4] = true;
|
masks[4] = true;
|
||||||
|
}
|
||||||
// bit 6: Game Genie active
|
// bit 6: Game Genie active
|
||||||
/*
|
/*
|
||||||
bit 7: Framerate
|
bit 7: Framerate
|
||||||
|
@ -1550,7 +1653,7 @@ namespace BizHawk.MultiClient
|
||||||
* if "1", "PAL" timing
|
* if "1", "PAL" timing
|
||||||
*/
|
*/
|
||||||
bool pal = (((data >> 7) & 0x1) != 0);
|
bool pal = (((data >> 7) & 0x1) != 0);
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
// 004 4-byte little-endian unsigned int: rerecord count
|
// 004 4-byte little-endian unsigned int: rerecord count
|
||||||
uint rerecordCount = r.ReadUInt32();
|
uint rerecordCount = r.ReadUInt32();
|
||||||
m.Rerecords = (int)rerecordCount;
|
m.Rerecords = (int)rerecordCount;
|
||||||
|
@ -1588,13 +1691,21 @@ namespace BizHawk.MultiClient
|
||||||
for (int player = 1; player <= masks.Length; player++)
|
for (int player = 1; player <= masks.Length; player++)
|
||||||
{
|
{
|
||||||
if (!masks[player - 1])
|
if (!masks[player - 1])
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
byte controllerState = r.ReadByte();
|
byte controllerState = r.ReadByte();
|
||||||
if (player != 5)
|
if (player != 5)
|
||||||
|
{
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (warningMsg == "")
|
else if (warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Extra input is not properly supported.";
|
warningMsg = "Extra input is not properly supported.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
|
@ -1669,7 +1780,9 @@ namespace BizHawk.MultiClient
|
||||||
MnemonicsGenerator mg = new MnemonicsGenerator();
|
MnemonicsGenerator mg = new MnemonicsGenerator();
|
||||||
bool[] controllersUsed = new bool[5];
|
bool[] controllersUsed = new bool[5];
|
||||||
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||||
|
{
|
||||||
controllersUsed[controller - 1] = (((controllerFlags >> (controller - 1)) & 0x1) != 0);
|
controllersUsed[controller - 1] = (((controllerFlags >> (controller - 1)) & 0x1) != 0);
|
||||||
|
}
|
||||||
// 015 1-byte flags "movie options"
|
// 015 1-byte flags "movie options"
|
||||||
byte movieFlags = r.ReadByte();
|
byte movieFlags = r.ReadByte();
|
||||||
/*
|
/*
|
||||||
|
@ -1686,7 +1799,7 @@ namespace BizHawk.MultiClient
|
||||||
}
|
}
|
||||||
// bit 1: if "0", movie is NTSC (60 fps); if "1", movie is PAL (50 fps)
|
// bit 1: if "0", movie is NTSC (60 fps); if "1", movie is PAL (50 fps)
|
||||||
bool pal = (((movieFlags >> 1) & 0x1) != 0);
|
bool pal = (((movieFlags >> 1) & 0x1) != 0);
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
// other: reserved, set to 0
|
// other: reserved, set to 0
|
||||||
/*
|
/*
|
||||||
016 1-byte flags "sync options":
|
016 1-byte flags "sync options":
|
||||||
|
@ -1745,7 +1858,9 @@ namespace BizHawk.MultiClient
|
||||||
byte[] metadata = r.ReadBytes((int)(savestateOffset - extraRomInfo - ((version != "1.43") ? 0x40 : 0x20)));
|
byte[] metadata = r.ReadBytes((int)(savestateOffset - extraRomInfo - ((version != "1.43") ? 0x40 : 0x20)));
|
||||||
string author = NullTerminated(Encoding.Unicode.GetString(metadata).Trim());
|
string author = NullTerminated(Encoding.Unicode.GetString(metadata).Trim());
|
||||||
if (author != "")
|
if (author != "")
|
||||||
|
{
|
||||||
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author);
|
m.Header.SetHeaderLine(MovieHeader.AUTHOR, author);
|
||||||
|
}
|
||||||
if (extraRomInfo == 30)
|
if (extraRomInfo == 30)
|
||||||
{
|
{
|
||||||
// 000 3 bytes of zero padding: 00 00 00 003 4-byte integer: CRC32 of the ROM 007 23-byte ascii string
|
// 000 3 bytes of zero padding: 00 00 00 003 4-byte integer: CRC32 of the ROM 007 23-byte ascii string
|
||||||
|
@ -1784,7 +1899,9 @@ namespace BizHawk.MultiClient
|
||||||
for (int player = 1; player <= controllersUsed.Length; player++)
|
for (int player = 1; player <= controllersUsed.Length; player++)
|
||||||
{
|
{
|
||||||
if (!controllersUsed[player - 1])
|
if (!controllersUsed[player - 1])
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Each frame consists of 2 bytes per controller. So if there are 3 controllers, a frame is 6 bytes and
|
Each frame consists of 2 bytes per controller. So if there are 3 controllers, a frame is 6 bytes and
|
||||||
if there is only 1 controller, a frame is 2 bytes.
|
if there is only 1 controller, a frame is 2 bytes.
|
||||||
|
@ -1796,7 +1913,9 @@ namespace BizHawk.MultiClient
|
||||||
reset. The reset is done through the S9xSoftReset routine.
|
reset. The reset is done through the S9xSoftReset routine.
|
||||||
*/
|
*/
|
||||||
if (controllerState1 != 0xFF || controllerState2 != 0xFF)
|
if (controllerState1 != 0xFF || controllerState2 != 0xFF)
|
||||||
|
{
|
||||||
controllers["Reset"] = false;
|
controllers["Reset"] = false;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
While the meaning of controller data (for 1.51 and up) for a single standard SNES controller pad
|
While the meaning of controller data (for 1.51 and up) for a single standard SNES controller pad
|
||||||
remains the same, each frame of controller data can contain additional bytes if input for peripherals
|
remains the same, each frame of controller data can contain additional bytes if input for peripherals
|
||||||
|
@ -1837,22 +1956,30 @@ namespace BizHawk.MultiClient
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (peripheral != "" && warningMsg == "")
|
if (peripheral != "" && warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to import " + peripheral + ".";
|
warningMsg = "Unable to import " + peripheral + ".";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ushort controllerState = (ushort)(((controllerState1 << 4) & 0x0F00) | controllerState2);
|
ushort controllerState = (ushort)(((controllerState1 << 4) & 0x0F00) | controllerState2);
|
||||||
if (player <= Global.PLAYERS[controllers.Type.Name])
|
if (player <= Global.PLAYERS[controllers.Type.Name])
|
||||||
|
{
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
{
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (
|
controllers["P" + player + " " + buttons[button]] = (
|
||||||
((controllerState >> button) & 0x1) != 0
|
((controllerState >> button) & 0x1) != 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (warningMsg == "")
|
else if (warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Controller " + player + " not supported.";
|
warningMsg = "Controller " + player + " not supported.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// The controller data contains <number_of_frames + 1> frames.
|
// The controller data contains <number_of_frames + 1> frames.
|
||||||
if (frame == 0)
|
if (frame == 0)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
}
|
}
|
||||||
|
@ -1937,7 +2064,9 @@ namespace BizHawk.MultiClient
|
||||||
*/
|
*/
|
||||||
bool[] controllersUsed = new bool[4];
|
bool[] controllersUsed = new bool[4];
|
||||||
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||||
|
{
|
||||||
controllersUsed[controller - 1] = (((controllerFlags >> (controller - 1)) & 0x1) != 0);
|
controllersUsed[controller - 1] = (((controllerFlags >> (controller - 1)) & 0x1) != 0);
|
||||||
|
}
|
||||||
if (!controllersUsed[0])
|
if (!controllersUsed[0])
|
||||||
{
|
{
|
||||||
errorMsg = "Controller 1 must be in use.";
|
errorMsg = "Controller 1 must be in use.";
|
||||||
|
@ -1966,11 +2095,17 @@ namespace BizHawk.MultiClient
|
||||||
// (If all 3 of these bits are "0", it is for regular GB.)
|
// (If all 3 of these bits are "0", it is for regular GB.)
|
||||||
string platform = "GB";
|
string platform = "GB";
|
||||||
if (is_gba)
|
if (is_gba)
|
||||||
|
{
|
||||||
platform = "GBA";
|
platform = "GBA";
|
||||||
|
}
|
||||||
if (is_gbc)
|
if (is_gbc)
|
||||||
|
{
|
||||||
platform = "GBC";
|
platform = "GBC";
|
||||||
|
}
|
||||||
if (is_sgb)
|
if (is_sgb)
|
||||||
|
{
|
||||||
m.Header.Comments.Add(SUPERGAMEBOYMODE + " True");
|
m.Header.Comments.Add(SUPERGAMEBOYMODE + " True");
|
||||||
|
}
|
||||||
m.Header.SetHeaderLine(MovieHeader.PLATFORM, platform);
|
m.Header.SetHeaderLine(MovieHeader.PLATFORM, platform);
|
||||||
// 017 1-byte flags: (values of some boolean emulator options)
|
// 017 1-byte flags: (values of some boolean emulator options)
|
||||||
flags = r.ReadByte();
|
flags = r.ReadByte();
|
||||||
|
@ -2048,7 +2183,14 @@ namespace BizHawk.MultiClient
|
||||||
r.BaseStream.Position = firstFrameOffset;
|
r.BaseStream.Position = firstFrameOffset;
|
||||||
SimpleController controllers = new SimpleController();
|
SimpleController controllers = new SimpleController();
|
||||||
controllers.Type = new ControllerDefinition();
|
controllers.Type = new ControllerDefinition();
|
||||||
controllers.Type.Name = "Gameboy Controller";
|
if (platform == "GBA")
|
||||||
|
{
|
||||||
|
controllers.Type.Name = "Gameboy Controller";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
controllers.Type.Name = "GBA Controller";
|
||||||
|
}
|
||||||
MnemonicsGenerator mg = new MnemonicsGenerator();
|
MnemonicsGenerator mg = new MnemonicsGenerator();
|
||||||
/*
|
/*
|
||||||
* 01 00 A
|
* 01 00 A
|
||||||
|
@ -2083,23 +2225,33 @@ namespace BizHawk.MultiClient
|
||||||
*/
|
*/
|
||||||
ushort controllerState = r.ReadUInt16();
|
ushort controllerState = r.ReadUInt16();
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers[buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
controllers[buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
||||||
|
}
|
||||||
// TODO: Handle the other buttons.
|
// TODO: Handle the other buttons.
|
||||||
if (warningMsg == "")
|
if (warningMsg == "")
|
||||||
{
|
{
|
||||||
for (int button = 0; button < other.Length; button++)
|
for (int button = 0; button < other.Length; button++)
|
||||||
|
{
|
||||||
if (((controllerState >> (button + 8)) & 0x1) != 0)
|
if (((controllerState >> (button + 8)) & 0x1) != 0)
|
||||||
{
|
{
|
||||||
warningMsg = other[button];
|
warningMsg = other[button];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (warningMsg != "")
|
if (warningMsg != "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to import " + warningMsg + " at frame " + frame + ".";
|
warningMsg = "Unable to import " + warningMsg + " at frame " + frame + ".";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO: Handle the additional controllers.
|
// TODO: Handle the additional controllers.
|
||||||
for (int player = 2; player <= controllersUsed.Length; player++)
|
for (int player = 2; player <= controllersUsed.Length; player++)
|
||||||
|
{
|
||||||
if (controllersUsed[player - 1])
|
if (controllersUsed[player - 1])
|
||||||
|
{
|
||||||
r.ReadBytes(2);
|
r.ReadBytes(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
}
|
}
|
||||||
|
@ -2143,7 +2295,9 @@ namespace BizHawk.MultiClient
|
||||||
*/
|
*/
|
||||||
bool[] controllersUsed = new bool[4];
|
bool[] controllersUsed = new bool[4];
|
||||||
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||||
|
{
|
||||||
controllersUsed[controller - 1] = (((flags >> (controller - 1)) & 0x1) != 0);
|
controllersUsed[controller - 1] = (((flags >> (controller - 1)) & 0x1) != 0);
|
||||||
|
}
|
||||||
bool fourscore = (controllersUsed[2] || controllersUsed[3]);
|
bool fourscore = (controllersUsed[2] || controllersUsed[3]);
|
||||||
m.Header.SetHeaderLine(MovieHeader.FOURSCORE, fourscore.ToString());
|
m.Header.SetHeaderLine(MovieHeader.FOURSCORE, fourscore.ToString());
|
||||||
/*
|
/*
|
||||||
|
@ -2164,29 +2318,29 @@ namespace BizHawk.MultiClient
|
||||||
becomes the controller data. TODO: Figure out what this means.
|
becomes the controller data. TODO: Figure out what this means.
|
||||||
Other bits: reserved, set to 0
|
Other bits: reserved, set to 0
|
||||||
*/
|
*/
|
||||||
// 014 DWORD Ext0; // ROM:program CRC FDS:program ID
|
// 014 DWORD Ext0; // ROM:program CRC FDS:program ID
|
||||||
r.ReadBytes(4);
|
r.ReadBytes(4);
|
||||||
// 018 WORD Ext1; // ROM:unused,0 FDS:maker ID
|
// 018 WORD Ext1; // ROM:unused,0 FDS:maker ID
|
||||||
r.ReadBytes(2);
|
r.ReadBytes(2);
|
||||||
// 01A WORD Ext2; // ROM:unused,0 FDS:disk no.
|
// 01A WORD Ext2; // ROM:unused,0 FDS:disk no.
|
||||||
r.ReadBytes(2);
|
r.ReadBytes(2);
|
||||||
// 01C 4-byte little-endian integer: rerecord count
|
// 01C 4-byte little-endian integer: rerecord count
|
||||||
uint rerecordCount = r.ReadUInt32();
|
uint rerecordCount = r.ReadUInt32();
|
||||||
m.Rerecords = (int)rerecordCount;
|
m.Rerecords = (int)rerecordCount;
|
||||||
/*
|
/*
|
||||||
020 BYTE RenderMethod
|
020 BYTE RenderMethod
|
||||||
0=POST_ALL,1=PRE_ALL
|
0=POST_ALL,1=PRE_ALL
|
||||||
2=POST_RENDER,3=PRE_RENDER
|
2=POST_RENDER,3=PRE_RENDER
|
||||||
4=TILE_RENDER
|
4=TILE_RENDER
|
||||||
*/
|
*/
|
||||||
r.ReadByte();
|
r.ReadByte();
|
||||||
// 021 BYTE IRQtype // IRQ type
|
// 021 BYTE IRQtype // IRQ type
|
||||||
r.ReadByte();
|
r.ReadByte();
|
||||||
// 022 BYTE FrameIRQ // FrameIRQ not allowed
|
// 022 BYTE FrameIRQ // FrameIRQ not allowed
|
||||||
r.ReadByte();
|
r.ReadByte();
|
||||||
// 023 1-byte flag: 0=NTSC (60 Hz), 1="PAL" (50 Hz)
|
// 023 1-byte flag: 0=NTSC (60 Hz), 1="PAL" (50 Hz)
|
||||||
bool pal = (r.ReadByte() == 1);
|
bool pal = (r.ReadByte() == 1);
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
// 024 8-bytes: reserved, set to 0
|
// 024 8-bytes: reserved, set to 0
|
||||||
r.ReadBytes(8);
|
r.ReadBytes(8);
|
||||||
// 02C 4-byte little-endian integer: save state start offset
|
// 02C 4-byte little-endian integer: save state start offset
|
||||||
|
@ -2234,7 +2388,9 @@ namespace BizHawk.MultiClient
|
||||||
for (int player = 1; player <= controllersUsed.Length; player++)
|
for (int player = 1; player <= controllersUsed.Length; player++)
|
||||||
{
|
{
|
||||||
if (!controllersUsed[player - 1])
|
if (!controllersUsed[player - 1])
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
byte controllerState = r.ReadByte();
|
byte controllerState = r.ReadByte();
|
||||||
if (controllerState >= 0xF0)
|
if (controllerState >= 0xF0)
|
||||||
{
|
{
|
||||||
|
@ -2243,6 +2399,7 @@ namespace BizHawk.MultiClient
|
||||||
ushort command = r.ReadUInt16();
|
ushort command = r.ReadUInt16();
|
||||||
string commandName = "";
|
string commandName = "";
|
||||||
if ((command & 0xFF00) == 0)
|
if ((command & 0xFF00) == 0)
|
||||||
|
{
|
||||||
switch (command & 0x00FF)
|
switch (command & 0x00FF)
|
||||||
{
|
{
|
||||||
// NESCMD_NONE
|
// NESCMD_NONE
|
||||||
|
@ -2292,22 +2449,31 @@ namespace BizHawk.MultiClient
|
||||||
commandName = "invalid command";
|
commandName = "invalid command";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
commandName = "NESCMD_EXCONTROLLER, " + (command & 0xFF00);
|
commandName = "NESCMD_EXCONTROLLER, " + (command & 0xFF00);
|
||||||
|
}
|
||||||
if (commandName != "" && warningMsg == "")
|
if (commandName != "" && warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to run command \"" + commandName + "\".";
|
warningMsg = "Unable to run command \"" + commandName + "\".";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (controllerState == 0xF3)
|
else if (controllerState == 0xF3)
|
||||||
{
|
{
|
||||||
uint dwdata = r.ReadUInt32();
|
uint dwdata = r.ReadUInt32();
|
||||||
// TODO: Make a clearer warning message.
|
// TODO: Make a clearer warning message.
|
||||||
if (warningMsg == "")
|
if (warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to run SetSyncExData(" + dwdata + ").";
|
warningMsg = "Unable to run SetSyncExData(" + dwdata + ").";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
controllerState = r.ReadByte();
|
controllerState = r.ReadByte();
|
||||||
}
|
}
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 0x1) != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
|
@ -2338,7 +2504,7 @@ namespace BizHawk.MultiClient
|
||||||
// 003 2-byte little-endian unsigned int: zsnes version number
|
// 003 2-byte little-endian unsigned int: zsnes version number
|
||||||
short version = r.ReadInt16();
|
short version = r.ReadInt16();
|
||||||
m.Header.Comments.Add(EMULATIONORIGIN + " ZSNES version " + version);
|
m.Header.Comments.Add(EMULATIONORIGIN + " ZSNES version " + version);
|
||||||
m.Header.Comments.Add(MOVIEORIGIN + " .ZMV");
|
m.Header.Comments.Add(MOVIEORIGIN + " .ZMV");
|
||||||
// 005 4-byte little-endian integer: CRC32 of the ROM
|
// 005 4-byte little-endian integer: CRC32 of the ROM
|
||||||
int crc32 = r.ReadInt32();
|
int crc32 = r.ReadInt32();
|
||||||
m.Header.SetHeaderLine(CRC32, crc32.ToString());
|
m.Header.SetHeaderLine(CRC32, crc32.ToString());
|
||||||
|
@ -2378,18 +2544,26 @@ namespace BizHawk.MultiClient
|
||||||
string peripheral = "";
|
string peripheral = "";
|
||||||
bool superScope = ((controllerFlags & 0x1) != 0);
|
bool superScope = ((controllerFlags & 0x1) != 0);
|
||||||
if (superScope)
|
if (superScope)
|
||||||
|
{
|
||||||
peripheral = "Super Scope";
|
peripheral = "Super Scope";
|
||||||
|
}
|
||||||
controllerFlags >>= 1;
|
controllerFlags >>= 1;
|
||||||
bool secondMouse = ((controllerFlags & 0x1) != 0);
|
bool secondMouse = ((controllerFlags & 0x1) != 0);
|
||||||
if (secondMouse && peripheral == "")
|
if (secondMouse && peripheral == "")
|
||||||
|
{
|
||||||
peripheral = "Second Mouse";
|
peripheral = "Second Mouse";
|
||||||
|
}
|
||||||
controllerFlags >>= 1;
|
controllerFlags >>= 1;
|
||||||
bool firstMouse = ((controllerFlags & 0x1) != 0);
|
bool firstMouse = ((controllerFlags & 0x1) != 0);
|
||||||
if (firstMouse && peripheral == "")
|
if (firstMouse && peripheral == "")
|
||||||
|
{
|
||||||
peripheral = "First Mouse";
|
peripheral = "First Mouse";
|
||||||
|
}
|
||||||
controllerFlags >>= 1;
|
controllerFlags >>= 1;
|
||||||
if (peripheral != "")
|
if (peripheral != "")
|
||||||
|
{
|
||||||
warningMsg = "Unable to import " + peripheral + ".";
|
warningMsg = "Unable to import " + peripheral + ".";
|
||||||
|
}
|
||||||
// 027 1-byte flags:
|
// 027 1-byte flags:
|
||||||
byte movieFlags = r.ReadByte();
|
byte movieFlags = r.ReadByte();
|
||||||
byte begins = (byte)(movieFlags & 0xC0);
|
byte begins = (byte)(movieFlags & 0xC0);
|
||||||
|
@ -2416,7 +2590,7 @@ namespace BizHawk.MultiClient
|
||||||
// if "11", movie begins from power-on with SRAM clear
|
// if "11", movie begins from power-on with SRAM clear
|
||||||
// bit 5: if "0", movie is NTSC (60 fps); if "1", movie is PAL (50 fps)
|
// bit 5: if "0", movie is NTSC (60 fps); if "1", movie is PAL (50 fps)
|
||||||
bool pal = (((movieFlags >> 5) & 0x1) != 0);
|
bool pal = (((movieFlags >> 5) & 0x1) != 0);
|
||||||
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
m.Header.SetHeaderLine(MovieHeader.PAL, pal.ToString());
|
||||||
// other: reserved, set to 0
|
// other: reserved, set to 0
|
||||||
/*
|
/*
|
||||||
028 3-byte little-endian unsigned int: initial save state size, highest bit specifies compression, next 23
|
028 3-byte little-endian unsigned int: initial save state size, highest bit specifies compression, next 23
|
||||||
|
@ -2483,10 +2657,14 @@ namespace BizHawk.MultiClient
|
||||||
// If the event is RLE data, next follows 4 bytes which is the frame to repeat current input till.
|
// If the event is RLE data, next follows 4 bytes which is the frame to repeat current input till.
|
||||||
uint frame = r.ReadUInt32();
|
uint frame = r.ReadUInt32();
|
||||||
if (frame > frameCount)
|
if (frame > frameCount)
|
||||||
|
{
|
||||||
throw new ArgumentException("RLE data repeats for frames beyond the total frame count.");
|
throw new ArgumentException("RLE data repeats for frames beyond the total frame count.");
|
||||||
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
for (; frames <= frame; frames++)
|
for (; frames <= frame; frames++)
|
||||||
|
{
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (((flag >> 2) & 0x1) != 0)
|
else if (((flag >> 2) & 0x1) != 0)
|
||||||
{
|
{
|
||||||
|
@ -2516,6 +2694,7 @@ namespace BizHawk.MultiClient
|
||||||
bool leftOver = false;
|
bool leftOver = false;
|
||||||
byte leftOverValue = 0x0;
|
byte leftOverValue = 0x0;
|
||||||
for (int player = 1; player <= 5; player++)
|
for (int player = 1; player <= 5; player++)
|
||||||
|
{
|
||||||
// If the controller has changed:
|
// If the controller has changed:
|
||||||
if (((flag >> (5 - player)) & 0x1) != 0)
|
if (((flag >> (5 - player)) & 0x1) != 0)
|
||||||
{
|
{
|
||||||
|
@ -2581,14 +2760,21 @@ namespace BizHawk.MultiClient
|
||||||
if (player <= Global.PLAYERS[controllers.Type.Name])
|
if (player <= Global.PLAYERS[controllers.Type.Name])
|
||||||
{
|
{
|
||||||
if (player != 2 || !superScope)
|
if (player != 2 || !superScope)
|
||||||
|
{
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
controllers["P" + player + " " + buttons[button]] = (
|
controllers["P" + player + " " + buttons[button]] = (
|
||||||
((controllerState >> button) & 0x1) != 0
|
((controllerState >> button) & 0x1) != 0
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (warningMsg == "")
|
else if (warningMsg == "")
|
||||||
|
{
|
||||||
warningMsg = "Controller " + player + " not supported.";
|
warningMsg = "Controller " + player + " not supported.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
frames++;
|
frames++;
|
||||||
|
|
Loading…
Reference in New Issue