public void SplitControllerInputs(M64 m64) { /* * Concept: * Read byte array of controllers */ }
public M64 Parse() { if (!_mupenFile.Exists) { throw new FileNotFoundException(ExceptionsResource.InvalidFilePath, nameof(_mupenFile)); } using var reader = new BinaryReader(_mupenFile.Open(FileMode.Open, FileAccess.Read)); var m64 = new M64 { Version = reader.ReadBytesAndConvertUInt32(0x4), VerticalInterrupts = reader.ReadBytesAndConvertUInt32(0xC), RerecordCount = reader.ReadBytesAndConvertUInt32(0x10), ViPerSecond = reader.ReadByte(0x15), NumberOfControllers = reader.ReadByte(0x16), InputFrames = reader.ReadBytesAndConvertUInt32(0x18), MovieStartType = reader.ReadBytesAndConvertUInt16(0x1C), ControllerFlags = reader.ReadBytesAndConvertUInt32(0x20), NameOfRom = reader.ReadBytesAndConvertString(0xC4, Encoding.ASCII), Crc32 = reader.ReadBytesAndConvertUInt32(0xE4), CountryCode = reader.ReadBytesAndConvertUInt16(0xE8), Author = reader.ReadBytesAndConvertString(0x222, Encoding.UTF8), MovieDescription = reader.ReadBytesAndConvertString(0x300, Encoding.UTF8) }; var frame = 0; reader.BaseStream.Seek(0x400, SeekOrigin.Begin); while (reader.BaseStream.Position != reader.BaseStream.Length && frame < m64.InputFrames) { m64.Inputs.Add((InputModel)reader.ReadBytes(4)); frame++; } return(m64); }
private static M64 ParseFile([NotNull] FileInfo m64File) { if (!ValidateReservedOffsets(m64File)) { throw new InvalidOperationException(ExceptionsResource.ReservedOffsetValueInvalid); } using var reader = new BinaryReader(m64File.Open(FileMode.Open, FileAccess.Read)); var stringAttributes = typeof(M64).GetPropertyAttributeDictionaryOfType <StringEncodingAttribute>(); var m64 = new M64 { Version = reader.ReadUInt32(0x4), MovieUid = reader.ReadInt32(0x8), ViCount = reader.ReadUInt32(0xC), RerecordCount = reader.ReadUInt32(0x10), ViPerSecond = reader.ReadByte(0x14), ControllerCount = reader.ReadByte(0x15), InputCount = reader.ReadUInt32(0x18), MovieStartType = reader.ReadUInt16(0x1C), ControllerFlags = reader.ReadUInt32(0x20), Crc32 = reader.ReadUInt32(0xE4), RegionCode = reader.ReadUInt16(0xE8), RomName = reader.ReadString(0xC4, stringAttributes[nameof(M64.RomName)].ByteSize, stringAttributes[nameof(M64.RomName)].Encoding), VideoPluginName = reader.ReadString(0x122, stringAttributes[nameof(M64.VideoPluginName)].ByteSize, stringAttributes[nameof(M64.VideoPluginName)].Encoding), AudioPluginName = reader.ReadString(0x162, stringAttributes[nameof(M64.AudioPluginName)].ByteSize, stringAttributes[nameof(M64.AudioPluginName)].Encoding), InputPluginName = reader.ReadString(0x1A2, stringAttributes[nameof(M64.InputPluginName)].ByteSize, stringAttributes[nameof(M64.InputPluginName)].Encoding), RspPluginName = reader.ReadString(0x1E2, stringAttributes[nameof(M64.RspPluginName)].ByteSize, stringAttributes[nameof(M64.RspPluginName)].Encoding), Author = reader.ReadString(0x222, stringAttributes[nameof(M64.Author)].ByteSize, stringAttributes[nameof(M64.Author)].Encoding), MovieDescription = reader.ReadString(0x300, stringAttributes[nameof(M64.MovieDescription)].ByteSize, stringAttributes[nameof(M64.MovieDescription)].Encoding) }; var numControllers = (m64.ControllerFlags & (uint)ControllerProperty.ControllerOnePresent) + ((m64.ControllerFlags & (uint)ControllerProperty.ControllerTwoPresent) >> 1) + ((m64.ControllerFlags & (uint)ControllerProperty.ControllerThreePresent) >> 2) + ((m64.ControllerFlags & (uint)ControllerProperty.ControllerFourPresent) >> 3); /* * Mupen does not delete old inputs when writing to an m64 file. * E.g. if someone loads a save-state and works over the top of the work. * Because of this, it is possible for the header to have an InputCount * that is smaller than the list of inputs. This is because Mupen64 plays the file * up until the header length. Any other data after is ignored. */ // Check the file size (minus the header) is not shorter to the header expected value var inputsBitLength = reader.BaseStream.Length - 0x400; var headerExpectedLength = m64.InputCount * numControllers; if (inputsBitLength < headerExpectedLength) { throw new InvalidFrameCountException( $"File size is too small. The header expects a minimum of {m64.InputCount * numControllers} bytes of input frame data, but got {reader.BaseStream.Length - 0x400}"); } reader.BaseStream.Seek(0x400, SeekOrigin.Begin); while (reader.BaseStream.Position != reader.BaseStream.Length) { m64.ControllerInputs.Add((InputModel)reader.ReadBytes(4)); } return(m64); }
void DoChecks() { if (MainForm.Path == null || MainForm.UsageType == MainForm.UsageTypes.Combo) { return; } lbl_info.Visible = false; lb_Checks.Items.Clear(); MovieStruct movieData; movieData = M64.ParseMovie(MainForm.Path).Item1; bool failedInputTest = false; FileStream fs = new FileStream(MainForm.Path, FileMode.Open); BinaryReader br = new BinaryReader(fs); br.BaseStream.Seek(M64.HEADER_LENGTH, SeekOrigin.Begin); ulong findx = 0; while (findx < movieData.length_samples) { if (br.BaseStream.Position + 4 > fs.Length) { findx++; continue; } inputs.Add(br.ReadInt32()); findx++; } for (ulong i = 0; i < movieData.length_samples; i++) { try { if (inputs[(int)i] != 0) { ; } } catch (ArgumentOutOfRangeException e) { failedInputTest = true; } } ////////////////////////////////////////////// string[] checks = new string[8]; int successfulChecks = 0, failedChecks = 0; lb_Checks.Items.Add((checks[0] = GetCheck(movieData.magic == 0x4D36341A || movieData.magic == 439629389, "Malformed magic cookie")).ToString()); lb_Checks.Items.Add((checks[1] = GetCheck(movieData.version == 3, "Old version")).ToString()); lb_Checks.Items.Add((checks[2] = GetCheck(movieData.num_controllers > 0 && movieData.num_controllers < 4, "Illegal controllers amount")).ToString()); lb_Checks.Items.Add((checks[3] = GetCheck(!DataHelper.GetMovieStartupType(movieData.startFlags).Contains("Unknown"), "Invalid movie startup type")).ToString()); lb_Checks.Items.Add((checks[4] = GetCheck(!failedInputTest, "Frame-Input value Mismatch")).ToString()); lb_Checks.Items.Add((checks[5] = GetCheck(movieData.vis_per_second > 10 && movieData.vis_per_second <= 60, "Non-standard VI/s")).ToString()); lb_Checks.Items.Add((checks[6] = GetCheck(movieData.length_vis > 0, "Not enough VIs")).ToString()); lb_Checks.Items.Add((checks[7] = GetCheck(!movieData.soundPluginName.Contains("Azimer"), "Bad Audio Plugin")).ToString()); foreach (var a in checks) { if (a.Equals("PASS")) { successfulChecks++; } } failedChecks = checks.Length - successfulChecks; if (failedChecks == 0) { lbl_Result.ForeColor = Color.DarkGreen; lbl_Result.Text = "All checks passed"; } else { lbl_Result.ForeColor = Color.Red; char[] a = ExtensionMethods.NumberToWords(failedChecks).ToCharArray(); a[0] = char.ToUpper(a[0]); if (failedChecks == 1) { lbl_Result.Text = "One check failed"; } else if (failedChecks == checks.Length) { lbl_Result.Text = "All checks failed"; } else { lbl_Result.Text = new string(a) + " checks failed"; } } br.Close(); fs.Close(); lbl_info.Visible = true; }