Beispiel #1
0
        public static void PerformRegionParse(ROM rom, List <Region> regions, int offset)
        {
            rom.PushOffset(offset);
            try
            {
                List <Region> displayListRegions = new List <Region>();

                int cmd;
                do
                {
                    cmd = rom.Read8();
                    int cmdSize = cmdSizeTable[cmd];
                    if (cmdSize == 0)
                    {
                        throw new ArgumentException("Loop detected");
                    }

                    parser[cmd](rom, displayListRegions);

                    if (cmdSize != 0xFF)
                    {
                        rom.AddOffset(cmdSize);
                    }
                } while (cmd != 0x01);

                // !!! : Group together all display list information in geolayout
                MergedRegionList compoundGraphicsData = new MergedRegionList();
                List <Region>    otherRegions         = new List <Region>();

                int count = 0;
                // Merge together vertex, texture, light descriptions
                // Enumerate display lists
                foreach (Region reg in displayListRegions)
                {
                    switch (reg.state)
                    {
                    case RegionState.GraphicsData:
                        compoundGraphicsData.AddRegion(reg.romStart, reg.length);
                        break;

                    case RegionState.DisplayList:
                        reg.number = count++;
                        otherRegions.Add(reg);
                        break;

                    default:
                        // Passthrough region that we do not need to compound
                        otherRegions.Add(reg);
                        break;
                    }
                }

                Region graphicsRegion = new DynamicRegion(compoundGraphicsData.start, compoundGraphicsData.length, RegionState.GraphicsData);
                regions.Add(graphicsRegion);

                regions.AddRange(otherRegions);

                Region region = new GeoLayoutRegion(offset, rom.offset - offset);
                regions.Add(region);
            }
            finally
            {
                rom.PopOffset();
            }
        }
Beispiel #2
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;
        }