176 lines
4.8 KiB
Python
176 lines
4.8 KiB
Python
from dataclasses import dataclass
|
|
from functools import partial
|
|
import struct
|
|
|
|
@dataclass
|
|
class IspTspInstructionWordMV:
|
|
volume_instruction: int
|
|
culling_mode: int
|
|
|
|
def __init__(self, value):
|
|
assert (value & 0x7ffffff) == 0
|
|
self.volume_instruction = (value >> 29) & 0b111
|
|
self.culling_mode = (value >> 27) & 0b11
|
|
|
|
@dataclass
|
|
class IspTspInstructionWord:
|
|
depth_compare_mode: int
|
|
culling_mode: int
|
|
z_write_disable: int
|
|
texture: int
|
|
offset: int
|
|
gouraud_shading: int
|
|
_16bit_uv: int
|
|
cache_bypass: int
|
|
dcalc_ctrl: int
|
|
|
|
def __init__(self, value):
|
|
assert (value & 0xfffff) == 0, (value, hex(value))
|
|
self.depth_compare_mode = (value >> 29) & 0b111
|
|
self.culling_mode = (value >> 27) & 0b11
|
|
self.z_write_disable = (value >> 26) & 1
|
|
self.texture = (value >> 25) & 1
|
|
self.offset = (value >> 24) & 1
|
|
self.gouraud_shading = (value >> 23) & 1
|
|
self._16bit_uv = (value >> 22) & 1
|
|
self.cache_bypass = (value >> 21) & 1
|
|
self.dcalc_ctrl = (value >> 20) & 1
|
|
|
|
@dataclass
|
|
class TspInstructionWord:
|
|
src_alpha_instr: int
|
|
dst_alpha_instr: int
|
|
src_select: int
|
|
dst_select: int
|
|
fog_control: int
|
|
color_clamp: int
|
|
use_alpha: int
|
|
ignore_texture_alpha: int
|
|
flip_uv: int
|
|
clamp_uv: int
|
|
filter_mode: int
|
|
super_sample_texture: int
|
|
mip_map_d_adjust: int
|
|
texture_shading_instruction: int
|
|
texture_u_size: int
|
|
texture_v_size: int
|
|
|
|
def __init__(self, value):
|
|
self.src_alpha_instr = (value >> 29) & 0b111
|
|
self.dst_alpha_instr = (value >> 26) & 0b111
|
|
self.src_select = (value >> 25) & 1
|
|
self.dst_select = (value >> 24) & 1
|
|
self.fog_control = (value >> 22) & 0b11
|
|
self.color_clamp = (value >> 21) & 1
|
|
self.use_alpha = (value >> 20) & 1
|
|
self.ignore_texture_alpha = (value >> 19) & 1
|
|
self.flip_uv = (value >> 17) & 0b11
|
|
self.clamp_uv = (value >> 15) & 0b11
|
|
self.filter_mode = (value >> 13) & 0b11
|
|
self.super_sample_texture = (value >> 12) & 1
|
|
self.mip_map_d_adjust = (value >> 8) & 0b1111
|
|
self.texture_shading_instruction = (value >> 6) & 0b11
|
|
self.texture_u_size = (value >> 3) & 0b111
|
|
self.texture_v_size = (value >> 0) & 0b111
|
|
|
|
@dataclass
|
|
class TextureControlWord:
|
|
mip_mapped: int
|
|
vq_compressed: int
|
|
pixel_format: int
|
|
scan_order: int
|
|
stride_select: int
|
|
texture_address: int
|
|
|
|
def __init__(self, value):
|
|
assert (value >> 21) & 0b1111 == 0
|
|
|
|
self.mip_mapped = (value >> 31) & 1
|
|
self.vq_compressed = (value >> 30) & 1
|
|
self.pixel_format = (value >> 27) & 0b111
|
|
self.scan_order = (value >> 26) & 1
|
|
self.stride_select = (value >> 25) & 1
|
|
self.texture_address = ((value >> 0) & 0x1fffff) * 8
|
|
|
|
@dataclass
|
|
class Vertex:
|
|
x: float
|
|
y: float
|
|
z: float
|
|
attributes: list
|
|
|
|
@dataclass
|
|
class ISPTSPParameter:
|
|
isp_tsp_instruction_word: IspTspInstructionWord
|
|
tsp_instruction_word: TspInstructionWord
|
|
texture_control_word: TextureControlWord
|
|
vertices: list[Vertex]
|
|
|
|
@dataclass
|
|
class ISPTSPParameterMV:
|
|
isp_tsp_instruction_word: IspTspInstructionWord
|
|
vertices: list[Vertex]
|
|
|
|
def expected_skip_size(isp_tsp):
|
|
pass
|
|
|
|
def parse_parameter(mem, offset, skip, shadow, tag_offset, vertex_count, modifier_volume):
|
|
assert skip >= 0, skip
|
|
assert shadow in {True, False}
|
|
if shadow:
|
|
skip = (skip * 2 + 3)
|
|
else:
|
|
skip = (skip + 3) # size of one vertex
|
|
|
|
params = []
|
|
|
|
def unpack(i, t):
|
|
i_offset = offset + i * 4
|
|
#print("I_OFFSET:", i_offset)
|
|
value, = struct.unpack("<" + t, mem[i_offset:i_offset + 4])
|
|
return value
|
|
|
|
unpack_int = partial(unpack, t="I")
|
|
unpack_float = partial(unpack, t="f")
|
|
|
|
if modifier_volume:
|
|
assert skip == 3, skip
|
|
parameter = ISPTSPParameterMV(
|
|
IspTspInstructionWordMV(unpack_int(0)),
|
|
vertices=[]
|
|
)
|
|
value1 = unpack_int(1)
|
|
assert value1 == 0, value1
|
|
value2 = unpack_int(2)
|
|
assert value2 == 0, value2
|
|
else:
|
|
parameter = ISPTSPParameter(
|
|
IspTspInstructionWord(unpack_int(0)),
|
|
TspInstructionWord(unpack_int(1)),
|
|
TextureControlWord(unpack_int(2)),
|
|
vertices=[]
|
|
)
|
|
|
|
|
|
assert tag_offset == 0, tag_offset # FIXME
|
|
|
|
i = 3
|
|
for _ in range(vertex_count):
|
|
vertex = Vertex(
|
|
x = unpack_float(i + 0),
|
|
y = unpack_float(i + 1),
|
|
z = unpack_float(i + 2),
|
|
attributes=[]
|
|
)
|
|
|
|
j = 3
|
|
while j < skip:
|
|
vertex.attributes.append(unpack_int(i + j))
|
|
j += 1
|
|
|
|
parameter.vertices.append(vertex)
|
|
|
|
i += skip
|
|
|
|
return offset + i * 4, parameter
|