示例#1
0
        private static void OptimizeParse_cmdB7(ROM rom, DisplayListRegion region, RegionOptimizeState state)
        {
            // Very failsafe approach
            state.lastB6Cmd = 0;

            Int64 cmd = rom.Read64();

            // Basically NOP
            if ((UInt64)cmd == 0xB700000000000000)
            {
                rom.Write64(0);
                return;
            }


            // initial state
            if (state.lastB7Cmd == 0)
            {
                state.lastB7Cmd = cmd;
                return;
            }

            // if current cmd loads the same, remove current cmd
            if (cmd == state.lastB7Cmd)
            {
                rom.Write64(0);
                return;
            }
        }
示例#2
0
        private static void RelocationParse_cmdB9(ROM rom, RelocationTable table, DisplayListRegion region)
        {
            if (!region.DLFixesNeeded)
            {
                return;
            }

            if (!region.isFogEnabled)
            {
                return;
            }

            if ((ulong)rom.Read64(-8) != 0xBA00140200000000)
            {
                return;
            }

            if (region.layer == 1)
            {
                rom.Write64(0xB900031D00552078);
            }
            if (region.layer == 4)
            {
                rom.Write64(0xB900031D00443078);
            }
            if (region.layer == 5)
            {
                rom.Write64(0xB900031D005049D8);
            }
        }
示例#3
0
        private static void FixParse_cmdB9(ROM rom, DisplayListRegion region, RegionFixState state)
        {
            if (state.config.disableFog)
            {
                rom.Write64(0);
                return;
            }

            if (!state.config.fixOtherMode)
            {
                return;
            }

            if (!region.isFogEnabled)
            {
                return;
            }

            if ((ulong)rom.Read64(-8) != 0xBA00140200000000 || (ulong)rom.Read64(8) != 0xB600000000010000)
            {
                return;
            }

            UInt64 B9Cmd = OtherMode.GetB9Cmd(region.layer);

            if (B9Cmd != 0)
            {
                rom.Write64(B9Cmd);
            }
        }
示例#4
0
        private static void OptimizeParse_cmd04(ROM rom, DisplayListRegion region, RegionOptimizeState state)
        {
            // initial state
            if (state.last04Cmd == 0)
            {
                state.last04Cmd = rom.Read64();
                return;
            }

            Int64 cmd = rom.Read64();

            // if current 04 loads the same vertices, remove current cmd
            if (cmd == state.last04Cmd)
            {
                rom.Write64(0);
                return;
            }

            // new vertices are being loaded, update the thing
            state.last04Cmd = cmd;

            // if previous cmd is 0x04, it will be overriden by current 04 anyways
            if (rom.Read8(-8) == 0x04)
            {
                rom.Write64(0, -8);
            }
        }
示例#5
0
        public static void PerformVisualMapRebuild(ROM realRom, Region region, int maxDLLength)
        {
            // This is fake rom but it works anyways, just more convenient
            // Want to be safe with overwriting the whole display list
            ROM fakeRom = new ROM(region.data);
            VisualMapParseState state = new VisualMapParseState();

            DisplayListRegion dlRegion = (DisplayListRegion)region;
            VisualMap         map      = new VisualMap();

            byte curCmdIndex;

            do
            {
                curCmdIndex = fakeRom.Read8();
                VisualMapParserCmd func = visualMapParser[curCmdIndex];
                func(fakeRom, map, state);
                fakeRom.AddOffset(8);
            }while (fakeRom.offset < region.length);

            ROM visualMapROM    = new ROM(new byte[maxDLLength]);
            int visualMapLength = map.MakeF3D(visualMapROM);


            // Now write data to real rom + trimming
            // bzero
            fakeRom.offset = 0;
            realRom.PushOffset(region.romStart);
            {
                do
                {
                    realRom.Write64(0x0101010101010101);
                    realRom.AddOffset(8);
                    fakeRom.AddOffset(8);
                } while (fakeRom.offset < region.length);
            }
            realRom.PopOffset();

            visualMapROM.offset = 0;
            realRom.PushOffset(region.romStart);
            {
                int start = region.romStart;
                do
                {
                    Int64 cmd = visualMapROM.Read64();
                    visualMapROM.AddOffset(8);

                    realRom.Write64((ulong)cmd);
                    realRom.AddOffset(8);
                } while (visualMapROM.offset < visualMapLength);

                region.length = realRom.offset - start;
                region.data   = new byte[region.length];
                realRom.ReadData(region.romStart, region.length, region.data);
            }
            realRom.PopOffset();
        }
示例#6
0
        public static void PerformRegionOptimize(ROM realRom, Region region, FixConfig config)
        {
            // This is fake rom but it works anyways, just more convenient
            // Want to be safe with overwriting the whole display list
            ROM fakeRom = new ROM(region.data);
            RegionOptimizeState state = new RegionOptimizeState(config);

            DisplayListRegion dlRegion = (DisplayListRegion)region;

            byte curCmdIndex;

            do
            {
                curCmdIndex = fakeRom.Read8();
                OptimizeParserCmd func = optimizeParser[curCmdIndex];
                func(fakeRom, dlRegion, state);
                fakeRom.AddOffset(8);
            }while (fakeRom.offset < region.length);

            // Now write data to real rom + trimming
            // bzero
            fakeRom.offset = 0;
            realRom.PushOffset(region.romStart);
            {
                do
                {
                    realRom.Write64(0x0101010101010101);
                    realRom.AddOffset(8);
                    fakeRom.AddOffset(8);
                } while (fakeRom.offset < region.length);
            }
            realRom.PopOffset();

            fakeRom.offset = 0;
            realRom.PushOffset(region.romStart);
            {
                int start = region.romStart;
                do
                {
                    Int64 cmd = fakeRom.Read64();
                    fakeRom.AddOffset(8);

                    if (config.trimNOPs && cmd == 0 && dlRegion.isUnusedTrimmingAllowed)
                    {
                        continue;
                    }

                    realRom.Write64((ulong)cmd);
                    realRom.AddOffset(8);
                } while (fakeRom.offset < region.length);

                region.length = realRom.offset - start;
                region.data   = new byte[region.length];
                realRom.ReadData(region.romStart, region.length, region.data);
            }
            realRom.PopOffset();
        }
示例#7
0
        public void MakeF3D(ROM rom)
        {
            foreach (UInt64 cmd04 in data.Keys)
            {
                rom.Write64(cmd04);
                rom.AddOffset(8);

                SortedSet <UInt64> set = data[cmd04];
                foreach (UInt64 cmdBF in set)
                {
                    rom.Write64(cmdBF);
                    rom.AddOffset(8);
                }
            }
        }
示例#8
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);
        }
示例#9
0
 private static void FixParse_cmdF8(ROM rom, DisplayListRegion region, RegionFixState state)
 {
     if (state.config.disableFog)
     {
         rom.Write64(0);
     }
 }
示例#10
0
        private static void FixParse_cmdBC(ROM rom, DisplayListRegion region, RegionFixState state)
        {
            if (state.config.disableFog)
            {
                rom.Write64(0);
                return;
            }

            if (state.config.nerfFog)
            {
                float A = rom.Read16(4);
                float B = rom.Read16(6);

                float min = 500 * (1 - B / A);
                float max = 128000 / A + min;

                // nerf fog
                min += 5;
                A    = 128000 / (max - min);
                B    = (500 - min) * 256 / (max - min);

                int Aint = (int)A;
                int Bint = (int)B;

                rom.Write16(Aint, 4);
                rom.Write16(Bint, 6);
            }
        }
示例#11
0
        private static void OptimizeParse_cmdFD(ROM rom, DisplayListRegion region, RegionOptimizeState state)
        {
            if (state.prevFDcmdAddr != 0)
            {
                rom.PushOffset(state.prevFDcmdAddr);
                rom.Write64(0);
                rom.PopOffset();
            }

            state.prevFDcmdAddr = rom.offset;
        }
示例#12
0
        public void MakeF3D(ROM rom)
        {
            foreach (UInt64 cmd in cmds)
            {
                rom.Write64(cmd);
                if ((cmd & 0xF200000000000000) == 0xF200000000000000)
                {
                    f2SegmentedAddress = rom.GetSegmentedAddress(rom.offset);
                }

                rom.AddOffset(8);
            }
        }
示例#13
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);
        }
示例#14
0
        private static void OptimizeParse_cmdBC(ROM rom, DisplayListRegion region, RegionOptimizeState state)
        {
            Int64 cmd = rom.Read64();

            // initial state
            if (state.lastBCCmd == 0)
            {
                state.lastBCCmd = cmd;
                return;
            }

            // if current cmd loads the same, remove current cmd
            if (cmd == state.lastBCCmd)
            {
                rom.Write64(0);
                return;
            }
        }
示例#15
0
        private static void FixParse_cmdFC(ROM rom, DisplayListRegion region, RegionFixState state)
        {
            if (!state.config.fixCombiners)
            {
                return;
            }

            if (state.FCCountFixed != 0)
            {
                return;
            }

            CombinerCommand cmd   = CombinerCommand.GetNewCombiner(region);
            UInt64          FCCmd = cmd.GetFCcmd();

            if (FCCmd != 0)
            {
                state.FCCountFixed++;
                rom.Write64(FCCmd);
            }
        }
示例#16
0
        private static void RelocationParse_cmdFC(ROM rom, RelocationTable table, DisplayListRegion region)
        {
            if (!region.DLFixesNeeded)
            {
                return;
            }


            UInt64 FCcmd = 0;

            if (region.FCCountFixed == 0)
            {
                if (region.isFogEnabled)
                {
                    if ((ulong)region.B9cmdfirst == 0xB900031DC8112078)
                    {
                        FCcmd = 0xFC127FFFFFFFF838;
                    }

                    if ((ulong)region.B9cmdfirst == 0xB900031DC8113078)
                    {
                        FCcmd = 0xFCFFFFFFFFFCF238;
                    }

                    if (region.isEnvcolorEnabled)
                    {
                        FCcmd = 0xFC127FFFFFFFFA38;
                    }
                }
                else
                {
                    if (region.FCCount == 1)
                    {
                        FCcmd = 0xFC127E24FFFFF9FC;
                    }
                    else
                    {
                        if (!region.isEnvcolorEnabled)
                        {
                            FCcmd = 0xFC121824FF33FFFF;
                        }
                        else
                        {
                            FCcmd = 0xFC122E24FFFFFBFD;
                        }
                    }
                }
            }
            else
            {
                FCcmd = 0xFC127E24FFFFF9FC;
            }

            if (FCcmd == 0)
            {
                MessageBox.Show("Parser could not choose the right combiner! Combiners won't be fixed", "Display List", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                region.FCCountFixed++;
                rom.Write64(FCcmd);
            }
        }