Exemple #1
0
        //public static 
        public static F3DEXReaderPackage ReadF3DEXAt(RomFile file, int offset)
        {
            ResetReaderVariables();
            
            byte[] data = file.GetAsBytes();

            F3DEXReaderPackage package = new F3DEXReaderPackage();

            if (offset < 0 || offset >= data.Length || offset % 8 != 0)
                return package;

            //Reset/Initialize what needs to be initialized/reset

            byte[] command = new byte[8];

            while (offset < data.Length)
            {
                //read the command
                Array.Copy(data, offset, command, 0, 8);

                F3DEXCommand f3Command = F3DEXCommandFactory.ReadCommand(offset, command);
                if (f3Command == null)
                    break;

                if (!_foundCommands.ContainsKey(file))
                    _foundCommands.Add(file, new List<F3DEXCommand>());

                _foundCommands[file].Add(f3Command);

                ParseCommand(f3Command);

                offset += 8;

                if (f3Command is F3DEX_G_EndDL)
                    break;
            }

            //Sort what needs to be sorted
            foreach(RomFile rom in _foundTextures.Keys)
            {
                _foundTextures[rom].Sort((s1, s2) => s1.FileOffset.CompareTo(s2.FileOffset));
                for (int i = 0; i < _foundTextures[rom].Count - 1; i++)
                {
                    if (_foundTextures[rom][i].FileOffset == _foundTextures[rom][i + 1].FileOffset)
                    {
                        _foundTextures[rom].RemoveAt(i);
                        i--;
                    }
                }
            }

            foreach (RomFile rom in _foundPalettes.Keys)
            {
                _foundPalettes[rom].Sort((s1, s2) => s1.FileOffset.CompareTo(s2.FileOffset));
                for (int i = 0; i < _foundPalettes[rom].Count - 1; i++)
                {
                    if (_foundPalettes[rom][i].FileOffset == _foundPalettes[rom][i + 1].FileOffset)
                    {
                        _foundPalettes[rom].RemoveAt(i);
                        i--;
                    }
                }
            }

            foreach (RomFile rom in _foundVertices.Keys)
            {
                _foundVertices[rom].Sort((s1, s2) => s1.FileOffset.CompareTo(s2.FileOffset));
                for (int i = 0; i < _foundVertices[rom].Count - 1; i++)
                {
                    if (_foundVertices[rom][i].FileOffset == _foundVertices[rom][i + 1].FileOffset)
                    {
                        _foundVertices[rom].RemoveAt(i);
                        i--;
                    }
                }
            }

            foreach (RomFile rom in _foundCommands.Keys)
            {
                _foundCommands[rom].Sort((s1, s2) => s1.FileOffset.CompareTo(s2.FileOffset));
                for (int i = 0; i < _foundCommands[rom].Count - 1; i++)
                {
                    if (_foundCommands[rom][i].FileOffset == _foundCommands[rom][i + 1].FileOffset)
                    {
                        _foundCommands[rom].RemoveAt(i);
                        i--;
                    }
                }
            }

            //Combine into the collections
            Dictionary<RomFile, List<F3DEXCommandCollection>> commandColls = new Dictionary<RomFile, List<F3DEXCommandCollection>>();
            Dictionary<RomFile, List<VertexCollection>> vertexColls = new Dictionary<RomFile, List<VertexCollection>>();

            //F3DEX Commands
            foreach (RomFile rom in _foundCommands.Keys)
            {
                commandColls.Add(rom, new List<F3DEXCommandCollection>());
                int startColl = 0;
                for (int endColl = 0; endColl < _foundCommands[rom].Count; endColl++)
                {
                    if (endColl == _foundCommands[rom].Count - 1 ||
                        _foundCommands[rom][endColl + 1].FileOffset != _foundCommands[rom][endColl].FileOffset + _foundCommands[rom][endColl].RawDataSize)
                    {
                        //Cut off the collection here
                        F3DEXCommandCollection newColl = new F3DEXCommandCollection(_foundCommands[rom][startColl].FileOffset,
                            _foundCommands[rom].GetRange(startColl, endColl - startColl + 1)); //NOTE: Shallow copying is done here

                        commandColls[rom].Add(newColl);

                        startColl = endColl + 1;
                    }
                }
            }

            //Vertices
            foreach (RomFile rom in _foundVertices.Keys)
            {
                vertexColls.Add(rom, new List<VertexCollection>());
                int startColl = 0;
                for (int endColl = 0; endColl < _foundVertices[rom].Count; endColl++)
                {
                    if (endColl == _foundVertices[rom].Count - 1 ||
                        _foundVertices[rom][endColl + 1].FileOffset != _foundVertices[rom][endColl].FileOffset + _foundVertices[rom][endColl].RawDataSize)
                    {
                        //Cut off the collection here
                        VertexCollection newVert = new VertexCollection(_foundVertices[rom][startColl].FileOffset,
                            _foundVertices[rom].GetRange(startColl, endColl - startColl + 1)); //NOTE: Shallow copying is done here

                        vertexColls[rom].Add(newVert);

                        startColl = endColl + 1;
                    }
                }
            }

            //double check that the package has all the files
            foreach (RomFile rom in _foundTextures.Keys.Union(_foundPalettes.Keys.Union(
                commandColls.Keys.Union(vertexColls.Keys))))
            {
                if (!package.Elements.ContainsKey(rom))
                    package.Elements.Add(rom, new List<N64DataElement>());
            }
            foreach (RomFile rom in _foundTextures.Keys)
                package.Elements[rom].AddRange(_foundTextures[rom]);
            foreach (RomFile rom in _foundPalettes.Keys)
                package.Elements[rom].AddRange(_foundPalettes[rom]);
            foreach (RomFile rom in commandColls.Keys)
                package.Elements[rom].AddRange(commandColls[rom]);
            foreach (RomFile rom in vertexColls.Keys)
                package.Elements[rom].AddRange(vertexColls[rom]);

            return package;
        }
 public void SetCommands(F3DEXCommandCollection commands)
 {
     openGLControl.GraphicsCollections.Add(VO64F3DEXReader.ReadCommands(commands));
 }
        private void btnRender_Click(object sender, EventArgs e)
        {
            if (SelectedCourse == null)
                return;

            for (; RomProject.Instance.Files.Count > 0;)
                RomProject.Instance.RemoveRomFile(RomProject.Instance.Files[0]);

            for (; RomProject.Instance.DMAProfiles.Count > 0; )
                RomProject.Instance.RemoveDmaProfile(RomProject.Instance.DMAProfiles[0]);

            //Take the blocks, and export them
            byte[] displayListBlock = new byte[SelectedCourse.DisplayListBlockEnd - SelectedCourse.DisplayListBlockStart];
            Array.Copy(_romData, SelectedCourse.DisplayListBlockStart,
                displayListBlock, 0, displayListBlock.Length);
            int vertexEndPackedDLStartOffset = SelectedCourse.DisplayListOffset & 0x00FFFFFF;
            byte[] vertexBlock = new byte[vertexEndPackedDLStartOffset];
            Array.Copy(_romData, SelectedCourse.VertexBlockStart,
                vertexBlock, 0, vertexBlock.Length);
            byte[] packedBlock = new byte[(SelectedCourse.VertexBlockEnd - SelectedCourse.VertexBlockStart) - vertexEndPackedDLStartOffset];
            Array.Copy(_romData, SelectedCourse.VertexBlockStart + vertexEndPackedDLStartOffset,
                packedBlock, 0, packedBlock.Length);
            byte[] textureBlock = new byte[SelectedCourse.TextureBlockEnd - SelectedCourse.TextureBlockStart];
            Array.Copy(_romData, SelectedCourse.TextureBlockStart,
                textureBlock, 0, textureBlock.Length);

            byte[] decodedDLData = Cereal64.Common.Utils.Encoding.MIO0.Decode(displayListBlock);

            List<Vertex> vertices = VertexPacker.BytesToVertices(Cereal64.Common.Utils.Encoding.MIO0.Decode(vertexBlock).ToList());
            VertexCollection vertCollection = new VertexCollection(0x00, vertices);
            byte[] vertsData = vertCollection.RawData;

            List<F3DEXCommand> commands = F3DEXPacker.BytesToCommands(packedBlock.ToList());
            F3DEXCommandCollection commandColl = new F3DEXCommandCollection(0x00, commands);
            byte[] commandsData = commandColl.RawData;

            List<TextureMIORef> textureSegPointers = ReadTextureBank(textureBlock);

            byte[] textureSegData = new byte[textureSegPointers.Sum(t => t.DecompressedSize)];
            int bytePointer = 0;
            for (int i = 0; i < textureSegPointers.Count; i++)
            {
                byte[] tempHolder = new byte[textureSegPointers[i].CompressedSize];
                Array.Copy(_romData, (textureSegPointers[i].RomOffset & 0x00FFFFFF) + MK64_TEXTURE_BANK_OFFSET,
                    tempHolder, 0, textureSegPointers[i].CompressedSize);
                byte[] decompressed = Cereal64.Common.Utils.Encoding.MIO0.Decode(tempHolder);
                Array.Copy(decompressed, 0, textureSegData, bytePointer, decompressed.Length);
                bytePointer += decompressed.Length;
            }

            //Use the F3DEXReader here
            RomProject.Instance.AddRomFile(new RomFile("Verts", 1, new Cereal64.Common.DataElements.UnknownData(0x00, vertsData)));
            RomProject.Instance.Files[0].FileLength = vertsData.Length;
            RomProject.Instance.AddRomFile(new RomFile("PackedDLs", 2, new Cereal64.Common.DataElements.UnknownData(0x00, commandsData)));
            RomProject.Instance.Files[1].FileLength = commandsData.Length;
            RomProject.Instance.AddRomFile(new RomFile("Textures", 3, new Cereal64.Common.DataElements.UnknownData(0x00, textureSegData)));
            RomProject.Instance.Files[2].FileLength = textureSegData.Length;

            DmaProfile profile = new DmaProfile("Levelviewer");
            DmaSegment segment = new DmaSegment();
            segment.File = RomProject.Instance.Files[0];
            segment.RamSegment = 0x04;
            segment.RamStartOffset = 0x00;
            segment.FileStartOffset = 0x00;
            segment.FileEndOffset = segment.File.FileLength;
            segment.TagInfo = "Vertices";
            profile.AddDmaSegment(0x04, segment);
            segment = new DmaSegment();
            segment.File = RomProject.Instance.Files[1];
            segment.RamSegment = 0x07;
            segment.RamStartOffset = 0x00;
            segment.FileStartOffset = 0x00;
            segment.FileEndOffset = segment.File.FileLength;
            segment.TagInfo = "PackedDLs";
            profile.AddDmaSegment(0x07, segment);
            segment = new DmaSegment();
            segment.File = RomProject.Instance.Files[2];
            segment.RamSegment = 0x05;
            segment.RamStartOffset = 0x00;
            segment.FileStartOffset = 0x00;
            segment.FileEndOffset = segment.File.FileLength;
            segment.TagInfo = "Textures";
            profile.AddDmaSegment(0x05, segment);
            RomProject.Instance.AddDmaProfile(profile);
            DmaManager.Instance.AddNewDmaProfile(profile);

            F3DEXReaderPackage package = F3DEXReader.ReadF3DEXAt(RomProject.Instance.Files[1], 0x00);
            F3DEXReaderPackage newPackage = package;
            newPackage = null;

            if (package.Elements[RomProject.Instance.Files[1]][0] is F3DEXCommandCollection)
            {
                OpenGLForm glForm = new OpenGLForm();
                glForm.Show();
                glForm.SetCommands((F3DEXCommandCollection)package.Elements[RomProject.Instance.Files[1]][0]);
            }
        }
        public static VO64GraphicsCollection ReadCommands(F3DEXCommandCollection commands)
        {
            //Set up the VO64 graphics
            VO64GraphicsCollection collection = new VO64GraphicsCollection();
            VO64GraphicsElement element = VO64GraphicsElement.CreateNewElement();

            Texture lastTexture = null;
            F3DEX_G_SetTile lastSetTile = null;
            F3DEX_G_Texture lastTextureCommand = null;

            List<uint> vertexOffsetList = new List<uint>(); //Keeps track of which vertices are loaded where
            List<Vertex> vertices = new List<Vertex>();
            F3DEXVertexWrapper newVertex = null;
            F3DEXTextureWrapper newTexture = null;
            bool recordTileCommands = true; //Use RDPLoadSync and RDPTileSync to determine when it's okay to pick up SetTile commands
            //Note: Not guaranteed for all ways of using F3DEX!!

            foreach(F3DEXCommand command in commands.Commands)
            {
                switch (command.CommandID)
                {
                    case F3DEXCommandID.F3DEX_G_RDPLOADSYNC:
                        recordTileCommands = true;
                        break;
                    case F3DEXCommandID.F3DEX_G_RDPTILESYNC:
                        recordTileCommands = true;
                        break;
                    case F3DEXCommandID.F3DEX_G_DL: //ignore this one for now
                        break;
                    case F3DEXCommandID.F3DEX_G_SETTILE:
                        if (((F3DEX_G_SetTile)command).Line != 0)//recordTileCommands)
                        {
                            //keep track of this command when setting up the texture
                            lastSetTile = (F3DEX_G_SetTile)command;
                            recordTileCommands = true;
                        }
                        break;
                    case F3DEXCommandID.F3DEX_G_TEXTURE:
                        lastTextureCommand = (F3DEX_G_Texture)command;
                        break;
                    case F3DEXCommandID.F3DEX_G_VTX:
                        //Record the vertex offset here, to keep track of vertex counts
                        F3DEX_G_Vtx vtxCommand = (F3DEX_G_Vtx)command;
                        break;
                    case F3DEXCommandID.F3DEX_G_TRI1:

                        if (((F3DEX_G_Tri1)command).TextureReference != null &&
                            lastTexture != ((F3DEX_G_Tri1)command).TextureReference)
                        {
                            //save the element
                            if (!element.IsEmpty)
                            {
                                collection.Add(element);
                                element = VO64GraphicsElement.CreateNewElement();
                            }
                            vertices.Clear();

                            //Set the texture here
                            lastTexture = ((F3DEX_G_Tri1)command).TextureReference;
                            newTexture = new F3DEXTextureWrapper(lastTexture, lastSetTile, lastTextureCommand);
                            element.SetTexture(newTexture);
                        }

                        F3DEX_G_Tri1 tri = (F3DEX_G_Tri1)command;
                        if (tri.Vertex1Reference != null && tri.Vertex2Reference != null && tri.Vertex3Reference != null)
                        {
                            if (!vertices.Contains(tri.Vertex1Reference))
                            {
                                vertices.Add(tri.Vertex1Reference);
                                newVertex = new F3DEXVertexWrapper(tri.Vertex1Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }
                            if (!vertices.Contains(tri.Vertex2Reference))
                            {
                                vertices.Add(tri.Vertex2Reference);
                                newVertex = new F3DEXVertexWrapper(tri.Vertex2Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }
                            if (!vertices.Contains(tri.Vertex3Reference))
                            {
                                vertices.Add(tri.Vertex3Reference);
                                newVertex = new F3DEXVertexWrapper(tri.Vertex3Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }

                            VO64SimpleTriangle triangle = new VO64SimpleTriangle((ushort)vertices.IndexOf(tri.Vertex1Reference),
                                (ushort)vertices.IndexOf(tri.Vertex2Reference),
                                    (ushort)vertices.IndexOf(tri.Vertex3Reference));//new F3DEXTriangleWrapper((F3DEX_G_Tri1)command);

                            element.AddTriangle(triangle);
                        }

                        break;
                    case F3DEXCommandID.F3DEX_G_TRI2:

                        if (((F3DEX_G_Tri2)command).TextureReference != null &&
                            lastTexture != ((F3DEX_G_Tri2)command).TextureReference)
                        {
                            //save the element
                            if (!element.IsEmpty)
                            {
                                collection.Add(element);
                                element = VO64GraphicsElement.CreateNewElement();
                            }
                            vertices.Clear();

                            //Set the texture here
                            lastTexture = ((F3DEX_G_Tri2)command).TextureReference;
                            newTexture = F3DEXWrapperBank.GetTextureWrapper(lastTexture, lastSetTile, lastTextureCommand);
                            element.SetTexture(newTexture);
                        }

                        F3DEX_G_Tri2 tri2 = (F3DEX_G_Tri2)command;

                        if (tri2.Vertex1Reference != null && tri2.Vertex2Reference != null && tri2.Vertex3Reference != null)
                        {
                            if (!vertices.Contains(tri2.Vertex1Reference))
                            {
                                vertices.Add(tri2.Vertex1Reference);
                                newVertex = F3DEXWrapperBank.GetVertexWrapper(tri2.Vertex1Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }
                            if (!vertices.Contains(tri2.Vertex2Reference))
                            {
                                vertices.Add(tri2.Vertex2Reference);
                                newVertex = F3DEXWrapperBank.GetVertexWrapper(tri2.Vertex2Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }
                            if (!vertices.Contains(tri2.Vertex3Reference))
                            {
                                vertices.Add(tri2.Vertex3Reference);
                                newVertex = F3DEXWrapperBank.GetVertexWrapper(tri2.Vertex3Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }

                            VO64SimpleTriangle triangle2 = new VO64SimpleTriangle((ushort)vertices.IndexOf(tri2.Vertex1Reference),
                                (ushort)vertices.IndexOf(tri2.Vertex2Reference),
                                    (ushort)vertices.IndexOf(tri2.Vertex3Reference));//new F3DEXTriangleWrapper((F3DEX_G_Tri1)command);

                            element.AddTriangle(triangle2);
                        }

                        if (tri2.Vertex4Reference != null && tri2.Vertex5Reference != null && tri2.Vertex6Reference != null)
                        {
                            if (!vertices.Contains(tri2.Vertex4Reference))
                            {
                                vertices.Add(tri2.Vertex4Reference);
                                newVertex = F3DEXWrapperBank.GetVertexWrapper(tri2.Vertex4Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }
                            if (!vertices.Contains(tri2.Vertex5Reference))
                            {
                                vertices.Add(tri2.Vertex5Reference);
                                newVertex = F3DEXWrapperBank.GetVertexWrapper(tri2.Vertex5Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }
                            if (!vertices.Contains(tri2.Vertex6Reference))
                            {
                                vertices.Add(tri2.Vertex6Reference);
                                newVertex = F3DEXWrapperBank.GetVertexWrapper(tri2.Vertex6Reference);
                                newVertex.SetTextureProperties(newTexture);
                                element.AddVertex(newVertex);
                            }

                            VO64SimpleTriangle triangle2 = new VO64SimpleTriangle((ushort)vertices.IndexOf(tri2.Vertex4Reference),
                                (ushort)vertices.IndexOf(tri2.Vertex5Reference),
                                    (ushort)vertices.IndexOf(tri2.Vertex6Reference));//new F3DEXTriangleWrapper((F3DEX_G_Tri1)command);

                            element.AddTriangle(triangle2);
                        }

                        break;
                }
            }

            collection.Add(element);

            return collection;
        }