Esempio n. 1
0
        public void SetPreviewTilemap(Unity_Map map, Unity_Tile[,] newTiles)
        {
            int w = newTiles.GetLength(0);
            int h = newTiles.GetLength(1);

            if (w <= 0 || h <= 0)
            {
                ClearPreviewTilemap();
                return;
            }
            int       cellSize = LevelEditorData.Level.CellSize;
            Texture2D tex      = new Texture2D(w * cellSize, h * cellSize);

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    Unity_Tile        newTile = newTiles[x, y];
                    Unity_TileTexture tile    = map.GetTile(newTile, LevelEditorData.CurrentSettings);
                    FillInTilePixels(tex, tile, newTile, x, y, cellSize, applyTexture: false);
                }
            }
            tex.filterMode = FilterMode.Point;
            tex.Apply();
            tilemapPreview.sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0, 0), LevelEditorData.Level.PixelsPerUnit, 0, SpriteMeshType.FullRect);
        }
Esempio n. 2
0
        public Unity_Level(Unity_Map[] maps,
                           Unity_ObjectManager objManager,
                           List <Unity_Object> eventData = null,
                           Unity_Object rayman           = null,
                           IReadOnlyDictionary <string, string[]> localization = null,
                           int defaultMap    = 0, int defaultCollisionMap = 0,
                           int pixelsPerUnit = 16,
                           int cellSize      = 16,
                           Func <ushort, string> getCollisionTypeNameFunc = null,
                           Func <ushort, Unity_MapCollisionTypeGraphic> getCollisionTypeGraphicFunc = null,
                           Texture2D background              = null,
                           Texture2D parallaxBackground      = null,
                           Unity_Sector[] sectors            = null,
                           Unity_IsometricData isometricData = null)
        {
            Maps                        = maps;
            ObjManager                  = objManager;
            EventData                   = eventData ?? new List <Unity_Object>();
            Rayman                      = rayman;
            Localization                = localization;
            DefaultMap                  = defaultMap;
            DefaultCollisionMap         = defaultCollisionMap == -1 ? 0 : defaultCollisionMap;
            PixelsPerUnit               = pixelsPerUnit;
            CellSize                    = cellSize;
            GetCollisionTypeNameFunc    = getCollisionTypeNameFunc ?? (x => ((R1_TileCollisionType)x).ToString());
            GetCollisionTypeGraphicFunc = getCollisionTypeGraphicFunc ?? (x => ((R1_TileCollisionType)x).GetCollisionTypeGraphic());
            Background                  = background;
            ParallaxBackground          = parallaxBackground;
            Sectors                     = sectors;
            IsometricData               = isometricData;

            MaxWidth  = Maps.Max(m => m.Width);
            MaxHeight = Maps.Max(m => m.Height);

            GridMap = new Unity_Map
            {
                Width   = MaxWidth,
                Height  = MaxHeight,
                TileSet = new Unity_TileSet[]
                {
                    new Unity_TileSet(Util.GetGridTex(cellSize), cellSize),
                },
                MapTiles = Enumerable.Range(0, MaxWidth * MaxHeight).Select(x => new Unity_Tile(new MapTile())).ToArray(),
                Type     = Unity_Map.MapType.Graphics,
                Layer    = Unity_Map.MapLayer.Overlay
            };
        }
Esempio n. 3
0
        public async UniTask<Unity_Level> LoadAsync(Context context, bool loadTextures)
        {
            Controller.DetailedState = $"Loading data";
            await Controller.WaitIfNecessary();

            // Read the rom
            var rom = FileFactory.Read<SNES_Proto_ROM>(GetROMFilePath, context);

            // Get the map
            var map = rom.MapData;

            var maps = new Unity_Map[]
            {
                new Unity_Map()
                {
                    // Set the dimensions
                    Width = map.Width,
                    Height = map.Height,

                    // Create the tile arrays
                    TileSet = new Unity_MapTileMap[1],
                    MapTiles = map.Tiles.Select(x => new Unity_Tile(x)).ToArray(),
                    TileSetWidth = 1
                }
            };

            // Convert levelData to common level format
            Unity_Level level = new Unity_Level(maps, new Unity_ObjectManager(context), getCollisionTypeGraphicFunc: x => ((R1Jaguar_TileCollisionType)x).GetCollisionTypeGraphic());

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

            // Load tile set and treat black as transparent
            level.Maps[0].TileSet[0] = GetTileSet(context, rom);

            return level;
        }
Esempio n. 4
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)
        {
            // Get the level folder path
            var basePath = await GetLevelFolderPath(context);

            // TODO: Parse .ini file to get background etc.
            // Get file paths
            var mapPath        = GetMapFilePath(basePath);
            var mapEventsPath  = GetMapEventsFilePath(basePath);
            var saveEventsPath = GetSaveEventsFilePath(basePath);
            var pcxPath        = GetPCXFilePath(context.Settings);
            var eventsCsvPath  = GetEventManfiestFilePath(context.Settings.R1_World);

            // Load files to context
            await AddFile(context, mapPath);
            await AddFile(context, mapEventsPath, endianness : BinaryFile.Endian.Big); // Big endian just like on Jaguar
            await AddFile(context, pcxPath);

            // Read the files

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

            var mapData = FileFactory.Read <MapData>(mapPath, context);

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

            var mapEvents  = FileFactory.Read <R1Jaguar_MapEvents>(mapEventsPath, context);
            var saveEvents = FileFactory.ReadText <R1_Mapper_SaveEvents>(saveEventsPath, context);
            var csv        = FileFactory.ReadText <R1_Mapper_EventManifest>(eventsCsvPath, context);

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

            var pcx = FileFactory.Read <PCX>(pcxPath, context);

            // Get the palette from the PCX file
            var vgaPalette = pcx.VGAPalette;

            // Load the sprites
            var eventDesigns = loadTextures ? await LoadSpritesAsync(context, vgaPalette) : new Unity_ObjectManager_R1.DESData[0];

            // Read the world data
            var worldData = FileFactory.Read <R1_PC_WorldFile>(GetWorldFilePath(context.Settings), context);

            var maps = new Unity_Map[]
            {
                new Unity_Map()
                {
                    // Set the dimensions
                    Width  = mapData.Width,
                    Height = mapData.Height,

                    // Create the tile arrays
                    TileSet      = new Unity_MapTileMap[1],
                    MapTiles     = mapData.Tiles.Select(x => new Unity_Tile(x)).ToArray(),
                    TileSetWidth = 1
                }
            };

            var allEventInstances = saveEvents.SaveEventInstances.SelectMany(x => x).ToArray();

            // Create a linking table
            var linkTable = new ushort[allEventInstances.Length];

            // Handle each event link group
            foreach (var linkedEvents in allEventInstances.Select((x, i) => new
            {
                Index = i,
                Data = x
            }).GroupBy(x => x.Data.LinkID))
            {
                // Get the group
                var group = linkedEvents.ToArray();

                // Handle every event
                for (int i = 0; i < group.Length; i++)
                {
                    // Get the item
                    var item = group[i];

                    if (group.Length == i + 1)
                    {
                        linkTable[item.Index] = (ushort)group[0].Index;
                    }
                    else
                    {
                        linkTable[item.Index] = (ushort)group[i + 1].Index;
                    }
                }
            }

            // Create the object manager
            var objManager = new Unity_ObjectManager_R1(
                context: context,
                des: eventDesigns.Select((x, i) => new Unity_ObjectManager_R1.DataContainer <Unity_ObjectManager_R1.DESData>(x, i, worldData.DESFileNames?.ElementAtOrDefault(i))).ToArray(),
                eta: GetCurrentEventStates(context).Select((x, i) => new Unity_ObjectManager_R1.DataContainer <R1_EventState[][]>(x.States, i, worldData.ETAFileNames?.ElementAtOrDefault(i))).ToArray(),
                linkTable: linkTable,
                usesPointers: false,
                hasDefinedDesEtaNames: true);

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

            var levelEvents = new List <Unity_Object>();

            // Create events
            for (var i = 0; i < saveEvents.SaveEventInstances.Length; i++)
            {
                // Get the map base position, based on the event map
                var mapPos = mapEvents.EventIndexMap.FindItemIndex(z => z == i + 1);

                // Get the x and y positions
                var mapY = (uint)Math.Floor(mapPos / (double)(mapEvents.Width));
                var mapX = (uint)(mapPos - (mapY * mapEvents.Width));

                // Calculate the actual position on the map
                mapX *= 4 * (uint)Settings.CellSize;
                mapY *= 4 * (uint)Settings.CellSize;

                // Add every instance
                foreach (var instance in saveEvents.SaveEventInstances[i])
                {
                    // Get the definition
                    var def = csv.EventDefinitions.FirstOrDefault(x => x.Name == instance.EventDefinitionKey);

                    if (def == null)
                    {
                        throw new Exception($"No matching event definition found for {instance.EventDefinitionKey}");
                    }

                    var ed = new R1_EventData()
                    {
                        Type            = def.Type,
                        Etat            = def.Etat,
                        SubEtat         = def.SubEtat,
                        XPosition       = (short)(mapX + instance.OffsetX),
                        YPosition       = (short)(mapY + instance.OffsetY),
                        OffsetBX        = def.OffsetBX,
                        OffsetBY        = def.OffsetBY,
                        OffsetHY        = def.OffsetHY,
                        FollowSprite    = def.FollowSprite,
                        ActualHitPoints = (uint)instance.HitPoints,
                        DisplayPrio     = instance.DisplayPrio,
                        HitSprite       = def.HitSprite,

                        PS1Demo_Unk1 = new byte[40],
                        Unk_98       = new byte[5],

                        LabelOffsets = new ushort[0],
                        Commands     = R1_EventCommandCollection.FromBytes(def.EventCommands, context.Settings),
                    };

                    ed.SetFollowEnabled(context.Settings, def.FollowEnabled > 0);

                    // Add the event
                    levelEvents.Add(new Unity_Object_R1(
                                        eventData: ed,
                                        objManager: objManager,
                                        ETAIndex: worldData.ETAFileNames.FindItemIndex(x => x == def.ETAFile))
                    {
                        DESIndex = worldData.DESFileNames.FindItemIndex(x => x.Length > 4 && x.Substring(0, x.Length - 4) == def.DESFile)
                    });
                }
            }

            // Convert levelData to common level format
            var level = new Unity_Level(maps, objManager, levelEvents, rayman: new Unity_Object_R1(R1_EventData.GetRayman(context, levelEvents.Cast <Unity_Object_R1>().FirstOrDefault(x => x.EventData.Type == R1_EventType.TYPE_RAY_POS)?.EventData), objManager));

            Controller.DetailedState = $"Creating tileset";
            await Controller.WaitIfNecessary();

            // Load the tile set
            level.Maps[0].TileSet[0] = LoadTileSet(pcx);

            // Return the level
            return(level);
        }
Esempio n. 5
0
        public async UniTask <Unity_Level> LoadAsync(Context context, bool loadTextures)
        {
            Controller.DetailedState = $"Loading data";
            await Controller.WaitIfNecessary();

            // Read the rom
            var rom = FileFactory.Read <SNES_Proto_ROM>(GetROMFilePath, context);

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

            // Get the tilesets
            var tileSet_0000_shadow = LoadTileSet(rom.TileSet_0000, rom.TilePalette, false, true, animatedTiles: rom.AnimatedTiles, shadow: true);
            var tileSet_0000        = LoadTileSet(rom.TileSet_0000, rom.TilePalette, false, true, animatedTiles: rom.AnimatedTiles);
            var tileSet_8000        = LoadTileSet(rom.TileSet_8000, rom.TilePalette, true, false);

            // Load the primary map
            var map = LoadMap(rom.BG1_Map, rom.BG1_Tiles).Select(x =>
            {
                x.TileMapY = (ushort)(x.PaletteIndex * tileSet_0000.SNES_BaseLength + x.TileMapY);
                return(new Unity_Tile(x));
            }).ToArray();

            var maps = new Unity_Map[]
            {
                // Background
                new Unity_Map()
                {
                    Type    = Unity_Map.MapType.Graphics,
                    Width   = 32,
                    Height  = 32,
                    TileSet = new Unity_TileSet[]
                    {
                        tileSet_8000
                    },
                    MapTiles = rom.BG3_Tiles.Select(x =>
                    {
                        x.TileMapY = (ushort)(x.PaletteIndex * tileSet_8000.SNES_BaseLength + x.TileMapY);
                        return(new Unity_Tile(x));
                    }).ToArray(),
                },
                // Map (no priority)
                new Unity_Map()
                {
                    Type    = Unity_Map.MapType.Graphics,
                    Width   = (ushort)(rom.BG1_Map.Width * 2),
                    Height  = (ushort)(rom.BG1_Map.Height * 2),
                    TileSet = new Unity_TileSet[]
                    {
                        tileSet_0000
                    },
                    MapTiles = map.Select(x => x.Data.Priority ? new Unity_Tile(new MapTile()) : x).ToArray(),
                },
                // Map (no priority)
                new Unity_Map()
                {
                    Type    = Unity_Map.MapType.Graphics,
                    Width   = (ushort)(rom.BG1_Map.Width * 2),
                    Height  = (ushort)(rom.BG1_Map.Height * 2),
                    TileSet = new Unity_TileSet[]
                    {
                        tileSet_0000_shadow
                    },
                    MapTiles = map.Select(x => x.Data.Priority ? x : new Unity_Tile(new MapTile())).ToArray(),
                },
                // Map (priority)
                new Unity_Map()
                {
                    Type    = Unity_Map.MapType.Graphics,
                    Width   = (ushort)(rom.BG1_Map.Width * 2),
                    Height  = (ushort)(rom.BG1_Map.Height * 2),
                    TileSet = new Unity_TileSet[]
                    {
                        tileSet_0000
                    },
                    MapTiles   = map.Select(x => !x.Data.Priority ? new Unity_Tile(new MapTile()) : x).ToArray(),
                    Layer      = Unity_Map.MapLayer.Front,
                    IsAdditive = true,
                    Alpha      = 1f
                },
                // Foreground
                new Unity_Map()
                {
                    Type    = Unity_Map.MapType.Graphics,
                    Width   = 32,
                    Height  = 32,
                    TileSet = new Unity_TileSet[]
                    {
                        tileSet_0000
                    },
                    MapTiles = rom.BG2_Tiles.Select(x =>
                    {
                        x.TileMapY = (ushort)(x.PaletteIndex * tileSet_0000.SNES_BaseLength + x.TileMapY);
                        return(new Unity_Tile(x));
                    }).ToArray(),
                    Layer = Unity_Map.MapLayer.Front,
                },
                // Collision
                new Unity_Map()
                {
                    Type     = Unity_Map.MapType.Collision,
                    Width    = rom.BG1_Map.Width,
                    Height   = rom.BG1_Map.Height,
                    TileSet  = new Unity_TileSet[0],
                    MapTiles = rom.BG1_Map.Tiles.Select(x => new Unity_Tile(x)).ToArray()
                },
            };

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

            var objManager = new Unity_ObjectManager_SNES(context, GetGraphicsGroups(rom));

            // Create Rayman
            var rayman = new Unity_Object_SNES(rom.Rayman, objManager);

            // Convert levelData to common level format
            return(new Unity_Level(
                       maps: maps,
                       objManager: objManager,
                       getCollisionTypeNameFunc: x => ((R1Jaguar_TileCollisionType)x).ToString(),
                       getCollisionTypeGraphicFunc: x => ((R1Jaguar_TileCollisionType)x).GetCollisionTypeGraphic(),
                       rayman: rayman,
                       cellSize: 8)
            {
                CellSizeOverrideCollision = 16
            });
        }
Esempio n. 6
0
        public override async UniTask <Unity_Level> LoadAsync(Context context, bool loadTextures)
        {
            if (GetLevelType(context) != LevelType.R3SinglePak)
            {
                return(await base.LoadAsync(context, loadTextures));
            }

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

            // Get the rom
            var rom = FileFactory.Read <GBA_ROM>(GetROMFilePath(context), context);

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

            var pal        = Util.ConvertGBAPalette(rom.R3SinglePak_Palette, transparentIndex: null);
            var tileSetTex = Util.ToTileSetTexture(rom.R3SinglePak_TileSet, pal, Util.TileEncoding.Linear_8bpp, CellSize, false);

            // Create the background map
            var map = new Unity_Map
            {
                Width   = 32,
                Height  = 32,
                TileSet = new Unity_TileSet[]
                {
                    new Unity_TileSet(tileSetTex, CellSize),
                },
                MapTiles = rom.R3SinglePak_TileMap.Select(x => new Unity_Tile(new MapTile()
                {
                    TileMapY = x
                })).ToArray(),
                Type = Unity_Map.MapType.Graphics,
            };

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

            // Create dummy actor models from the puppets, with one action for every animation
            var actorModels = rom.R3SinglePak_Puppets.Select((x, i) => new Unity_ObjectManager_GBA.ModelData(
                                                                 index: i,
                                                                 actions: Enumerable.Range(0, x.AnimationsCount).Select(animIndex => new GBA_Action()
            {
                AnimationIndex = (ushort)animIndex
            }).ToArray(),
                                                                 puppets: new Unity_ObjGraphics[]
            {
                GetCommonDesign(x, false, null, new GBA_Animation[0])
            })).ToArray();

            // Create an object manager
            var objManager = new Unity_ObjectManager_GBA(context, actorModels);

            // Create a single dummy game object
            var obj = new Unity_Object_GBA(new GBA_Actor()
            {
                Type       = GBA_Actor.ActorType.Actor,
                ActorModel = new GBA_ActorModel(),
                XPos       = 128,
                YPos       = 128
            }, objManager);

            // Return the level
            return(new Unity_Level(
                       maps: new Unity_Map[]
            {
                map
            },
                       objManager: objManager,
                       eventData: new List <Unity_Object>()
            {
                obj
            },
                       cellSize: CellSize));
        }