示例#1
0
        private static void RegionParse_cmd24(ROM rom, List <Region> regions, RegionParseState state)
        {
            int behaviour = rom.Read32(0x14);

            if (behaviour == scrollBehaviour || behaviour == scrollBehaviourLegacy || behaviour == scrollF2)
            {
                EditorScroll scroll = new EditorScroll(rom);
                if (scroll.acts != 0)
                {
                    if (state.scrolls.TryGetValue(state.area, out List <ScrollObject> scrolls))
                    {
                        scrolls.Add(scroll);
                    }
                    else
                    {
                        state.scrolls[state.area] = new List <ScrollObject> {
                            scroll
                        };
                    }

                    if (state.regionState != RegionState.AreaScrolls)
                    {
                        CutRegion(rom, regions, state, rom.offset, RegionState.AreaScrolls);
                    }
                    return;
                }
            }

            if (state.regionState != RegionState.AreaData)
            {
                CutRegion(rom, regions, state, rom.offset, RegionState.AreaData);
            }
        }
示例#2
0
 private static void RegionParse_cmdB9(ROM rom, List <Region> regions, RegionParseState state)
 {
     if (state.B9cmdfirst == 0)
     {
         state.B9cmdfirst = rom.Read64();
     }
 }
示例#3
0
        private static void RelocationParse_cmd24(ROM rom, RelocationTable table, RegionParseState state)
        {
            int behaviour = rom.Read32(0x14);

            if (behaviour == scrollBehaviour || behaviour == scrollBehaviourLegacy)
            {
                int address = 0;

                int    intX  = rom.Read16(0x04);
                float  X     = intX;
                byte[] Xdata = BitConverter.GetBytes(X);

                address += Xdata[2] * 0x10000;
                address += (ushort)rom.Read16(0x10);

                int segmentedAddress = address - 0x20000 + 0x0E000000;

                int newSegmentedAddress = table.Relocate((int)state.area, segmentedAddress);
                if (newSegmentedAddress == -1)
                {
                    throw new ArgumentException("Failed to relocate scrolling texture!");
                }

                int newAddress = newSegmentedAddress - 0x0E000000 + 0x20000;

                Xdata[2] = (byte)((newAddress >> 16) & 0xFF);
                float newX    = BitConverter.ToSingle(Xdata, 0);
                int   newIntX = Convert.ToInt16(newX);

                rom.Write16(newIntX, 0x04);
                rom.Write16(newAddress & 0xFFFF, 0x10);
                rom.Write32(scrollBehaviourLegacy, 0x14);
            }
        }
示例#4
0
        private static void RegionParse_cmd06(ROM rom, List <Region> regions, RegionParseState state)
        {
            int segment = rom.Read8(4);

            if (segment != 0x0e)
            {
                return;
            }

            int type = rom.Read8(1);

            if (type != 0)
            {
                throw new NotSupportedException("Terminating Branch not supported!");
            }

            int segmentedAddress = rom.Read32(4);
            int address          = rom.GetROMAddress(segmentedAddress);

            List <Region>    regionsBranch = new List <Region>();
            RegionParseState stateBranch   = PerformRegionParseInternal(rom, regionsBranch, address, 0);

            // TODO: Copy/update more if needed
            if (stateBranch.FDAddress != -1)
            {
                state.FDAddress = stateBranch.FDAddress;
            }

            foreach (Region region in regionsBranch)
            {
                state.textureData.AddRegion(region.romStart, region.length);
            }
        }
示例#5
0
 private static void RegionParse_cmdB7(ROM rom, List <Region> regions, RegionParseState state)
 {
     if ((rom.Read32(4) & 0x00010000) != 0)
     {
         state.isFogEnabled = true;
     }
 }
示例#6
0
 private static void RegionParse_cmd26(ROM rom, List <Region> regions, RegionParseState state)
 {
     if (state.regionState != RegionState.AreaData)
     {
         CutRegion(rom, regions, state, rom.offset, RegionState.AreaData);
     }
 }
示例#7
0
        private static void RegionParse_cmd2E(ROM rom, List <Region> regions, RegionParseState state)
        {
            int segmentedAddress = rom.Read32(4);
            int segment          = rom.Read8(4);

            // Only 0x19 or 0x0E commands are supported
            if (segment != 0x19 && segment != 0x0E)
            {
                return;
            }

            try
            {
                List <Region> collisionRegions = new List <Region>();
                Collision.PerformRegionParse(rom, collisionRegions, (int)rom.GetROMAddress(segmentedAddress));
                foreach (Region region in collisionRegions)
                {
                    region.area = state.area;
                }

                regions.AddRange(collisionRegions);
            }
            catch (NotSupportedException e)
            {
                MessageBox.Show(String.Format("Model {0} collision parsing is not supported! Reason : '{1}'", state.area, e.Message), "Level Parser", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception e)
            {
                MessageBox.Show(String.Format("Failed to parse model {0} collision! Reason : '{1}'", state.area, e.Message), "Level Parser", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
示例#8
0
        public static void PerformRegionRelocation(Region region, RelocationTable table, sbyte area = -1)
        {
            // This is fake rom but it works anyways, just more convenient
            ROM rom = new ROM(region.data);
            RegionParseState state = new RegionParseState();

            state.area = area;

            byte curCmdIndex;

            while (rom.offset < region.length)
            {
                curCmdIndex = rom.Read8();
                byte curCmdSize = rom.Read8(1);

                if (curCmdSize == 0)
                {
                    throw new ArgumentException("cmd size is 0, loop detected");
                }

                RelocationParseCmd func = relocationParser[curCmdIndex];
                func(rom, table, state);

                if (curCmdIndex != 0x7)
                {
                    rom.AddOffset(curCmdSize);
                }
            }
        }
示例#9
0
        private static void RegionParse_cmd24(ROM rom, List <Region> regions, RegionParseState state)
        {
            int behaviour = rom.Read32(0x14);

            if (behaviour == scrollBehaviour || behaviour == scrollBehaviourLegacy)
            {
                if (state.regionState != RegionState.AreaScrolls)
                {
                    CutRegion(rom, regions, state, rom.offset, RegionState.AreaScrolls);
                }
            }
            else if (behaviour == f2ScrollBehaviour)
            {
                if (state.regionState != RegionState.AreaF2Scrolls)
                {
                    CutRegion(rom, regions, state, rom.offset, RegionState.AreaF2Scrolls);
                }
            }
            else
            {
                if (state.regionState != RegionState.AreaData)
                {
                    CutRegion(rom, regions, state, rom.offset, RegionState.AreaData);
                    return;
                }
            }
        }
示例#10
0
 private static void RegionParse_cmdFC(ROM rom, List <Region> regions, RegionParseState state)
 {
     if (state.FCcmd == -1)
     {
         state.FCcmd = rom.Read64();
     }
     state.FCCount++;
 }
示例#11
0
        private static void RegionParse_common(ROM rom, List <Region> regions, RegionParseState state)
        {
            int curCmd = rom.Read8();

            if ((state.regionState == RegionState.AreaData || state.regionState == RegionState.AreaScrolls) && curCmd != 0x24 && curCmd != 0x26)
            {
                CutRegion(rom, regions, state, rom.offset, RegionState.AreaFooter);
            }
        }
示例#12
0
        private static void RegionParse_cmd07(ROM rom, List <Region> regions, RegionParseState state)
        {
            CutRegion(rom, regions, state, rom.offset, state.regionState);

            int retAddr = state.retAddressStack.Pop();

            rom.offset  = retAddr;
            state.start = retAddr;
        }
示例#13
0
        private static void RegionParse_cmdF0(ROM rom, List <Region> regions, RegionParseState state)
        {
            if (state.FDAddress == -1)
            {
                return;
            }

            int w0         = rom.Read16(5);
            int colorCount = (w0 >> (4 + 2)) + 1;

            state.textureData.AddRegion(state.FDAddress, colorCount * 2);
        }
示例#14
0
        private static void RegionParse_cmd03(ROM rom, List <Region> regions, RegionParseState state)
        {
            int segment = rom.Read8(4);

            if (segment != 0x0e)
            {
                return;
            }

            int segmentedAddress = rom.Read32(4);
            int address          = rom.GetROMAddress(segmentedAddress);

            state.lightData.AddRegion(address, 0x8);
        }
示例#15
0
        private static void RegionParse_cmd04(ROM rom, List <Region> regions, RegionParseState state)
        {
            int segment = rom.Read8(4);

            if (segment != 0x0e)
            {
                return;
            }

            int segmentedAddress = rom.Read32(4);
            int address          = rom.GetROMAddress(segmentedAddress);

            state.vertexData.AddRegion(address, rom.Read16(2));
            //regions.Add(new Region(address, rom.Read16(2), RegionState.VertexInfo));
        }
示例#16
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);
        }
示例#17
0
        private static void RegionParse_cmdFD(ROM rom, List <Region> regions, RegionParseState state)
        {
            state.FDAddress = -1;

            int segment = rom.Read8(4);

            if (segment != 0x0e)
            {
                return;
            }

            int segmentedAddress = rom.Read32(4);
            int address          = (int)rom.GetROMAddress(segmentedAddress);

            state.FDAddress = address;
        }
示例#18
0
        private static void RegionParse_cmdF3(ROM rom, List <Region> regions, RegionParseState state)
        {
            if (state.FDAddress == -1)
            {
                return;
            }

            int w0  = (int)rom.Read32(0);
            int w1  = (int)rom.Read32(4);
            int uls = (w0 >> 12) & 0x3FF;
            int ult = w0 & 0x3FF;
            int lrs = (w1 >> 12) & 0x3FF;
            int dxt = w1 & 0x3FF;

            // idk how this actually works
            int textureSize = (lrs + 1) * 4;

            state.textureData.AddRegion(state.FDAddress, textureSize);
        }
示例#19
0
        private static void RegionParse_cmd06(ROM rom, List <Region> regions, RegionParseState state)
        {
            int segmentedAddress = rom.Read32(4);
            int segment          = SegmentedAddressHelper.GetSegment(segmentedAddress);

            // 06 command will return one way or another, so just wait for it
            if (segment != 0x19)
            {
                return;
            }

            CutRegion(rom, regions, state, rom.offset, state.regionState);

            state.retAddressStack.Push(rom.offset + rom.Read8(1));
            int offset = (int)rom.GetROMAddress(segmentedAddress);

            rom.offset  = offset - 8; // kostul for next cmd switching
            state.start = offset;
        }
示例#20
0
        public static void PerformHeaderParse(ROM rom, int offset)
        {
            rom.PushOffset(offset);

            RegionParseState state = new RegionParseState();

            state.start = rom.offset;

            byte curCmdIndex;
            int  stepCounter = 0;

            do
            {
                curCmdIndex = rom.Read8();
                byte curCmdSize = rom.Read8(1);

                if (curCmdSize == 0)
                {
                    throw new ArgumentException("cmd size is 0, loop detected");
                }

                if (curCmdIndex == 0x00)
                {
                    HeaderParse_cmd00(rom);
                }

                if (curCmdIndex == 0x17)
                {
                    HeaderParse_cmd17(rom);
                }

                rom.AddOffset(curCmdSize);
                stepCounter++;

                if (stepCounter > 100)
                {
                    throw new ArgumentException("Bank 0x19 && 0x0E loader was not detected");
                }
            }while (rom.GetSegmentDescriptor(0x0E) == null || rom.GetSegmentDescriptor(0x19) == null);

            rom.PopOffset();
        }
示例#21
0
        public static void FixLoadAddresses(ROM initROM, Region region)
        {
            // This is fake rom but it works anyways, just more convenient
            ROM rom = new ROM(region.data);

            RegionParseState state = new RegionParseState();

            state.start = rom.offset;

            byte curCmdIndex;
            int  stepCounter = 0;

            do
            {
                curCmdIndex = rom.Read8();
                byte curCmdSize = rom.Read8(1);

                if (curCmdSize == 0)
                {
                    throw new ArgumentException("cmd size is 0, loop detected");
                }

                if (curCmdIndex == 0x17)
                {
                    bool isFixed;
                    HeaderFix_cmd17(rom, initROM, out isFixed);
                    if (isFixed)
                    {
                        break;
                    }
                }

                rom.AddOffset(curCmdSize);
                stepCounter++;

                if (stepCounter > 100)
                {
                    throw new ArgumentException("Bank 0x19 && 0x0E loader was not detected");
                }
            }while (rom.GetSegmentDescriptor(0x0E) == null || rom.GetSegmentDescriptor(0x19) == null);
        }
示例#22
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;
        }
示例#23
0
        private static void RegionParse_cmd22(ROM rom, List <Region> regions, RegionParseState state)
        {
            if (state.regionState != RegionState.ModelsLoader)
            {
                CutRegion(rom, regions, state, rom.offset, RegionState.ModelsLoader);
            }

            int segmentedAddress = rom.Read32(4);
            int segment          = rom.Read8(4);
            int model            = rom.Read8(3);

            // Only 0x19 or 0x0E commands are supported
            if (segment != 0x19 && segment != 0x0E)
            {
                return;
            }

            try
            {
                List <Region> modelRegions = new List <Region>();

                int geoLayoutROMAddress = rom.GetROMAddress(segmentedAddress);
                GeoLayout.PerformRegionParse(rom, modelRegions, geoLayoutROMAddress);

                foreach (Region region in modelRegions)
                {
                    region.model = model;
                }

                regions.AddRange(modelRegions);
            }
            catch (NotSupportedException e)
            {
                MessageBox.Show(String.Format("Model {0} graphics parsing is not supported! Reason : '{1}'", state.area, e.Message), "Level Parser", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception e)
            {
                MessageBox.Show(String.Format("Failed to parse model {0} graphics! Reason : '{1}'", state.area, e.Message), "Level Parser", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
示例#24
0
        private static void RegionParse_cmd1F(ROM rom, List <Region> regions, RegionParseState state)
        {
            CutRegion(rom, regions, state, rom.offset, RegionState.AreaHeader);

            int   segmentedAddress = rom.Read32(4);
            int   segment          = rom.Read8(4);
            sbyte area             = (sbyte)rom.Read8(2);

            state.area        = area;
            state.regionState = RegionState.AreaHeader;

            // Only 0x19 or 0x0E commands are supported
            // Usually it is in segment 19 anyways
            if (segment != 0x19 && segment != 0x0E)
            {
                return;
            }

            int           geoLayoutROMAddress  = rom.GetROMAddress(segmentedAddress);
            List <Region> areaGeolayoutRegions = new List <Region>();

            try
            {
                GeoLayout.PerformRegionParse(rom, areaGeolayoutRegions, geoLayoutROMAddress);
                foreach (Region region in areaGeolayoutRegions)
                {
                    region.area = area;
                }

                regions.AddRange(areaGeolayoutRegions);
            }
            catch (NotSupportedException e)
            {
                MessageBox.Show(String.Format("Area {0} graphics parsing is not supported! Reason : '{1}'", state.area, e.Message), "Level Parser", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception e)
            {
                MessageBox.Show(String.Format("Failed to parse area {0} graphics! Reason : '{1}'", state.area, e.Message), "Level Parser", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
示例#25
0
        public static void PerformRegionParse(ROM rom, List <Region> regions, int offset, bool isOldScrollBehaviour)
        {
            rom.PushOffset(offset);

            RegionParseState state = new RegionParseState
            {
                start = rom.offset,
                isOldBehaviourChecked = isOldScrollBehaviour
            };

            byte curCmdIndex;

            do
            {
                curCmdIndex = rom.Read8();
                byte curCmdSize = rom.Read8(1);

                if (curCmdSize == 0)
                {
                    throw new ArgumentException("cmd size is 0, loop detected");
                }

                RegionParseCmd func = regionParser[curCmdIndex];
                if (func != RegionParse_common)
                {
                    RegionParse_common(rom, regions, state);
                }

                func(rom, regions, state);

                if (curCmdIndex != 0x7)
                {
                    rom.AddOffset(curCmdSize);
                }
            }while (curCmdIndex != terminateCmd);

            rom.PopOffset();
        }
示例#26
0
        private static void CutRegion(ROM rom, List <Region> regions, RegionParseState state, int regionEnd, RegionState newState)
        {
            // Trim 0x1008000000000000 commands from beginning
            int regionStart = state.start;

            if (rom.PRead64(regionStart) == 0x1008000000000000)
            {
                regionStart += 8;
            }

            if (regionStart == regionEnd)
            {
                return;
            }

            Region region = new LevelScriptRegion(regionStart, regionEnd - regionStart, state.regionState);

            region.area = state.area;
            regions.Add(region);

            state.regionState = newState;
            state.start       = regionEnd;
        }
示例#27
0
 private static void RegionParse_cmd10(ROM rom, List <Region> regions, RegionParseState state)
 {
     if (rom.Read64() == 0x1008000000000000)
     {
         if (rom.offset == state.start)
         {
             state.start = rom.offset + rom.Read8(1);
         }
         // Skip empty commands in the beginning of any region
         else if (rom.offset == state.start + rom.Read8(1))
         {
             state.start = rom.offset + rom.Read8(1);
         }
         else
         {
             // Commands is not in the beginning, cut area, start new one that is same as it was before
             if (state.regionState == RegionState.ModelsLoader)
             {
                 CutRegion(rom, regions, state, rom.offset, state.regionState);
             }
         }
     }
 }
示例#28
0
        public static void PerformRegionParse(ROM rom, List <Region> regions, int offset, out Dictionary <int, List <ScrollObject> > scrolls)
        {
            rom.PushOffset(offset);

            RegionParseState state = new RegionParseState();

            state.start = rom.offset;

            byte curCmdIndex;

            do
            {
                curCmdIndex = rom.Read8();
                byte curCmdSize = rom.Read8(1);

                if (curCmdSize == 0)
                {
                    throw new ArgumentException("cmd size is 0, loop detected");
                }

                RegionParseCmd func = regionParser[curCmdIndex];
                if (func != RegionParse_common)
                {
                    RegionParse_common(rom, regions, state);
                }

                func(rom, regions, state);

                if (curCmdIndex != 0x7)
                {
                    rom.AddOffset(curCmdSize);
                }
            }while (curCmdIndex != terminateCmd);

            rom.PopOffset();
            scrolls = state.scrolls;
        }
示例#29
0
 private static void RelocationParse_cmd2E(ROM rom, RelocationTable table, RegionParseState state)
 {
     table.RelocateOffset((int)state.area, rom, 4);
 }
示例#30
0
        private static void RelocationParse_cmd22(ROM rom, RelocationTable table, RegionParseState state)
        {
            int model = rom.Read8(3);

            table.RelocateOffset(model, rom, 4);
        }