-ImportSMV
--Fixed "controller in use" handling. ---Applied the same logic to ImportVBM, refactored ImportVMV to match. --Prevented more than 2 controllers from crashing the controller types check for 1.51 and up. -ImportZMV --Showed warning messages for both mouses if enabled. --Marked the controllers used just like I mentioned previously, though it seems to show that no controllers are plugged in... --Went past the savestate data.
This commit is contained in:
parent
f9b392511b
commit
bdd74e356c
|
@ -1568,7 +1568,6 @@ namespace BizHawk.MultiClient
|
||||||
uint frameCount = r.ReadUInt32();
|
uint frameCount = r.ReadUInt32();
|
||||||
// 014 1-byte flags "controller mask"
|
// 014 1-byte flags "controller mask"
|
||||||
byte controllerFlags = r.ReadByte();
|
byte controllerFlags = r.ReadByte();
|
||||||
int players = 0;
|
|
||||||
/*
|
/*
|
||||||
* bit 0: controller 1 in use
|
* bit 0: controller 1 in use
|
||||||
* bit 1: controller 2 in use
|
* bit 1: controller 2 in use
|
||||||
|
@ -1581,9 +1580,9 @@ namespace BizHawk.MultiClient
|
||||||
controllers.Type = new ControllerDefinition();
|
controllers.Type = new ControllerDefinition();
|
||||||
controllers.Type.Name = "SNES Controller";
|
controllers.Type.Name = "SNES Controller";
|
||||||
MnemonicsGenerator mg = new MnemonicsGenerator();
|
MnemonicsGenerator mg = new MnemonicsGenerator();
|
||||||
for (int controller = 1; controller <= Global.PLAYERS[controllers.Type.Name]; controller++)
|
bool[] controllersUsed = new bool[5];
|
||||||
if (((controllerFlags >> (controller - 1)) & 0x1) != 0)
|
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||||
players++;
|
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();
|
||||||
/*
|
/*
|
||||||
|
@ -1695,8 +1694,10 @@ namespace BizHawk.MultiClient
|
||||||
for (int frame = 0; frame <= frameCount; frame++)
|
for (int frame = 0; frame <= frameCount; frame++)
|
||||||
{
|
{
|
||||||
controllers["Reset"] = true;
|
controllers["Reset"] = true;
|
||||||
for (int player = 1; player <= players; player++)
|
for (int player = 1; player <= controllersUsed.Length; player++)
|
||||||
{
|
{
|
||||||
|
if (!controllersUsed[player - 1])
|
||||||
|
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.
|
||||||
|
@ -1714,7 +1715,7 @@ namespace BizHawk.MultiClient
|
||||||
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
|
||||||
is being recorded.
|
is being recorded.
|
||||||
*/
|
*/
|
||||||
if (version != "1.43")
|
if (version != "1.43" && player <= controllerTypes.Length)
|
||||||
{
|
{
|
||||||
string peripheral = "";
|
string peripheral = "";
|
||||||
switch (controllerTypes[player - 1])
|
switch (controllerTypes[player - 1])
|
||||||
|
@ -1752,8 +1753,15 @@ namespace BizHawk.MultiClient
|
||||||
warningMsg = "Unable to import " + peripheral + ".";
|
warningMsg = "Unable to import " + peripheral + ".";
|
||||||
}
|
}
|
||||||
ushort controllerState = (ushort)(((controllerState1 << 4) & 0x0F00) | controllerState2);
|
ushort controllerState = (ushort)(((controllerState1 << 4) & 0x0F00) | controllerState2);
|
||||||
for (int button = 0; button < buttons.Length; button++)
|
if (player <= Global.PLAYERS[controllers.Type.Name])
|
||||||
controllers["P" + player + " " + buttons[button]] = (((controllerState >> button) & 1) == 1);
|
for (int button = 0; button < buttons.Length; button++)
|
||||||
|
{
|
||||||
|
controllers["P" + player + " " + buttons[button]] = (
|
||||||
|
((controllerState >> button) & 1) == 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (warningMsg != "")
|
||||||
|
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)
|
||||||
|
@ -1833,28 +1841,23 @@ namespace BizHawk.MultiClient
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// 015 1-byte flags: controller flags
|
// 015 1-byte flags: controller flags
|
||||||
flags = r.ReadByte();
|
byte controllerFlags = r.ReadByte();
|
||||||
// TODO: Handle the additional controllers.
|
/*
|
||||||
int players = 0;
|
* bit 0: controller 1 in use
|
||||||
// bit 0: controller 1 in use
|
* bit 1: controller 2 in use (SGB games can be 2-player multiplayer)
|
||||||
if ((flags & 1) == 1)
|
* bit 2: controller 3 in use (SGB games can be 3- or 4-player multiplayer with multitap)
|
||||||
players++;
|
* bit 3: controller 4 in use (SGB games can be 3- or 4-player multiplayer with multitap)
|
||||||
else
|
*/
|
||||||
|
bool[] controllersUsed = new bool[4];
|
||||||
|
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||||
|
controllersUsed[controller - 1] = (((controllerFlags >> (controller - 1)) & 0x1) != 0);
|
||||||
|
if (!controllersUsed[0])
|
||||||
{
|
{
|
||||||
errorMsg = "Controller 1 must be in use.";
|
errorMsg = "Controller 1 must be in use.";
|
||||||
r.Close();
|
r.Close();
|
||||||
fs.Close();
|
fs.Close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// bit 1: controller 2 in use (SGB games can be 2-player multiplayer)
|
|
||||||
if (((flags >> 1) & 1) == 1)
|
|
||||||
players++;
|
|
||||||
// bit 2: controller 3 in use (SGB games can be 3- or 4-player multiplayer with multitap)
|
|
||||||
if (((flags >> 2) & 1) == 1)
|
|
||||||
players++;
|
|
||||||
// bit 3: controller 4 in use (SGB games can be 3- or 4-player multiplayer with multitap)
|
|
||||||
if (((flags >> 3) & 1) == 1)
|
|
||||||
players++;
|
|
||||||
// other: reserved
|
// other: reserved
|
||||||
// 016 1-byte flags: system flags (game always runs at 60 frames/sec)
|
// 016 1-byte flags: system flags (game always runs at 60 frames/sec)
|
||||||
flags = r.ReadByte();
|
flags = r.ReadByte();
|
||||||
|
@ -2001,7 +2004,9 @@ namespace BizHawk.MultiClient
|
||||||
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.
|
||||||
r.ReadBytes((players - 1) * 2);
|
for (int player = 2; player <= controllersUsed.Length; player++)
|
||||||
|
if (controllersUsed[player - 1])
|
||||||
|
r.ReadBytes(2);
|
||||||
mg.SetSource(controllers);
|
mg.SetSource(controllers);
|
||||||
m.AppendFrame(mg.GetControllersAsMnemonic());
|
m.AppendFrame(mg.GetControllersAsMnemonic());
|
||||||
}
|
}
|
||||||
|
@ -2037,15 +2042,16 @@ namespace BizHawk.MultiClient
|
||||||
m.Header.Comments.Add(COMMENT + " Record version " + recordVersion);
|
m.Header.Comments.Add(COMMENT + " Record version " + recordVersion);
|
||||||
// 010 4-byte flags (control byte)
|
// 010 4-byte flags (control byte)
|
||||||
uint flags = r.ReadUInt32();
|
uint flags = r.ReadUInt32();
|
||||||
// bit 0: controller 1 in use
|
/*
|
||||||
bool controller1 = ((flags & 1) == 1);
|
* bit 0: controller 1 in use
|
||||||
// bit 1: controller 2 in use
|
* bit 1: controller 2 in use
|
||||||
bool controller2 = (((flags >> 1) & 1) == 1);
|
* bit 2: controller 3 in use
|
||||||
// bit 2: controller 3 in use
|
* bit 3: controller 4 in use
|
||||||
bool controller3 = (((flags >> 2) & 1) == 1);
|
*/
|
||||||
// bit 3: controller 4 in use
|
bool[] controllersUsed = new bool[4];
|
||||||
bool controller4 = (((flags >> 3) & 1) == 1);
|
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||||
bool fourscore = (controller3 || controller4);
|
controllersUsed[controller - 1] = (((flags >> (controller - 1)) & 0x1) != 0);
|
||||||
|
bool fourscore = (controllersUsed[2] || controllersUsed[3]);
|
||||||
m.Header.SetHeaderLine(MovieHeader.FOURSCORE, fourscore.ToString());
|
m.Header.SetHeaderLine(MovieHeader.FOURSCORE, fourscore.ToString());
|
||||||
/*
|
/*
|
||||||
bit 6: 1=reset-based, 0=savestate-based (movie version <= 0x300 is always savestate-based)
|
bit 6: 1=reset-based, 0=savestate-based (movie version <= 0x300 is always savestate-based)
|
||||||
|
@ -2099,7 +2105,7 @@ namespace BizHawk.MultiClient
|
||||||
// 03C 4-byte little-endian integer: CRC (CRC excluding this data(to prevent cheating))
|
// 03C 4-byte little-endian integer: CRC (CRC excluding this data(to prevent cheating))
|
||||||
int crc32 = r.ReadInt32();
|
int crc32 = r.ReadInt32();
|
||||||
m.Header.SetHeaderLine("CRC32", crc32.ToString());
|
m.Header.SetHeaderLine("CRC32", crc32.ToString());
|
||||||
if (!controller1 && !controller2 && !controller3 && !controller4)
|
if (!controllersUsed[0] && !controllersUsed[1] && !controllersUsed[2] && !controllersUsed[3])
|
||||||
{
|
{
|
||||||
warningMsg = "No input recorded.";
|
warningMsg = "No input recorded.";
|
||||||
r.Close();
|
r.Close();
|
||||||
|
@ -2122,7 +2128,6 @@ namespace BizHawk.MultiClient
|
||||||
* 80 Right
|
* 80 Right
|
||||||
*/
|
*/
|
||||||
string[] buttons = new string[8] { "A", "B", "Select", "Start", "Up", "Down", "Left", "Right" };
|
string[] buttons = new string[8] { "A", "B", "Select", "Start", "Up", "Down", "Left", "Right" };
|
||||||
bool[] masks = new bool[4] {controller1, controller2, controller3, controller4};
|
|
||||||
for (int frame = 1; frame <= frameCount; frame++)
|
for (int frame = 1; frame <= frameCount; frame++)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -2132,9 +2137,9 @@ namespace BizHawk.MultiClient
|
||||||
3 takes 1 byte, and controller 4 takes 1 byte. If all four exist, the frame is 4 bytes. For example, if
|
3 takes 1 byte, and controller 4 takes 1 byte. If all four exist, the frame is 4 bytes. For example, if
|
||||||
the movie only has controller 1 data, a frame is 1 byte.
|
the movie only has controller 1 data, a frame is 1 byte.
|
||||||
*/
|
*/
|
||||||
for (int player = 1; player <= masks.Length; player++)
|
for (int player = 1; player <= controllersUsed.Length; player++)
|
||||||
{
|
{
|
||||||
if (!masks[player - 1])
|
if (!controllersUsed[player - 1])
|
||||||
continue;
|
continue;
|
||||||
// TODO: Check for commands: Lines 207-239 of Nesmock.
|
// TODO: Check for commands: Lines 207-239 of Nesmock.
|
||||||
byte controllerState = r.ReadByte();
|
byte controllerState = r.ReadByte();
|
||||||
|
@ -2181,16 +2186,16 @@ namespace BizHawk.MultiClient
|
||||||
r.ReadBytes(4);
|
r.ReadBytes(4);
|
||||||
// 015 4-byte little-endian unsigned int: number of frames advanced step by step
|
// 015 4-byte little-endian unsigned int: number of frames advanced step by step
|
||||||
r.ReadBytes(4);
|
r.ReadBytes(4);
|
||||||
// 016 1-byte: average recording frames per second
|
// 019 1-byte: average recording frames per second
|
||||||
r.ReadByte();
|
r.ReadBytes(1);
|
||||||
// 020 4-byte little-endian unsigned int: number of key combos
|
// 01A 4-byte little-endian unsigned int: number of key combos
|
||||||
r.ReadBytes(4);
|
r.ReadBytes(4);
|
||||||
// 01E 2-byte little-endian unsigned int: number of internal chapters
|
// 01E 2-byte little-endian unsigned int: number of internal chapters
|
||||||
r.ReadBytes(2);
|
r.ReadBytes(2);
|
||||||
// 020 2-byte little-endian unsigned int: length of the author name field in bytes
|
// 020 2-byte little-endian unsigned int: length of the author name field in bytes
|
||||||
ushort authorSize = r.ReadUInt16();
|
ushort authorSize = r.ReadUInt16();
|
||||||
// 022 3-byte little-endian unsigned int: size of an uncompressed save state in bytes
|
// 022 3-byte little-endian unsigned int: size of an uncompressed save state in bytes
|
||||||
r.ReadBytes(3);
|
uint savestateSize = (uint)(r.ReadByte() | (r.ReadByte() << 8) | (r.ReadByte() << 16));
|
||||||
/*
|
/*
|
||||||
025 1-byte flags: initial input configuration
|
025 1-byte flags: initial input configuration
|
||||||
bit 7: first input enabled
|
bit 7: first input enabled
|
||||||
|
@ -2207,10 +2212,18 @@ namespace BizHawk.MultiClient
|
||||||
warningMsg = "Super Scope";
|
warningMsg = "Super Scope";
|
||||||
controllerFlags >>= 1;
|
controllerFlags >>= 1;
|
||||||
if ((controllerFlags & 0x1) != 0 && warningMsg != "")
|
if ((controllerFlags & 0x1) != 0 && warningMsg != "")
|
||||||
warningMsg = "Mouse";
|
warningMsg = "Second Mouse";
|
||||||
|
controllerFlags >>= 1;
|
||||||
|
if ((controllerFlags & 0x1) != 0 && warningMsg != "")
|
||||||
|
warningMsg = "First Mouse";
|
||||||
controllerFlags >>= 1;
|
controllerFlags >>= 1;
|
||||||
if (warningMsg != "")
|
if (warningMsg != "")
|
||||||
warningMsg = "Unable to import " + warningMsg + ".";
|
warningMsg = "Unable to import " + warningMsg + ".";
|
||||||
|
bool[] controllersUsed = new bool[5];
|
||||||
|
for (int controller = 1; controller <= controllersUsed.Length; controller++)
|
||||||
|
controllersUsed[controllersUsed.Length - controller] = (
|
||||||
|
((controllerFlags >> (controller - 1)) & 0x1) != 0
|
||||||
|
);
|
||||||
// 026 1-byte: reserved
|
// 026 1-byte: reserved
|
||||||
r.ReadByte();
|
r.ReadByte();
|
||||||
// 027 1-byte flags:
|
// 027 1-byte flags:
|
||||||
|
@ -2246,6 +2259,8 @@ namespace BizHawk.MultiClient
|
||||||
specifies size
|
specifies size
|
||||||
*/
|
*/
|
||||||
r.ReadBytes(3);
|
r.ReadBytes(3);
|
||||||
|
// Next follows a ZST format savestate.
|
||||||
|
r.ReadBytes((int)savestateSize);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue