From 3fc152282664a7b1220fcdcec7a1339c7018e64a Mon Sep 17 00:00:00 2001 From: Lila Date: Sun, 15 Sep 2024 22:16:09 +0100 Subject: [PATCH] [F3D Bleed] Fix rendermode not being reverted We cannot just assume that othermodeh or othermodel are always setting the same bits, so instead we write the diff of the current cmd to the one already in the reset dict, this means that if a materials sets rendermode and another sets alpha compare (for example) it will still revert the rendermode because those bits will be carried over in the reset dict --- fast64_internal/f3d/f3d_bleed.py | 11 ++++++++--- fast64_internal/f3d/f3d_gbi.py | 11 +++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/fast64_internal/f3d/f3d_bleed.py b/fast64_internal/f3d/f3d_bleed.py index 0e6faaa9b..3f8322e6b 100644 --- a/fast64_internal/f3d/f3d_bleed.py +++ b/fast64_internal/f3d/f3d_bleed.py @@ -45,6 +45,7 @@ GfxList, FTriGroup, GbiMacro, + get_F3D_GBI, ) @@ -58,6 +59,7 @@ class BleedGraphics: def __init__(self): self.bled_gfx_lists = dict() # build world default cmds to compare against, f3d types needed for reset cmd building + self.f3d = get_F3D_GBI() self.is_f3d_old = bpy.context.scene.f3d_type == "F3D" self.is_f3dex2 = "F3DEX2" in bpy.context.scene.f3d_type self.build_default_geo() @@ -298,7 +300,7 @@ def inline_triGroup( tri_cmds = [c for c in tri_list.commands if type(c) == SP1Triangle or type(c) == SP2Triangles] if tri_cmds: reset_cmd_dict[DPPipeSync] = DPPipeSync() - [bleed_gfx_lists.add_reset_cmd(cmd, reset_cmd_dict) for cmd in bleed_gfx_lists.bled_mats] + [bleed_gfx_lists.add_reset_cmd(self.f3d, cmd, reset_cmd_dict) for cmd in bleed_gfx_lists.bled_mats] # pre processes cmd_list and removes cmds deemed useless. subclass and override if this causes a game specific issue def on_bleed_start(self, cmd_list: GfxList): @@ -524,7 +526,7 @@ class BleedGfxLists: bled_mats: GfxList = field(default_factory=list) bled_tex: GfxList = field(default_factory=list) - def add_reset_cmd(self, cmd: GbiMacro, reset_cmd_dict: dict[GbiMacro]): + def add_reset_cmd(self, f3d: F3D, cmd: GbiMacro, reset_cmd_dict: dict[GbiMacro]): reset_cmd_list = ( SPLoadGeometryMode, SPSetGeometryMode, @@ -533,7 +535,10 @@ def add_reset_cmd(self, cmd: GbiMacro, reset_cmd_dict: dict[GbiMacro]): ) # separate other mode H and othermode L if type(cmd) == SPSetOtherMode: - reset_cmd_dict[cmd.cmd] = cmd + if cmd.cmd in reset_cmd_dict: + reset_cmd_dict[cmd.cmd].add_diff(f3d, cmd) + else: + reset_cmd_dict[cmd.cmd] = copy.deepcopy(cmd) if type(cmd) in reset_cmd_list: reset_cmd_dict[type(cmd)] = cmd diff --git a/fast64_internal/f3d/f3d_gbi.py b/fast64_internal/f3d/f3d_gbi.py index 1eb5b7d80..ea290da6f 100644 --- a/fast64_internal/f3d/f3d_gbi.py +++ b/fast64_internal/f3d/f3d_gbi.py @@ -4329,6 +4329,17 @@ class SPSetOtherMode(GbiMacro): length: int flagList: list + def add_diff(self, f3d, other: SPSetOtherMode): + for flag in self.flagList.copy(): # remove any flag overriden by other + if (getattr(f3d, str(flag), flag) << other.sft) & other.length: + self.flagList.remove(flag) + # add other's flags + self.flagList = list(set(self.flagList + other.flagList)) + + min_max = min(self.sft, other.sft), max(self.sft, other.sft) + max(self.length, other.length) + self.sft = min_max[0] + self.length = min_max[1] - min_max[0] + def to_binary(self, f3d, segments): data = 0 for flag in self.flagList: