Exemple #1
0
 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);
    }
Exemple #4
0
        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;
        }