core_decoder/region_array.py
2025-02-11 18:31:17 -06:00

58 lines
1.7 KiB
Python

import struct
from dataclasses import dataclass
@dataclass
class RegionArrayTile:
last_region: int
z_clear: int
flush_accumulate: int
tile_y_position: int
tile_x_position: int
def __init__(self, value):
assert (value >> 29) & 1 == 0, value
assert (value >> 14) & 0x3fff == 0, value
assert (value >> 0) & 0b11 == 0, value
self.last_region = (value >> 31) & 0b1
self.z_clear = (value >> 30) & 0b1
self.flush_accumulate = (value >> 28) & 0b1
self.tile_y_position = (value >> 8) & 0b111111
self.tile_x_position = (value >> 2) & 0b111111
@dataclass
class RegionArrayPointer:
empty_ptr: int
pointer_to_object_list: int
def __init__(self, value):
assert (value >> 24) & 0x7f == 0
assert (value >> 0) & 0b11 == 0
self.empty_ptr = (value >> 31) & 1
self.pointer_to_object_list = value & 0xffffff
@dataclass
class RegionArrayEntry:
tile: RegionArrayTile
opaque_list_pointer: RegionArrayPointer
opaque_modifier_volume_list_pointer: RegionArrayPointer
translucent_list_pointer: RegionArrayPointer
translucent_modifier_volume_list_pointer: RegionArrayPointer
punch_through_list_pointer: RegionArrayPointer
def decode_region_array_entry(mem, offset):
next_offset = offset + 6 * 4
tile, *pointers = struct.unpack("<IIIIII", mem[offset:next_offset])
return next_offset, RegionArrayEntry(
RegionArrayTile(tile),
*map(RegionArrayPointer, pointers),
)
def decode_region_array_entries(mem, offset):
entries = []
while True:
offset, entry = decode_region_array_entry(mem, offset)
entries.append(entry)
if entry.tile.last_region:
break
return entries