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; }
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); }
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; }
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); }