Exemplo n.º 1
0
        private static void TriangleMapParse_cmd04(ROM rom, TriangleMap map, TriangleMapParseState state)
        {
            state.vertexLoadCmd = (UInt64)rom.Read64();
            byte vertexDesc = rom.Read8(1);

            byte  vertexCount            = (byte)(((vertexDesc & 0xF0) >> 4) + 1);
            byte  vertexOffset           = (byte)((vertexDesc & 0x0F));
            Int32 vertexSegmentedAddress = rom.Read32(4);

            state.segmentedVertexBufferAddress = vertexSegmentedAddress;

            Int32 romPtr = rom.GetROMAddress(vertexSegmentedAddress);

            if (romPtr == -1)
            {
                throw new ArgumentException("Invalid segmented address!");
            }

            rom.PushOffset(romPtr);
            for (int vertex = vertexOffset; vertex < vertexCount; vertex++)
            {
                Int64 lo = rom.Read64();
                Int64 hi = rom.Read64(8);

                state.vbuf[vertex]         = new Vertex((UInt64)lo, (UInt64)hi);
                state.vbufRomStart[vertex] = rom.offset;
                state.scrollBuf[vertex]    = FindMatchingScroll(state.scrolls, vertexSegmentedAddress, state.td);

                rom.AddOffset(0x10);
                vertexSegmentedAddress += 0x10;
            }
            rom.PopOffset();
        }
Exemplo n.º 2
0
        private static void TriangleMapParse_cmdBB(ROM rom, TriangleMap map, TriangleMapParseState state)
        {
            if ((UInt64)rom.Read64() == 0xBB000000FFFFFFFF)
            {
                state.state = VisualMapParseStateCmd.Footer;
            }

            TriangleMapParse_common(rom, map, state);
        }
Exemplo n.º 3
0
        private static void TriangleMapParse_cmdFD(ROM rom, TriangleMap map, TriangleMapParseState state)
        {
            UInt64 fdCmd = state.td.GetTextureCMD();

            if (state.state != VisualMapParseStateCmd.Texture)
            {
                state.state = VisualMapParseStateCmd.Texture;
                state.td    = new ScrollingTextureDescription();
                if (state.envColorCmd != null)
                {
                    state.td.Add(state.envColorCmd.GetValueOrDefault(), 0 /*FIXME*/);
                }
            }
            TriangleMapParse_common(rom, map, state);
        }
Exemplo n.º 4
0
        private static void TriangleMapParse_cmdFB(ROM rom, TriangleMap map, TriangleMapParseState state)
        {
            // Some importers have the only EnvColor func for everything lmfao
            if (rom.Read8(8) != 0xFD)
            {
                goto fini;
            }

            state.state       = VisualMapParseStateCmd.Texture;
            state.envColorCmd = (ulong)rom.Read64();
            state.td          = new ScrollingTextureDescription();

fini:
            TriangleMapParse_common(rom, map, state);
        }
Exemplo n.º 5
0
        private static void TriangleMapParse_cmdBF(ROM rom, TriangleMap map, TriangleMapParseState state)
        {
            state.isHeader = false;
            state.state    = VisualMapParseStateCmd.Footer;

            byte v0index = (byte)(rom.Read8(5) / 0xA);
            byte v1index = (byte)(rom.Read8(6) / 0xA);
            byte v2index = (byte)(rom.Read8(7) / 0xA);

            state.vertexBytes.AddRegion(state.vbufRomStart[v0index], 0x10);
            state.vertexBytes.AddRegion(state.vbufRomStart[v1index], 0x10);
            state.vertexBytes.AddRegion(state.vbufRomStart[v2index], 0x10);

            // This assumes all scrolls are scrolling at the same speed which is usually true :3
            if (state.scrollBuf[v0index] != state.scrollBuf[v1index] ||
                state.scrollBuf[v0index] != state.scrollBuf[v2index] ||
                state.scrollBuf[v1index] != state.scrollBuf[v2index])
            {
                throw new Exception("Vertices are scrolling at different scrolls");
            }

            Scroll scroll = state.scrollBuf[v0index];

            if ((scroll == null && state.td.scroll != null) ||
                (scroll != null && !scroll.Equals(state.td.scroll)))
            {
                ScrollingTextureDescription oldTd = state.td;

                state.td = new ScrollingTextureDescription();
                state.td.AddRange(oldTd);
                state.td.scroll = scroll;
                if (scroll is EditorScroll editorScroll)
                {
                    state.td.RegisterScroll(editorScroll);
                }
                if (scroll is TextureScroll)
                {
                    state.td.omitScrollCheck = true;
                }
            }

            state.td.RegisterVertex(state.segmentedVertexBufferAddress + v0index * 0x10);
            state.td.RegisterVertex(state.segmentedVertexBufferAddress + v1index * 0x10);
            state.td.RegisterVertex(state.segmentedVertexBufferAddress + v2index * 0x10);
            map.AddTriangle(state.td, state.vbuf[v0index], state.vbuf[v1index], state.vbuf[v2index]);
        }
Exemplo n.º 6
0
        private static void TriangleMapParse_common(ROM rom, TriangleMap map, TriangleMapParseState state)
        {
            switch (state.state)
            {
            case VisualMapParseStateCmd.Header:
                map.AddHeaderCmd((UInt64)rom.Read64());
                break;

            case VisualMapParseStateCmd.Texture:
                state.td.Add((UInt64)rom.Read64(), rom.GetSegmentedAddress(rom.offset));
                break;

            case VisualMapParseStateCmd.Footer:
                map.AddFooterCmd((UInt64)rom.Read64());
                break;
            }
        }
Exemplo n.º 7
0
        public static void PerformTriangleMapRebuild(ROM realRom, Region region, int maxDLLength, List <ScrollObject> scrolls)
        {
            TriangleMapParseState state    = new TriangleMapParseState(scrolls);
            DisplayListRegion     dlRegion = (DisplayListRegion)region;
            TriangleMap           map      = new TriangleMap();

            realRom.PushOffset(region.romStart);
            byte curCmdIndex;

            do
            {
                curCmdIndex = realRom.Read8();
                TriangleMapParserCmd func = triangleMapParser[curCmdIndex];
                func(realRom, map, state);
                realRom.AddOffset(8);
            }while (realRom.offset < region.romStart + region.length);
            realRom.PopOffset();

            ROM fakeRom = (ROM)realRom.Clone();

            // bzero
            fakeRom.PushOffset(region.romStart);
            {
                do
                {
                    fakeRom.Write64(0x0101010101010101);
                    fakeRom.AddOffset(8);
                } while (fakeRom.offset < region.romStart + region.length);
            }
            fakeRom.PopOffset();

            fakeRom.offset = region.romStart;
            int triangleMapLength = map.MakeF3D(fakeRom, state.vertexBytes, new ScrollFactory(scrolls));

            if (triangleMapLength > maxDLLength)
            {
                throw new OutOfMemoryException("No memory for DL available :(");
            }

            realRom.TransferFrom(fakeRom);

            realRom.offset = fakeRom.offset;
            region.length  = realRom.offset - region.romStart;
            region.data    = new byte[region.length];
            realRom.ReadData(region.romStart, region.length, region.data);
        }
Exemplo n.º 8
0
        public Mesh Create(int X, int Y, Map Map_, TerrainTileSet TileSet)
        {
            Map map = Map_;

            // Create vertex array
            Vector3[] array_vec = new Vector3[PARTITION_WIDTH * PARTITION_HEIGHT * 4];
            // Create triangles array
            int[] array_tri = new int[PARTITION_WIDTH * PARTITION_HEIGHT * 6];
            // Create UV arrays
            Vector2[] uv1 = new Vector2[array_vec.Length];
            Vector2[] uv2 = new Vector2[array_vec.Length];
            Vector4[] uv3 = new Vector4[array_vec.Length];
            // Triangle map
            m_TerrainMap = new TriangleMap[PARTITION_WIDTH * PARTITION_HEIGHT * 2];
            // Go through all tiles
            int partition_begin_x = 0;
            int partition_begin_y = 0;
            int partition_height  = PARTITION_HEIGHT;
            int partition_width   = PARTITION_WIDTH;

            for (int i = partition_begin_y, last_vertex = 0; i < partition_height; ++i)
            {
                for (int j = partition_begin_x; j < partition_width; ++j)
                {
                    // Get Tile
                    ja2.TerrainTile tile = map.GetTile(j + X * PARTITION_WIDTH, i + Y * PARTITION_HEIGHT);
                    // Create vertices
                    array_vec[GetVertexIndex(j, i)]     = TileVertex(j, i, 0);
                    array_vec[GetVertexIndex(j, i) + 1] = TileVertex(j, i, 1);
                    array_vec[GetVertexIndex(j, i) + 2] = TileVertex(j, i, 2);
                    array_vec[GetVertexIndex(j, i) + 3] = TileVertex(j, i, 3);

                    last_vertex += 4;
                    // Get the tile material types
                    byte mat_v0 = tile.GetTerrainType(ja2.TerrainTile.Vertex.NORTH),
                         mat_v1 = tile.GetTerrainType(ja2.TerrainTile.Vertex.WEST),
                         mat_v2 = tile.GetTerrainType(ja2.TerrainTile.Vertex.SOUTH),
                         mat_v3 = tile.GetTerrainType(ja2.TerrainTile.Vertex.EAST);
                    // Get 1. and 2. material
                    byte mat_1 = mat_v0;
                    byte mat_2 = mat_1;
                    if (mat_v0 != mat_v1)
                    {
                        mat_2 = mat_v1;
                    }
                    else if (mat_v0 != mat_v2)
                    {
                        mat_2 = mat_v2;
                    }
                    else if (mat_v0 != mat_v3)
                    {
                        mat_2 = mat_v3;
                    }
                    // Get alpha splat index
                    byte alpha_index = 1;
                    alpha_index |= (byte)((mat_v1 == mat_1) ? 2 : 0);
                    alpha_index |= (byte)((mat_v2 == mat_1) ? 4 : 0);
                    alpha_index |= (byte)((mat_v3 == mat_1) ? 8 : 0);
                    // If materials need to be inverted
                    if (alpha_index > 7)
                    {
                        byte mat_helper = mat_1;
                        mat_1       = mat_2;
                        mat_2       = mat_helper;
                        alpha_index = (byte)(~alpha_index & 15);
                    }
                    // Get the primary tile type information
                    TextureAtlasInfo primary_mat_info = TileSet.GetTileType(mat_1, tile.variant);
                    // Get secondary tile type information
                    TextureAtlasInfo secondary_mat_info = TileSet.GetTileType(mat_2, tile.variant);
                    // Get the alpha splat info for tile
                    TextureAtlasInfo alpha_splat_mat_info = TileSet.splatUsed.GetSplat(alpha_index);

                    // Texture coordinates
                    uv1[last_vertex - 4] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth / 2, primary_mat_info.uvOffsetH);
                    uv1[last_vertex - 3] = new Vector2(primary_mat_info.uvOffsetW, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight / 2);
                    uv1[last_vertex - 2] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth / 2, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight);
                    uv1[last_vertex - 1] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight / 2);

                    uv2[last_vertex - 4] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth / 2, secondary_mat_info.uvOffsetH);
                    uv2[last_vertex - 3] = new Vector2(secondary_mat_info.uvOffsetW, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight / 2);
                    uv2[last_vertex - 2] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth / 2, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight);
                    uv2[last_vertex - 1] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight / 2);

                    uv3[last_vertex - 4] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth / 2, alpha_splat_mat_info.uvOffsetH, 0);
                    uv3[last_vertex - 3] = new Vector4(alpha_splat_mat_info.uvOffsetW, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight / 2, 0, 0);
                    uv3[last_vertex - 2] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth / 2, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight, 0, 0);
                    uv3[last_vertex - 1] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight / 2, 0, 0);
                    // Create triangles
                    int triangle_index = GetTriIndex(j, i);
                    array_tri[triangle_index]     = last_vertex - 4;
                    array_tri[triangle_index + 1] = last_vertex - 1;
                    array_tri[triangle_index + 2] = last_vertex - 3;

                    array_tri[triangle_index + 3] = last_vertex - 3;
                    array_tri[triangle_index + 4] = last_vertex - 1;
                    array_tri[triangle_index + 5] = last_vertex - 2;
                    // Save triangles
                    int triangle_index_raw = j * 2 + i * PARTITION_WIDTH * 2;
                    m_TerrainMap[triangle_index_raw]     = new TriangleMap(tile.x, tile.y);
                    m_TerrainMap[triangle_index_raw + 1] = new TriangleMap(tile.x, tile.y);
                }
            }

            Mesh mesh = new Mesh();

            mesh.vertices  = array_vec;
            mesh.triangles = array_tri;
            mesh.uv        = uv1;
            mesh.uv2       = uv2;
            mesh.tangents  = uv3;
            mesh.RecalculateNormals();

            return(mesh);
        }
Exemplo n.º 9
0
        public Mesh Create(int X, int Y, Map Map_, TerrainTileSet TileSet)
        {
            Map map = Map_;
            // Create vertex array
            Vector3[] array_vec = new Vector3[PARTITION_WIDTH * PARTITION_HEIGHT * 4];
            // Create triangles array
            int[] array_tri = new int[PARTITION_WIDTH * PARTITION_HEIGHT * 6];
            // Create UV arrays
            Vector2[] uv1 = new Vector2[array_vec.Length];
            Vector2[] uv2 = new Vector2[array_vec.Length];
            Vector4[] uv3 = new Vector4[array_vec.Length];
            // Triangle map
            m_TerrainMap = new TriangleMap[PARTITION_WIDTH * PARTITION_HEIGHT * 2];
            // Go through all tiles
            int partition_begin_x = 0;
            int partition_begin_y = 0;
            int partition_height = PARTITION_HEIGHT;
            int partition_width = PARTITION_WIDTH;
            for (int i = partition_begin_y, last_vertex = 0; i < partition_height; ++i)
            {
                for (int j = partition_begin_x; j < partition_width; ++j)
                {
                    // Get Tile
                    ja2.TerrainTile tile = map.GetTile(j + X * PARTITION_WIDTH, i + Y * PARTITION_HEIGHT);
                    // Create vertices
                    array_vec[GetVertexIndex(j, i)] = TileVertex(j, i, 0);
                    array_vec[GetVertexIndex(j, i) + 1] = TileVertex(j, i, 1);
                    array_vec[GetVertexIndex(j, i) + 2] = TileVertex(j, i, 2);
                    array_vec[GetVertexIndex(j, i) + 3] = TileVertex(j, i, 3);

                    last_vertex += 4;
                    // Get the tile material types
                    byte mat_v0 = tile.GetTerrainType(ja2.TerrainTile.Vertex.NORTH),
                        mat_v1 = tile.GetTerrainType(ja2.TerrainTile.Vertex.WEST),
                        mat_v2 = tile.GetTerrainType(ja2.TerrainTile.Vertex.SOUTH),
                        mat_v3 = tile.GetTerrainType(ja2.TerrainTile.Vertex.EAST);
                    // Get 1. and 2. material
                    byte mat_1 = mat_v0;
                    byte mat_2 = mat_1;
                    if (mat_v0 != mat_v1)
                        mat_2 = mat_v1;
                    else if (mat_v0 != mat_v2)
                        mat_2 = mat_v2;
                    else if (mat_v0 != mat_v3)
                        mat_2 = mat_v3;
                    // Get alpha splat index
                    byte alpha_index = 1;
                    alpha_index |= (byte)((mat_v1 == mat_1) ? 2 : 0);
                    alpha_index |= (byte)((mat_v2 == mat_1) ? 4 : 0);
                    alpha_index |= (byte)((mat_v3 == mat_1) ? 8 : 0);
                    // If materials need to be inverted
                    if (alpha_index > 7)
                    {
                        byte mat_helper = mat_1;
                        mat_1 = mat_2;
                        mat_2 = mat_helper;
                        alpha_index = (byte)(~alpha_index & 15);
                    }
                    // Get the primary tile type information
                    TextureAtlasInfo primary_mat_info = TileSet.GetTileType(mat_1, tile.variant);
                    // Get secondary tile type information
                    TextureAtlasInfo secondary_mat_info = TileSet.GetTileType(mat_2, tile.variant);
                    // Get the alpha splat info for tile
                    TextureAtlasInfo alpha_splat_mat_info = TileSet.splatUsed.GetSplat(alpha_index);

                    // Texture coordinates
                    uv1[last_vertex - 4] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth / 2, primary_mat_info.uvOffsetH);
                    uv1[last_vertex - 3] = new Vector2(primary_mat_info.uvOffsetW, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight / 2);
                    uv1[last_vertex - 2] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth / 2, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight);
                    uv1[last_vertex - 1] = new Vector2(primary_mat_info.uvOffsetW + primary_mat_info.uvWidth, primary_mat_info.uvOffsetH - primary_mat_info.uvHeight / 2);

                    uv2[last_vertex - 4] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth / 2, secondary_mat_info.uvOffsetH);
                    uv2[last_vertex - 3] = new Vector2(secondary_mat_info.uvOffsetW, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight / 2);
                    uv2[last_vertex - 2] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth / 2, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight);
                    uv2[last_vertex - 1] = new Vector2(secondary_mat_info.uvOffsetW + secondary_mat_info.uvWidth, secondary_mat_info.uvOffsetH - secondary_mat_info.uvHeight / 2);

                    uv3[last_vertex - 4] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth / 2, alpha_splat_mat_info.uvOffsetH, 0);
                    uv3[last_vertex - 3] = new Vector4(alpha_splat_mat_info.uvOffsetW, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight / 2, 0, 0);
                    uv3[last_vertex - 2] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth / 2, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight, 0, 0);
                    uv3[last_vertex - 1] = new Vector4(alpha_splat_mat_info.uvOffsetW + alpha_splat_mat_info.uvWidth, alpha_splat_mat_info.uvOffsetH - alpha_splat_mat_info.uvHeight / 2, 0, 0);
                    // Create triangles
                    int triangle_index = GetTriIndex(j, i);
                    array_tri[triangle_index] = last_vertex - 4;
                    array_tri[triangle_index + 1] = last_vertex - 1;
                    array_tri[triangle_index + 2] = last_vertex - 3;

                    array_tri[triangle_index + 3] = last_vertex - 3;
                    array_tri[triangle_index + 4] = last_vertex - 1;
                    array_tri[triangle_index + 5] = last_vertex - 2;
                    // Save triangles
                    int triangle_index_raw = j * 2 + i * PARTITION_WIDTH * 2;
                    m_TerrainMap[triangle_index_raw] = new TriangleMap(tile.x, tile.y);
                    m_TerrainMap[triangle_index_raw + 1] = new TriangleMap(tile.x, tile.y);
                }
            }

            Mesh mesh = new Mesh();
            mesh.vertices = array_vec;
            mesh.triangles = array_tri;
            mesh.uv = uv1;
            mesh.uv2 = uv2;
            mesh.tangents = uv3;
            mesh.RecalculateNormals();

            return mesh;
        }
Exemplo n.º 10
0
 private static void TriangleMapParse_cmdF2(ROM rom, TriangleMap map, TriangleMapParseState state)
 {
     TriangleMapParse_common(rom, map, state);
     state.state = state.isHeader ? VisualMapParseStateCmd.Header : VisualMapParseStateCmd.Footer; // Case for fog
 }
Exemplo n.º 11
0
        public static void RebuildTriangleMap(ROM realRom, Region region, int maxDLLength, TriangleMap map, SortedRegionList vertexData, ScrollFactory factory)
        {
            ROM fakeRom = (ROM)realRom.Clone();

            // bzero
            fakeRom.PushOffset(region.romStart);
            {
                do
                {
                    fakeRom.Write64(0x0101010101010101);
                    fakeRom.AddOffset(8);
                } while (fakeRom.offset < region.romStart + region.length);
            }
            fakeRom.PopOffset();

            fakeRom.offset = region.romStart;
            int triangleMapLength = map.MakeF3D(fakeRom, vertexData, factory);

            if (triangleMapLength > maxDLLength)
            {
                throw new OutOfMemoryException("No memory for DL available :(");
            }

            realRom.TransferFrom(fakeRom);

            realRom.offset = fakeRom.offset;
            region.length  = realRom.offset - region.romStart;
            region.data    = new byte[region.length];
            realRom.ReadData(region.romStart, region.length, region.data);
        }
Exemplo n.º 12
0
        public static void GetTriangleMap(ROM realRom, Region region, int maxDLLength, List <ScrollObject> scrolls, out TriangleMap map, out SortedRegionList vertexData)
        {
            TriangleMapParseState state    = new TriangleMapParseState(scrolls);
            DisplayListRegion     dlRegion = (DisplayListRegion)region;

            map = new TriangleMap();

            realRom.PushOffset(region.romStart);
            byte curCmdIndex;

            do
            {
                curCmdIndex = realRom.Read8();
                TriangleMapParserCmd func = triangleMapParser[curCmdIndex];
                func(realRom, map, state);
                realRom.AddOffset(8);
            }while (realRom.offset < region.romStart + region.length);
            realRom.PopOffset();

            // Check map validity
            // There are 2 possible ways to mess up scroll
            // 'Too much' - scroll is performing too much scrolling, 1st warn detect, 2nd falsing, 3rd can fix such scroll if scrolls are done properly
            // 'Not enough' - scroll is not scrolling the whole texture, 2nd warn may be able to detect that, no fix yet but 'stretch' the scroll should work

            // I assume there is no scrolls that do not correspond to no texture, such case will leave weird things :)

            // Currently ScrollingTextures cannot be longed so it is impossible to fix 'Not enough' :(
            List <ScrollingTextureDescription> brokenTextures = new List <ScrollingTextureDescription>();

            {
                // Not enough
                HashSet <TextureDescription> scrollingTds = new HashSet <TextureDescription>(map.map.Keys.Where(k => k.scroll != null));
                foreach (TextureDescription td in scrollingTds)
                {
                    var stds = map.map.Keys.Where(k => k.Equals(td)).ToList();
                    if (stds.Count() > 1)
                    {
                        int a = 0;
                    }
                }

                // Check if scroll 'fits'
                foreach (ScrollingTextureDescription std in map.map.Keys)
                {
                    if (std.scroll == null)
                    {
                        continue;
                    }

                    if (!std.vertexRegions.Equals(std.scrollRegions))
                    {
                        brokenTextures.Add(std);
                    }
                }
            }

            foreach (ScrollingTextureDescription brokenTd in brokenTextures)
            {
                if (brokenTd.omitScrollCheck)
                {
                    continue;
                }

                // Figure out the way to "heal", either drop scroll or extend it
                // If scroll does not start at the same  place, just drop it, such solution may backfire if 2 scrolls intersect
                bool shouldDrop = brokenTd.scrollRegions.RegionList.First().Key != brokenTd.vertexRegions.RegionList.First().Key;

                if (shouldDrop)
                {
                    // Find if texture without scroll exists, if it does, merge tris in it, otherwise drop the scroll
                    List <ScrollingTextureDescription> similarTextures = map.map.Keys.Where(k => k.scroll == null).Where(k => TextureDescription.Equals(brokenTd, k)).ToList();
                    if (similarTextures.Count() != 0)
                    {
                        ScrollingTextureDescription stdNoScroll = similarTextures[0];
                        List <Triangle>             tris        = map.map[brokenTd];
                        map.map.Remove(brokenTd);
                        map.map[stdNoScroll].AddRange(tris);
                    }
                    else
                    {
                        state.td.scroll = null;
                    }
                }
                else
                {
                    // Find if texture without scroll exists, if it does, merge tris from it (make it scroll)
                    List <ScrollingTextureDescription> similarTextures = map.map.Keys.Where(k => k.scroll == null).Where(k => TextureDescription.Equals(brokenTd, k)).ToList();
                    foreach (ScrollingTextureDescription similarStd in similarTextures)
                    {
                        List <Triangle> tris = map.map[similarStd];
                        map.map.Remove(similarStd);
                        map.map[brokenTd].AddRange(tris);
                    }
                }
            }

            vertexData = state.vertexBytes;
        }
Exemplo n.º 13
0
        private void button1_Click(object sender, EventArgs e)
        {
            GC.Collect();
            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                rom.segments = (SegmentDescriptor[])row.Cells[8].Value;
                List <ScrollObject> scrolls = (List <ScrollObject>)row.Cells[9].Value;

                DisplayListRegion     dlRegion       = (DisplayListRegion)row.Cells[0].Value;
                Boolean               fixingCheckBox = (Boolean)row.Cells[1].Value;
                DisplayList.FixConfig config         = new DisplayList.FixConfig(checkBoxNerfFog.Checked, checkBoxOptimizeVertex.Checked, checkBoxTrimNops.Checked, checkBoxCombiners.Checked, checkBoxOtherMode.Checked, checkBoxNoFog.Checked);

                if (fixingCheckBox)
                {
                    if (checkBoxNoFog.Checked)
                    {
                        dlRegion.isFogEnabled = false;
                    }

                    int maxDlLength = dlRegion.length;
                    DisplayList.PerformRegionFix(rom, dlRegion, config);
                    if (checkBoxOptimizeVertex.Checked)
                    {
                        DisplayList.PerformRegionOptimize(rom, dlRegion, config);
                    }

                    try
                    {
                        if (checkBoxGroupByTexture.Checked && !checkBoxRebuildVertices.Checked)
                        {
                            DisplayList.PerformVisualMapRebuild(rom, dlRegion, maxDlLength);
                        }
                        //DisplayList.PerformRegionOptimize(rom, dlRegion, config);
                    }
                    catch (Exception) { }
                }
            }

            if (checkBoxGroupByTexture.Checked && checkBoxRebuildVertices.Checked)
            {
                Dictionary <int, List <DataGridViewRow> > levelDatas = new Dictionary <int, List <DataGridViewRow> >();
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    Boolean fixingCheckBox = (Boolean)row.Cells[1].Value;
                    if (!fixingCheckBox)
                    {
                        continue;
                    }

                    int level = (int)row.Cells[3].Value;
                    if (!levelDatas.Keys.Contains(level))
                    {
                        levelDatas[level] = new List <DataGridViewRow>();
                    }

                    levelDatas[level].Add(row);
                }

                foreach (int level in levelDatas.Keys)
                {
                    ROM romCopy = (ROM)rom.Clone();
                    try
                    {
                        List <DataGridViewRow> rows = levelDatas[level];
                        rom.segments = (SegmentDescriptor[])rows[0].Cells[8].Value;
                        List <ScrollObject> scrolls = (List <ScrollObject>)rows[0].Cells[9].Value;
                        foreach (ScrollObject scr in scrolls)
                        {
                            scr.Disable(rom);
                        }
                        ScrollFactory factory = new ScrollFactory(scrolls);

                        SortedRegionList vertexData = new SortedRegionList();
                        List <KeyValuePair <DataGridViewRow, TriangleMap> > rowMaps = new List <KeyValuePair <DataGridViewRow, TriangleMap> >();

                        foreach (DataGridViewRow row in rows)
                        {
                            DisplayListRegion dlRegion = (DisplayListRegion)row.Cells[0].Value;
                            int maxDlLength            = dlRegion.length;

                            DisplayList.GetTriangleMap(rom, dlRegion, maxDlLength, scrolls, out TriangleMap map, out SortedRegionList levelVertexData);
                            rowMaps.Add(new KeyValuePair <DataGridViewRow, TriangleMap>(row, map));
                            vertexData.AddRegions(levelVertexData);
                        }

                        foreach (KeyValuePair <DataGridViewRow, TriangleMap> kvp in rowMaps)
                        {
                            DataGridViewRow row = kvp.Key;
                            TriangleMap     map = kvp.Value;

                            DisplayListRegion dlRegion = (DisplayListRegion)row.Cells[0].Value;
                            int maxDlLength            = dlRegion.length;

                            DisplayList.RebuildTriangleMap(rom, dlRegion, maxDlLength, map, vertexData, factory);
                        }
                    }
                    catch (Exception)
                    {
                        rom = romCopy;
                    }
                }
            }

            File.WriteAllBytes(path, rom.rom);

            MessageBox.Show(String.Format("ROM was patched successfully"), "f3d fix", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }