Exemplo n.º 1
0
        public void SetSegment(int segment, SegmentDescriptor descriptor)
        {
            if (segment > 0x20)
            {
                return;
            }

            segments[segment] = descriptor;
        }
Exemplo n.º 2
0
        private static void HeaderParse_cmd17(ROM rom)
        {
            int segment      = rom.Read8(3);
            int startAddress = rom.Read32(4);
            int endAddress   = rom.Read32(8);

            SegmentDescriptor descriptor = new SegmentDescriptor(startAddress, endAddress - startAddress);

            rom.SetSegment(segment, descriptor);
        }
Exemplo n.º 3
0
        private static void RegionParse_cmd17(ROM rom, List <Region> regions, RegionParseState state)
        {
            int segment      = rom.Read8(3);
            int startAddress = rom.Read32(4);
            int endAddress   = rom.Read32(8);

            if ((uint)startAddress > 0x4000000)
            {
                return;
            }

            SegmentDescriptor descriptor = new SegmentDescriptor(startAddress, endAddress - startAddress);

            rom.SetSegment(segment, descriptor);
        }
Exemplo n.º 4
0
        public int GetSegmentedAddress(int romAddress)
        {
            for (int currentSegment = 0; currentSegment < 0x20; currentSegment++)
            {
                SegmentDescriptor descriptor = segments[currentSegment];
                if (descriptor == null)
                {
                    continue;
                }

                if (descriptor.start <= romAddress && romAddress <= descriptor.start + descriptor.length)
                {
                    return(SegmentedAddressHelper.GetSegmentedAddress(currentSegment, romAddress - descriptor.start));
                }
            }

            return(-1);
        }
Exemplo n.º 5
0
        private static void RegionParse_cmd00(ROM rom, List <Region> regions, RegionParseState state)
        {
            int segment = rom.Read8(3);

            if (segment != 0x19)
            {
                throw new MessageException("ROM does not use bank 0x19. Did you import a level?");
            }

            int startAddress             = rom.Read32(4);
            int endAddress               = rom.Read32(8);
            SegmentDescriptor descriptor = new SegmentDescriptor(startAddress, endAddress - startAddress);

            rom.SetSegment(segment, descriptor);

            int segmentedAddress   = rom.Read32(12);
            int levelscriptAddress = rom.GetROMAddress(segmentedAddress);

            rom.offset  = levelscriptAddress - 0x10; // kostul for adding 0x10
            state.start = levelscriptAddress;
        }
Exemplo n.º 6
0
        private static void HeaderParse_cmd00(ROM rom)
        {
            int segment = rom.Read8(3);

            if (segment != 0x19)
            {
                throw new MessageException("ROM does not use bank 0x19. Did you import a level?");
            }

            int startAddress             = rom.Read32(4);
            int endAddress               = rom.Read32(8);
            SegmentDescriptor descriptor = new SegmentDescriptor(startAddress, endAddress - startAddress);

            rom.SetSegment(segment, descriptor);

            //rom.levelScriptEntryOffset = rom.offset + 12;

            int segmentedAddress   = rom.Read32(12);
            int levelscriptAddress = rom.GetROMAddress(segmentedAddress);

            rom.offset = levelscriptAddress - 0x10; // kostul for adding 0x10
        }
Exemplo n.º 7
0
        private void button1_Click(object sender, EventArgs e)
        {
            GC.Collect();

            OpenFileDialog openFileDialog1 = new OpenFileDialog();

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

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

            string path = openFileDialog1.FileName;

            path = Path.GetFullPath(path);

            ROM rom    = new ROM(File.ReadAllBytes(path));
            int offset = Convert.ToInt32(addressTextBox.Text, 16);

            if (offset == 0)
            {
                MessageBox.Show("Failed to parse address, input correct address", "Level Split", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            LevelScript.PerformHeaderParse(rom, offset);

            SegmentDescriptor segmentDescriptor0E = rom.GetSegmentDescriptor(0x0E);
            SegmentDescriptor segmentDescriptor19 = rom.GetSegmentDescriptor(0x19);

            DataBuilder segment0E = new DataBuilder(segmentDescriptor0E.start, segmentDescriptor0E.length);
            DataBuilder segment19 = new DataBuilder(segmentDescriptor19.start, segmentDescriptor19.length);

            string dirname = splittedPathTextBox.Text;

            // Fill in area relocation table + geolayouts
            KeyRelocationTable areaGraphicsDescrRelocationTable = new KeyRelocationTable();
            KeyRelocationTable areaGraphicsDataRelocationTable  = new KeyRelocationTable();
            KeyRelocationTable areaCollisionRelocationTable     = new KeyRelocationTable();

            for (int area = 1; area <= 8; area++)
            {
                if (!PathComposer.IsRegionFileExists(dirname, RegionState.GraphicsData, area: area))
                {
                    continue;
                }

                // Area graphics
                ParseGraphics(dirname, segment0E, segment19, rom, out RelocationUnit descrUnit, out RelocationUnit dataUnit, area: area);
                areaGraphicsDescrRelocationTable.AddUnit(area, descrUnit);
                areaGraphicsDataRelocationTable.AddUnit(area, dataUnit);

                // Area collision
                DynamicRegion collision = new DynamicRegion(dirname, RegionState.Collision, area: area);
                // No relocation needed
                segment0E.AddRegion(collision);
                segment0E.RoundOffset();

                RelocationUnit collisionRelocationUnit = new RelocationUnit(collision, rom, isFromStatic: true);
                areaCollisionRelocationTable.AddUnit(area, collisionRelocationUnit);
            }

            // Fill in model relocation table + geolayouts
            KeyRelocationTable modelRelocationTable = new KeyRelocationTable();

            for (int model = 0x00; model < 0xFF; model++)
            {
                if (!PathComposer.IsRegionFileExists(dirname, RegionState.GraphicsData, model: model))
                {
                    continue;
                }

                ParseGraphics(dirname, segment0E, segment19, rom, out RelocationUnit descrUnit, out RelocationUnit graphicsUnit, model: model);
                modelRelocationTable.AddUnit(model, descrUnit);
            }

            // As everything is prepared, we can finally start building level!
            LevelScriptRegion levelHeader = new LevelScriptRegion(dirname, RegionState.LevelHeader);

            LevelScript.FixLoadAddresses(rom, levelHeader);
            segment19.AddRegion(levelHeader);

            int levelScriptSegmentedAddressStart = rom.GetSegmentedAddress(levelHeader.romStart);

            LevelScriptRegion modelsLoader = new LevelScriptRegion(dirname, RegionState.ModelsLoader);

            modelsLoader.Relocate(modelRelocationTable);
            segment19.AddRegion(modelsLoader);

            for (sbyte area = 0; area < 8; area++)
            {
                if (!PathComposer.IsRegionFileExists(dirname, RegionState.GraphicsData, area: area))
                {
                    continue;
                }

                // Area header initializes graphics
                LevelScriptRegion areaHeader = new LevelScriptRegion(dirname, RegionState.AreaHeader, area: area);
                LevelScript.PerformRegionRelocation(areaHeader, areaGraphicsDescrRelocationTable, area);
                segment19.AddRegion(areaHeader);

                LevelScriptRegion areaData = new LevelScriptRegion(dirname, RegionState.AreaData, area: area);
                // No relocation needed
                segment19.AddRegion(areaData);

                if (PathComposer.IsRegionFileExists(dirname, RegionState.AreaScrolls, area: area))
                {
                    LevelScriptRegion scrollsData = new LevelScriptRegion(dirname, RegionState.AreaScrolls, area: area);
                    LevelScript.PerformRegionRelocation(scrollsData, areaGraphicsDataRelocationTable, area);
                    segment19.AddRegion(scrollsData);
                }

                // Area footer initializes collision
                LevelScriptRegion areaFooter = new LevelScriptRegion(dirname, RegionState.AreaFooter, area: area);
                LevelScript.PerformRegionRelocation(areaFooter, areaCollisionRelocationTable, area);
                segment19.AddRegion(areaFooter);
            }

            LevelScriptRegion levelFooter = new LevelScriptRegion(dirname, RegionState.LevelFooter);

            // no relocation needed
            segment19.AddRegion(levelFooter);


            // At this point we know that all data fit in rom
            // So just write all that in rom
            using (Stream stream = new FileStream(path, FileMode.Open))
            {
                stream.Seek(segmentDescriptor0E.start, SeekOrigin.Begin);
                stream.Write(segment0E.Data, 0, segment0E.Offset);

                stream.Seek(segmentDescriptor19.start, SeekOrigin.Begin);
                stream.Write(segment19.Data, 0, segment19.Offset);

                // Also start of level script moved so write that thing too
                int    endianData    = IPAddress.HostToNetworkOrder(levelScriptSegmentedAddressStart);
                byte[] convertedData = BitConverter.GetBytes(endianData);

                stream.Seek(rom.levelScriptEntryOffset, SeekOrigin.Begin);
                stream.Write(convertedData, 0, 4);
            }

            MessageBox.Show(String.Format("ROM was build successfully from {0}", dirname), "Level Split", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }