Exemplo n.º 1
0
        public static VO64GraphicsCollection ReadCommands(F3DZEXCommandCollection commands)
        {
            //Set up the VO64 graphics
            VO64GraphicsCollection collection = new VO64GraphicsCollection();
            VO64GraphicsElement element = VO64GraphicsElement.CreateNewElement();

            Texture lastTexture = null;
            F3DZEX_G_SetTile lastSetTile = null;
            F3DZEX_G_Texture lastTextureCommand = null;

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

            foreach(F3DZEXCommand command in commands.Commands)
            {
                switch (command.CommandID)
                {
                    case F3DZEXCommandID.F3DZEX_G_RDPLOADSYNC:
                        recordTileCommands = true;
                        break;
                    case F3DZEXCommandID.F3DZEX_G_RDPTILESYNC:
                        recordTileCommands = false;
                        break;
                    case F3DZEXCommandID.F3DZEX_G_DL: //ignore this one for now
                        break;
                    case F3DZEXCommandID.F3DZEX_G_SETTILE:
                        if (recordTileCommands)
                        {
                            //keep track of this command when setting up the texture
                            lastSetTile = (F3DZEX_G_SetTile)command;
                            recordTileCommands = false;
                        }
                        break;
                    case F3DZEXCommandID.F3DZEX_G_TEXTURE:
                        lastTextureCommand = (F3DZEX_G_Texture)command;
                        break;
                    case F3DZEXCommandID.F3DZEX_G_VTX:
                        //Record the vertex offset here, to keep track of vertex counts
                        F3DZEX_G_Vtx vtxCommand = (F3DZEX_G_Vtx)command;
                        break;
                    case F3DZEXCommandID.F3DZEX_G_TRI1:

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

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

                        F3DZEX_G_Tri1 tri = (F3DZEX_G_Tri1)command;
                        if (!vertices.Contains(tri.Vertex1Reference))
                        {
                            vertices.Add(tri.Vertex1Reference);
                            newVertex = new F3DZEXVertexWrapper(tri.Vertex1Reference);
                            newVertex.SetTextureProperties(newTexture);
                            element.AddVertex(newVertex);
                        }
                        if (!vertices.Contains(tri.Vertex2Reference))
                        {
                            vertices.Add(tri.Vertex2Reference);
                            newVertex = new F3DZEXVertexWrapper(tri.Vertex2Reference);
                            newVertex.SetTextureProperties(newTexture);
                            element.AddVertex(newVertex);
                        }
                        if (!vertices.Contains(tri.Vertex3Reference))
                        {
                            vertices.Add(tri.Vertex3Reference);
                            newVertex = new F3DZEXVertexWrapper(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 F3DZEXTriangleWrapper((F3DZEX_G_Tri1)command);

                        element.AddTriangle(triangle);

                        break;
                    case F3DZEXCommandID.F3DZEX_G_TRI2:

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

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

                        F3DZEX_G_Tri2 tri2 = (F3DZEX_G_Tri2)command;
                        if (!vertices.Contains(tri2.Vertex1Reference))
                        {
                            vertices.Add(tri2.Vertex1Reference);
                            newVertex = F3DZEXWrapperBank.GetVertexWrapper(tri2.Vertex1Reference);
                            newVertex.SetTextureProperties(newTexture);
                            element.AddVertex(newVertex);
                        }
                        if (!vertices.Contains(tri2.Vertex2Reference))
                        {
                            vertices.Add(tri2.Vertex2Reference);
                            newVertex = F3DZEXWrapperBank.GetVertexWrapper(tri2.Vertex2Reference);
                            newVertex.SetTextureProperties(newTexture);
                            element.AddVertex(newVertex);
                        }
                        if (!vertices.Contains(tri2.Vertex3Reference))
                        {
                            vertices.Add(tri2.Vertex3Reference);
                            newVertex = F3DZEXWrapperBank.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 F3DZEXTriangleWrapper((F3DZEX_G_Tri1)command);

                        element.AddTriangle(triangle2);

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

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

                        element.AddTriangle(triangle2);

                        break;
                }
            }

            collection.Add(element);

            return collection;
        }
Exemplo n.º 2
0
        //public static 
        public static F3DZEXReaderPackage ReadF3DZEXAt(RomFile file, int offset)
        {
            ResetReaderVariables();
            
            byte[] data = file.GetAsBytes();

            F3DZEXReaderPackage package = new F3DZEXReaderPackage();

            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);

                F3DZEXCommand f3Command = F3DZEXCommandFactory.ReadCommand(offset, command);
                if (f3Command == null)
                    break;

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

                _foundCommands[file].Add(f3Command);

                ParseCommand(f3Command);

                offset += 8;

                if (f3Command is F3DZEX_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<F3DZEXCommandCollection>> commandColls = new Dictionary<RomFile, List<F3DZEXCommandCollection>>();
            Dictionary<RomFile, List<VertexCollection>> vertexColls = new Dictionary<RomFile, List<VertexCollection>>();

            //F3DZEX Commands
            foreach (RomFile rom in _foundCommands.Keys)
            {
                commandColls.Add(rom, new List<F3DZEXCommandCollection>());
                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
                        F3DZEXCommandCollection newColl = new F3DZEXCommandCollection(_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;
        }