Skip to content

Commit

Permalink
re-wrote tile bleed to work with new texture writer, and made all tex…
Browse files Browse the repository at this point in the history
…tureDLs go to a single gfx_list instead of separate ones per tile
  • Loading branch information
scut committed Mar 17, 2023
1 parent a096c1f commit c3962ed
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 51 deletions.
97 changes: 60 additions & 37 deletions fast64_internal/f3d/f3d_bleed.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,42 +80,63 @@ def bleed_fmesh(self, f3d: F3D, fMesh: FMesh, lastMat: FMaterial, cmd_list: GfxL
self.on_bleed_end(f3d, lastMat, bleed_gfx_lists, cmd_list, default_render_mode)
return lastMat

def build_tmem_dict(self, cmd_list: GfxList):
im_buffer = None
tmem_dict = dict()
tile_dict = {i:0 for i in range(8)} # an assumption that hopefully never needs correction
for cmd in cmd_list.commands:
if type(cmd) == DPSetTextureImage:
im_buffer = cmd
continue
if type(cmd) == DPSetTile:
tile_dict[cmd.tile] = cmd.tmem
if type(cmd) in (DPLoadTLUTCmd, DPLoadTile, DPLoadBlock):
tmem_dict[tile_dict[cmd.tile]] = im_buffer
continue
return tmem_dict

def bleed_textures(self, curMat: FMaterial, lastMat: FMaterial, cmd_list: GfxList, bleed_state: int):
if lastMat:
bled_tex = []
# bleed cmds if matching tile has duplicate cmds
for j, (LastTex, TexCmds) in enumerate(zip(lastMat.texture_DLs, curMat.texture_DLs)):
# deep copy breaks on Image objects so I will only copy the levels needed
commands_bled = copy.copy(TexCmds)
commands_bled.commands = copy.copy(TexCmds.commands) # copy the commands also
lastList = LastTex.commands
# eliminate set tex images
set_tex = (c for c in TexCmds.commands if type(c) == DPSetTextureImage)
removed_tex = [c for c in set_tex if c in lastList] # needs to be a list to check "in" multiple times
rm_load = None # flag to elim loads once
for j, cmd in enumerate(TexCmds.commands):
# remove set tex explicitly
if cmd in removed_tex:
commands_bled.commands.remove(cmd)
rm_load = True
continue
if rm_load and type(cmd) in (DPLoadTLUTCmd, DPLoadTile, DPLoadBlock):
commands_bled.commands.remove(cmd)
rm_load = None
continue
# now eval as normal conditionals
iter_cmds = copy.copy(commands_bled.commands) # need extra list to iterate with
for j, cmd in enumerate(iter_cmds):
if self.bleed_individual_cmd(commands_bled, cmd, bleed_state):
if cmd in lastList:
commands_bled.commands[j] = None
# remove Nones from list
while None in commands_bled.commands:
commands_bled.commands.remove(None)
bled_tex.append(commands_bled)
# deep copy breaks on Image objects so I will only copy the levels needed
commands_bled = copy.copy(curMat.texture_DL)
commands_bled.commands = copy.copy(curMat.texture_DL.commands) # copy the commands also
# eliminate set tex images, but only if there is an overlap of the same image at the same tmem location
last_im_loads = self.build_tmem_dict(lastMat.texture_DL)
new_im_loads = self.build_tmem_dict(commands_bled)
removable_images = []
for tmem, image in new_im_loads.items():
if tmem in last_im_loads and last_im_loads[tmem] == image:
removable_images.append(image)
# now go through list and cull out loads for the specific cmds
# this will be the set tex image, and the loading cmds
rm_load = False
for j, cmd in enumerate(curMat.texture_DL.commands):
# remove set tex explicitly
if cmd in removable_images:
commands_bled.commands[j] = None
rm_load = True
continue
if rm_load and type(cmd) == DPSetTile:
commands_bled.commands[j] = None
if rm_load and type(cmd) in (DPLoadTLUTCmd, DPLoadTile, DPLoadBlock):
commands_bled.commands[j] = None
rm_load = None
continue
# now eval as normal conditionals
for j, cmd in enumerate(curMat.texture_DL.commands):
if not cmd:
continue # some cmds are None from previous step
if self.bleed_individual_cmd(commands_bled, cmd, bleed_state):
if cmd in lastMat.texture_DL.commands:
commands_bled.commands[j] = None
# remove Nones from list
while None in commands_bled.commands:
commands_bled.commands.remove(None)
bled_tex = commands_bled
else:
bled_tex = curMat.texture_DLs
return bled_tex
bled_tex = curMat.texture_DL
return bled_tex.commands

def bleed_mat(self, curMat: FMaterial, lastMat: FMaterial, cmd_list: GfxList, bleed_state: int):
if lastMat:
Expand All @@ -136,7 +157,7 @@ def bleed_mat(self, curMat: FMaterial, lastMat: FMaterial, cmd_list: GfxList, bl
# remove SPEndDisplayList
while SPEndDisplayList() in commands_bled.commands:
commands_bled.commands.remove(SPEndDisplayList())
return commands_bled
return commands_bled.commands

def bleed_tri_group(
self, f3d: F3D, triGroup: FTriGroup, bleed_gfx_lists: BleedGfxLists, cmd_list: GfxList, bleed_state: int
Expand Down Expand Up @@ -167,10 +188,9 @@ def bleed_cmd_list(self, target_cmd_list: GfxList, bleed_state: int):
# Put triGroup bleed gfx in the FMesh.draw object
def inline_triGroup(self, f3d: F3D, triGroup: FTriGroup, bleed_gfx_lists: BleedGfxLists, cmd_list: GfxList):
# add material
cmd_list.commands.extend(bleed_gfx_lists.bled_mats.commands)
cmd_list.commands.extend(bleed_gfx_lists.bled_mats)
# add textures
for tile, texGfx in enumerate(bleed_gfx_lists.bled_tex):
cmd_list.commands.extend(texGfx.commands)
cmd_list.commands.extend(bleed_gfx_lists.bled_tex)
# add in triangles
cmd_list.commands.extend(triGroup.triList.commands)
# skinned meshes don't draw tris sometimes, use this opportunity to save a sync
Expand Down Expand Up @@ -221,7 +241,9 @@ def bleed_individual_cmd(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: in
SPBranchLessZraw,
SPModifyVertex,
SPEndDisplayList,
DPSetTextureImage,
DPLoadBlock,
DPLoadTile,
DPLoadTLUTCmd,
DPFullSync,
]:
Expand All @@ -238,6 +260,7 @@ def bleed_SPSetOtherMode(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: in
return True

def bleed_DPSetTileSize(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: int):
print(cmd.tags, cmd.tags != GfxTag.TileScroll0 and cmd.tags != GfxTag.TileScroll1)
return cmd.tags != GfxTag.TileScroll0 and cmd.tags != GfxTag.TileScroll1

def bleed_DPSetTile(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: int):
Expand Down Expand Up @@ -278,7 +301,7 @@ def bleed_DPLoadSync(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: int):
@dataclass
class BleedGfxLists:
bled_mats: GfxList = field(default_factory=list)
bled_tex: list[GfxList] = field(default_factory=list) # list of GfxList
bled_tex: GfxList = field(default_factory=list)
reset_cmds: set[GbiMacro] = field(default_factory=set) # set of cmds to reset

def __post_init__(self):
Expand Down
17 changes: 7 additions & 10 deletions fast64_internal/f3d/f3d_gbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2309,7 +2309,7 @@ def writeTexRefCITextures(
# Called before SPEndDisplayList
def onMaterialCommandsBuilt(self, fMaterial, material, drawLayer):
fMaterial.material.commands.extend(fMaterial.mat_only_DL.commands)
[fMaterial.material.commands.extend(tile_gfx_list.commands) for tile_gfx_list in fMaterial.texture_DLs]
fMaterial.material.commands.extend(fMaterial.texture_DL.commands)
return

def getDrawLayerV3(self, obj):
Expand Down Expand Up @@ -2903,10 +2903,10 @@ def get_f3d_mat_from_version(material: bpy.types.Material):

class FMaterial:
def __init__(self, name, DLFormat):
self.material = GfxList("mat_" + name, GfxListTag.Material, DLFormat)
self.mat_only_DL = GfxList("mat_only_" + name, GfxListTag.Material, DLFormat)
self.texture_DLs = [GfxList(f"tex_{i}_" + name, GfxListTag.Material, DLFormat.Static) for i in range(2)]
self.revert = GfxList("mat_revert_" + name, GfxListTag.MaterialRevert, DLFormat.Static)
self.material = GfxList(f"mat_{name}", GfxListTag.Material, DLFormat)
self.mat_only_DL = GfxList(f"mat_only_{name}", GfxListTag.Material, DLFormat)
self.texture_DL = GfxList(f"tex_{name}", GfxListTag.Material, DLFormat.Static)
self.revert = GfxList(f"mat_revert_{name}", GfxListTag.MaterialRevert, DLFormat.Static)
self.DLFormat = DLFormat
self.scrollData = FScrollData()

Expand All @@ -2924,9 +2924,6 @@ def __init__(self, name, DLFormat):
self.imageKey = [None, None]
self.texPaletteIndex = [0, 0]

def getTexturesGfxList(self, tile):
return self.texture_DLs[tile]

def getScrollData(self, material, dimensions):
self.getScrollDataField(material, 0, 0)
self.getScrollDataField(material, 0, 1)
Expand Down Expand Up @@ -4328,8 +4325,8 @@ class DPSetTextureImage(GbiMacro):
siz: str
width: int
image: FImage
_segptrs = True # calls segmented_to_virtualon name when needed

_segptrs = True # calls segmented_to_virtual on name when needed
def to_binary(self, f3d, segments):
fmt = f3d.G_IM_FMT_VARS[self.fmt]
siz = f3d.G_IM_SIZ_VARS[self.siz]
Expand Down
6 changes: 3 additions & 3 deletions fast64_internal/f3d/f3d_texture_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ def writeAll(
)

# Write loads
loadGfx = fMaterial.mat_only_DL
# loadGfx = fMaterial.mat_only_DL # I don't know what the point of this was
f3d = fModel.f3d
if self.loadPal:
savePaletteLoad(loadGfx, fPalette, self.palFormat, self.palAddr, self.palLen, 5 - self.indexInMat, f3d)
Expand Down Expand Up @@ -866,8 +866,8 @@ def writeAll(
+ "bytes, ex. 2 32x32 RGBA 16 bit textures.\nNote that texture width will be internally padded to 64 bit boundaries."
)

self.ti0.writeAll(fMaterial.getTexturesGfxList(0), fMaterial, fModel, convertTextureData)
self.ti1.writeAll(fMaterial.getTexturesGfxList(1), fMaterial, fModel, convertTextureData)
self.ti0.writeAll(fMaterial.texture_DL, fMaterial, fModel, convertTextureData)
self.ti1.writeAll(fMaterial.texture_DL, fMaterial, fModel, convertTextureData)

def getTexDimensions(self):
return self.texDimensions
Expand Down
2 changes: 1 addition & 1 deletion fast64_internal/sm64/sm64_f3d_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def processGfxScrollCommand(self, commandIndex: int, command: GbiMacro, gfxListN
return "", ""
elif tags & (GfxTag.TileScroll0 | GfxTag.TileScroll1):
textureIndex = 0 if tags & GfxTag.TileScroll0 else 1
return get_tile_scroll_code(fMaterial.texture_DLs[textureIndex].name, fMaterial.scrollData, textureIndex, commandIndex)
return get_tile_scroll_code(fMaterial.texture_DL.name, fMaterial.scrollData, textureIndex, commandIndex)
else:
return "", ""

Expand Down

0 comments on commit c3962ed

Please sign in to comment.