コード例 #1
0
ファイル: Form1.cs プロジェクト: aglab2/f3dfix
        private void splitROM_Click(object sender, EventArgs e)
        {
            GC.Collect();
            dataGridView1.Rows.Clear();
            //object[] row = { "aaaa", true, false, "old", "new", false };
            //dataGridView1.Rows.Add(row);
            //return;

            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            openFileDialog1.Filter = "ROM File|*.z64";
            openFileDialog1.Title  = "Select a ROM";

            if (openFileDialog1.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            path = openFileDialog1.FileName;
            path = Path.GetFullPath(path);

            rom = new ROM(File.ReadAllBytes(path));
            for (int i = 0; i <= 30; i++)
            {
                try
                {
                    int offset = LevelInfo.GetLevelScriptEntryPoint(i);

                    List <Region> regions = new List <Region>();

                    // 1st pass : find out where regions are
                    LevelScript.PerformRegionParse(rom, regions, offset, out Dictionary <int, List <ScrollObject> > scrolls);

                    // Fill in data from rom
                    foreach (Region region in regions)
                    {
                        region.data = new byte[region.length];
                        rom.ReadData(region.romStart, region.length, region.data);
                    }

                    foreach (Region region in regions)
                    {
                        if (region.state == RegionState.DisplayList)
                        {
                            DisplayListRegion dlRegion = (DisplayListRegion)region;
                            scrolls.TryGetValue(1, out List <ScrollObject> areaScrolls);
                            if (areaScrolls == null)
                            {
                                areaScrolls = new List <ScrollObject>();
                            }

                            object[] row = { dlRegion, true, region.romStart.ToString("X"), i, dlRegion.isFogEnabled, dlRegion.isEnvcolorEnabled, new CombinerCommand(dlRegion.FCcmdfirst), CombinerCommand.GetNewCombiner(dlRegion), rom.segments.Clone(), areaScrolls };
                            dataGridView1.Rows.Add(row);
                        }
                    }
                }
                catch (Exception) { }
            }
            dataGridView1.Sort(new RowComparer(SortOrder.Ascending));
        }
コード例 #2
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);
            }
        }
コード例 #3
0
 private static void FixParse_cmdF8(ROM rom, DisplayListRegion region, RegionFixState state)
 {
     if (state.config.disableFog)
     {
         rom.Write64(0);
     }
 }
コード例 #4
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;
            }
        }
コード例 #5
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);
            }
        }
コード例 #6
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);
            }
        }
コード例 #7
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);
            }
        }
コード例 #8
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();
        }
コード例 #9
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();
        }
コード例 #10
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;
        }
コード例 #11
0
ファイル: DisplayListHelper.cs プロジェクト: aglab2/f3dfix
        public static CombinerCommand GetNewCombiner(DisplayListRegion dlRegion)
        {
            CombinerCommand oldCmd = new CombinerCommand(dlRegion.FCcmdfirst);

            if (dlRegion.isEnvcolorEnabled)
            {
                return(new CombinerCommand(fog: dlRegion.isFogEnabled, alpha: true));
            }

            if (oldCmd.opaque)
            {
                return(new CombinerCommand(fog: dlRegion.isFogEnabled, opaque: true));
            }

            return(new CombinerCommand(fog: dlRegion.isFogEnabled, solid: true));
        }
コード例 #12
0
 private static void OptimizeParse_cmdFB(ROM rom, DisplayListRegion region, RegionOptimizeState state)
 {
     /*
      * Int64 cmd = rom.Read64();
      * if (state.lastFBCmd == 0)
      * {
      *  state.lastFBCmd = cmd;
      *  return;
      * }
      *
      * if (cmd == state.lastFBCmd)
      * {
      *  rom.Write64(0);
      *  return;
      * }
      */
 }
コード例 #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
        public static void PerformRegionFix(ROM rom, Region region, FixConfig config)
        {
            RegionFixState    state    = new RegionFixState(config);
            DisplayListRegion dlRegion = (DisplayListRegion)region;

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

            do
            {
                curCmdIndex = rom.Read8();
                FixParseCmd func = fixParser[curCmdIndex];
                func(rom, dlRegion, state);
                rom.AddOffset(8);
            }while (rom.offset < region.romStart + region.length);
            rom.PopOffset();
            rom.ReadData(region.romStart, region.length, region.data);
        }
コード例 #15
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;
            }
        }
コード例 #16
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);
            }
        }
コード例 #17
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;
        }
コード例 #18
0
 private static void OptimizeParse_common(ROM rom, DisplayListRegion region, RegionOptimizeState state)
 {
 }
コード例 #19
0
 private static void OptimizeParse_cmdBF(ROM rom, DisplayListRegion region, RegionOptimizeState state)
 {
     state.prevF2cmdAddr = 0;
     state.prevFDcmdAddr = 0;
 }
コード例 #20
0
 private static void FixParse_common(ROM rom, DisplayListRegion region, RegionFixState state)
 {
 }
コード例 #21
0
 private static void RelocationParse_cmdFD(ROM rom, RelocationTable table, DisplayListRegion region)
 {
     table.RelocateOffset(rom, 4);
 }
コード例 #22
0
 private static void RelocationParse_common(ROM rom, RelocationTable table, DisplayListRegion region)
 {
 }
コード例 #23
0
ファイル: Form1.cs プロジェクト: aglab2/f3dfix
        private void button2_Click(object sender, EventArgs e)
        {
            List <Region> regions = new List <Region>();

            if (!Int32.TryParse(textBoxF3DPtr.Text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int offset))
            {
                MessageBox.Show("Custom DL", "Invalid ptr", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (!Int32.TryParse(textBoxSegNum.Text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int segment))
            {
                MessageBox.Show("Custom DL", "Invalid segment", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (!Int32.TryParse(textBoxROMAddr.Text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int addr))
            {
                MessageBox.Show("Custom DL", "Invalid rom addr", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            rom.SetSegment(segment, new SegmentDescriptor(addr, 0x00400000));
            DisplayList.FixConfig config = new DisplayList.FixConfig(checkBoxNerfFog.Checked, checkBoxOptimizeVertex.Checked, checkBoxTrimNops.Checked, checkBoxCombiners.Checked, checkBoxOtherMode.Checked, checkBoxNoFog.Checked);

            DisplayList.PerformRegionParse(rom, regions, offset, int.Parse(textBoxLayer.Text));
            foreach (Region region in regions)
            {
                if (region.state != RegionState.DisplayList)
                {
                    continue;
                }

                DisplayListRegion dlRegion = (DisplayListRegion)region;
                region.data = new byte[region.length];
                rom.ReadData(region.romStart, region.length, region.data);

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

                if (checkBoxGroupByTexture.Checked)
                {
                    if (checkBoxRebuildVertices.Checked)
                    {
                        DisplayList.PerformTriangleMapRebuild(rom, dlRegion, maxDLLength, new List <ScrollObject>());
                    }
                    else
                    {
                        DisplayList.PerformVisualMapRebuild(rom, dlRegion, maxDLLength);
                    }
                }

                DisplayList.PerformRegionOptimize(rom, dlRegion, config);
            }

            File.WriteAllBytes(path, rom.rom);

            rom.SetSegment(segment, null);
            MessageBox.Show(String.Format("Ptr was fixed successfully"), "f3d fix", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
コード例 #24
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);
            }
        }
コード例 #25
0
ファイル: Form1.cs プロジェクト: aglab2/f3dfix
        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);
        }
コード例 #26
0
        static RegionParseState PerformRegionParseInternal(ROM rom, List <Region> regions, int offset, int layer)
        {
            RegionParseState state = new RegionParseState();

            rom.PushOffset(offset);
            try
            {
                int cmd = 0;
                do
                {
                    cmd = rom.Read8();
                    parser[cmd](rom, regions, state);
                    rom.AddOffset(8);
                }while (cmd != 0xB8);

                Region           region;
                SortedRegionList graphicsData = new SortedRegionList();

                foreach (KeyValuePair <int, int> lightRegion in state.lightData.RegionList)
                {
                    //region = new Region(lightRegion.Key, lightRegion.Value, RegionState.LightData);
                    graphicsData.AddRegion(lightRegion.Key, lightRegion.Value);
                    //regions.Add(region);
                }

                // kostul
                if (state.lightData.RegionList.Count == 0)
                {
                    graphicsData.AddRegion(rom.GetROMAddress(0x0E000000), 0x10);
                }

                foreach (KeyValuePair <int, int> textureRegion in state.textureData.RegionList)
                {
                    //region = new Region(textureRegion.Key, textureRegion.Value, RegionState.TextureInfo);
                    graphicsData.AddRegion(textureRegion.Key, textureRegion.Value);
                    //regions.Add(region);
                }

                foreach (KeyValuePair <int, int> vertexRegion in state.vertexData.RegionList)
                {
                    //region = new Region(vertexRegion.Key, vertexRegion.Value, RegionState.VertexInfo);
                    graphicsData.AddRegion(vertexRegion.Key, vertexRegion.Value);
                    //regions.Add(region);
                }

                int count = 0;
                foreach (KeyValuePair <int, int> notFixedRegion in graphicsData.RegionList)
                {
                    region        = new DynamicRegion(notFixedRegion.Key, notFixedRegion.Value, RegionState.GraphicsData);
                    region.number = count++;
                    regions.Add(region);
                }


                region = new DisplayListRegion(offset, rom.offset - offset, state.isFogEnabled, state.isEnvColorEnabled, state.FCCount, state.B9cmdfirst, layer);
                regions.Add(region);
            }
            finally
            {
                rom.PopOffset();
            }
            return(state);
        }
コード例 #27
0
        private void ParseGraphics(string dirname, DataBuilder segment0E, DataBuilder segmentGeoLayouts, ROM rom, out RelocationUnit unit, out RelocationUnit graphicsDataUnit, int area = -1, int model = -1)
        {
            RelocationUnit retValue     = null;
            RelocationUnit graphicsUnit = null;

            segmentGeoLayouts.Backup();
            segment0E.Backup();
            try
            {
                DynamicRegion graphicsDataRegion = new DynamicRegion(dirname, RegionState.GraphicsData, area, model);
                // no relocation needed for dynamic region
                segment0E.AddRegion(graphicsDataRegion);
                segment0E.RoundOffset();

                // Display lists needs to be relocated with static graphics relocation table
                StaticRelocationTable graphicsRelocationTable = new StaticRelocationTable();
                graphicsUnit = new RelocationUnit(graphicsDataRegion, rom, isFromStatic: true);
                graphicsRelocationTable.AddUnit(graphicsUnit);

                // Geolayouts needs to be relocated with queued display lists, will be filled during relocation with graphicsRelocationTable
                QueueRelocationTable dispRelocationTable = new QueueRelocationTable();

                RelocationUnit dispRelocationUnit = null;
                for (int dispNumber = 0; dispNumber < 0xFF; dispNumber++)
                {
                    if (!PathComposer.IsRegionFileExists(dirname, RegionState.DisplayList, area, model, dispNumber))
                    {
                        break;
                    }

                    DisplayListRegion dispRegion = new DisplayListRegion(dirname, area, model, dispNumber);
                    DisplayList.PerformRegionRelocation(dispRegion, graphicsRelocationTable);
                    segment0E.AddRegion(dispRegion);
                    segment0E.RoundOffset();

                    dispRelocationUnit = new RelocationUnit(dispRegion, rom, isFromStatic: true);
                    dispRelocationTable.AddUnit(dispRelocationUnit);
                }

                // Not even one disp relocation unit, sounds like a bug
                if (dispRelocationUnit == null)
                {
                    throw new IOException("No display lists found!");
                }

                // Geolayout might or might not exist for model, check if it exists and if needed, relocate it
                if (PathComposer.IsRegionFileExists(dirname, RegionState.GeoLayout, area, model))
                {
                    // Load geolayout and relocate it with display lists
                    GeoLayoutRegion modelGeoLayoutRegion = new GeoLayoutRegion(dirname, area, model);
                    GeoLayout.PerformRegionRelocation(modelGeoLayoutRegion, dispRelocationTable);
                    segmentGeoLayouts.AddRegion(modelGeoLayoutRegion);
                    segmentGeoLayouts.RoundOffset();

                    // Finalize with returning geolayout for model
                    retValue = new RelocationUnit(modelGeoLayoutRegion, rom, isFromStatic: true);
                }
                else
                {
                    // Return display list only, there should be only one, if more, it is undefinied behaviour :3
                    retValue = dispRelocationUnit;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("Failed to load model {0}, reason : '{1}'", model, ex.Message), "Level Combiner", MessageBoxButtons.OK, MessageBoxIcon.Error);
                segment0E.Restore();
                segmentGeoLayouts.Restore();
            }

            unit             = retValue;
            graphicsDataUnit = graphicsUnit;
        }