extends Node const LENGTH := 0x500 / 2 # Expanded length 0x500, RLE step produces 0x280 tile mappings func decompress_battle_tilemap(buffer: StreamPeerBuffer) -> Array: # Decompresses the tilemap for a battle background. # Battle BGs use a type of RLE with 2byte repeat and 1byte incremental repeat. var mappings := [] while len(mappings) < LENGTH: var byte := buffer.get_u8() if byte != 0xFF: mappings.append(TileMapping.from_battle_byte(byte)) else: # Byte begins a repeat code var repeat_code := buffer.get_u8() var repeat := repeat_code & 0x3F byte = buffer.get_u8() if repeat_code & 0x80: # Repeat 2 tiles var byte2 := buffer.get_u8() for i in repeat: mappings.append(TileMapping.from_battle_byte(byte)) mappings.append(TileMapping.from_battle_byte(byte2)) else: # Incremental repeat var inc := buffer.get_u8() if repeat_code & 0x40: # Negative increment inc = -inc for i in repeat: mappings.append(TileMapping.from_battle_byte(byte)) byte += inc return mappings func apply_battle_tilemap_flips(buffer: StreamPeerBuffer, id: int, tilemap: Array): if id==0xFF: return buffer.seek(0x14C736+(id*2)) var ptr := 0x140000 + buffer.get_u16() buffer.seek(ptr) var tile_i := 0 while tile_i < LENGTH: var a := buffer.get_u8() if a == 0x00: # Skip N*8 tiles tile_i += buffer.get_u8() * 8 else: # Each bit is a tile, 1 means flip horizontally for b in range(7, -1, -1): tilemap[tile_i].h_flip = bool((a>>b) & 0x01) tile_i += 1 class TileMapping: var tile_index: int var palette: int var priority: bool var h_flip: bool var v_flip: bool static func from_tilemap_word(w: int) -> TileMapping: var t := TileMapping.new() t.tile_index = w & 0x03FF t.palette = (w & 0x1C00) >> 10 t.priority = bool(w & 0x2000) t.h_flip = bool(w & 0x4000) t.v_flip = bool(w & 0x8000) return t static func from_battle_byte(b: int) -> TileMapping: var t := TileMapping.new() t.tile_index = b | 0x80 t.palette = 1 + (b >> 7) return t