Example #1
0
        /// <summary>
        /// Loads the specified level for the editor
        /// </summary>
        /// <param name="context">The serialization context</param>
        /// <param name="loadTextures">Indicates if textures should be loaded</param>
        /// <returns>The level</returns>
        public override async UniTask <Unity_Level> LoadAsync(Context context, bool loadTextures)
        {
            await Controller.WaitIfNecessary();

            Controller.DetailedState = $"Loading files";

            uint baseAddress = 0x80018000;

            var fixDTAPath   = FixDataPath;
            var fixGRPPath   = FixGraphicsPath;
            var sprPLSPath   = SpritePalettesPath;
            var levelDTAPath = GetLevelDataPath(context.Settings);
            var levelSPRPath = GetLevelImageDescriptorsPath(context.Settings);
            var levelGRPPath = GetLevelGraphicsPath(context.Settings);

            baseAddress += await LoadFile(context, fixDTAPath, baseAddress);

            baseAddress -= 94; // FIX.DTA header size
            Pointer fixDTAHeader = new Pointer(baseAddress, context.FilePointer(fixDTAPath).file);

            R1_R2AllfixFooter footer = null;

            context.Deserializer.DoAt(fixDTAHeader, () => footer = context.Deserializer.SerializeObject <R1_R2AllfixFooter>(null, name: "AllfixFooter"));
            await LoadFile(context, fixGRPPath, 0);
            await LoadFile(context, sprPLSPath, 0);

            baseAddress += await LoadFile(context, levelSPRPath, baseAddress);

            baseAddress += await LoadFile(context, levelDTAPath, baseAddress);
            await LoadFile(context, levelGRPPath, 0);

            // Load every map
            for (int i = 0; i < 4; i++)
            {
                await LoadFile(context, GetSubMapPalettePath(i), 0);
                await LoadFile(context, GetSubMapTilesetPath(i), 0);
                await LoadFile(context, GetSubMapPath(i), 0);
            }

            await Controller.WaitIfNecessary();

            Controller.DetailedState = $"Loading level data";

            // Read the level data
            var lvlData = FileFactory.Read <R1_R2LevDataFile>(levelDTAPath, context);

            // Read the map blocks
            var maps = Enumerable.Range(0, MapCount).Select(x => FileFactory.Read <MapData>(GetSubMapPath(x), context)).ToArray();

            await Controller.WaitIfNecessary();

            Controller.DetailedState = $"Loading sprite data";

            var commonEvents = new List <Unity_Object>();

            if (loadTextures)
            {
                // Get the v-ram
                FillVRAM(context, VRAMMode.Level);
            }


            // Create the global design list

            var lvlImgDescriptors = FileFactory.Read <ObjectArray <R1_ImageDescriptor> >(levelSPRPath, context, onPreSerialize: (s, a) => a.Length = s.CurrentLength / 0xC).Value;

            var imgDescriptors = lvlData.FixImageDescriptors.Concat(lvlImgDescriptors).ToArray();

            // Get every sprite
            var globalDesigns = imgDescriptors.Select(img => GetSpriteTexture(context, null, img)).Select(tex => tex == null ? null : tex.CreateSprite()).ToArray();

            // Get the events
            var events = lvlData.Events.Concat(lvlData.AlwaysEvents).ToArray();

            Controller.DetailedState = $"Loading animations";
            await Controller.WaitIfNecessary();

            // Get the animation groups
            var r2AnimGroups = events.Select(x => x.AnimGroup).Append(footer.RaymanAnimGroup).Distinct().ToArray();

            Unity_ObjectManager_R2.AnimGroup[] animGroups = new Unity_ObjectManager_R2.AnimGroup[r2AnimGroups.Length];
            for (int i = 0; i < animGroups.Length; i++)
            {
                animGroups[i] = await getGroupAsync(r2AnimGroups[i]);

                await Controller.WaitIfNecessary();
            }

            async UniTask <Unity_ObjectManager_R2.AnimGroup> getGroupAsync(R1_R2EventAnimGroup animGroup)
            {
                await UniTask.CompletedTask;

                // Add DES and ETA
                return(new Unity_ObjectManager_R2.AnimGroup(
                           pointer: animGroup?.Offset, eta: animGroup?.ETA.EventStates ?? new R1_EventState[0][],
                           animations: animGroup?.AnimationDecriptors?.Select(x => x.ToCommonAnimation()).ToArray(),
                           filePath: animGroup?.AnimationDescriptorsPointer?.file.filePath));
            }

            var objManager = new Unity_ObjectManager_R2(
                context: context,
                linkTable: lvlData.EventLinkTable,
                animGroups: animGroups,
                sprites: globalDesigns,
                imageDescriptors: imgDescriptors,
                levData: lvlData);

            Controller.DetailedState = $"Loading events";
            await Controller.WaitIfNecessary();

            // Add every event
            foreach (var e in events)
            {
                // Add the event
                commonEvents.Add(new Unity_Object_R2(e, objManager)
                {
                    IsAlwaysEvent = lvlData.AlwaysEvents.Contains(e)
                });
            }

            await Controller.WaitIfNecessary();

            Controller.DetailedState = $"Loading tiles";

            var levelMaps = maps.Select((x, i) => new Unity_Map()
            {
                // Set the dimensions
                Width  = x.Width,
                Height = x.Height,

                // Create the tile array
                TileSet      = new Unity_MapTileMap[1],
                TileSetWidth = TileSetWidth
            }).ToArray();

            // Convert levelData to common level format
            Unity_Level level = new Unity_Level(levelMaps, objManager, commonEvents, rayman: new Unity_Object_R2(R1_R2EventData.GetRayman(events.FirstOrDefault(x => x.EventType == R1_R2EventType.RaymanPosition), footer), objManager), getCollisionTypeGraphicFunc: x => ((R2_TileCollsionType)x).GetCollisionTypeGraphic());

            await Controller.WaitIfNecessary();

            // Load maps
            for (int i = 0; i < MapCount; i++)
            {
                // Get the tile set
                Unity_MapTileMap tileSet = GetTileSet(context, i);

                level.Maps[i].TileSet[0] = tileSet;

                // Set the tiles
                level.Maps[i].MapTiles = maps[i].Tiles.Select(x => new Unity_Tile(x)).ToArray();
            }

            // Return the level
            return(level);
        }
        public static GBAVV_Isometric_Animation CrateAndSerialize(SerializerObject s, Pointer framesPointer, int framesCount, int width, int height, Pointer palPointer)
        {
            var anim = new GBAVV_Isometric_Animation
            {
                Width          = width * 8,
                Height         = height * 8,
                XPos           = (FixedPointInt)(-width * 4 / 16f),
                YPos           = (FixedPointInt)(-height * 4 / 16f),
                FramesPointer  = framesPointer,
                PalettePointer = palPointer,
                FramesCount    = framesCount,
            };

            anim.SerializeData(s);

            return(anim);
        }
        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}]"));
            }
        }
Example #4
0
 public DataContainer(T data, Pointer primaryPointer, string name = null)
 {
     Data           = data;
     PrimaryPointer = primaryPointer;
     Name           = name;
 }
Example #5
0
 public DESData(Unity_ObjGraphics graphics, R1_ImageDescriptor[] imageDescriptors, Pointer imageDescriptorPointer = null, Pointer animationDescriptorPointer = null, Pointer imageBufferPointer = null)
 {
     Graphics                   = graphics;
     ImageDescriptors           = imageDescriptors ?? new R1_ImageDescriptor[0];
     ImageDescriptorPointer     = imageDescriptorPointer;
     AnimationDescriptorPointer = animationDescriptorPointer;
     ImageBufferPointer         = imageBufferPointer;
 }
Example #6
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            ETAPointer      = s.SerializePointer(ETAPointer, name: nameof(ETAPointer));
            CommandsPointer = s.SerializePointer(CommandsPointer, name: nameof(CommandsPointer));
            XPosition       = s.Serialize <short>(XPosition, name: nameof(XPosition));
            YPosition       = s.Serialize <short>(YPosition, name: nameof(YPosition));
            DisplayPrio     = s.Serialize <ushort>(DisplayPrio, name: nameof(DisplayPrio));
            LinkGroup       = s.Serialize <ushort>(LinkGroup, name: nameof(LinkGroup));
            Etat            = s.Serialize <byte>(Etat, name: nameof(Etat));
            SubEtat         = s.Serialize <byte>(SubEtat, name: nameof(SubEtat));
            OffsetBX        = s.Serialize <byte>(OffsetBX, name: nameof(OffsetBX));
            OffsetBY        = s.Serialize <byte>(OffsetBY, name: nameof(OffsetBY));
            OffsetHY        = s.Serialize <byte>(OffsetHY, name: nameof(OffsetHY));
            FollowEnabled   = s.Serialize <bool>(FollowEnabled, name: nameof(FollowEnabled));
            FollowSprite    = s.Serialize <byte>(FollowSprite, name: nameof(FollowSprite));
            HitPoints       = s.Serialize <byte>(HitPoints, name: nameof(HitPoints));
            Type            = s.Serialize <R1_EventType>(Type, name: nameof(Type));
            HitSprite       = s.Serialize <byte>(HitSprite, name: nameof(HitSprite));
            Unk             = s.Serialize <byte>(Unk, name: nameof(Unk));

            // Serialize data from pointers

            // Serialize the current state
            if (ETAPointer != null)
            {
                do
                {
                    var hasSerialized = ETA != null && s is BinaryDeserializer;

                    int etatCount;

                    if (!hasSerialized)
                    {
                        etatCount = Etat + 1;

                        // Get correct etat count on GBA
                        if (s.GameSettings.EngineVersion == EngineVersion.R1_GBA)
                        {
                            s.DoAt(ETAPointer, () => {
                                int curEtatCount = 0;
                                Pointer off_prev = null;
                                while (true)
                                {
                                    Pointer off_next = s.SerializePointer(null, allowInvalid: true, name: "TestPointer");
                                    if (curEtatCount < etatCount ||
                                        (off_next != null &&
                                         off_next != ETAPointer &&
                                         (off_prev == null ||
                                          ((off_next.AbsoluteOffset - off_prev.AbsoluteOffset > 0) && (off_next.AbsoluteOffset - off_prev.AbsoluteOffset < 0x10000)) ||
                                          (off_next.file != off_prev.file && off_next.file != Offset.file)
                                         )))
                                    {
                                        curEtatCount++;
                                        off_prev = off_next;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                etatCount = curEtatCount;
                            });
                        }
                    }
                    else
                    {
                        etatCount = ETA.Length;
                    }

                    // Get max linked etat if we've already serialized ETA
                    if (hasSerialized)
                    {
                        var maxLinked = ETA.SelectMany(x => x).Where(x => x != null).Max(x => x.LinkedEtat) + 1;

                        if (etatCount < maxLinked)
                        {
                            etatCount = maxLinked;
                        }
                    }

                    // Serialize etat pointers
                    Pointer[] EtatPointers = s.DoAt(ETAPointer, () => s.SerializePointerArray(default, etatCount, name: $"{nameof(EtatPointers)}"));
Example #7
0
        protected override bool DoMemoryLoading(Context gameMemoryContext, Pointer offset)
        {
            var              lvl       = LevelEditorData.Level;
            bool             madeEdits = false;
            Pointer          currentOffset;
            SerializerObject s;

            void SerializeEvent(Unity_Object_R1 ed, Context context)
            {
                s = ed.HasPendingEdits ? (SerializerObject)context.Serializer : context.Deserializer;
                s.Goto(currentOffset);
                ed.EventData.Init(s.CurrentPointer);
                ed.EventData.Serialize(s);

                if (s is BinarySerializer)
                {
                    Debug.Log($"Edited event {ed.EventData.EventIndex}");
                    madeEdits = true;
                }

                ed.HasPendingEdits = false;
                currentOffset      = s.CurrentPointer;
            }

            // Events
            if (GameMemoryData.EventArrayOffset != null)
            {
                currentOffset = GameMemoryData.EventArrayOffset;
                foreach (var ed in lvl.EventData.OfType <Unity_Object_R1>())
                {
                    SerializeEvent(ed, gameMemoryContext);
                }
            }

            // Rayman
            if (GameMemoryData.RayEventOffset != null && lvl.Rayman is Unity_Object_R1 r1Ray)
            {
                currentOffset = GameMemoryData.RayEventOffset;
                SerializeEvent(r1Ray, gameMemoryContext);
            }

            // Tiles
            if (GameMemoryData.TileArrayOffset != null)
            {
                currentOffset = GameMemoryData.TileArrayOffset;
                var map = lvl.Maps[0];

                for (int y = 0; y < map.Height; y++)
                {
                    for (int x = 0; x < map.Width; x++)
                    {
                        var tileIndex = y * map.Width + x;
                        var mapTile   = map.MapTiles[tileIndex];

                        s = mapTile.HasPendingEdits ? (SerializerObject)gameMemoryContext.Serializer : gameMemoryContext.Deserializer;

                        s.Goto(currentOffset);

                        var prevX = mapTile.Data.TileMapX;
                        var prevY = mapTile.Data.TileMapY;

                        mapTile.Data.Init(s.CurrentPointer);
                        mapTile.Data.Serialize(s);

                        if (s is BinarySerializer)
                        {
                            madeEdits = true;
                        }

                        mapTile.HasPendingEdits = false;

                        if (prevX != mapTile.Data.TileMapX || prevY != mapTile.Data.TileMapY)
                        {
                            Controller.obj.levelController.controllerTilemap.SetTileAtPos(x, y, mapTile);
                        }

                        currentOffset = s.CurrentPointer;

                        // On PC we need to also update the BigMap pointer table
                        if (GameMemoryData.BigMap != null && s is BinarySerializer)
                        {
                            var pointerOffset = GameMemoryData.BigMap.MapTileTexturesPointersPointer + (4 * tileIndex);
                            var newPointer    = GameMemoryData.BigMap.TileTexturesPointer + (lvl.Maps[0].PCTileOffsetTable[mapTile.Data.TileMapY]).SerializedOffset;
                            s.Goto(pointerOffset);

                            s.SerializePointer(newPointer);
                        }
                    }
                }
            }

            // Global values
            GlobalData.Update(new ToggleSerializer(gameMemoryContext, x => GlobalPendingEdits || GlobalDataForceWrite.Contains(x), offset));

            GlobalPendingEdits = false;

            return(madeEdits);
        }
Example #8
0
 public override Pointer <T> SerializePointer <T>(Pointer <T> obj, Pointer anchor = null, bool resolve = false, Action <T> onPreSerialize = null, bool allowInvalid = false, string name = null)
 {
     UpdateCurrentSerializer(name);
     return(CurrentSerializer.SerializePointer(obj, anchor, resolve, onPreSerialize, allowInvalid, name));
 }
Example #9
0
 public override Pointer SerializePointer(Pointer obj, Pointer anchor = null, bool allowInvalid = false, string name = null)
 {
     UpdateCurrentSerializer(name);
     return(CurrentSerializer.SerializePointer(obj, anchor, allowInvalid, name));
 }
Example #10
0
 public override void Goto(Pointer offset) => CurrentSerializer.Goto(offset);
Example #11
0
        public override Pointer <T>[] SerializePointerArray <T>(Pointer <T>[] obj, long count, Pointer anchor = null, bool resolve = false, Action <T> onPreSerialize = null, bool allowInvalid = false, string name = null)
        {
            if (obj == null)
            {
                obj = new Pointer <T> [count];
            }
            else if (count != obj.Length)
            {
                Array.Resize(ref obj, (int)count);
            }

            for (int i = 0; i < count; i++)
            {
                obj[i] = SerializePointer <T>(obj[i], anchor: anchor, resolve: resolve, onPreSerialize: onPreSerialize, allowInvalid: allowInvalid, name: name == null ? null : name + "[" + i + "]");
            }

            return(obj);
        }
Example #12
0
        public ToggleSerializer(Context context, Func <string, bool> shouldWriteFunc, Pointer baseOffset) : base(context)
        {
            // Set properties
            ShouldWriteFunc = shouldWriteFunc;
            Serializer      = context.Serializer;
            Deserializer    = context.Deserializer;
            CurrentName     = new Stack <string>();

            // Init serializers
            Serializer.Goto(baseOffset);
            Deserializer.Goto(baseOffset);
            CurrentSerializer = Deserializer;
        }