Finally figured out ZMV input...wasn't fun at all. Still need to figure out commands (Reset) and author data, but I removed the INTERIM flag check because this is functional enough to be included in the next release.

This commit is contained in:
brandman211 2012-10-06 20:28:32 +00:00
parent 05cbd4c3bd
commit 9199012b5f
1 changed files with 30 additions and 32 deletions

View File

@ -79,8 +79,6 @@ namespace BizHawk.MultiClient
m = ImportVMV(path, out errorMsg, out warningMsg); m = ImportVMV(path, out errorMsg, out warningMsg);
break; break;
case ".ZMV": case ".ZMV":
if (!Global.MainForm.INTERIM)
return m;
m = ImportZMV(path, out errorMsg, out warningMsg); m = ImportZMV(path, out errorMsg, out warningMsg);
break; break;
} }
@ -2359,7 +2357,7 @@ namespace BizHawk.MultiClient
// 01A 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
ushort internalChapters = r.ReadUInt16(); ushort internalChaptersCount = r.ReadUInt16();
// 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
@ -2393,11 +2391,6 @@ namespace BizHawk.MultiClient
controllerFlags >>= 1; controllerFlags >>= 1;
if (peripheral != "") if (peripheral != "")
warningMsg = "Unable to import " + peripheral + "."; warningMsg = "Unable to import " + peripheral + ".";
bool[] controllersUsed = new bool[5];
for (int controller = 1; controller <= controllersUsed.Length; controller++)
controllersUsed[controllersUsed.Length - controller] = (
((controllerFlags >> (controller - 1)) & 0x1) != 0
);
// 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);
@ -2439,13 +2432,12 @@ namespace BizHawk.MultiClient
MnemonicsGenerator mg = new MnemonicsGenerator(); MnemonicsGenerator mg = new MnemonicsGenerator();
// R, L, X, A, Right, Left, Down, Up, Start, Select, Y, B. TODO: Confirm. // R, L, X, A, Right, Left, Down, Up, Start, Select, Y, B. TODO: Confirm.
string[] buttons = new string[12] { string[] buttons = new string[12] {
"R", "L", "X", "A", "Right", "Left", "Down", "Up", "Start", "Select", "Y", "B" "Right", "Left", "Down", "Up", "Start", "Select", "Y", "B", "R", "L", "X", "A"
}; };
int events = (int)(frameCount + internalChapters);
int frames = 1; int frames = 1;
for (int e = 1; e <= events; e++) int internalChapters = 1;
while (frames <= frameCount || internalChapters <= internalChaptersCount)
{ {
controllers["Reset"] = false;
/* /*
000 1-byte flags: 000 1-byte flags:
bit 7: "1" if controller 1 changed, "0" otherwise bit 7: "1" if controller 1 changed, "0" otherwise
@ -2466,7 +2458,13 @@ namespace BizHawk.MultiClient
*/ */
flag >>= 1; flag >>= 1;
if (flag == 0x0) if (flag == 0x0)
{
controllers["Reset"] = true; controllers["Reset"] = true;
mg.SetSource(controllers);
m.AppendFrame(mg.GetControllersAsMnemonic());
frames++;
controllers["Reset"] = false;
}
// TODO: Other commands. // TODO: Other commands.
} }
else if (((flag >> 1) & 0x1) != 0) else if (((flag >> 1) & 0x1) != 0)
@ -2474,13 +2472,10 @@ 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("Invalid handling of RLE data."); 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());
e++;
}
} }
else if (((flag >> 2) & 0x1) != 0) else if (((flag >> 2) & 0x1) != 0)
{ {
@ -2497,6 +2492,7 @@ namespace BizHawk.MultiClient
r.ReadBytes(2); r.ReadBytes(2);
// above size+007 9-byte: previous controller input bits // above size+007 9-byte: previous controller input bits
r.ReadBytes(9); r.ReadBytes(9);
internalChapters++;
} }
else else
{ {
@ -2506,42 +2502,44 @@ namespace BizHawk.MultiClient
bits per controller, or 20 bits in the case of the super scope, zeropadding up to full bytes. The bits per controller, or 20 bits in the case of the super scope, zeropadding up to full bytes. The
minimum length of the controller data is 2 bytes, and the maximum length is 9 bytes. minimum length of the controller data is 2 bytes, and the maximum length is 9 bytes.
*/ */
byte leftOver = 0x0; bool leftOver = false;
for (int player = 1; player <= controllersUsed.Length; player++) byte leftOverValue = 0x0;
for (int player = 1; player <= 5; player++)
// If the controller has changed: // If the controller has changed:
if (((flag >> (controllersUsed.Length - player)) & 0x1) != 0) if (((flag >> (5 - player)) & 0x1) != 0)
{ {
byte controllerState1 = r.ReadByte(); byte controllerState1 = r.ReadByte();
uint controllerState; uint controllerState;
if (leftOver == 0x0) if (!leftOver)
{ {
byte controllerState2 = r.ReadByte(); byte controllerState2 = r.ReadByte();
if (player == 2 && superScope) if (player == 2 && superScope)
{ {
byte controllerState3 = r.ReadByte(); byte controllerState3 = r.ReadByte();
controllerState = (uint)(((controllerState1 << 16) & 0x0F0000) | controllerState = (uint)((controllerState1 | (controllerState2 << 8) |
(controllerState2 << 8) | controllerState3); (controllerState3 << 12)) & 0x0FFFFF);
leftOverValue = (byte)((controllerState3 >> 4) & 0x0F);
} }
else else
controllerState = (uint)(((controllerState1 << 8) & 0x0F00) | controllerState2); {
leftOver = (byte)((controllerState1 >> 4) & 0x0F); controllerState = (uint)((controllerState1 | (controllerState2 << 4)) & 0x0FFF);
leftOverValue = (byte)((controllerState2 >> 4) & 0x0F);
}
} }
else if ((leftOver & 0x0F) == leftOver) else
{ {
controllerState = (uint)((controllerState1 >> 4) | (leftOverValue << 4) |
((controllerState1 << 8) & 0x0F00));
if (player == 2 && superScope) if (player == 2 && superScope)
{ {
byte controllerState2 = r.ReadByte(); byte controllerState2 = r.ReadByte();
controllerState = (uint)((leftOver << 16) | (controllerState1 << 8) | controllerState |= (uint)(controllerState2 << 12);
controllerState2);
} }
else
controllerState = (uint)((leftOver << 8) | controllerState1);
} }
else leftOver = !leftOver;
throw new ArgumentException("Unexpected number of leftover bits.");
if (player <= Global.PLAYERS[controllers.Type.Name]) if (player <= Global.PLAYERS[controllers.Type.Name])
{ {
if (controllersUsed[player - 1] && (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