From e80af7bdda47a3deab7306e91423188ea9bc4d7c Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Sat, 12 Aug 2023 23:12:28 +0930 Subject: [PATCH] Make battle tilemap code more idiomatic --- scripts/loaders/snes/battle_bgs.gd | 61 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/scripts/loaders/snes/battle_bgs.gd b/scripts/loaders/snes/battle_bgs.gd index aab68b4..107317d 100644 --- a/scripts/loaders/snes/battle_bgs.gd +++ b/scripts/loaders/snes/battle_bgs.gd @@ -1,43 +1,38 @@ extends Node -const LENGTH := 0x500 / 2 # Expanded length 0x500, RLE step produces 0x280 bytes +const LENGTH := 0x500 / 2 # Expanded length 0x500, RLE step produces 0x280 tile mappings -func decompress_battle_tilemap(buffer: StreamPeerBuffer) -> PoolByteArray: +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 o1 := PoolByteArray() - while len(o1) < LENGTH: + var mappings := [] + while len(mappings) < LENGTH: var byte := buffer.get_u8() if byte != 0xFF: - o1.append(byte) + 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 b := buffer.get_u8() + var byte2 := buffer.get_u8() for i in repeat: - o1.append(byte) - o1.append(b) + 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: - o1.append(byte + (inc * i)) - var output := PoolByteArray() - for byte in o1: - # 0bYXXXXXXX -> 0b0000YY00_1XXXXXXX - output.append(byte | 0x80) - output.append(((1+(byte>>7)) << 2) & 0xDF) - return output + mappings.append(TileMapping.from_battle_byte(byte)) + byte += inc + return mappings -func apply_battle_tilemap_flips(buffer: StreamPeerBuffer, id: int, tilemap: PoolByteArray): +func apply_battle_tilemap_flips(buffer: StreamPeerBuffer, id: int, tilemap: Array): if id==0xFF: - return tilemap + return buffer.seek(0x14C736+(id*2)) var ptr := 0x140000 + buffer.get_u16() buffer.seek(ptr) - var output = tilemap var tile_i := 0 while tile_i < LENGTH: var a := buffer.get_u8() @@ -46,22 +41,28 @@ func apply_battle_tilemap_flips(buffer: StreamPeerBuffer, id: int, tilemap: Pool else: # Each bit is a tile, 1 means flip horizontally for b in range(7, -1, -1): - var tile_flip := (a>>b) & 0x01 - output[(tile_i*2)+1] |= tile_flip << 6 # Set the OAM flag for this tile + tilemap[tile_i].h_flip = bool((a>>b) & 0x01) tile_i += 1 - return output class TileMapping: var tile_index: int var palette: int - var priority: int - var h_flip: int - var v_flip: int + var priority: bool + var h_flip: bool + var v_flip: bool - func _init(w: int): - self.tile_index = w & 0x03FF - self.palette = (w & 0x1C00) >> 10 - self.priority = (w & 0x2000) >> 13 - self.h_flip = (w & 0x4000) >> 14 - self.v_flip = (w & 0x8000) >> 15 + 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