예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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;
                }
            }
        }
예제 #4
0
        private static void TriangleMapParse_cmd04(ROM rom, TriangleMap map, TriangleMapParseState state)
        {
            state.vertexLoadCmd = (UInt64)rom.Read64();
            byte vertexDesc = rom.Read8(1);

            byte  vertexCount            = (byte)(((vertexDesc & 0xF0) >> 4) + 1);
            byte  vertexOffset           = (byte)((vertexDesc & 0x0F));
            Int32 vertexSegmentedAddress = rom.Read32(4);

            state.segmentedVertexBufferAddress = vertexSegmentedAddress;

            Int32 romPtr = rom.GetROMAddress(vertexSegmentedAddress);

            if (romPtr == -1)
            {
                throw new ArgumentException("Invalid segmented address!");
            }

            rom.PushOffset(romPtr);
            for (int vertex = vertexOffset; vertex < vertexCount; vertex++)
            {
                Int64 lo = rom.Read64();
                Int64 hi = rom.Read64(8);

                state.vbuf[vertex]         = new Vertex((UInt64)lo, (UInt64)hi);
                state.vbufRomStart[vertex] = rom.offset;
                state.scrollBuf[vertex]    = FindMatchingScroll(state.scrolls, vertexSegmentedAddress, state.td);

                rom.AddOffset(0x10);
                vertexSegmentedAddress += 0x10;
            }
            rom.PopOffset();
        }
예제 #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_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);
            }
        }
예제 #7
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);
            }
        }
예제 #8
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);
            }
        }
예제 #9
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);
            }
        }
예제 #10
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);
        }
예제 #11
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;
        }
예제 #12
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
        }
예제 #13
0
        private static void RegionParse_cmd15(ROM rom, List <Region> regions)
        {
            int segment = rom.Read8(4);

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

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

            DisplayList.PerformRegionParse(rom, regions, address, rom.Read8(1));
        }
예제 #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_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;
        }
예제 #17
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;
        }
예제 #18
0
        public void RelocateOffset(object key, ROM rom, int romOffset)
        {
            int segment = rom.Read8(romOffset);

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

            int segmentedAddress = rom.Read32(romOffset);

            int newSegmentedAddress = Relocate(key, segmentedAddress);

            if (newSegmentedAddress == -1)
            {
                throw new ArgumentException(String.Format("Relocation Table does not have address {0:x}", segmentedAddress));
            }

            rom.Write32(newSegmentedAddress, romOffset);
        }
예제 #19
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);
            }
        }
예제 #20
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);
            }
        }
예제 #21
0
파일: Scrolls.cs 프로젝트: aglab2/f3dfix
 public TextureScroll(ROM rom) : base(rom)
 {
     segmentedAddress = rom.Read32(0x10);
 }
예제 #22
0
파일: Scrolls.cs 프로젝트: aglab2/f3dfix
 public ScrollObject(ROM rom)
 {
     romOffset = rom.offset;
     behavior  = rom.Read32(0x14);
 }