main: fix rendering
This commit is contained in:
parent
0b73dbff8a
commit
c7ff986012
@ -25,7 +25,7 @@ class IspTspInstructionWord:
|
|||||||
dcalc_ctrl: int
|
dcalc_ctrl: int
|
||||||
|
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
assert (value & 0xfffff) == 0
|
assert (value & 0xfffff) == 0, (value, hex(value))
|
||||||
self.depth_compare_mode = (value >> 29) & 0b111
|
self.depth_compare_mode = (value >> 29) & 0b111
|
||||||
self.culling_mode = (value >> 27) & 0b11
|
self.culling_mode = (value >> 27) & 0b11
|
||||||
self.z_write_disable = (value >> 26) & 1
|
self.z_write_disable = (value >> 26) & 1
|
||||||
@ -114,14 +114,19 @@ class ISPTSPParameterMV:
|
|||||||
def expected_skip_size(isp_tsp):
|
def expected_skip_size(isp_tsp):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def parse_parameter(mem, offset, skip, tag_offset, vertex_count, modifier_volume):
|
def parse_parameter(mem, offset, skip, shadow, tag_offset, vertex_count, modifier_volume):
|
||||||
assert skip >= 0, skip
|
assert skip >= 0, skip
|
||||||
skip = (skip + 3) # size of one vertex
|
assert shadow in {True, False}
|
||||||
|
if shadow:
|
||||||
|
skip = (skip * 2 + 3)
|
||||||
|
else:
|
||||||
|
skip = (skip + 3) # size of one vertex
|
||||||
|
|
||||||
params = []
|
params = []
|
||||||
|
|
||||||
def unpack(i, t):
|
def unpack(i, t):
|
||||||
i_offset = offset + i * 4
|
i_offset = offset + i * 4
|
||||||
|
#print("I_OFFSET:", i_offset)
|
||||||
value, = struct.unpack("<" + t, mem[i_offset:i_offset + 4])
|
value, = struct.unpack("<" + t, mem[i_offset:i_offset + 4])
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
45
main.py
45
main.py
@ -28,10 +28,12 @@ assert (holly.REGION_BASE & 0b11) == 0, holly.REGION_BASE
|
|||||||
|
|
||||||
region_array_entries = decode_region_array_entries(texture_memory, holly.REGION_BASE)
|
region_array_entries = decode_region_array_entries(texture_memory, holly.REGION_BASE)
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = True
|
||||||
|
|
||||||
def walk_region_array(*, tile_callback=None, parameter_callback=None, flush_callback=None):
|
def walk_region_array(*, tile_callback=None, parameter_callback=None, flush_callback=None):
|
||||||
for entry in region_array_entries:
|
for entry in region_array_entries:
|
||||||
|
if DEBUG:
|
||||||
|
print(entry.tile)
|
||||||
lists = [
|
lists = [
|
||||||
("opaque_list_pointer", entry.opaque_list_pointer),
|
("opaque_list_pointer", entry.opaque_list_pointer),
|
||||||
("opaque_modifier_volume_list_pointer", entry.opaque_modifier_volume_list_pointer),
|
("opaque_modifier_volume_list_pointer", entry.opaque_modifier_volume_list_pointer),
|
||||||
@ -56,15 +58,15 @@ def walk_region_array(*, tile_callback=None, parameter_callback=None, flush_call
|
|||||||
print(ol_entry)
|
print(ol_entry)
|
||||||
offset += 4
|
offset += 4
|
||||||
if type(ol_entry) == triangle_array:
|
if type(ol_entry) == triangle_array:
|
||||||
param_offset = ol_entry.triangle_array_start
|
param_offset = holly.PARAM_BASE + ol_entry.triangle_array_start
|
||||||
for i in range(ol_entry.number_of_triangles + 1):
|
for i in range(ol_entry.number_of_triangles + 1):
|
||||||
modifier_volume = list_type_name in {"opaque_modifier_volume_list_pointer", "translucent_modifier_volume_list_pointer"}
|
modifier_volume = list_type_name in {"opaque_modifier_volume_list_pointer", "translucent_modifier_volume_list_pointer"}
|
||||||
param_offset, parameter = parse_parameter(texture_memory, param_offset,
|
param_offset, parameter = parse_parameter(texture_memory, param_offset,
|
||||||
skip=ol_entry.skip,
|
skip=ol_entry.skip,
|
||||||
|
shadow=ol_entry.shadow,
|
||||||
tag_offset=0,
|
tag_offset=0,
|
||||||
vertex_count=3,
|
vertex_count=3,
|
||||||
modifier_volume=modifier_volume)
|
modifier_volume=modifier_volume)
|
||||||
|
|
||||||
if parameter_callback is not None:
|
if parameter_callback is not None:
|
||||||
parameter_callback(entry.tile, list_type_name, list_pointer, ol_entry, parameter)
|
parameter_callback(entry.tile, list_type_name, list_pointer, ol_entry, parameter)
|
||||||
|
|
||||||
@ -85,7 +87,7 @@ def walk_region_array(*, tile_callback=None, parameter_callback=None, flush_call
|
|||||||
flush_callback(entry.tile)
|
flush_callback(entry.tile)
|
||||||
|
|
||||||
def new_tile_surface():
|
def new_tile_surface():
|
||||||
surface = pygame.Surface((32, 32), pygame.SRCALPHA)
|
surface = pygame.Surface((32, 32))
|
||||||
surface.fill((0, 0, 0, 0))
|
surface.fill((0, 0, 0, 0))
|
||||||
return surface
|
return surface
|
||||||
|
|
||||||
@ -98,9 +100,11 @@ def draw_background(tile):
|
|||||||
t = holly.ISP_BACKGND_T
|
t = holly.ISP_BACKGND_T
|
||||||
skip = (t >> 24) & 0b111
|
skip = (t >> 24) & 0b111
|
||||||
tag_address = ((t >> 3) & 0x1fffff) * 4
|
tag_address = ((t >> 3) & 0x1fffff) * 4
|
||||||
|
parameter_address = tag_address + holly.PARAM_BASE
|
||||||
|
|
||||||
param_offset, parameter = parse_parameter(texture_memory, tag_address,
|
param_offset, parameter = parse_parameter(texture_memory, parameter_address,
|
||||||
skip=skip,
|
skip=skip,
|
||||||
|
shadow=0,
|
||||||
tag_offset=0,
|
tag_offset=0,
|
||||||
vertex_count=3,
|
vertex_count=3,
|
||||||
modifier_volume=False)
|
modifier_volume=False)
|
||||||
@ -115,49 +119,49 @@ def draw_background(tile):
|
|||||||
|
|
||||||
points = [(0, 0), (640, 0), (640, 480), (0, 480)]
|
points = [(0, 0), (640, 0), (640, 480), (0, 480)]
|
||||||
|
|
||||||
tile_ix = tile.tile_y_position * x_tiles + tile.tile_x_position
|
global primary_buffer
|
||||||
pygame.draw.polygon(primary_buffer, color, points)
|
pygame.draw.polygon(primary_buffer, color, points)
|
||||||
|
|
||||||
def tile_callback(tile):
|
def tile_callback(tile):
|
||||||
draw_background(tile)
|
draw_background(tile)
|
||||||
|
|
||||||
def flush_callback(tile, *, screen):
|
def flush_callback(tile, *, screen):
|
||||||
tile_ix = tile.tile_y_position * x_tiles + tile.tile_x_position
|
global primary_buffer
|
||||||
screen.blit(primary_buffer, (tile.tile_x_position * 32, tile.tile_y_position * 32))
|
screen.blit(primary_buffer, (tile.tile_x_position * 32, tile.tile_y_position * 32))
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
def parameter_callback(tile, list_type_name, list_pointer, ol_entry, parameter):
|
def parameter_callback(tile, list_type_name, list_pointer, ol_entry, parameter):
|
||||||
# tile=RegionArrayTile(last_region=1, z_clear=0, flush_accumulate=0, tile_y_position=14, tile_x_position=19)
|
|
||||||
if list_type_name != "opaque_list_pointer":
|
|
||||||
return
|
|
||||||
|
|
||||||
left = tile.tile_x_position * 32
|
left = tile.tile_x_position * 32
|
||||||
top = tile.tile_y_position * 32
|
top = tile.tile_y_position * 32
|
||||||
|
|
||||||
tile_ix = tile.tile_y_position * x_tiles + tile.tile_x_position
|
|
||||||
|
|
||||||
assert type(ol_entry) == triangle_array, ol_entry
|
assert type(ol_entry) == triangle_array, ol_entry
|
||||||
assert len(parameter.vertices) == 3, parameter.vertices
|
assert len(parameter.vertices) == 3, parameter.vertices
|
||||||
assert len(parameter.vertices[0].attributes) >= 1, parameter
|
|
||||||
|
if list_type_name in {"opaque_modifier_volume_list_pointer", "translucent_modifier_volume_list_pointer"}:
|
||||||
|
argb_color = 0x00000000
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
assert len(parameter.vertices[0].attributes) >= 1, parameter
|
||||||
|
argb_color = parameter.vertices[0].attributes[0]
|
||||||
|
|
||||||
points = [
|
points = [
|
||||||
(vertex.x - left, vertex.y - top)
|
(vertex.x - left, vertex.y - top)
|
||||||
for vertex in parameter.vertices
|
for vertex in parameter.vertices
|
||||||
]
|
]
|
||||||
|
|
||||||
argb_color = parameter.vertices[0].attributes[0]
|
|
||||||
alpha = (argb_color >> 24) & 0xff
|
alpha = (argb_color >> 24) & 0xff
|
||||||
red = (argb_color >> 16) & 0xff
|
red = (argb_color >> 16) & 0xff
|
||||||
green = (argb_color >> 8) & 0xff
|
green = (argb_color >> 8) & 0xff
|
||||||
blue = (argb_color >> 0) & 0xff
|
blue = (argb_color >> 0) & 0xff
|
||||||
color = (red, green, blue, alpha)
|
color = (red, green, blue)
|
||||||
|
|
||||||
assert red > 10 or blue > 10 or green > 10, argb_color
|
|
||||||
|
|
||||||
pygame.draw.polygon(primary_buffer, color, points)
|
pygame.draw.polygon(primary_buffer, color, points)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
walk_region_array(tile_callback=None,
|
||||||
|
parameter_callback=None,
|
||||||
|
flush_callback=None)
|
||||||
|
|
||||||
def draw():
|
def draw():
|
||||||
pygame.init()
|
pygame.init()
|
||||||
screen = pygame.display.set_mode((640, 480))
|
screen = pygame.display.set_mode((640, 480))
|
||||||
@ -178,4 +182,5 @@ def draw():
|
|||||||
|
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
|
|
||||||
|
#main()
|
||||||
draw()
|
draw()
|
||||||
|
@ -16,6 +16,14 @@ class triangle_strip:
|
|||||||
self.skip = (value >> 21) & 0b111
|
self.skip = (value >> 21) & 0b111
|
||||||
self.triangle_strip_start = (value & 0x1fffff) << 2
|
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
|
@dataclass
|
||||||
class triangle_array:
|
class triangle_array:
|
||||||
number_of_triangles: int
|
number_of_triangles: int
|
||||||
@ -31,6 +39,14 @@ class triangle_array:
|
|||||||
self.skip = (value >> 21) & 0b111
|
self.skip = (value >> 21) & 0b111
|
||||||
self.triangle_array_start = (value & 0x1fffff) << 2
|
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
|
@dataclass
|
||||||
class quad_array:
|
class quad_array:
|
||||||
number_of_quads: int
|
number_of_quads: int
|
||||||
@ -46,6 +62,14 @@ class quad_array:
|
|||||||
self.skip = (value >> 21) & 0b111
|
self.skip = (value >> 21) & 0b111
|
||||||
self.quad_array_start = (value & 0x1fffff) << 2
|
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
|
@dataclass
|
||||||
class object_pointer_block_link:
|
class object_pointer_block_link:
|
||||||
end_of_list: int
|
end_of_list: int
|
||||||
@ -58,6 +82,13 @@ class object_pointer_block_link:
|
|||||||
self.end_of_list = (value >> 28) & 1
|
self.end_of_list = (value >> 28) & 1
|
||||||
self.next_pointer_block = value & 0xffffff
|
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):
|
def decode_ol_entry(mem, offset):
|
||||||
value, = struct.unpack("<I", mem[offset:offset+4])
|
value, = struct.unpack("<I", mem[offset:offset+4])
|
||||||
|
@ -30,6 +30,14 @@ class RegionArrayPointer:
|
|||||||
self.empty_ptr = (value >> 31) & 1
|
self.empty_ptr = (value >> 31) & 1
|
||||||
self.pointer_to_object_list = value & 0xffffff
|
self.pointer_to_object_list = 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)})'
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RegionArrayEntry:
|
class RegionArrayEntry:
|
||||||
tile: RegionArrayTile
|
tile: RegionArrayTile
|
||||||
|
Loading…
x
Reference in New Issue
Block a user