Skip to content

Commit

Permalink
Implement geo modes and their parsing + added bleed support
Browse files Browse the repository at this point in the history
  • Loading branch information
Lilaa3 committed Jun 7, 2024
1 parent e936216 commit 45a1125
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 14 deletions.
15 changes: 8 additions & 7 deletions fast64_internal/f3d/f3d_bleed.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
SPLine3D,
SPLineW3D,
SP2Triangles,
SPNTrianglesInit_5b,
SP5bitTriangles,
SPNTrianglesInit_7b,
SP7bitTriangles,
SPCullDisplayList,
SPSegment,
SPBranchLessZraw,
Expand Down Expand Up @@ -48,6 +52,7 @@
GbiMacro,
)

TRI_CMDS = [SP2Triangles, SP1Triangle, SPLine3D, SPLineW3D, SPNTrianglesInit_5b, SP5bitTriangles, SPNTrianglesInit_7b, SP7bitTriangles]

class BleedGraphics:
# bleed_state "enums"
Expand Down Expand Up @@ -297,7 +302,7 @@ def inline_triGroup(
# add in triangles
cmd_list.commands.extend(tri_list.commands)
# skinned meshes don't draw tris sometimes, use this opportunity to save a sync
tri_cmds = [c for c in tri_list.commands if type(c) == SP1Triangle or type(c) == SP2Triangles]
tri_cmds = [c for c in tri_list.commands if type(c) in TRI_CMDS]
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]
Expand Down Expand Up @@ -423,10 +428,6 @@ def bleed_individual_cmd(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: in
SPViewport,
SPDisplayList,
SPBranchList,
SP1Triangle,
SPLine3D,
SPLineW3D,
SP2Triangles,
SPCullDisplayList,
SPSegment,
SPBranchLessZraw,
Expand All @@ -436,7 +437,7 @@ def bleed_individual_cmd(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: in
DPLoadBlock,
DPLoadTile,
DPLoadTLUTCmd,
DPFullSync,
DPFullSync, *TRI_CMDS
]:
return False

Expand Down Expand Up @@ -507,7 +508,7 @@ def bleed_between_tris(self, cmd_list: GfxList, cmd: GbiMacro, bleed_state: int,
for parse_cmd in cmd_list.commands:
if parse_cmd is cmd:
return tri_buffered
if type(parse_cmd) in [SP2Triangles, SP1Triangle, SPLine3D, SPLineW3D]:
if type(parse_cmd) in TRI_CMDS:
tri_buffered = False
continue
if type(parse_cmd) in conflict_cmds:
Expand Down
17 changes: 13 additions & 4 deletions fast64_internal/f3d/f3d_gbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def __init__(self, F3D_VER):
F3DEX_GBI_3 = self.F3DEX_GBI_3 = isUcodeF3DEX3(F3D_VER)
F3DLP_GBI = self.F3DLP_GBI = self.F3DEX_GBI
self.F3D_OLD_GBI = not (F3DEX_GBI or F3DEX_GBI_2 or F3DEX_GBI_3)
F3DZEX_AC_EXT = self.F3DZEX_AC_EXT = (F3D_VER == "F3DZEX (AC)")
F3DZEX_AC_EXT = self.F3DZEX_AC_EXT = F3D_VER == "F3DZEX (AC)"

# F3DEX2 is F3DEX1 and F3DEX3 is F3DEX2, but F3DEX3 is not F3DEX1
if F3DEX_GBI_2:
Expand Down Expand Up @@ -347,7 +347,7 @@ def __init__(self, F3D_VER):
self.G_DECAL_LEQUAL = 0x00000000
self.G_DECAL_GEQUAL = 0x00000010
self.G_DECAL_EQUAL = 0x00000020
self.G_DECAL_ALWAYS = 0x00000030
self.G_DECAL_ALWAYS = self.G_DECAL_GEQUAL | self.G_DECAL_LEQUAL
self.G_DECAL_SPECIAL = 0x00000040
self.G_DECAL_ALL = self.G_DECAL_ALWAYS | self.G_DECAL_SPECIAL
else:
Expand Down Expand Up @@ -392,6 +392,15 @@ def __init__(self, F3D_VER):
"G_FRESNEL_COLOR",
"G_FRESNEL_ALPHA",
}
elif F3DZEX_AC_EXT:
self.allGeomModeFlags |= {
"G_DECAL_LEQUAL",
"G_DECAL_GEQUAL",
"G_DECAL_EQUAL",
"G_DECAL_ALWAYS",
"G_DECAL_SPECIAL",
"G_DECAL_ALL",
}

self.G_FOG_H = self.G_FOG / 0x10000
self.G_LIGHTING_H = self.G_LIGHTING / 0x10000
Expand Down Expand Up @@ -3818,10 +3827,10 @@ def to_binary(self, f3d, segments):
words = (
(
_SHIFTL(gsSPNTriangleData2(self.v6, self.v7, self.v8, f3d), 11, 21)
| _SHIFTR(gsSPNTriangleData2(self.v3, self.v4, self.v5, f3d), 21 - 10, 10) # Upper 10 bits
| _SHIFTR(gsSPNTriangleData2(self.v3, self.v4, self.v5, f3d), 21 - 10, 10) # Upper 10 bits
),
(
_SHIFTL(gsSPNTriangleData2(self.v3, self.v4, self.v5, f3d), 32 - 11, 11) # Lower 11 bits
_SHIFTL(gsSPNTriangleData2(self.v3, self.v4, self.v5, f3d), 32 - 11, 11) # Lower 11 bits
| _SHIFTR(gsSPNTriangleData2(self.v0, self.v1, self.v2, f3d), 1, 21)
| _SHIFTL(f3d.G_VTX_MODE_7bit, 0, 1)
),
Expand Down
28 changes: 28 additions & 0 deletions fast64_internal/f3d/f3d_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,12 @@ def indentGroup(parent: UILayout, textOrProp: Union[str, "F3DMaterialProperty"],
elif blendWarnings and not shadeInBlender and settings.g_fog:
c.label(text="Fog not used in rendermode / blender, can disable.", icon="INFO")

if bpy.context.scene.f3d_type == "F3DZEX (AC)":
c = indentGroup(inputGroup, "Decals:", True)
c.prop(settings, "g_decal_gequal")
c.prop(settings, "g_decal_equal")
c.prop(settings, "g_decal_special")

if isF3DEX3:
c = indentGroup(inputGroup, "Attribute offsets:", True)
c.prop(settings, "g_attroffset_st_enable")
Expand Down Expand Up @@ -2999,6 +3005,25 @@ class RDPSettings(PropertyGroup):
update=update_node_values_with_preset,
description="F3DEX3: Enables offsets to vertex ST values, usually for UV scrolling",
)
# AC Decal Modes
g_decal_gequal: bpy.props.BoolProperty(
name="Greater or Equal",
default=False,
update=update_node_values_with_preset,
description="F3DZEX (AC): Render with a positive offset (closer to the camera) instead of the default negative offset", # TODO: Double check
)
g_decal_equal: bpy.props.BoolProperty(
name="Equal",
default=False,
update=update_node_values_with_preset,
description="F3DZEX (AC): Render with no offset", # TODO: Double check
)
g_decal_special: bpy.props.BoolProperty(
name="Special",
default=False,
update=update_node_values_with_preset,
description="F3DZEX (AC): ", # TODO: Write description
)
# v1/2 difference
g_cull_front: bpy.props.BoolProperty(
name="Cull Front",
Expand Down Expand Up @@ -3323,6 +3348,9 @@ def key(self):
return (
self.g_zbuffer,
self.g_shade,
self.g_decal_gequal,
self.g_decal_equal,
self.g_decal_special,
self.g_cull_front,
self.g_cull_back,
self.g_attroffset_st_enable,
Expand Down
17 changes: 17 additions & 0 deletions fast64_internal/f3d/f3d_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,13 @@ def setGeoFlags(self, command: "ParsedMacro", value: bool):
rdp_settings.g_fresnel_color = value
if bitFlags & self.f3d.G_FRESNEL_ALPHA:
rdp_settings.g_fresnel_alpha = value
elif self.f3d.F3DZEX_AC_EXT:
if bitFlags & self.f3d.G_DECAL_GEQUAL:
rdp_settings.g_decal_gequal = value
if bitFlags & self.f3d.G_DECAL_EQUAL:
rdp_settings.g_decal_equal = value
if bitFlags & self.f3d.G_DECAL_SPECIAL:
rdp_settings.g_decal_special = value
if bitFlags & self.f3d.G_FOG:
rdp_settings.g_fog = value
if bitFlags & self.f3d.G_LIGHTING:
Expand Down Expand Up @@ -939,6 +946,15 @@ def loadGeoFlags(self, command: "ParsedMacro"):
rdp_settings.g_lighting_specular = False
rdp_settings.g_fresnel_color = False
rdp_settings.g_fresnel_alpha = False
if self.f3d.F3DZEX_AC_EXT:
rdp_settings.g_gequal = bitFlags & self.f3d.G_DECAL_GEQUAL != 0
rdp_settings.g_equal = bitFlags & self.f3d.G_DECAL_EQUAL != 0
rdp_settings.g_decal_special = bitFlags & self.f3d.G_DECAL_SPECIAL != 0
else:
rdp_settings.g_gequal = False
rdp_settings.g_equal = False
rdp_settings.g_decal_special = False

rdp_settings.g_fog = bitFlags & self.f3d.G_FOG != 0
rdp_settings.g_lighting = bitFlags & self.f3d.G_LIGHTING != 0
rdp_settings.g_tex_gen = bitFlags & self.f3d.G_TEXTURE_GEN != 0
Expand Down Expand Up @@ -1551,6 +1567,7 @@ def processCommands(self, dlData: str, dlName: str, dlCommands: "list[ParsedMacr
self.addTriangle(command.params[0:3], dlData)
elif command.name == "gsSP2Triangles":
self.addTriangle(command.params[0:3] + command.params[4:7], dlData)
# TODO: Parse Animal Crossing's F3DZEX extended 5/7 bit tri commands
elif command.name == "gsSPDisplayList" or command.name.startswith("gsSPBranch"):
newDLName = self.processDLName(command.params[0])
if newDLName is not None:
Expand Down
10 changes: 7 additions & 3 deletions fast64_internal/f3d/f3d_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1233,9 +1233,9 @@ def createTriangleCommands(triangles, vertexBuffer, triConverterInfo):
def getIndices(*tris):
return [vertexBuffer.index(v) for tri in tris for v in tri]

def get_n_tris_indices(triangles: list, i: int, n: int): # Includes dummy data to fill out the command
def get_n_tris_indices(triangles: list, i: int, n: int): # Includes dummy data to fill out the command
if len(triangles) - i >= n:
return getIndices(*triangles[i:i+n])
return getIndices(*triangles[i : i + n])
indices = getIndices(*triangles[i:])
while len(indices) < n * 3:
indices.extend((0, 0, 0))
Expand All @@ -1251,7 +1251,7 @@ def get_n_tris_indices(triangles: list, i: int, n: int): # Includes dummy data t
commands.append(SPNTrianglesInit_5b(tri_5_bit_len, *get_n_tris_indices(triangles, t, 3)))
t += 3
while t < tri_5_bit_len:
commands.append(SP5bitTriangles( *get_n_tris_indices(triangles, t, 4)))
commands.append(SP5bitTriangles(*get_n_tris_indices(triangles, t, 4)))
t += 4
if left == 3:
commands.append(SPNTrianglesInit_5b(left, *get_n_tris_indices(triangles, t, 3)))
Expand Down Expand Up @@ -1630,6 +1630,10 @@ def saveGeoModeCommon(saveFunc: Callable, settings: RDPSettings, defaults: RDPSe
saveFunc(settings.g_lighting_specular, defaults.g_lighting_specular, "G_LIGHTING_SPECULAR", *args)
saveFunc(settings.g_fresnel_color, defaults.g_fresnel_color, "G_FRESNEL_COLOR", *args)
saveFunc(settings.g_fresnel_alpha, defaults.g_fresnel_alpha, "G_FRESNEL_ALPHA", *args)
elif bpy.context.scene.f3d_type == "F3DZEX (AC)":
saveFunc(settings.g_decal_gequal, defaults.g_decal_gequal, "G_DECAL_GEQUAL", *args)
saveFunc(settings.g_decal_equal, defaults.g_decal_equal, "G_DECAL_EQUAL", *args)
saveFunc(settings.g_decal_special, defaults.g_decal_special, "G_DECAL_SPECIAL", *args)
saveFunc(settings.g_fog, defaults.g_fog, "G_FOG", *args)
saveFunc(settings.g_lighting, defaults.g_lighting, "G_LIGHTING", *args)
saveFunc(settings.g_tex_gen, defaults.g_tex_gen, "G_TEXTURE_GEN", *args)
Expand Down

0 comments on commit 45a1125

Please sign in to comment.