コード例 #1
0
        public override void SerializeImpl(SerializerObject s)
        {
            Offsets   = s.SerializePointerArray <Array <ushort> >(Offsets, 6, resolve: true, onPreSerialize: x => x.Length = 690, name: nameof(Offsets));
            LocTables = s.SerializePointerArray(LocTables, 6, name: nameof(LocTables));
            if (Localization == null)
            {
                Localization = new string[Offsets.Length][];
                for (int i = 0; i < Localization.Length; i++)
                {
                    Localization[i] = new string[Offsets[i].Value.Length];
                    s.DoAt(LocTables[i], () => {
                        s.DoEncoded(new RHREncoder(), () => {
                            Pointer basePtr = s.CurrentPointer;
                            for (int j = 0; j < Offsets[i].Value.Length; j++)
                            {
                                s.DoAt(basePtr + Offsets[i].Value.Value[j], () => {
                                    Localization[i][j] = s.SerializeString(Localization[i][j], encoding: Encoding.GetEncoding(1252), name: $"{nameof(Localization)}[{i}][{j}]");
                                });
                            }

                            // Go to end
                            s.Goto(s.CurrentPointer + s.CurrentLength);
                        });
                    });
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            // Hack to get length
            Pointer smpOff1 = null;

            s.DoAt(Offset, () => {
                smpOff1 = s.SerializePointer(smpOff1, anchor: BaseOffset, name: nameof(smpOff1));
            });
            Samples = s.SerializePointerArray <MusyX_Sample>(Samples, (smpOff1 - Offset) / 4, anchor: BaseOffset, resolve: true, name: nameof(Samples));
        }
コード例 #3
0
 public override void SerializeImpl(SerializerObject s)
 {
     FramePointers = s.SerializePointerArray(FramePointers, Length, name: nameof(FramePointers));
     if (Frames == null)
     {
         Frames = new GBARRR_Mode7AnimationFrame[Length];
         for (int i = 0; i < Length; i++)
         {
             Frames[i] = s.DoAt(FramePointers[i], () => s.SerializeObject <GBARRR_Mode7AnimationFrame>(Frames[i], name: $"{nameof(Frames)}[{i}]"));
         }
     }
 }
コード例 #4
0
        public override void SerializeImpl(SerializerObject s)
        {
            var manager = ((GBA_Milan_Manager)s.GameSettings.GetGameManager);

            Pointers = s.SerializePointerArray(Pointers, manager.Milan_LocTableLength * manager.Milan_LocTableLangCount, name: nameof(Pointers));

            if (Strings == null)
            {
                Strings = new string[Pointers.Length];
            }

            for (int i = 0; i < Strings.Length; i++)
            {
                Strings[i] = s.DoAt(Pointers[i], () => s.SerializeString(Strings[i], encoding: Encoding.GetEncoding(1252), name: $"{nameof(Strings)}[{i}]"));
            }
        }
コード例 #5
0
        public override void SerializeImpl(SerializerObject s)
        {
            StringCount           = s.Serialize <uint>(StringCount, name: nameof(StringCount));
            StringPointersPointer = s.SerializePointer(StringPointersPointer, name: nameof(StringPointersPointer));

            Pointers = s.DoAt(StringPointersPointer, () => s.SerializePointerArray(Pointers, StringCount, name: nameof(Pointers)));

            if (Strings == null)
            {
                Strings = new string[Pointers.Length];
            }

            for (int i = 0; i < Strings.Length; i++)
            {
                Strings[i] = s.DoAt(Pointers[i], () => s.SerializeString(Strings[i], encoding: Encoding.GetEncoding(1252), name: $"{nameof(Strings)}[{i}]"));
            }
        }
コード例 #6
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            Length = s.Serialize <uint>(Length, name: nameof(Length));
            Songs  = s.SerializePointerArray(Songs, Length, anchor: BaseOffset, name: nameof(Songs));

            if (SongBytes == null)
            {
                SongBytes = new byte[Songs.Length][];
                for (int i = 0; i < Songs.Length; i++)
                {
                    Pointer nextOff = (i < Songs.Length - 1) ? Songs[i + 1] : EndOffset;
                    s.DoAt(Songs[i], () => {
                        SongBytes[i] = s.SerializeArray <byte>(SongBytes[i], nextOff - Songs[i], name: $"{nameof(SongBytes)}[{i}]");
                    });
                }
            }
        }
コード例 #7
0
        public override void SerializeImpl(SerializerObject s)
        {
            AnimationsPointer    = s.SerializePointer(AnimationsPointer, name: nameof(AnimationsPointer));
            FramePointersPointer = s.SerializePointer(FramePointersPointer, name: nameof(FramePointersPointer));
            Ushort_08            = s.Serialize <ushort>(Ushort_08, name: nameof(Ushort_08));
            AnimationsCount      = s.Serialize <ushort>(AnimationsCount, name: nameof(AnimationsCount));

            Animations    = s.DoAt(AnimationsPointer, () => s.SerializeObjectArray <GBAVV_Map2D_Animation>(Animations, AnimationsCount, name: nameof(Animations)));
            FramePointers = s.DoAt(FramePointersPointer, () => s.SerializePointerArray(FramePointers, Animations.SelectMany(x => x.FrameTable).Max() + 1, name: nameof(FramePointers)));

            if (AnimationFrames == null)
            {
                AnimationFrames = new GBAVV_Map2D_AnimationFrame[FramePointers.Length];
            }

            for (int i = 0; i < AnimationFrames.Length; i++)
            {
                AnimationFrames[i] = s.DoAt(FramePointers[i], () => s.SerializeObject <GBAVV_Map2D_AnimationFrame>(AnimationFrames[i], name: $"{nameof(AnimationFrames)}[{i}]"));
            }
        }
コード例 #8
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            // Hack to get length of instrument table & instrument bytes
            Pointer instrOff1 = null;

            s.DoAt(Offset, () => {
                instrOff1 = s.SerializePointer(instrOff1, anchor: BaseOffset, name: nameof(instrOff1));
            });
            Instruments = s.SerializePointerArray(Instruments, (instrOff1 - Offset) / 4, anchor: BaseOffset, name: nameof(Instruments));
            if (InstrumentBytes == null)
            {
                InstrumentBytes = new byte[Instruments.Length][];
                for (int i = 0; i < Instruments.Length; i++)
                {
                    Pointer nextOff = (i < Instruments.Length - 1) ? Instruments[i + 1] : EndOffset;
                    s.DoAt(Instruments[i], () => {
                        InstrumentBytes[i] = s.SerializeArray <byte>(InstrumentBytes[i], nextOff - Instruments[i], name: $"{nameof(InstrumentBytes)}[{i}]");
                    });
                }
            }
        }
コード例 #9
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            // Serialize pointers
            LayersPointer      = s.SerializePointer(LayersPointer, name: nameof(LayersPointer));
            FramesPointer      = s.SerializePointer(FramesPointer, name: nameof(FramesPointer));
            UnkAnimDataPointer = s.SerializePointer(UnkAnimDataPointer, name: nameof(UnkAnimDataPointer)); // ^points to 8 bytes

            // Serialize values
            LayersPerFrame   = s.Serialize <ushort>(LayersPerFrame, name: nameof(LayersPerFrame));
            FrameCount       = s.Serialize <byte>(FrameCount, name: nameof(FrameCount));
            UnkAnimDataCount = s.Serialize <byte>(UnkAnimDataCount, name: nameof(UnkAnimDataCount));

            // Serialize layers
            s.DoAt(LayersPointer, () =>
            {
                // Serialize the layer pointers
                LayerPointers = s.SerializePointerArray(LayerPointers, FrameCount, name: nameof(LayerPointers));

                if (Layers == null)
                {
                    Layers = new R1_AnimationLayer[FrameCount][];
                }

                // Serialize the layers for each frame
                for (int i = 0; i < Layers.Length; i++)
                {
                    Layers[i] = s.SerializeObjectArray <R1_AnimationLayer>(Layers[i], LayersPerFrame, name: $"{nameof(Layers)} [{i}]");
                }
            });

            // Serialize frames
            s.DoAt(FramesPointer, () => Frames = s.SerializeObjectArray <R1_AnimationFrame>(Frames, FrameCount, name: nameof(Frames)));

            // Serialize unknown animation data
            s.DoAt(UnkAnimDataPointer, () => UnkAnimData = s.SerializeObjectArray <R1_R2UnknownAnimData>(UnkAnimData, UnkAnimDataCount, name: nameof(UnkAnimData)));
        }
コード例 #10
0
        public override void SerializeImpl(SerializerObject s)
        {
            // Get the language count for the current game
            var langCount    = ((GBAIsometric_Spyro_Manager)s.GameSettings.GetGameManager).GetLanguages.Count();
            var pointerTable = PointerTables.GBAIsometric_Spyro_PointerTable(s.GameSettings.GameModeSelection, Offset.file);

            if (s.GameSettings.EngineVersion == EngineVersion.GBAIsometric_Spyro3)
            {
                // Parse loc tables
                LocalizationBlockIndices = s.DoAt(pointerTable.TryGetItem(GBAIsometric_Spyro_Pointer.LocalizationBlockIndices), () => s.SerializeObjectArray <GBAIsometric_Spyro_DataBlockIndex>(LocalizationBlockIndices, langCount, x => x.HasPadding = true, name: nameof(LocalizationBlockIndices)));
                LocalizationDecompressionBlockIndices = s.DoAt(pointerTable.TryGetItem(GBAIsometric_Spyro_Pointer.LocalizationDecompressionBlockIndices), () => s.SerializeObjectArray <GBAIsometric_Spyro_DataBlockIndex>(LocalizationDecompressionBlockIndices, langCount, x => x.HasPadding = true, name: nameof(LocalizationDecompressionBlockIndices)));

                LocTables = s.DoAt(pointerTable.TryGetItem(GBAIsometric_Spyro_Pointer.LocTables), () => s.SerializeObjectArray <GBAIsometric_Spyro_LocTable>(LocTables, 38, name: nameof(LocTables)));

                // Parse block data

                if (LocDecompressHelpers == null)
                {
                    LocDecompressHelpers = new GBAIsometric_Spyro_LocDecompress[langCount][];
                }

                for (int i = 0; i < LocDecompressHelpers.Length; i++)
                {
                    LocDecompressHelpers[i] = LocalizationDecompressionBlockIndices[i].DoAtBlock(size => s.SerializeObjectArray <GBAIsometric_Spyro_LocDecompress>(LocDecompressHelpers[i], size / 3, name: $"{nameof(LocDecompressHelpers)}[{i}]"));
                }

                if (LocBlocks == null)
                {
                    LocBlocks = new GBAIsometric_Spyro_LocBlock[langCount];
                }

                for (int i = 0; i < LocBlocks.Length; i++)
                {
                    LocBlocks[i] = LocalizationBlockIndices[i].DoAtBlock(size =>
                                                                         s.SerializeObject <GBAIsometric_Spyro_LocBlock>(LocBlocks[i], onPreSerialize: lb =>
                    {
                        lb.Length            = LocTables.Max(lt => lt.StartIndex + lt.NumEntries);
                        lb.DecompressHelpers = LocDecompressHelpers[i];
                    }, name: $"{nameof(LocBlocks)}[{i}]"));
                }
            }
            else
            {
                LocalizationPointers = s.DoAt(pointerTable.TryGetItem(GBAIsometric_Spyro_Pointer.LocalizationPointers), () => s.SerializePointerArray(LocalizationPointers, langCount, name: nameof(LocalizationPointers)));

                if (LocBlocks == null)
                {
                    LocBlocks = new GBAIsometric_Spyro_LocBlock[langCount];
                }

                for (int i = 0; i < LocBlocks.Length; i++)
                {
                    LocBlocks[i] = s.DoAt(LocalizationPointers[i], () => s.SerializeObject <GBAIsometric_Spyro_LocBlock>(LocBlocks[i], name: $"{nameof(LocBlocks)}[{i}]"));
                }
            }

            // Store the localization tables so we can access them to get the strings
            s.Context.StoreObject("Loc", LocBlocks.Select(x => x.Strings).ToArray());
        }
コード例 #11
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            // Serialize ROM header
            base.SerializeImpl(s);

            var pointerTable = PointerTables.GBAIsometric_RHR_PointerTable(s.GameSettings.GameModeSelection, Offset.file);

            // Serialize localization
            Localization = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Localization], () => s.SerializeObject <GBAIsometric_RHR_Localization>(Localization, name: nameof(Localization)));

            if (s.GameSettings.World == 0)
            {
                // Serialize level infos
                s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Levels], () =>
                {
                    if (LevelInfos == null)
                    {
                        LevelInfos = new GBAIsometric_RHR_LevelInfo[20];
                    }

                    for (int i = 0; i < LevelInfos.Length; i++)
                    {
                        LevelInfos[i] = s.SerializeObject(LevelInfos[i], x => x.SerializeData = i == s.GameSettings.Level, name: $"{nameof(LevelInfos)}[{i}]");
                    }
                });

                PaletteAnimations = new GBAIsometric_RHR_PaletteAnimationTable[3];
                s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.PaletteAnimations0], () => {
                    PaletteAnimations[0] = s.SerializeObject <GBAIsometric_RHR_PaletteAnimationTable>(PaletteAnimations[0], name: $"{nameof(PaletteAnimations)}[0]");
                });
                s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.PaletteAnimations1], () => {
                    PaletteAnimations[1] = s.SerializeObject <GBAIsometric_RHR_PaletteAnimationTable>(PaletteAnimations[1], name: $"{nameof(PaletteAnimations)}[1]");
                });
                s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.PaletteAnimations2], () => {
                    PaletteAnimations[2] = s.SerializeObject <GBAIsometric_RHR_PaletteAnimationTable>(PaletteAnimations[2], name: $"{nameof(PaletteAnimations)}[2]");
                });

                // Serialize object types
                ObjectTypes = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.ObjTypes], () => s.SerializeObjectArray <GBAIsometric_ObjectType>(ObjectTypes, 105, name: nameof(ObjectTypes)));

                // Serialize the crab type and add to the array (the crab entry points to memory)
                ObjectTypes[13].Data = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.CrabObjType], () => s.SerializeObject <GBAIsometric_ObjectTypeData>(ObjectTypes[13].Data, name: $"CrabObjectTypeData"));

                // Serialize additional object types
                var additionalObjTypePointers = ObjTypePointers[s.GameSettings.GameModeSelection];
                if (AdditionalObjectTypes == null)
                {
                    AdditionalObjectTypes = new GBAIsometric_ObjectTypeData[additionalObjTypePointers.Length];
                }

                for (int i = 0; i < AdditionalObjectTypes.Length; i++)
                {
                    AdditionalObjectTypes[i] = s.DoAt(new Pointer(additionalObjTypePointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_ObjectTypeData>(AdditionalObjectTypes[i], name: $"{nameof(AdditionalObjectTypes)}[{i}]"));
                }

                // Serialize additional animation sets
                var additionalAnimSetPointers = AnimSetPointers[s.GameSettings.GameModeSelection];
                if (AdditionalAnimSets == null)
                {
                    AdditionalAnimSets = new GBAIsometric_RHR_AnimSet[additionalAnimSetPointers.Length];
                }

                for (int i = 0; i < AdditionalAnimSets.Length; i++)
                {
                    AdditionalAnimSets[i] = s.DoAt(new Pointer(additionalAnimSetPointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_RHR_AnimSet>(AdditionalAnimSets[i], name: $"{nameof(AdditionalAnimSets)}[{i}]"));
                }

                // Serialize sprite sets
                var spriteSetPointers = SpriteSetPointers[s.GameSettings.GameModeSelection];
                if (SpriteSets == null)
                {
                    SpriteSets = new GBAIsometric_RHR_SpriteSet[spriteSetPointers.Length];
                }

                for (int i = 0; i < SpriteSets.Length; i++)
                {
                    SpriteSets[i] = s.DoAt(new Pointer(spriteSetPointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_RHR_SpriteSet>(SpriteSets[i], name: $"{nameof(SpriteSets)}[{i}]"));
                }

                // Serialize sprites
                var spritePointers = SpritePointers[s.GameSettings.GameModeSelection];
                if (Sprites == null)
                {
                    Sprites = new GBAIsometric_RHR_Sprite[spritePointers.Length];
                }

                for (int i = 0; i < Sprites.Length; i++)
                {
                    Sprites[i] = s.DoAt(new Pointer(spritePointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_RHR_Sprite>(Sprites[i], name: $"{nameof(Sprites)}[{i}]"));
                }

                // Serialize sprite icons
                SpriteIconPointers = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.SpriteIcons], () => s.SerializePointerArray(SpriteIconPointers, 84, name: nameof(SpriteIconPointers)));

                if (SpriteIcons == null)
                {
                    SpriteIcons = new GBAIsometric_RHR_Sprite[SpriteIconPointers.Length];
                }

                for (int i = 0; i < SpriteIcons.Length; i++)
                {
                    SpriteIcons[i] = s.DoAt(SpriteIconPointers[i], () => s.SerializeObject <GBAIsometric_RHR_Sprite>(SpriteIcons[i], name: $"{nameof(SpriteIcons)}[{i}]"));
                }

                // Serialize flag sprites
                FlagSpritesUS = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.SpriteFlagsUS], () => s.SerializeObjectArray <GBAIsometric_RHR_FlagSprite>(FlagSpritesUS, 3, name: nameof(FlagSpritesUS)));
                FlagSpritesEU = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.SpriteFlagsEU], () => s.SerializeObjectArray <GBAIsometric_RHR_FlagSprite>(FlagSpritesEU, 6, name: nameof(FlagSpritesEU)));

                // Serialize font
                Font0 = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Font0], () => s.SerializeObject <GBAIsometric_RHR_Font>(Font0, name: nameof(Font0)));
                Font1 = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Font1], () => s.SerializeObject <GBAIsometric_RHR_Font>(Font1, name: nameof(Font1)));
                Font2 = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Font2], () => s.SerializeObject <GBAIsometric_RHR_Font>(Font2, name: nameof(Font2)));

                // Serialize portraits
                PortraitPointers = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Portraits], () => s.SerializePointerArray(PortraitPointers, 10, name: nameof(PortraitPointers)));

                if (Portraits == null)
                {
                    Portraits = new GBAIsometric_RHR_AnimSet[PortraitPointers.Length];
                }

                for (int i = 0; i < Portraits.Length; i++)
                {
                    Portraits[i] = s.DoAt(PortraitPointers[i], () => s.SerializeObject <GBAIsometric_RHR_AnimSet>(Portraits[i], name: $"{nameof(Portraits)}[{i}]"));
                }

                // Serialize alternative anim set palettes
                var alternativeAnimSetPalettes = AlternativeAnimSetPalettes[s.GameSettings.GameModeSelection];

                foreach (GBAIsometric_RHR_AnimSet animSet in GetAllAnimSets().Where(x => alternativeAnimSetPalettes.ContainsKey(x.Name)))
                {
                    animSet.SerializeAlternativePalettes(s, alternativeAnimSetPalettes[animSet.Name]);
                }
            }
            else
            {
                var maps = ((GBAIsometric_RHR_Manager)s.GameSettings.GetGameManager).GetMenuMaps(s.GameSettings.Level);
                MenuMaps = new GBAIsometric_RHR_MapLayer[maps.Length];

                for (int i = 0; i < MenuMaps.Length; i++)
                {
                    MenuMaps[i] = s.DoAt(pointerTable[maps[i]], () => s.SerializeObject <GBAIsometric_RHR_MapLayer>(default, name: $"{maps[i]}"));
コード例 #12
0
        public override void SerializeImpl(SerializerObject s)
        {
            NamePointer           = s.SerializePointer(NamePointer, name: nameof(NamePointer));
            MapWidth              = s.Serialize <ushort>(MapWidth, name: nameof(MapWidth));
            MapHeight             = s.Serialize <ushort>(MapHeight, name: nameof(MapHeight));
            TileSetCount_Total    = s.Serialize <ushort>(TileSetCount_Total, name: nameof(TileSetCount_Total));
            TileSetCount_4bpp     = s.Serialize <ushort>(TileSetCount_4bpp, name: nameof(TileSetCount_4bpp));
            TileSetPointer        = s.SerializePointer(TileSetPointer, name: nameof(TileSetPointer));
            MapTilesPointer       = s.SerializePointer(MapTilesPointer, name: nameof(MapTilesPointer));
            MapLayerPointers      = s.SerializePointerArray(MapLayerPointers, 4, name: nameof(MapLayerPointers));
            TilePalettePointer    = s.SerializePointer(TilePalettePointer, name: nameof(TilePalettePointer));
            CollisionWidth        = s.Serialize <ushort>(CollisionWidth, name: nameof(CollisionWidth));
            CollisionHeight       = s.Serialize <ushort>(CollisionHeight, name: nameof(CollisionHeight));
            CollisionMapPointer   = s.SerializePointer(CollisionMapPointer, name: nameof(CollisionMapPointer));
            CollisionTilesPointer = s.SerializePointer(CollisionTilesPointer, name: nameof(CollisionTilesPointer));
            CollisionTypePointers = s.SerializePointer(CollisionTypePointers, name: nameof(CollisionTypePointers));
            Pointer_38            = s.SerializePointer(Pointer_38, name: nameof(Pointer_38));
            Pointer_3C            = s.SerializePointer(Pointer_3C, name: nameof(Pointer_3C));
            Pointer_40            = s.SerializePointer(Pointer_40, name: nameof(Pointer_40));
            Pointer_44            = s.SerializePointer(Pointer_44, name: nameof(Pointer_44));
            Pointer_48            = s.SerializePointer(Pointer_48, name: nameof(Pointer_48));
            Pointer_4C            = s.SerializePointer(Pointer_4C, name: nameof(Pointer_4C));
            XPosition             = s.SerializeObject <FixedPointInt>(XPosition, name: nameof(XPosition));
            YPosition             = s.SerializeObject <FixedPointInt>(YPosition, name: nameof(YPosition));

            Name = s.DoAt(NamePointer, () => s.SerializeString(Name, name: nameof(Name)));

            if (!SerializeData)
            {
                return;
            }

            TileSet = s.DoAt(TileSetPointer, () => s.SerializeObject <GBAVV_Isometric_TileSet>(TileSet, x =>
            {
                x.TileSetCount_Total = TileSetCount_Total;
                x.TileSetCount_4bpp  = TileSetCount_4bpp;
            }, name: nameof(TileSet)));

            if (MapLayers == null)
            {
                MapLayers = new GBAVV_Isometric_MapLayer[MapLayerPointers.Length];
            }

            for (int i = 0; i < MapLayers.Length; i++)
            {
                MapLayers[i] = s.DoAt(MapLayerPointers[i], () => s.SerializeObject <GBAVV_Isometric_MapLayer>(MapLayers[i], name: $"{nameof(MapLayers)}[{i}]"));
            }

            var mapTilesLength = MapLayers.SelectMany(x => x.TileMapRows).SelectMany(x => x.Commands).Select(x => x.Params?.Max() ?? x.Param).Max() + 1;

            MapTiles    = s.DoAt(MapTilesPointer, () => s.SerializeObjectArray <MapTile>(MapTiles, mapTilesLength * 4, x => x.Is8Bpp = true, name: nameof(MapTiles)));
            TilePalette = s.DoAt(TilePalettePointer, () => s.SerializeObjectArray <RGBA5551Color>(TilePalette, 256, name: nameof(TilePalette)));

            CollisionMap   = s.DoAt(CollisionMapPointer, () => s.SerializeArray <ushort>(CollisionMap, CollisionWidth * CollisionHeight, name: nameof(CollisionMap)));
            CollisionTiles = s.DoAt(CollisionTilesPointer, () => s.SerializeObjectArray <GBAVV_Isometric_CollisionTile>(CollisionTiles, CollisionMap.Max() + 1, name: nameof(CollisionTiles)));
            CollisionTypes = s.DoAt(CollisionTypePointers, () => s.SerializeObjectArray <GBAVV_Isometric_CollisionType>(CollisionTypes, CollisionTiles.Max(x => x.TypeIndex) + 1, name: nameof(CollisionTypes)));

            s.DoAt(Pointer_4C, () =>
            {
                if (Pointer_4C_Structs == null)
                {
                    var objects = new List <GBAVV_Isometric_UnkStruct_0>();
                    var index   = 0;

                    while (true)
                    {
                        var obj = s.SerializeObject <GBAVV_Isometric_UnkStruct_0>(default, name: $"{nameof(Pointer_4C_Structs)}[{index++}]");
コード例 #13
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            if (s.GameSettings.EngineVersion == EngineVersion.R1Jaguar_Proto && StructType != 29)
            {
                UnkPointers = s.SerializePointerArray(UnkPointers, 64, allowInvalid: true, name: nameof(UnkPointers));
            }

            if (StructType != 29)
            {
                UnkBytes = s.SerializeArray <byte>(UnkBytes, 0x10, name: nameof(UnkBytes));
            }

            ImageDescriptorsPointer = s.SerializePointer(ImageDescriptorsPointer, name: nameof(ImageDescriptorsPointer));

            if (StructType != 29)
            {
                Transitions = s.SerializeObjectArray <R1Jaguar_EventComplexDataTransition>(Transitions, s.GameSettings.EngineVersion == EngineVersion.R1Jaguar_Proto ? 5 : 7, onPreSerialize: g => {
                    g.StructType = StructType;
                    g.NumLayers  = NumLayers;
                }, name: nameof(Transitions));
            }

            // Serialize from first state index
            {
                var temp = new List <R1Jaguar_EventComplexDataState>();

                var index = 0;
                while (true)
                {
                    // Always check for pointer
                    {
                        Pointer CheckPtr0 = null;
                        bool    success   = true;
                        s.DoAt(s.CurrentPointer, () => {
                            try {
                                CheckPtr0 = s.SerializePointer(CheckPtr0, name: nameof(CheckPtr0));
                            } catch (Exception) {
                                success = false;
                            }
                        });
                        if (!success ||
                            (CheckPtr0 != null && CheckPtr0.file != Offset.file))
                        {
                            break;
                        }
                        else if (CheckPtr0 != null)
                        {
                            // Can't check animation header, the frame pointer doesn't always point to the start of the actual animation

                            /*byte[] CheckBytes = null;
                             * s.DoAt(CheckPtr0 - 4, () => {
                             *      CheckBytes = s.SerializeArray<byte>(CheckBytes, 4, name: nameof(CheckBytes));
                             *      if (CheckBytes[1] != 0 || CheckBytes[3] != 0
                             || CheckBytes[0] == 0 || CheckBytes[2] == 0) {
                             ||             // Padding should be padding, other values should be filled in
                             ||             success = false;
                             ||     }
                             ||});*/
                            if (!success)
                            {
                                break;
                            }
                        }
                    }
                    var i = s.SerializeObject <R1Jaguar_EventComplexDataState>(default, onPreSerialize: state => state.LayersPerFrame = NumLayers, name: $"{nameof(States)}[{index}]");
コード例 #14
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            // Get the pointer table
            var pointerTable = PointerTables.R1_DSi_PointerTable(s.GameSettings.GameModeSelection, this.Offset.file);

            s.DoAt(pointerTable[R1_DSi_Pointer.WorldLevelOffsetTable],
                   () => WorldLevelOffsetTable = s.SerializeArray <byte>(WorldLevelOffsetTable, 8, name: nameof(WorldLevelOffsetTable)));

            // Get the global level index
            var levelIndex = WorldLevelOffsetTable[s.GameSettings.World] + (s.GameSettings.Level - 1);

            DES_Ray = s.DoAt(pointerTable[R1_DSi_Pointer.DES_Ray], () => s.SerializeObject <R1_GBA_EventGraphicsData>(DES_Ray, name: nameof(DES_Ray)));
            ETA_Ray = s.DoAt(pointerTable.TryGetItem(R1_DSi_Pointer.ETA_Ray), () => s.SerializeObject <R1_GBA_ETA>(ETA_Ray, x => x.Lengths = new byte[] { 66, 12, 34, 53, 14, 14, 1, 2 }, name: nameof(ETA_Ray)));

            DES_RayLittle = s.DoAt(pointerTable[R1_DSi_Pointer.DES_RayLittle], () => s.SerializeObject <R1_GBA_EventGraphicsData>(DES_RayLittle, name: nameof(DES_RayLittle)));

            DES_Clock = s.DoAt(pointerTable[R1_DSi_Pointer.DES_Clock], () => s.SerializeObject <R1_GBA_EventGraphicsData>(DES_Clock, name: nameof(DES_Clock)));
            ETA_Clock = s.DoAt(pointerTable.TryGetItem(R1_DSi_Pointer.ETA_Clock), () => s.SerializeObject <R1_GBA_ETA>(ETA_Clock, x => x.Lengths = new byte[] { 3 }, name: nameof(ETA_Clock)));

            DES_Div = s.DoAt(pointerTable[R1_DSi_Pointer.DES_Div], () => s.SerializeObject <R1_GBA_EventGraphicsData>(DES_Div, name: nameof(DES_Div)));
            ETA_Div = s.DoAt(pointerTable.TryGetItem(R1_DSi_Pointer.ETA_Div), () => s.SerializeObject <R1_GBA_ETA>(ETA_Div, x => x.Lengths = new byte[] { 1, 1, 1, 1, 1, 1, 2, 2, 12, 12, 4 }, name: nameof(ETA_Div)));

            DES_Map = s.DoAt(pointerTable[R1_DSi_Pointer.DES_Map], () => s.SerializeObject <R1_GBA_EventGraphicsData>(DES_Map, name: nameof(DES_Map)));
            ETA_Map = s.DoAt(pointerTable.TryGetItem(R1_DSi_Pointer.ETA_Map), () => s.SerializeObject <R1_GBA_ETA>(ETA_Map, x => x.Lengths = new byte[] { 64, 1, 19, 1, 1, 69, 3 }, name: nameof(ETA_Map)));

            // Serialize data from the ROM
            if (s.GameSettings.R1_World != R1_World.Menu)
            {
                s.DoAt((s.GameSettings.R1_World == R1_World.Jungle ? pointerTable[R1_DSi_Pointer.JungleMaps] : pointerTable[R1_DSi_Pointer.LevelMaps]) + (levelIndex * 32),
                       () => LevelMapData = s.SerializeObject <R1_GBA_LevelMapData>(LevelMapData, name: nameof(LevelMapData)));
            }

            s.DoAt(pointerTable[R1_DSi_Pointer.BackgroundVignette],
                   () => BackgroundVignettes = s.SerializeObjectArray <R1_GBA_BackgroundVignette>(BackgroundVignettes, 48, name: nameof(BackgroundVignettes)));

            WorldMapVignette = s.SerializeObject <R1_GBA_WorldMapVignette>(WorldMapVignette, name: nameof(WorldMapVignette));

            // Serialize the level event data
            if (s.GameSettings.R1_World != R1_World.Menu)
            {
                LevelEventData = new R1_GBA_LevelEventData();
                LevelEventData.SerializeData(s, pointerTable[R1_DSi_Pointer.EventGraphicsPointers], pointerTable[R1_DSi_Pointer.EventDataPointers], pointerTable[R1_DSi_Pointer.EventGraphicsGroupCountTablePointers], pointerTable[R1_DSi_Pointer.LevelEventGraphicsGroupCounts]);
            }

            s.DoAt(pointerTable[R1_DSi_Pointer.SpecialPalettes], () => Palettes = s.SerializeObjectArray <R1_DSi_PaletteReference>(Palettes, 10, name: nameof(Palettes)));

            // Serialize strings
            s.DoAt(pointerTable[R1_DSi_Pointer.StringPointers], () =>
            {
                StringPointerTable = s.SerializePointerArray(StringPointerTable, 5 * 394, name: nameof(StringPointerTable));

                if (Strings == null)
                {
                    Strings = new string[5][];
                }

                var enc = new Encoding[]
                {
                    // Spanish
                    Encoding.GetEncoding(1252),
                    // English
                    Encoding.GetEncoding(437),
                    // French
                    Encoding.GetEncoding(1252),
                    // Italian
                    Encoding.GetEncoding(1252),
                    // German
                    Encoding.GetEncoding(437),
                };

                for (int i = 0; i < Strings.Length; i++)
                {
                    if (Strings[i] == null)
                    {
                        Strings[i] = new string[394];
                    }

                    for (int j = 0; j < Strings[i].Length; j++)
                    {
                        s.DoAt(StringPointerTable[i * 394 + j], () => Strings[i][j] = s.SerializeString(Strings[i][j], encoding: enc[i], name: $"{nameof(Strings)}[{i}][{j}]"));
                    }
                }
            });

            // Serialize tables
            s.DoAt(pointerTable[R1_DSi_Pointer.TypeZDC], () => TypeZDC       = s.SerializeObjectArray <R1_ZDCEntry>(TypeZDC, 262, name: nameof(TypeZDC)));
            s.DoAt(pointerTable[R1_DSi_Pointer.ZdcData], () => ZdcData       = s.SerializeObjectArray <R1_ZDCData>(ZdcData, 200, name: nameof(ZdcData)));
            s.DoAt(pointerTable[R1_DSi_Pointer.EventFlags], () => EventFlags = s.SerializeArray <R1_EventFlags>(EventFlags, 262, name: nameof(EventFlags)));

            if (s.GameSettings.R1_World != R1_World.Menu)
            {
                WorldVignetteIndicesPointers = s.DoAt(pointerTable[R1_DSi_Pointer.WorldVignetteIndices], () => s.SerializePointerArray(WorldVignetteIndicesPointers, 7, name: nameof(WorldVignetteIndicesPointers)));
                WorldVignetteIndices         = s.DoAt(WorldVignetteIndicesPointers[s.GameSettings.World], () => s.SerializeArray <byte>(WorldVignetteIndices, 8, name: nameof(WorldVignetteIndices))); // The max size is 8

                // Get the background indices
                s.DoAt(pointerTable[R1_DSi_Pointer.LevelMapsBGIndices] + (levelIndex * 32), () =>
                {
                    LevelMapData.Unk_10                  = s.Serialize <byte>(LevelMapData.Unk_10, name: nameof(LevelMapData.Unk_10));
                    LevelMapData.Unk_11                  = s.Serialize <byte>(LevelMapData.Unk_11, name: nameof(LevelMapData.Unk_11));
                    LevelMapData.BackgroundIndex         = s.Serialize <byte>(LevelMapData.BackgroundIndex, name: nameof(LevelMapData.BackgroundIndex));
                    LevelMapData.ParallaxBackgroundIndex = s.Serialize <byte>(LevelMapData.ParallaxBackgroundIndex, name: nameof(LevelMapData.ParallaxBackgroundIndex));
                });
            }

            WorldInfos = s.DoAt(pointerTable[R1_DSi_Pointer.WorldInfo], () => s.SerializeObjectArray <R1_WorldMapInfo>(WorldInfos, 24, name: nameof(WorldInfos)));
        }
コード例 #15
0
        public override void SerializeImpl(SerializerObject s)
        {
            // Serialize ROM header
            base.SerializeImpl(s);

            // Get pointer table
            var pointerTable = PointerTables.GBARRR_PointerTable(s.GameSettings.GameModeSelection, Offset.file);

            // Serialize offset table
            OffsetTable = s.DoAt(pointerTable[GBARRR_Pointer.OffsetTable], () => s.SerializeObject <GBARRR_OffsetTable>(OffsetTable, name: nameof(OffsetTable)));

            // Serialize localization
            OffsetTable.DoAtBlock(s.Context, 3, size =>
                                  Localization = s.SerializeObject <GBARRR_LocalizationBlock>(Localization, name: nameof(Localization)));

            var gameMode = GBA_RRR_Manager.GetCurrentGameMode(s.GameSettings);

            if (gameMode == GBA_RRR_Manager.GameMode.Game || gameMode == GBA_RRR_Manager.GameMode.Village)
            {
                // Serialize level info
                VillageLevelInfo = s.DoAt(pointerTable[GBARRR_Pointer.VillageLevelInfo],
                                          () => s.SerializeObjectArray <GBARRR_LevelInfo>(VillageLevelInfo, 3,
                                                                                          name: nameof(VillageLevelInfo)));
                LevelInfo = s.DoAt(pointerTable[GBARRR_Pointer.LevelInfo],
                                   () => s.SerializeObjectArray <GBARRR_LevelInfo>(LevelInfo, 32, name: nameof(LevelInfo)));
                LevelProperties = s.DoAt(pointerTable[GBARRR_Pointer.LevelProperties],
                                         () => s.SerializeObjectArray <GBARRR_LevelProperties>(LevelProperties, 32, name: nameof(LevelProperties)));

                // Get the current level info
                var lvlInfo = GetLevelInfo(s.GameSettings);

                // Serialize tile maps
                OffsetTable.DoAtBlock(s.Context, lvlInfo.LevelTilesetIndex, size =>
                                      LevelTileset = s.SerializeObject <GBARRR_Tileset>(LevelTileset, name: nameof(LevelTileset),
                                                                                        onPreSerialize: x => x.BlockSize = size));
                OffsetTable.DoAtBlock(s.Context, lvlInfo.BG0TilesetIndex, size =>
                                      BG0TileSet = s.SerializeObject <GBARRR_Tileset>(BG0TileSet, name: nameof(BG0TileSet),
                                                                                      onPreSerialize: x => x.BlockSize = size));
                OffsetTable.DoAtBlock(s.Context, lvlInfo.FGTilesetIndex, size =>
                                      FGTileSet = s.SerializeObject <GBARRR_Tileset>(FGTileSet, name: nameof(FGTileSet),
                                                                                     onPreSerialize: x => x.BlockSize = size));
                OffsetTable.DoAtBlock(s.Context, lvlInfo.BG1TilesetIndex, size =>
                                      BG1TileSet = s.SerializeObject <GBARRR_Tileset>(BG1TileSet, name: nameof(BG1TileSet),
                                                                                      onPreSerialize: x => x.BlockSize = size));

                // Serialize level scene
                OffsetTable.DoAtBlock(s.Context, lvlInfo.ObjectArrayIndex,
                                      size => ObjectArray = s.SerializeObject <GBARRR_ObjectArray>(ObjectArray, name: nameof(ObjectArray)));

                // Serialize maps
                OffsetTable.DoAtBlock(s.Context, lvlInfo.BG0MapIndex, size =>
                                      BG0Map = s.SerializeObject <GBARRR_BGMapBlock>(BG0Map, name: nameof(BG0Map)));
                OffsetTable.DoAtBlock(s.Context, lvlInfo.BG1MapIndex, size =>
                                      BG1Map = s.SerializeObject <GBARRR_BGMapBlock>(BG1Map, name: nameof(BG1Map)));
                OffsetTable.DoAtBlock(s.Context, lvlInfo.CollisionMapIndex, size =>
                                      CollisionMap = s.SerializeObject <GBARRR_MapBlock>(CollisionMap, name: nameof(CollisionMap),
                                                                                         onPreSerialize: x => x.Type = GBARRR_MapBlock.MapType.Collision));
                OffsetTable.DoAtBlock(s.Context, lvlInfo.LevelMapIndex, size =>
                                      LevelMap = s.SerializeObject <GBARRR_MapBlock>(LevelMap, name: nameof(LevelMap),
                                                                                     onPreSerialize: x => x.Type = GBARRR_MapBlock.MapType.Tiles));
                OffsetTable.DoAtBlock(s.Context, lvlInfo.FGMapIndex, size =>
                                      FGMap = s.SerializeObject <GBARRR_MapBlock>(FGMap, name: nameof(FGMap),
                                                                                  onPreSerialize: x => x.Type = GBARRR_MapBlock.MapType.Foreground));

                // Serialize palettes
                var tilePalIndex = GetLevelTilePaletteOffsetIndex(s.GameSettings);
                if (tilePalIndex != null)
                {
                    OffsetTable.DoAtBlock(s.Context, tilePalIndex.Value, size =>
                                          TilePalette = s.SerializeObjectArray <RGBA5551Color>(TilePalette, 0x100, name: nameof(TilePalette)));
                }
                OffsetTable.DoAtBlock(s.Context, lvlInfo.SpritePaletteIndex, size =>
                                      SpritePalette = s.SerializeObjectArray <RGBA5551Color>(SpritePalette, 0x100, name: nameof(SpritePalette)));

                if (AnimatedPalettes == null)
                {
                    AnimatedPalettes = new RGBA5551Color[5][];
                }

                for (int i = 0; i < AnimatedPalettes.Length; i++)
                {
                    OffsetTable.DoAtBlock(s.Context, 764 + i, size =>
                                          AnimatedPalettes[i] = s.SerializeObjectArray <RGBA5551Color>(AnimatedPalettes[i], 0x100, name: $"{nameof(AnimatedPalettes)}[{i}]"));
                }

                // Serialize tables
                s.DoAt(pointerTable[GBARRR_Pointer.GraphicsTables], () =>
                {
                    var counts = new uint[] { 0x47, 0x40, 0x45, 0x44, 0x50, 0x42 };

                    if (GraphicsTable0 == null)
                    {
                        GraphicsTable0 = new GBARRR_GraphicsTableEntry[counts.Length][];
                    }
                    if (GraphicsTable1 == null)
                    {
                        GraphicsTable1 = new uint[counts.Length][];
                    }
                    if (GraphicsTable2 == null)
                    {
                        GraphicsTable2 = new uint[counts.Length][];
                    }
                    if (GraphicsTable3 == null)
                    {
                        GraphicsTable3 = new uint[counts.Length][];
                    }
                    if (GraphicsTable4 == null)
                    {
                        GraphicsTable4 = new uint[counts.Length][];
                    }

                    for (int i = 0; i < counts.Length; i++)
                    {
                        GraphicsTable0[i] = s.SerializeObjectArray <GBARRR_GraphicsTableEntry>(GraphicsTable0[i],
                                                                                               counts[i], name: $"{nameof(GraphicsTable0)}[{i}]");
                        GraphicsTable1[i] = s.SerializeArray <uint>(GraphicsTable1[i], counts[i],
                                                                    name: $"{nameof(GraphicsTable1)}[{i}]");
                        GraphicsTable2[i] = s.SerializeArray <uint>(GraphicsTable2[i], counts[i],
                                                                    name: $"{nameof(GraphicsTable2)}[{i}]");
                        GraphicsTable3[i] = s.SerializeArray <uint>(GraphicsTable3[i], counts[i],
                                                                    name: $"{nameof(GraphicsTable3)}[{i}]");
                        GraphicsTable4[i] = s.SerializeArray <uint>(GraphicsTable4[i], counts[i],
                                                                    name: $"{nameof(GraphicsTable4)}[{i}]");
                        if (i == 2 || i == 3)
                        {
                            s.Serialize <uint>(1, name: "Padding");
                        }
                    }
                });
            }
            else if (gameMode == GBA_RRR_Manager.GameMode.Mode7)
            {
                // Serialize pointer tables
                Mode7_MapTilesPointers         = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_MapTiles], () => s.SerializePointerArray(Mode7_MapTilesPointers, 3, name: nameof(Mode7_MapTilesPointers)));
                Mode7_BG1TilesPointers         = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_BG1Tiles], () => s.SerializePointerArray(Mode7_BG1TilesPointers, 3, name: nameof(Mode7_BG1TilesPointers)));
                Mode7_BG1MapPointers           = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_Bg1Map], () => s.SerializePointerArray(Mode7_BG1MapPointers, 3, name: nameof(Mode7_BG1MapPointers)));
                Mode7_BG0TilesPointers         = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_BG0Tiles], () => s.SerializePointerArray(Mode7_BG0TilesPointers, 3, name: nameof(Mode7_BG0TilesPointers)));
                Mode7_BG0MapPointers           = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_BG0Map], () => s.SerializePointerArray(Mode7_BG0MapPointers, 3, name: nameof(Mode7_BG0MapPointers)));
                Mode7_MapPointers              = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_MapData], () => s.SerializePointerArray(Mode7_MapPointers, 3, name: nameof(Mode7_MapPointers)));
                Mode7_CollisionMapDataPointers = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_CollisionMapData], () => s.SerializePointerArray(Mode7_CollisionMapDataPointers, 3, name: nameof(Mode7_CollisionMapDataPointers)));
                Mode7_MapPalettePointers       = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_TilePalette], () => s.SerializePointerArray(Mode7_MapPalettePointers, 3, name: nameof(Mode7_MapPalettePointers)));
                Mode7_BG1PalettePointers       = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_BG1Palette], () => s.SerializePointerArray(Mode7_BG1PalettePointers, 3, name: nameof(Mode7_BG1PalettePointers)));
                Mode7_BG0PalettePointers       = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_BG0Palette], () => s.SerializePointerArray(Mode7_BG0PalettePointers, 3, name: nameof(Mode7_BG0PalettePointers)));
                Mode7_ObjectsPointers          = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_Objects], () => s.SerializePointerArray(Mode7_ObjectsPointers, 3, name: nameof(Mode7_ObjectsPointers)));
                Mode7_CollisionTypesPointers   = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_CollisionTypesArray], () => s.SerializePointerArray(Mode7_CollisionTypesPointers, 3, name: nameof(Mode7_CollisionTypesPointers)));
                Mode7_WaypointsCount           = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_WaypointsCount], () => s.SerializeArray <short>(Mode7_WaypointsCount, 3, name: nameof(Mode7_WaypointsCount)));
                Mode7_WaypointsPointers        = s.DoAt(pointerTable[GBARRR_Pointer.Mode7_Waypoints], () => s.SerializePointerArray(Mode7_WaypointsPointers, 3, name: nameof(Mode7_WaypointsPointers)));

                // Serialize compressed tile data
                s.DoAt(Mode7_MapTilesPointers[s.GameSettings.Level], () => {
                    s.DoEncoded(new RNCEncoder(hasHeader: false), () => Mode7_MapTiles = s.SerializeArray <byte>(Mode7_MapTiles, s.CurrentLength, name: nameof(Mode7_MapTiles)));
                });
                s.DoAt(Mode7_BG0TilesPointers[s.GameSettings.Level], () => {
                    s.DoEncoded(new RNCEncoder(hasHeader: false), () => Mode7_BG0Tiles = s.SerializeArray <byte>(Mode7_BG0Tiles, s.CurrentLength, name: nameof(Mode7_BG0Tiles)));
                });
                s.DoAt(Mode7_BG1TilesPointers[s.GameSettings.Level], () => {
                    s.DoEncoded(new RNCEncoder(hasHeader: false), () => Mode7_BG1Tiles = s.SerializeArray <byte>(Mode7_BG1Tiles, s.CurrentLength, name: nameof(Mode7_BG1Tiles)));
                });

                // Serialize map data
                if (s.GameSettings.GameModeSelection == GameModeSelection.RaymanRavingRabbidsGBAEU)
                {
                    Mode7_MapData = s.DoAt(Mode7_MapPointers[s.GameSettings.Level], () => s.SerializeObjectArray <MapTile>(Mode7_MapData, 256 * 256, onPreSerialize: x => x.GBARRRType = GBARRR_MapBlock.MapType.Mode7Tiles, name: nameof(Mode7_MapData)));
                }
                else
                {
                    s.DoAt(Mode7_MapPointers[s.GameSettings.Level], () =>
                    {
                        s.DoEncoded(new RNCEncoder(hasHeader: false), () =>
                                    Mode7_MapData = s.SerializeObjectArray <MapTile>(Mode7_MapData, 256 * 256, onPreSerialize: x => x.GBARRRType = GBARRR_MapBlock.MapType.Mode7Tiles, name: nameof(Mode7_MapData)));
                    });
                }
                s.DoAt(Mode7_BG0MapPointers[s.GameSettings.Level], () =>
                {
                    s.DoEncoded(new RNCEncoder(hasHeader: false), () => Mode7_BG0MapData = s.SerializeObjectArray <MapTile>(Mode7_BG0MapData, 32 * 32,
                                                                                                                            onPreSerialize: x => x.GBARRRType = GBARRR_MapBlock.MapType.Foreground, name: nameof(Mode7_BG0MapData)));
                });
                s.DoAt(Mode7_BG1MapPointers[s.GameSettings.Level], () =>
                {
                    s.DoEncoded(new RNCEncoder(hasHeader: false), () => Mode7_BG1MapData = s.SerializeObjectArray <MapTile>(Mode7_BG1MapData, 32 * 32,
                                                                                                                            onPreSerialize: x => x.GBARRRType = GBARRR_MapBlock.MapType.Foreground,
                                                                                                                            name: nameof(Mode7_BG1MapData)));
                });
                s.DoAt(Mode7_ObjectsPointers[s.GameSettings.Level], () =>
                {
                    s.DoEncoded(new RNCEncoder(hasHeader: false), () => Mode7_Objects = s.SerializeObjectArray <GBARRR_Mode7Object>(Mode7_Objects, 141, name: nameof(Mode7_Objects)));
                });
                if (s.GameSettings.GameModeSelection == GameModeSelection.RaymanRavingRabbidsGBAEU)
                {
                    s.DoAt(Mode7_CollisionMapDataPointers[s.GameSettings.Level], () => {
                        Mode7_CollisionMapData = s.SerializeArray <ushort>(Mode7_CollisionMapData, 256 * 256, name: nameof(Mode7_CollisionMapData));
                    });
                }
                else
                {
                    s.DoAt(Mode7_CollisionMapDataPointers[s.GameSettings.Level], () => {
                        s.DoEncoded(new RNCEncoder(hasHeader: false), () =>
                                    Mode7_CollisionMapData = s.SerializeArray <ushort>(Mode7_CollisionMapData, 256 * 256, name: nameof(Mode7_CollisionMapData)));
                    });
                }
                s.DoAt(Mode7_CollisionTypesPointers[s.GameSettings.Level], () => {
                    s.DoEncoded(new RNCEncoder(hasHeader: false), () => Mode7_CollisionTypes = s.SerializeArray <byte>(Mode7_CollisionTypes, s.CurrentLength, name: nameof(Mode7_CollisionTypes)));
                });
                s.DoAt(Mode7_WaypointsPointers[s.GameSettings.Level], () => {
                    Mode7_Waypoints = s.SerializeObjectArray <GBARRR_Mode7Waypoint>(Mode7_Waypoints, Mode7_WaypointsCount[s.GameSettings.Level], name: nameof(Mode7_Waypoints));
                });

                // Serialize palettes
                Mode7_MapPalette = s.DoAt(Mode7_MapPalettePointers[s.GameSettings.Level], () => s.SerializeObjectArray <RGBA5551Color>(Mode7_MapPalette, 16 * 16, name: nameof(Mode7_MapPalette)));
                Mode7_BG1Palette = s.DoAt(Mode7_BG1PalettePointers[s.GameSettings.Level], () => s.SerializeObjectArray <RGBA5551Color>(Mode7_BG1Palette, 16, name: nameof(Mode7_BG1Palette)));
                Mode7_BG0Palette = s.DoAt(Mode7_BG0PalettePointers[s.GameSettings.Level], () => s.SerializeObjectArray <RGBA5551Color>(Mode7_BG0Palette, 16, name: nameof(Mode7_BG0Palette)));

                // Fill in full tilemap palette
                Mode7_TilemapPalette = new RGBA5551Color[16 * 16];

                for (int i = 0; i < 12 * 16; i++)
                {
                    Mode7_TilemapPalette[i] = Mode7_MapPalette[i];
                }
                for (int i = 0; i < 16; i++)
                {
                    Mode7_TilemapPalette[12 * 16 + i] = Mode7_BG0Palette[i];
                }
                for (int i = 0; i < 16; i++)
                {
                    Mode7_TilemapPalette[14 * 16 + i] = Mode7_BG1Palette[i];
                }
            }
            else if (gameMode == GBA_RRR_Manager.GameMode.Mode7Unused)
            {
                OffsetTable.DoAtBlock(s.Context, 1180, size =>
                {
                    ObjectArray   = s.SerializeObject <GBARRR_ObjectArray>(ObjectArray, onPreSerialize: x => x.IsUnusedMode7 = true, name: nameof(ObjectArray));
                    Mode7_MapData = s.SerializeObjectArray <MapTile>(Mode7_MapData, 256 * 256, onPreSerialize: x => x.GBARRRType = GBARRR_MapBlock.MapType.Foreground, name: nameof(Mode7_MapData));
                });
                OffsetTable.DoAtBlock(s.Context, 1181, size =>
                                      CollisionMap = s.SerializeObject <GBARRR_MapBlock>(CollisionMap, name: nameof(CollisionMap),
                                                                                         onPreSerialize: x => x.Type = GBARRR_MapBlock.MapType.Collision));

                OffsetTable.DoAtBlock(s.Context, 1177, size => BG0TileSet   = s.SerializeObject <GBARRR_Tileset>(BG0TileSet, onPreSerialize: x => x.BlockSize = size, name: nameof(BG0TileSet)));
                OffsetTable.DoAtBlock(s.Context, 1178, size => BG1TileSet   = s.SerializeObject <GBARRR_Tileset>(BG1TileSet, onPreSerialize: x => x.BlockSize = size, name: nameof(BG1TileSet)));
                OffsetTable.DoAtBlock(s.Context, 1179, size => LevelTileset = s.SerializeObject <GBARRR_Tileset>(LevelTileset, onPreSerialize: x => x.BlockSize = size, name: nameof(LevelTileset)));
            }
            else if (gameMode == GBA_RRR_Manager.GameMode.Menu)
            {
                Menu_Pointers = s.DoAt(pointerTable[GBARRR_Pointer.MenuArray], () => s.SerializePointerArray(Menu_Pointers, 15 * 3, name: nameof(Menu_Pointers)));

                var manager    = (GBA_RRR_Manager)s.GameSettings.GetGameManager;
                var menuLevels = manager.GetMenuLevels(s.GameSettings.Level);

                Menu_Tiles   = new byte[menuLevels.Length][];
                Menu_MapData = new MapTile[menuLevels.Length][];
                Menu_Palette = new RGBA5551Color[menuLevels.Length][];

                for (int i = 0; i < menuLevels.Length; i++)
                {
                    var lvl          = menuLevels[i];
                    var size         = manager.GetMenuSize(lvl);
                    var isCompressed = manager.IsMenuCompressed(lvl);
                    var mapType      = manager.HasMenuAlphaBlending(lvl) ? GBARRR_MapBlock.MapType.Menu : GBARRR_MapBlock.MapType.Foreground;

                    if (isCompressed)
                    {
                        s.DoAt(Menu_Pointers[lvl * 3 + 0], () => {
                            s.DoEncoded(new RNCEncoder(hasHeader: false), () => Menu_Tiles[i] = s.SerializeArray <byte>(Menu_Tiles[i], s.CurrentLength, name: $"{nameof(Menu_Tiles)}[{i}]"));
                        });
                        s.DoAt(Menu_Pointers[lvl * 3 + 1], () =>
                        {
                            s.DoEncoded(new RNCEncoder(hasHeader: false), () => Menu_MapData[i] = s.SerializeObjectArray <MapTile>(Menu_MapData[i], size.Width * size.Height, onPreSerialize: x => x.GBARRRType = mapType, name: $"{nameof(Menu_MapData)}[{i}]"));
                        });
                    }
                    else
                    {
                        s.DoAt(Menu_Pointers[lvl * 3 + 0], () =>
                               Menu_Tiles[i] = s.SerializeArray <byte>(Menu_Tiles[i], 0x4B00 * 2, name: $"{nameof(Menu_Tiles)}[{i}]"));
                        s.DoAt(Menu_Pointers[lvl * 3 + 1], () =>
                               Menu_MapData[i] = s.SerializeObjectArray <MapTile>(Menu_MapData[i], size.Width * size.Height, onPreSerialize: x => x.GBARRRType = mapType, name: $"{nameof(Menu_MapData)}[{i}]"));
                    }

                    Menu_Palette[i] = s.DoAt(Menu_Pointers[lvl * 3 + 2], () => s.SerializeObjectArray <RGBA5551Color>(Menu_Palette[i], 16 * 16, name: $"{nameof(Menu_Palette)}[{i}]"));
                }
            }
        }
コード例 #16
0
ファイル: GAX2_Song.cs プロジェクト: rtsonneveld/Ray1Map
        public override void SerializeImpl(SerializerObject s)
        {
            NumChannels           = s.Serialize <ushort>(NumChannels, name: nameof(NumChannels));
            NumRowsPerPattern     = s.Serialize <ushort>(NumRowsPerPattern, name: nameof(NumRowsPerPattern));
            NumPatternsPerChannel = s.Serialize <ushort>(NumPatternsPerChannel, name: nameof(NumPatternsPerChannel));
            UShort_06             = s.Serialize <ushort>(UShort_06, name: nameof(UShort_06));
            Volume               = s.Serialize <ushort>(Volume, name: nameof(Volume));
            UShort_0A            = s.Serialize <ushort>(UShort_0A, name: nameof(UShort_0A));
            SequenceDataPointer  = s.SerializePointer(SequenceDataPointer, name: nameof(SequenceDataPointer));
            InstrumentSetPointer = s.SerializePointer(InstrumentSetPointer, name: nameof(InstrumentSetPointer));
            SampleSetPointer     = s.SerializePointer(SampleSetPointer, name: nameof(SampleSetPointer));
            SampleRate           = s.Serialize <ushort>(SampleRate, name: nameof(SampleRate));
            UShort_1A            = s.Serialize <ushort>(UShort_1A, name: nameof(UShort_1A));
            UShort_1C            = s.Serialize <ushort>(UShort_1C, name: nameof(UShort_1C));
            UShort_1E            = s.Serialize <ushort>(UShort_1E, name: nameof(UShort_1E));
            PatternTablePointers = s.SerializePointerArray(PatternTablePointers, NumChannels, name: nameof(PatternTablePointers));
            Reserved             = s.SerializeArray <uint>(Reserved, NumChannels, name: nameof(Reserved));

            List <int> instruments = new List <int>();

            if (PatternTable == null)
            {
                int instrumentCount = 0;
                PatternTable = new GAX2_PatternHeader[PatternTablePointers.Length][];
                Patterns     = new GAX2_Pattern[PatternTablePointers.Length][];
                for (int i = 0; i < PatternTablePointers.Length; i++)
                {
                    s.DoAt(PatternTablePointers[i], () => {
                        PatternTable[i] = s.SerializeObjectArray <GAX2_PatternHeader>(PatternTable[i], NumPatternsPerChannel, name: $"{nameof(PatternTable)}[{i}]");
                        if (Patterns[i] == null)
                        {
                            Patterns[i] = new GAX2_Pattern[PatternTable[i].Length];
                            for (int j = 0; j < Patterns[i].Length; j++)
                            {
                                s.DoAt(SequenceDataPointer + PatternTable[i][j].SequenceOffset, () => {
                                    Patterns[i][j]  = s.SerializeObject <GAX2_Pattern>(Patterns[i][j], onPreSerialize: t => t.Duration = NumRowsPerPattern, name: $"{nameof(Patterns)}[{i}][{j}]");
                                    instrumentCount = Math.Max(instrumentCount, Patterns[i][j].Rows.Max(cmd => cmd.Command == GAX2_PatternRow.Cmd.Note ? cmd.Instrument + 1 : 0));
                                    instruments.AddRange(Patterns[i][j].Rows.Where(cmd => cmd.Command == GAX2_PatternRow.Cmd.Note).Select(cmd => (int)cmd.Instrument));
                                });
                            }
                        }
                    });
                }
                InstrumentIndices = instruments.Distinct().Where(i => i != 250).ToArray();
                s.Log("Instrument Count: " + InstrumentIndices.Length);
                Pointer endOffset = Patterns.Max(ta => ta.Max(t => t.EndOffset));
                s.DoAt(endOffset, () => {
                    Name           = s.Serialize <string>(Name, name: nameof(Name));
                    string[] parse = Name.Split('"');
                    ParsedName     = parse[1];
                    ParsedArtist   = parse[2].Substring(3, 0xF);
                    s.Log(ParsedName + " - " + ParsedArtist);
                });
                s.DoAt(InstrumentSetPointer, () => {
                    InstrumentSet = s.SerializePointerArray <GAX2_Instrument>(InstrumentSet, instrumentCount, resolve: true, name: nameof(InstrumentSet));
                });
                Samples = new GAX2_Sample[InstrumentIndices.Length];
                for (int i = 0; i < InstrumentIndices.Length; i++)
                {
                    int ind   = InstrumentIndices[i];
                    var instr = InstrumentSet[ind].Value;
                    if (instr != null)
                    {
                        s.DoAt(SampleSetPointer + (instr.Sample) * 8, () => {
                            Samples[i] = s.SerializeObject <GAX2_Sample>(Samples[i], name: $"{nameof(Samples)}[{i}]");
                        });
                    }
                }
            }
        }
コード例 #17
0
ファイル: R1_PS1_ETA.cs プロジェクト: rtsonneveld/Ray1Map
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            // Get number of ETAs, hack
            if (s is BinaryDeserializer)
            {
                // Save the current pointer
                var pointer = s.CurrentPointer;

                // Get the number of etats
                s.DoAt(pointer, () => {
                    Pointer p = s.SerializePointer(null, name: "FirstEtat");

                    if (p.file != pointer.file || p.AbsoluteOffset < pointer.AbsoluteOffset + 4 || (p.AbsoluteOffset - pointer.AbsoluteOffset) % 4 != 0)
                    {
                        Debug.LogWarning("Number of ETAs wasn't correctly determined");
                    }

                    NumEtats = (p.AbsoluteOffset - pointer.AbsoluteOffset) / 4;
                });
            }

            // Serialize the Etat pointers
            EtatPointers = s.SerializePointerArray(EtatPointers, NumEtats, name: nameof(EtatPointers));

            // Get number of SubEtats for each Etat
            if (NumSubEtats == null)
            {
                // Get the state size
                uint stateSize;

                if (s.GameSettings.EngineVersion == EngineVersion.R2_PS1)
                {
                    stateSize = 16u;
                }
                else if (s.GameSettings.EngineVersion == EngineVersion.R1_PS1_JPDemoVol3)
                {
                    stateSize = 14u;
                }
                else if (s.GameSettings.EngineVersion == EngineVersion.R1_PS1_JPDemoVol6)
                {
                    stateSize = 12u;
                }
                else
                {
                    stateSize = 8;
                }

                NumSubEtats = new uint[NumEtats];

                // Enumerate every Etat, except last one
                for (int i = 0; i < EtatPointers.Length - 1; i++)
                {
                    // Make sure we have a valid pointer
                    if (EtatPointers[i] == null)
                    {
                        continue;
                    }

                    // Get size and make sure the next one is not null
                    if (EtatPointers[i + 1] != null)
                    {
                        NumSubEtats[i] = (EtatPointers[i + 1].AbsoluteOffset - EtatPointers[i].AbsoluteOffset) / stateSize;
                    }
                    else
                    {
                        Debug.LogWarning("An Etat Pointer was null - Number of SubEtats couldn't be determined");
                    }
                }

                // Get the size of the last Etat
                if (EtatPointers[NumEtats - 1] != null)
                {
                    // TODO: Find better way to parse this

                    s.DoAt(EtatPointers.Last(), () =>
                    {
                        uint count         = 0;
                        const int maxCount = 69;

                        while (true)
                        {
                            // Make sure we can read more
                            if (s.CurrentLength - stateSize < s.CurrentPointer.FileOffset)
                            {
                                break;
                            }

                            // Make sure it's not a pointer
                            if (s.DoAt(s.CurrentPointer, () => s.SerializePointer(default, allowInvalid: true, name: $"Dummy pointer {count}")) != null)
コード例 #18
0
        public void SerializeData(SerializerObject s)
        {
            if (FramesCountPointer == 0 && FramesCount == 0)
            {
                FramesPointers = new Pointer[]
                {
                    FramesPointer
                };
            }
            else
            {
                if (FramesCount == 0)
                {
                    if (s.GameSettings.GameModeSelection == GameModeSelection.Crash2GBAUS)
                    {
                        switch (FramesCountPointer)
                        {
                        case 0x02000578: FramesCount = 0x0A; break;

                        case 0x02000574: FramesCount = 0x0E; break;

                        case 0x0200057c: FramesCount = 0x0A; break;

                        case 0x02000580: FramesCount = 0x0A; break;

                        case 0x02000588: FramesCount = 0x02; break;

                        case 0x02000584: FramesCount = 0x0F; break;

                        default: throw new ArgumentOutOfRangeException(nameof(FramesCountPointer), FramesCountPointer, null);
                        }
                    }
                    else if (s.GameSettings.GameModeSelection == GameModeSelection.Crash2GBAEU)
                    {
                        switch (FramesCountPointer)
                        {
                        case 0x0200058C: FramesCount = 0x0A; break;

                        case 0x02000588: FramesCount = 0x0E; break;

                        case 0x02000590: FramesCount = 0x0A; break;

                        case 0x02000594: FramesCount = 0x0A; break;

                        case 0x0200059C: FramesCount = 0x02; break;

                        case 0x02000598: FramesCount = 0x0F; break;

                        default: throw new ArgumentOutOfRangeException(nameof(FramesCountPointer), FramesCountPointer, null);
                        }
                    }
                    else if (s.GameSettings.GameModeSelection == GameModeSelection.Crash2GBAJP)
                    {
                        switch (FramesCountPointer)
                        {
                        case 0x0200059C: FramesCount = 0x0A; break;

                        case 0x02000598: FramesCount = 0x0E; break;

                        case 0x020005A0: FramesCount = 0x0A; break;

                        case 0x020005A4: FramesCount = 0x0A; break;

                        case 0x020005AC: FramesCount = 0x02; break;

                        case 0x020005A8: FramesCount = 0x0F; break;

                        default: throw new ArgumentOutOfRangeException(nameof(FramesCountPointer), FramesCountPointer, null);
                        }
                    }
                }

                FramesPointers = s.DoAt(FramesPointer, () => s.SerializePointerArray(FramesPointers, FramesCount, name: nameof(FramesPointer)));
            }

            if (PalettePointer != null)
            {
                Palette = s.DoAt(PalettePointer, () => s.SerializeObjectArray <RGBA5551Color>(Palette, 16, name: nameof(Palette)));
            }

            if (AnimFrames == null)
            {
                AnimFrames = new byte[FramesPointers.Length][];
            }

            for (int i = 0; i < AnimFrames.Length; i++)
            {
                AnimFrames[i] = s.DoAt(FramesPointers[i], () => s.SerializeArray <byte>(AnimFrames[i], (Width * Height) / 2, name: $"{nameof(AnimFrames)}[{i}]"));
            }
        }
コード例 #19
0
        public override void SerializeImpl(SerializerObject s)
        {
            // Serialize ROM header
            base.SerializeImpl(s);

            // Get the pointer table
            var pointerTable = PointerTables.GBAVV_PointerTable(s.GameSettings.GameModeSelection, Offset.file);

            // Get the current lev info
            var manager = (GBAVV_BaseManager)s.GameSettings.GetGameManager;

            if (pointerTable.ContainsKey(GBAVV_Pointer.Localization))
            {
                var multipleLanguages = s.GameSettings.GameModeSelection == GameModeSelection.Crash1GBAEU || s.GameSettings.GameModeSelection == GameModeSelection.Crash2GBAEU;

                if (multipleLanguages)
                {
                    LocTablePointers = s.DoAt(pointerTable[GBAVV_Pointer.Localization], () => s.SerializePointerArray(LocTablePointers, 6, name: nameof(LocTablePointers)));
                }
                else
                {
                    LocTablePointers = new Pointer[]
                    {
                        pointerTable[GBAVV_Pointer.Localization]
                    }
                };

                if (LocTables == null)
                {
                    LocTables = new GBAVV_LocTable[LocTablePointers.Length];
                }

                for (int i = 0; i < LocTables.Length; i++)
                {
                    LocTables[i] = s.DoAt(LocTablePointers[i], () => s.SerializeObject <GBAVV_LocTable>(LocTables[i], name: $"{nameof(LocTables)}[{i}]"));
                }
            }

            s.Context.StoreObject(GBAVV_BaseManager.LocTableID, LocTables?.FirstOrDefault());

            s.DoAt(pointerTable[GBAVV_Pointer.LevelInfo], () =>
            {
                if (LevelInfos == null)
                {
                    LevelInfos = new GBAVV_LevelInfo[manager.LevInfos.Max(x => x.LevelIndex) + 1];
                }

                for (int i = 0; i < LevelInfos.Length; i++)
                {
                    LevelInfos[i] = s.SerializeObject <GBAVV_LevelInfo>(LevelInfos[i], x => x.LevInfo = i == CurrentLevInfo.LevelIndex ? CurrentLevInfo : null, name: $"{nameof(LevelInfos)}[{i}]");
                }
            });

            if (CurrentMapInfo.MapType == GBAVV_MapInfo.GBAVV_MapType.Normal ||
                CurrentMapInfo.MapType == GBAVV_MapInfo.GBAVV_MapType.Normal_Vehicle_0 ||
                CurrentMapInfo.MapType == GBAVV_MapInfo.GBAVV_MapType.Normal_Vehicle_1 ||
                CurrentMapInfo.MapType == GBAVV_MapInfo.GBAVV_MapType.WorldMap)
            {
                Map2D_Graphics = s.DoAt(pointerTable[GBAVV_Pointer.Map2D_Graphics], () => s.SerializeObject <GBAVV_Map2D_Graphics>(Map2D_Graphics, name: nameof(Map2D_Graphics)));
            }

            if (CurrentMapInfo.MapType == GBAVV_MapInfo.GBAVV_MapType.Mode7)
            {
                s.DoAt(pointerTable[GBAVV_Pointer.Mode7_LevelInfo], () =>
                {
                    if (Mode7_LevelInfos == null)
                    {
                        Mode7_LevelInfos = new GBAVV_Mode7_LevelInfo[7];
                    }

                    var index3D = CurrentMapInfo.Index3D;

                    for (int i = 0; i < Mode7_LevelInfos.Length; i++)
                    {
                        Mode7_LevelInfos[i] = s.SerializeObject <GBAVV_Mode7_LevelInfo>(Mode7_LevelInfos[i], x => x.SerializeData = i == index3D, name: $"{nameof(Mode7_LevelInfos)}[{i}]");
                    }
                });

                if (s.GameSettings.EngineVersion == EngineVersion.GBAVV_Crash2)
                {
                    GBAVV_Pointer palPointer = CurrentMode7LevelInfo.LevelType == 0 ? GBAVV_Pointer.Mode7_TilePalette_Type0 : GBAVV_Pointer.Mode7_TilePalette_Type1_Flames;

                    Mode7_TilePalette = s.DoAt(pointerTable[palPointer], () => s.SerializeObjectArray <RGBA5551Color>(Mode7_TilePalette, CurrentMode7LevelInfo.LevelType == 0 ? 256 : 16, name: nameof(Mode7_TilePalette)));
                }
                else if (s.GameSettings.EngineVersion == EngineVersion.GBAVV_Crash1 && CurrentMode7LevelInfo.LevelType == 0)
                {
                    Mode7_Crash1_Type0_TilePalette_0F = s.DoAt(pointerTable[GBAVV_Pointer.Mode7_Crash1_Type0_TilePalette_0F], () => s.SerializeObjectArray <RGBA5551Color>(Mode7_Crash1_Type0_TilePalette_0F, 16, name: nameof(Mode7_Crash1_Type0_TilePalette_0F)));
                }

                if (s.GameSettings.EngineVersion == EngineVersion.GBAVV_Crash2 && CurrentMode7LevelInfo.LevelType == 0)
                {
                    Mode7_Crash2_Type0_BG1 = s.DoAt(pointerTable[GBAVV_Pointer.Mode7_Crash2_Type0_BG1], () => s.SerializeArray <byte>(Mode7_Crash2_Type0_BG1, 38 * 9 * 32, name: nameof(Mode7_Crash2_Type0_BG1)));
                }
                else if (s.GameSettings.EngineVersion == EngineVersion.GBAVV_Crash2 && CurrentMode7LevelInfo.LevelType == 1)
                {
                    Mode7_Crash2_Type1_FlamesTileMapsPointers = s.DoAt(pointerTable[GBAVV_Pointer.Mode7_Crash2_Type1_FlamesTileMaps], () => s.SerializePointerArray(Mode7_Crash2_Type1_FlamesTileMapsPointers, 20, name: nameof(Mode7_Crash2_Type1_FlamesTileMapsPointers)));

                    if (Mode7_Crash2_Type1_FlamesTileMaps == null)
                    {
                        Mode7_Crash2_Type1_FlamesTileMaps = new MapTile[20][];
                    }

                    for (int i = 0; i < Mode7_Crash2_Type1_FlamesTileMaps.Length; i++)
                    {
                        Mode7_Crash2_Type1_FlamesTileMaps[i] = s.DoAt(Mode7_Crash2_Type1_FlamesTileMapsPointers[i], () => s.SerializeObjectArray <MapTile>(Mode7_Crash2_Type1_FlamesTileMaps[i], 0x1E * 0x14, name: $"{nameof(Mode7_Crash2_Type1_FlamesTileMaps)}[{i}]"));
                    }

                    Mode7_Crash2_Type1_FlamesTileSetLengths = s.DoAt(pointerTable[GBAVV_Pointer.Mode7_Crash2_Type1_FlamesTileSetLengths], () => s.SerializeArray <uint>(Mode7_Crash2_Type1_FlamesTileSetLengths, 20, name: nameof(Mode7_Crash2_Type1_FlamesTileSetLengths)));

                    Mode7_Crash2_Type1_FlamesTileSetsPointers = s.DoAt(pointerTable[GBAVV_Pointer.Mode7_Crash2_Type1_FlamesTileSets], () => s.SerializePointerArray(Mode7_Crash2_Type1_FlamesTileSetsPointers, 20, name: nameof(Mode7_Crash2_Type1_FlamesTileSetsPointers)));

                    if (Mode7_Crash2_Type1_FlamesTileSets == null)
                    {
                        Mode7_Crash2_Type1_FlamesTileSets = new byte[20][];
                    }

                    for (int i = 0; i < Mode7_Crash2_Type1_FlamesTileSets.Length; i++)
                    {
                        Mode7_Crash2_Type1_FlamesTileSets[i] = s.DoAt(Mode7_Crash2_Type1_FlamesTileSetsPointers[i], () => s.SerializeArray <byte>(Mode7_Crash2_Type1_FlamesTileSets[i], Mode7_Crash2_Type1_FlamesTileSetLengths[i], name: $"{nameof(Mode7_Crash2_Type1_FlamesTileSets)}[{i}]"));
                    }
                }
            }

            if (CurrentMapInfo.MapType == GBAVV_MapInfo.GBAVV_MapType.Isometric)
            {
                var index3D = CurrentMapInfo.Index3D;

                s.DoAt(pointerTable[GBAVV_Pointer.Isometric_MapDatas], () =>
                {
                    if (Isometric_MapDatas == null)
                    {
                        Isometric_MapDatas = new GBAVV_Isometric_MapData[7];
                    }


                    for (int i = 0; i < Isometric_MapDatas.Length; i++)
                    {
                        Isometric_MapDatas[i] = s.SerializeObject <GBAVV_Isometric_MapData>(Isometric_MapDatas[i], x => x.SerializeData = i == index3D + 4, name: $"{nameof(Isometric_MapDatas)}[{i}]");
                    }
                });

                s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjectDatas], () =>
                {
                    if (Isometric_ObjectDatas == null)
                    {
                        Isometric_ObjectDatas = new GBAVV_Isometric_ObjectData[7];
                    }

                    for (int i = 0; i < Isometric_ObjectDatas.Length; i++)
                    {
                        Isometric_ObjectDatas[i] = s.SerializeObject <GBAVV_Isometric_ObjectData>(Isometric_ObjectDatas[i], x =>
                        {
                            x.SerializeData = i == index3D + 4;
                            x.IsMultiplayer = i < 4;
                        }, name: $"{nameof(Isometric_ObjectDatas)}[{i}]");
                    }
                });

                Isometric_CharacterInfos = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_Characters], () => s.SerializeObjectArray <GBAVV_Isometric_CharacterInfo>(Isometric_CharacterInfos, 12, name: nameof(Isometric_CharacterInfos)));
                Isometric_CharacterIcons = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_CharacterIcons], () => s.SerializeObjectArray <GBAVV_Isometric_CharacterIcon>(Isometric_CharacterIcons, 11, name: nameof(Isometric_CharacterIcons)));
                Isometric_ObjAnimations  = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjAnimations], () => s.SerializeObjectArray <GBAVV_Isometric_Animation>(Isometric_ObjAnimations, 22, name: nameof(Isometric_ObjAnimations)));

                Isometric_ObjPalette_0  = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjPalette_0], () => s.SerializeObjectArray <RGBA5551Color>(Isometric_ObjPalette_0, 16, name: nameof(Isometric_ObjPalette_0)));
                Isometric_ObjPalette_1  = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjPalette_1], () => s.SerializeObjectArray <RGBA5551Color>(Isometric_ObjPalette_1, 16, name: nameof(Isometric_ObjPalette_1)));
                Isometric_ObjPalette_2  = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjPalette_2], () => s.SerializeObjectArray <RGBA5551Color>(Isometric_ObjPalette_2, 16, name: nameof(Isometric_ObjPalette_2)));
                Isometric_ObjPalette_4  = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjPalette_4], () => s.SerializeObjectArray <RGBA5551Color>(Isometric_ObjPalette_4, 16, name: nameof(Isometric_ObjPalette_4)));
                Isometric_ObjPalette_11 = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjPalette_11], () => s.SerializeObjectArray <RGBA5551Color>(Isometric_ObjPalette_11, 16, name: nameof(Isometric_ObjPalette_11)));
                Isometric_ObjPalette_12 = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjPalette_12], () => s.SerializeObjectArray <RGBA5551Color>(Isometric_ObjPalette_12, 16, name: nameof(Isometric_ObjPalette_12)));
                Isometric_ObjPalette_13 = s.DoAt(pointerTable[GBAVV_Pointer.Isometric_ObjPalette_13], () => s.SerializeObjectArray <RGBA5551Color>(Isometric_ObjPalette_13, 16, name: nameof(Isometric_ObjPalette_13)));

                // These animations are all hard-coded from functions:
                Isometric_AdditionalAnimations = new GBAVV_Isometric_Animation[]
                {
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim0_Frames], 0x03, 4, 4, 2),                                                               // Green barrel
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim1_Frames], 0x03, 4, 4, 2),                                                               // Laser beam
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim2_Frames], 0x06, 4, 4, 1),                                                               // Crate breaks
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim3_Frames], 0x07, 4, 4, 1),                                                               // Checkpoint breaks
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim4_Frames], 0x18, 8, 4, 0),                                                               // Checkpoint text
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim5_Frames], 0x08, 4, 4, 2),                                                               // Nitro explosion
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim6_Frames], 0x08, 4, 4, 2),                                                               // Nitro switch
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim7_Frames], 0x0E, 4, 4, 0),                                                               // Wumpa HUD
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim8_Frames], 0x0A, 8, 8, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim8_Palette]),   // Crystal collected
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim9_Frames], 0x03, 4, 4, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim9_Palette]),   // Multiplayer base
                    GBAVV_Isometric_Animation.CrateAndSerialize(s, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim10_Frames], 0x0A, 2, 2, pointerTable[GBAVV_Pointer.Isometric_AdditionalAnim10_Palette]), // Multiplayer item
                };
            }

            if (CurrentMapInfo.MapType == GBAVV_MapInfo.GBAVV_MapType.WorldMap)
            {
                if (pointerTable.ContainsKey(GBAVV_Pointer.WorldMap))
                {
                    WorldMap = s.DoAt(pointerTable[GBAVV_Pointer.WorldMap], () => s.SerializeObject(WorldMap, name: nameof(WorldMap)));
                }

                if (s.GameSettings.EngineVersion == EngineVersion.GBAVV_Crash1)
                {
                    WorldMap_Crash1_LevelIcons = s.DoAt(pointerTable[GBAVV_Pointer.WorldMap_Crash1_LevelIcons], () => s.SerializeObjectArray <GBAVV_WorldMap_Crash1_LevelIcon>(WorldMap_Crash1_LevelIcons, 10, name: nameof(WorldMap_Crash1_LevelIcons)));
                }
            }
        }
    }