Beispiel #1
0
        public RawMapData ExtractLevelData(LevelIdentifier level)
        {
            RawMapData res;
            LevelInfo  info = GetLevelInfo(level);

            rom.Seek(info.DataBaseAddress, SeekOrigin.Begin);
            long startPos = rom.Position;

            res.RawData = LzCompression.Decompress(rom, info.DataUncompressedSize);
            int length = (int)(rom.Position - startPos);

            rom.Seek(startPos, SeekOrigin.Begin);
            res.CompressedData = (new BinaryReader(rom)).ReadBytes(length);

            rom.Seek(info.GraphicalBaseAddress, SeekOrigin.Begin);
            startPos         = rom.Position;
            res.RawGraphical = LzCompression.Decompress(rom, info.GraphicalUncompressedSize);
            length           = (int)(rom.Position - startPos);
            rom.Seek(startPos, SeekOrigin.Begin);
            res.CompressedGraphical = (new BinaryReader(rom)).ReadBytes(length);

            rom.Seek(info.BackgroundBaseAddress, SeekOrigin.Begin);
            startPos          = rom.Position;
            res.RawBackground = LzCompression.Decompress(rom, info.BackgroundUncompressedSize);
            length            = (int)(rom.Position - startPos);
            rom.Seek(startPos, SeekOrigin.Begin);
            res.CompressedBackground = (new BinaryReader(rom)).ReadBytes(length);

            rom.Seek(info.MinimapBaseAddress, SeekOrigin.Begin);
            res.RawMinimap = (new BinaryReader(rom)).ReadBytes(info.MinimapSize);

            return(res);
        }
 private void Awake()
 {
     if (instance != null && instance != this)
     {
         Destroy(this.gameObject);
         return;
     }
     else
     {
         instance = this;
     }
     DontDestroyOnLoad(transform.gameObject);
     levelName = SceneManager.GetActiveScene().name;
 }
Beispiel #3
0
        public LevelInfo GetLevelInfo(LevelIdentifier level)
        {
            int       w         = (int)level.world;
            int       l         = level.level;
            int       base_addr = world_entries[w].WorldDataBaseAddress;
            LevelInfo res;

            res.DataBaseAddress            = base_addr + level_entries[w][l].level_data_offset;
            res.DataUncompressedSize       = level_entries[w][l].level_uncompressed_size;
            res.GraphicalBaseAddress       = base_addr + level_entries[w][l].graphical_data_offset;
            res.GraphicalUncompressedSize  = level_entries[w][l].graphical_uncompressed_size;
            res.BackgroundBaseAddress      = base_addr + level_entries[w][l].background_data_offset;
            res.BackgroundUncompressedSize = level_entries[w][l].background_uncompressed_size;
            res.MinimapBaseAddress         = base_addr + level_entries[w][l].minimap_data_offset;
            res.MinimapSize = level_entries[w][l].minimap_size;
            return(res);
        }
Beispiel #4
0
        int WriteDataWithCompression(LevelIdentifier level, byte[] original_raw, byte[] original_compressed, byte[] new_raw, int baseAddr, int endAddr)
        {
            rom.Seek(baseAddr, SeekOrigin.Begin);
            if (new_raw == null && (endAddr < 0 || baseAddr + original_compressed.Length <= endAddr))
            {
                rom.Write(original_compressed);
                return(original_raw.Length);
            }
            else if (new_raw == null)
            {
                new_raw = original_raw;
            }
            int uncompressed_length_written = LzCompression.Compress(rom, new_raw, endAddr);

            if (uncompressed_length_written < new_raw.Length)
            {
                Console.WriteLine(string.Format("Warning: The new level {0} has been truncated.", level.ToString()));
            }
            Debug.Assert(uncompressed_length_written <= new_raw.Length);
            return(floorToMultiple(uncompressed_length_written, 4));
            //return new_raw.Length;
        }
Beispiel #5
0
        public bool AlterLevelData(LevelIdentifier level, byte[] new_data, byte[] new_graphical, byte[] new_background, byte[] new_minimap, bool relocate)
        {
            RawMapData original = ExtractLevelData(level);

            if (new_data != null && original.RawData.SequenceEqual(new_data))
            {
                new_data = null;
            }
            if (new_graphical != null && original.RawGraphical.SequenceEqual(new_graphical))
            {
                new_graphical = null;
            }
            if (new_background != null && original.RawBackground.SequenceEqual(new_background))
            {
                new_background = null;
            }
            if (new_minimap != null && original.RawMinimap.SequenceEqual(new_minimap))
            {
                new_minimap = null;
            }

            if (new_data == null && new_graphical == null && new_background == null && new_minimap == null)
            {
                return(false);
            }

            // Write compressed data
            int       w    = (int)level.world;
            int       l    = level.level;
            LevelInfo info = GetLevelInfo(level);

            int pos0 = relocate ? ceilToMultiple((int)rom.Length, 4) : info.DataBaseAddress;

            level_entries[w][l].level_data_offset       = pos0 - world_entries[w].WorldDataBaseAddress;
            level_entries[w][l].level_uncompressed_size =
                WriteDataWithCompression(level, original.RawData, original.CompressedData, new_data, pos0, relocate ? -1 : info.GraphicalBaseAddress);

            int pos1 = ceilToMultiple((int)rom.Position, 4);

            level_entries[w][l].graphical_data_offset       = pos1 - world_entries[w].WorldDataBaseAddress;
            level_entries[w][l].graphical_uncompressed_size =
                WriteDataWithCompression(level, original.RawGraphical, original.CompressedGraphical, new_graphical, pos1, relocate ? -1 : info.BackgroundBaseAddress);

            int pos2 = ceilToMultiple((int)rom.Position, 4);

            level_entries[w][l].background_data_offset       = pos2 - world_entries[w].WorldDataBaseAddress;
            level_entries[w][l].background_uncompressed_size =
                WriteDataWithCompression(level, original.RawBackground, original.CompressedBackground, new_background, pos2, relocate ? -1 : info.MinimapBaseAddress);

            int pos3 = ceilToMultiple((int)rom.Position, 4);

            level_entries[w][l].minimap_data_offset = pos3 - world_entries[w].WorldDataBaseAddress;
            byte[] minimap = new_minimap == null ? original.RawMinimap : new_minimap;
            int    endAddr = (relocate ? pos3 : info.MinimapBaseAddress) + info.MinimapSize;

            rom.Seek(pos3, SeekOrigin.Begin);
            rom.Write(minimap, Math.Max(0, minimap.Length + pos3 - endAddr), Math.Min(endAddr - pos3, minimap.Length));

            // Update LevelEntry structure
            rom.Seek(world_entries[w].WorldInfoBaseAddress + Marshal.SizeOf(typeof(WorldInfo)), SeekOrigin.Begin);
            BinaryWriter writer = new BinaryWriter(rom);

            foreach (LevelEntry entry in level_entries[w])
            {
                Utils.TypeToByte(writer, entry);
            }

            return(true);
        }