107 lines
3.2 KiB
Python
107 lines
3.2 KiB
Python
from dataclasses import dataclass
|
|
import struct
|
|
|
|
@dataclass
|
|
class triangle_strip:
|
|
mask: int
|
|
shadow: int
|
|
skip: int
|
|
triangle_strip_start: int
|
|
|
|
def __init__(self, value):
|
|
assert (value >> 31) & 1 == 0, value
|
|
|
|
self.mask = (value >> 25) & 0b111111
|
|
self.shadow = (value >> 24) & 0b1
|
|
self.skip = (value >> 21) & 0b111
|
|
self.triangle_strip_start = (value & 0x1fffff) << 2
|
|
|
|
def __repr__(self):
|
|
fields = (
|
|
f'{name}={hex(value)}'
|
|
for field in self.__dataclass_fields__.values() if field.repr
|
|
for name, value in ((field.name, self.__getattribute__(field.name)),)
|
|
)
|
|
return f'{self.__class__.__name__}({", ".join(fields)})'
|
|
|
|
@dataclass
|
|
class triangle_array:
|
|
number_of_triangles: int
|
|
shadow: int
|
|
skip: int
|
|
triangle_array_start: int
|
|
|
|
def __init__(self, value):
|
|
assert (value >> 29) & 0b111 == 0b100, value
|
|
|
|
self.number_of_triangles = (value >> 25) & 0b1111
|
|
self.shadow = (value >> 24) & 0b1
|
|
self.skip = (value >> 21) & 0b111
|
|
self.triangle_array_start = (value & 0x1fffff) << 2
|
|
|
|
def __repr__(self):
|
|
fields = (
|
|
f'{name}={hex(value)}'
|
|
for field in self.__dataclass_fields__.values() if field.repr
|
|
for name, value in ((field.name, self.__getattribute__(field.name)),)
|
|
)
|
|
return f'{self.__class__.__name__}({", ".join(fields)})'
|
|
|
|
@dataclass
|
|
class quad_array:
|
|
number_of_quads: int
|
|
shadow: int
|
|
skip: int
|
|
quad_array_start: int
|
|
|
|
def __init__(self, value):
|
|
assert (value >> 29) & 0b111 == 0b101, value
|
|
|
|
self.number_of_quads = (value >> 25) & 0b1111
|
|
self.shadow = (value >> 24) & 0b1
|
|
self.skip = (value >> 21) & 0b111
|
|
self.quad_array_start = (value & 0x1fffff) << 2
|
|
|
|
def __repr__(self):
|
|
fields = (
|
|
f'{name}={hex(value)}'
|
|
for field in self.__dataclass_fields__.values() if field.repr
|
|
for name, value in ((field.name, self.__getattribute__(field.name)),)
|
|
)
|
|
return f'{self.__class__.__name__}({", ".join(fields)})'
|
|
|
|
@dataclass
|
|
class object_pointer_block_link:
|
|
end_of_list: int
|
|
next_pointer_block: int
|
|
|
|
def __init__(self, value):
|
|
assert (value >> 29) & 0b111 == 0b111, value
|
|
assert (value >> 0) & 0b11 == 0b00, value
|
|
|
|
self.end_of_list = (value >> 28) & 1
|
|
self.next_pointer_block = value & 0xffffff
|
|
|
|
def __repr__(self):
|
|
fields = (
|
|
f'{name}={hex(value)}'
|
|
for field in self.__dataclass_fields__.values() if field.repr
|
|
for name, value in ((field.name, self.__getattribute__(field.name)),)
|
|
)
|
|
return f'{self.__class__.__name__}({", ".join(fields)})'
|
|
|
|
def decode_ol_entry(mem, offset):
|
|
value, = struct.unpack("<I", mem[offset:offset+4])
|
|
selector = (value >> 29) & 0b111
|
|
|
|
if selector == 0b111:
|
|
return object_pointer_block_link(value)
|
|
elif selector == 0b101:
|
|
return quad_array(value)
|
|
elif selector == 0b100:
|
|
return triangle_array(value)
|
|
elif (value >> 31) & 1 == 0:
|
|
return triangle_strip(value)
|
|
else:
|
|
assert False, value
|