Beispiel #1
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);
        }
Beispiel #2
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;
        }
Beispiel #3
0
        static DisplayList()
        {
            Type t = typeof(DisplayList);

            for (int i = 0x00; i < 0xFF; i++)
            {
                parser[i] = RegionParse_common;

                string     name = "RegionParse_cmd" + string.Format("{0:X2}", i);
                MethodInfo info = t.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static);
                if (info == null)
                {
                    continue;
                }

                RegionParseCmd cmd = Delegate.CreateDelegate(typeof(RegionParseCmd), info) as RegionParseCmd;
                if (cmd == null)
                {
                    continue;
                }

                parser[i] = cmd;
            }

            for (int i = 0; i < 0xFF; i++)
            {
                fixParser[i] = FixParse_common;

                string     name = "FixParse_cmd" + string.Format("{0:X2}", i);
                MethodInfo info = t.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static);
                if (info == null)
                {
                    continue;
                }

                FixParseCmd cmd = Delegate.CreateDelegate(typeof(FixParseCmd), info) as FixParseCmd;
                if (cmd == null)
                {
                    continue;
                }

                fixParser[i] = cmd;
            }

            for (int i = 0; i < 0xFF; i++)
            {
                optimizeParser[i] = OptimizeParse_common;

                string     name = "OptimizeParse_cmd" + string.Format("{0:X2}", i);
                MethodInfo info = t.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static);
                if (info == null)
                {
                    continue;
                }

                OptimizeParserCmd cmd = Delegate.CreateDelegate(typeof(OptimizeParserCmd), info) as OptimizeParserCmd;
                if (cmd == null)
                {
                    continue;
                }

                optimizeParser[i] = cmd;
            }

            for (int i = 0; i < 0xFF; i++)
            {
                visualMapParser[i] = VisualMapParse_common;

                string     name = "VisualMapParse_cmd" + string.Format("{0:X2}", i);
                MethodInfo info = t.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static);
                if (info == null)
                {
                    continue;
                }

                VisualMapParserCmd cmd = Delegate.CreateDelegate(typeof(VisualMapParserCmd), info) as VisualMapParserCmd;
                if (cmd == null)
                {
                    continue;
                }

                visualMapParser[i] = cmd;
            }

            for (int i = 0; i < 0xFF; i++)
            {
                triangleMapParser[i] = TriangleMapParse_common;

                string     name = "TriangleMapParse_cmd" + string.Format("{0:X2}", i);
                MethodInfo info = t.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static);
                if (info == null)
                {
                    continue;
                }

                TriangleMapParserCmd cmd = Delegate.CreateDelegate(typeof(TriangleMapParserCmd), info) as TriangleMapParserCmd;
                if (cmd == null)
                {
                    continue;
                }

                triangleMapParser[i] = cmd;
            }
        }