Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
821c4c9
initial work on 8 texture slots (ui, flipbooks, code improvements, uv…
Lilaa3 Apr 19, 2025
4801a47
Merge remote-tracking branch 'upstream/main' into libdragon-texture-comp
Lilaa3 Apr 21, 2025
74533db
some more neat UI code for no load textures
Lilaa3 Apr 21, 2025
075f711
UI: dithering
Lilaa3 Apr 23, 2025
86dc202
pseudo fmt ui
Lilaa3 Apr 24, 2025
69a81d9
show forced for more props
Lilaa3 Apr 24, 2025
b2215a9
export fix
Lilaa3 Apr 24, 2025
749782f
i hate preventing recursion so much
Lilaa3 Apr 25, 2025
407cd33
speed ui, allow extra yuv case
Lilaa3 Apr 26, 2025
cc8a99d
speed ui, allow extra yuv case
Lilaa3 Apr 26, 2025
ae88496
speed ui, allow extra yuv case
Lilaa3 Apr 26, 2025
f4e28cb
some more UI opts, force 2 cycle for textures
Lilaa3 Apr 27, 2025
be3bb67
impl do not set other mode ui
Lilaa3 Apr 27, 2025
5c45437
use NONE for sm64 othermodes
Lilaa3 Apr 27, 2025
1e6cadb
rename properties for consistency
Lilaa3 Apr 27, 2025
d44c083
finish ui part
Lilaa3 Apr 27, 2025
87a0b90
fix typo (pt keyboard moment)
Lilaa3 May 17, 2025
ba800b2
check for tex1 instead of multitex
Lilaa3 May 17, 2025
9201705
texture tab
Lilaa3 May 17, 2025
d701bfe
first iter of placeholder under rdpq
Lilaa3 May 17, 2025
091cf2a
fix some rdpq conditions
Lilaa3 May 17, 2025
3c89cec
New experimental tex param UI
Lilaa3 May 19, 2025
03beddf
improve naming and add description for dither
Lilaa3 May 19, 2025
d10ce00
on export (dragorn suggestion)
Lilaa3 May 19, 2025
766860f
seperate slot for pal
Lilaa3 May 21, 2025
b817968
add not
Lilaa3 May 21, 2025
7fb7086
respect rdpq in nodes
Lilaa3 May 21, 2025
eee4760
ignored instead of infinite without autoprop
Lilaa3 May 21, 2025
633eedc
RendermodeBlender class
Lilaa3 May 21, 2025
375fcb3
othermode do not set code impl
Lilaa3 May 21, 2025
fade1e6
fix num_textures_mipmapped
Lilaa3 May 21, 2025
7bcb59f
fix repo settings
Lilaa3 May 21, 2025
53cc58f
Merge remote-tracking branch 'upstream/main' into libdragon-texture-comp
Lilaa3 May 21, 2025
180ad8b
write all in revert
Lilaa3 May 21, 2025
c7754db
Merge remote-tracking branch 'upstream/main' into libdragon-texture-comp
Lilaa3 May 27, 2025
8ae9f1a
Merge remote-tracking branch 'upstream/main' into libdragon-texture-comp
Lilaa3 May 30, 2025
fb2a91e
fix mode exports
Lilaa3 Jun 1, 2025
505bbf7
Merge remote-tracking branch 'upstream/main' into libdragon-texture-comp
Lilaa3 Aug 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 192 additions & 10 deletions fast64_internal/f3d/f3d_enums.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
from typing import NamedTuple


combiner_enums = {
"Case A": (
("COMBINED", "Combined Color", "Combined Color"),
Expand Down Expand Up @@ -147,12 +150,35 @@
"0": ("0", 0),
}

DO_NOT_SET = (
"NONE",
"Don't Set",
"In write different this means not attempting to set, in write all it means fetching the world default",
"X",
)


def add_do_not_set(enum_list: list[tuple[str, str, str]]):
if enum_list and len(enum_list[0]) <= 3:
index = len(enum_list)
else:
index = next((i for i, e in enumerate(enum_list) if e[3] != i), len(enum_list))
with_no_set = [(*DO_NOT_SET, index)] + [(*knd[:3], i) for i, knd in enumerate(enum_list)]

def run(self, context):
if getattr(context, "material", None) is None:
return enum_list
return with_no_set

return run


# hardware v2
enumAlphaDither = [
("G_AD_PATTERN", "Pattern", "Pattern"),
("G_AD_NOTPATTERN", "NOT Pattern", "NOT Pattern"),
("G_AD_NOISE", "Noise", "Noise"),
("G_AD_DISABLE", "Disable", "Disable"),
("G_AD_PATTERN", "Pattern", "Pattern", 0),
("G_AD_NOTPATTERN", "NOT Pattern", "NOT Pattern", 1),
("G_AD_NOISE", "Noise", "Noise", 2),
("G_AD_DISABLE", "Disable", "Disable", 3),
]

# hardware v2
Expand Down Expand Up @@ -343,19 +369,14 @@
("CI8", "Color Index 8-bit", "Color Index 8-bit"),
("RGBA16", "RGBA 16-bit", "RGBA 16-bit"),
("RGBA32", "RGBA 32-bit", "RGBA 32-bit"),
# ('YUV16','YUV 16-bit', 'YUV 16-bit'),
("YUV16", "YUV 16-bit", "YUV 16-bit"),
]

enumCIFormat = [
("RGBA16", "RGBA 16-bit", "RGBA 16-bit"),
("IA16", "Intensity Alpha 16-bit", "Intensity Alpha 16-bit"),
]

enumTexUV = [
("TEXEL0", "Texture 0", "Texture 0"),
("TEXEL1", "Texture 1", "Texture 1"),
]

texBitSizeInt = {
"I4": 4,
"IA4": 4,
Expand Down Expand Up @@ -455,3 +476,164 @@
("Segment", "Segment", "Call a segmented DL to set the tint, can change at runtime"),
("Light", "From Light", "Automatically load tint color from selectable light slot. Tint level stored in DL"),
]

bitSizeDict = {
"G_IM_SIZ_4b": 4,
"G_IM_SIZ_8b": 8,
"G_IM_SIZ_16b": 16,
"G_IM_SIZ_32b": 32,
}

texBitSizeF3D = {
"I4": "G_IM_SIZ_4b",
"IA4": "G_IM_SIZ_4b",
"CI4": "G_IM_SIZ_4b",
"I8": "G_IM_SIZ_8b",
"IA8": "G_IM_SIZ_8b",
"CI8": "G_IM_SIZ_8b",
"RGBA16": "G_IM_SIZ_16b",
"IA16": "G_IM_SIZ_16b",
"YUV16": "G_IM_SIZ_16b",
"RGBA32": "G_IM_SIZ_32b",
}

texFormatOf = {
"I4": "G_IM_FMT_I",
"IA4": "G_IM_FMT_IA",
"CI4": "G_IM_FMT_CI",
"I8": "G_IM_FMT_I",
"IA8": "G_IM_FMT_IA",
"CI8": "G_IM_FMT_CI",
"RGBA16": "G_IM_FMT_RGBA",
"IA16": "G_IM_FMT_IA",
"YUV16": "G_IM_FMT_YUV",
"RGBA32": "G_IM_FMT_RGBA",
}


sm64EnumDrawLayers = [
("0", "Background (0x00)", "Background"),
("1", "Opaque (0x01)", "Opaque"),
("2", "Opaque Decal (0x02)", "Opaque Decal"),
("3", "Opaque Intersecting (0x03)", "Opaque Intersecting"),
("4", "Cutout (0x04)", "Cutout"),
("5", "Transparent (0x05)", "Transparent"),
("6", "Transparent Decal (0x06)", "Transparent Decal"),
("7", "Transparent Intersecting (0x07)", "Transparent Intersecting"),
]

ootEnumDrawLayers = [
("Opaque", "Opaque", "Opaque"),
("Transparent", "Transparent", "Transparent"),
("Overlay", "Overlay", "Overlay"),
]


drawLayerSM64toOOT = {
"0": "Opaque",
"1": "Opaque",
"2": "Opaque",
"3": "Opaque",
"4": "Opaque",
"5": "Transparent",
"6": "Transparent",
"7": "Transparent",
}

drawLayerOOTtoSM64 = {
"Opaque": "1",
"Transparent": "5",
"Overlay": "1",
}

enumF3DSource = [
("None", "None", "None"),
("Texture", "Texture", "Texture"),
("Tile Size", "Tile Size", "Tile Size"),
("Primitive", "Primitive", "Primitive"),
("Environment", "Environment", "Environment"),
("Shade", "Shade", "Shade"),
("Key", "Key", "Key"),
("LOD Fraction", "LOD Fraction", "LOD Fraction"),
("Convert", "Convert", "Convert"),
]

defaultMaterialPresets = {
"Shaded Solid": {"SM64": "Shaded Solid", "OOT": "oot_shaded_solid"},
"Shaded Texture": {"SM64": "Shaded Texture", "OOT": "oot_shaded_texture"},
}

F3D_GEO_MODES = {
"zBuffer": "g_zbuffer",
"shade": "g_shade",
"cullFront": "g_cull_front",
"cullBack": "g_cull_back",
"fog": "g_fog",
"lighting": "g_lighting",
"texGen": "g_tex_gen",
"texGenLinear": "g_tex_gen_linear",
"lod": "g_lod",
"shadeSmooth": "g_shade_smooth",
}

F3DLX_GEO_MODES = {
"clipping": "g_clipping",
}

F3DEX3_GEO_MODES = {
"ambientOcclusion": "g_ambocclusion",
"attroffsetZ": "g_attroffset_z_enable",
"attroffsetST": "g_attroffset_st_enable",
"packedNormals": "g_packed_normals",
"lightToAlpha": "g_lighttoalpha",
"specularLighting": "g_lighting_specular",
"fresnelToColor": "g_fresnel_color",
"fresnelToAlpha": "g_fresnel_alpha",
}


T3D_GEO_MODES = {
"cullFront": "g_cull_front",
"cullBack": "g_cull_back",
"fog": "g_fog",
"texGen": "g_tex_gen",
}


class PropWithDefault(NamedTuple):
dict_name: str
default: str
name: str = ""


OTHERMODE_H_ATTRS = {
"g_mdsft_alpha_dither": PropWithDefault("alphaDither", "G_AD_DISABLE", "Alpha Dither"),
"g_mdsft_rgb_dither": PropWithDefault("colorDither", "G_CD_MAGICSQ", "RGB Dither"),
"g_mdsft_combkey": PropWithDefault("chromaKey", "G_CK_NONE", "Chroma Key"),
"g_mdsft_textconv": PropWithDefault("textureConvert", "G_TC_CONV", "Texture Convert"),
"g_mdsft_text_filt": PropWithDefault("textureFilter", "G_TF_POINT", "Texture Filter"),
"g_mdsft_textlut": PropWithDefault("lutFormat", "G_TT_NONE", "Texture LUT"),
"g_mdsft_textlod": PropWithDefault("textureLoD", "G_TL_TILE", "Texture LoD"),
"g_mdsft_textdetail": PropWithDefault("textureDetail", "G_TD_CLAMP", "Texture Detail"),
"g_mdsft_textpersp": PropWithDefault("perspectiveCorrection", "G_TP_NONE", "Texture Perspective Correction"),
"g_mdsft_cycletype": PropWithDefault("cycleType", "G_CYC_1CYCLE", "Cycle Type"),
"g_mdsft_pipeline": PropWithDefault("pipelineMode", "G_PM_NPRIMITIVE", "Pipeline Span Buffer Coherency"),
}

OTHERMODE_L_ATTRS = {
"g_mdsft_alpha_compare": PropWithDefault("alphaCompare", "G_AC_NONE", "Alpha Compare"),
"g_mdsft_zsrcsel": PropWithDefault("zSourceSelection", "G_ZS_PIXEL", "Z Source Selection"),
}

RENDERMODE_FLAG_ATTRS = {
"aa_en": PropWithDefault("aa", False),
"z_cmp": PropWithDefault("zTest", False),
"z_upd": PropWithDefault("zWrite", False),
"clr_on_cvg": PropWithDefault("colorOnCvg", False),
"alpha_cvg_sel": PropWithDefault("alphaOnCvg", False),
"cvg_x_alpha": PropWithDefault("mulCvgXAlpha", False),
"force_bl": PropWithDefault("forceBlend", False),
"im_rd": PropWithDefault("readFB", False),
"cvg_dst": PropWithDefault("cvgDst", "CVG_DST_CLAMP"),
"zmode": PropWithDefault("zMode", "ZMODE_OPA"),
}
65 changes: 30 additions & 35 deletions fast64_internal/f3d/f3d_gbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ def __init__(self, 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)
self.F3D_GBI = is_ucode_f3d(F3D_VER)
self.RDPQ = not self.F3D_GBI

# F3DEX2 is F3DEX1 and F3DEX3 is F3DEX2, but F3DEX3 is not F3DEX1
if F3DEX_GBI_2:
Expand Down Expand Up @@ -1892,7 +1893,7 @@ def get_tex_sts_code(
def get_tile_scroll_code(
variableName: str, scrollData: "FScrollData", textureIndex: int, commandIndex: int
) -> Tuple[str, str]:
scrollInfo: FSetTileSizeScrollField = getattr(scrollData, f"tile_scroll_tex{textureIndex}")
scrollInfo: FSetTileSizeScrollField = scrollData.tile_scrolls[textureIndex]
if scrollInfo.s or scrollInfo.t:
variables = []
lines = []
Expand All @@ -1914,7 +1915,7 @@ def get_tile_scroll_code(
def vertexScrollTemplate(
fScrollData, name, count, absFunc, signFunc, cosFunc, randomFloatFunc, randomSignFunc, segToVirtualFunc
):
scrollDataFields = fScrollData.fields[0]
scrollDataFields = fScrollData.fields
if scrollDataFields[0].animType == "None" and scrollDataFields[1].animType == "None":
return ""
data = [
Expand Down Expand Up @@ -2369,7 +2370,7 @@ def processTexRefNonCITextures(self, fMaterial: FMaterial, material: bpy.types.M
image), for creating image / palette keys
- an object containing info about the additional textures, or None
"""
texProp = getattr(material.f3d_mat, f"tex{index}")
texProp = material.f3d_mat.all_textures[index]
imDependencies = set() if texProp.tex is None else {texProp.tex}
return imDependencies, None

Expand All @@ -2389,7 +2390,7 @@ def processTexRefCITextures(self, fMaterial: FMaterial, material: bpy.types.Mate
- an object containing info about the additional textures, or None
- the palette to use (or None)
"""
texProp = getattr(material.f3d_mat, f"tex{index}")
texProp = material.f3d_mat.all_textures[index]
imDependencies = set() if texProp.tex is None else {texProp.tex}
return imDependencies, None, None

Expand Down Expand Up @@ -3006,10 +3007,9 @@ def __init__(self):

class FScrollData:
def __init__(self):
self.fields = [[FScrollDataField(), FScrollDataField()], [FScrollDataField(), FScrollDataField()]]
self.fields = [FScrollDataField(), FScrollDataField()]
self.dimensions = [0, 0]
self.tile_scroll_tex0 = FSetTileSizeScrollField()
self.tile_scroll_tex1 = FSetTileSizeScrollField()
self.tile_scrolls: list[FSetTileSizeScrollField] = []


def get_f3d_mat_from_version(material: bpy.types.Material):
Expand Down Expand Up @@ -3040,25 +3040,16 @@ def __init__(self, name, DLFormat):
self.texPaletteIndex = [0, 0]

def getScrollData(self, material, dimensions):
self.getScrollDataField(material, 0, 0)
self.getScrollDataField(material, 0, 1)
self.getScrollDataField(material, 1, 0)
self.getScrollDataField(material, 1, 1)
self.getScrollDataField(material, 0)
self.getScrollDataField(material, 1)
self.scrollData.dimensions = dimensions
self.getSetTileSizeScrollData(material)

def getScrollDataField(self, material, texIndex, fieldIndex):
UVanim0 = material.f3d_mat.UVanim0 if material.mat_ver > 3 else material.UVanim
UVanim1 = material.f3d_mat.UVanim1 if material.mat_ver > 3 else material.UVanim_tex1
def getScrollDataField(self, material, fieldIndex):
UVanim0 = material.f3d_mat.UVanim0
field = getattr(UVanim0, "xyz"[fieldIndex])

if texIndex == 0:
field = getattr(UVanim0, "xyz"[fieldIndex])
elif texIndex == 1:
field = getattr(UVanim1, "xyz"[fieldIndex])
else:
raise PluginError("Invalid texture index.")

scrollField = self.scrollData.fields[texIndex][fieldIndex]
scrollField = self.scrollData.fields[fieldIndex]

scrollField.animType = field.animType
scrollField.speed = field.speed
Expand All @@ -3071,13 +3062,13 @@ def getScrollDataField(self, material, texIndex, fieldIndex):
def getSetTileSizeScrollData(self, material):
tex0 = get_f3d_mat_from_version(material).tex0
tex1 = get_f3d_mat_from_version(material).tex1

self.scrollData.tile_scroll_tex0.s = tex0.tile_scroll.s
self.scrollData.tile_scroll_tex0.t = tex0.tile_scroll.t
self.scrollData.tile_scroll_tex0.interval = tex0.tile_scroll.interval
self.scrollData.tile_scroll_tex1.s = tex1.tile_scroll.s
self.scrollData.tile_scroll_tex1.t = tex1.tile_scroll.t
self.scrollData.tile_scroll_tex1.interval = tex1.tile_scroll.interval
self.scrollData.tile_scrolls = []
for tex_prop in material.f3d_mat.all_textures:
tile_scroll = FSetTileSizeScrollField()
tile_scroll.s = tex_prop.tile_scroll.s
tile_scroll.t = tex_prop.tile_scroll.t
tile_scroll.interval = tex_prop.tile_scroll.interval
self.scrollData.tile_scrolls.append(tile_scroll)

def get_ptr_addresses(self, f3d):
addresses = self.material.get_ptr_addresses(f3d)
Expand Down Expand Up @@ -4355,7 +4346,7 @@ class RendermodeBlender:
cycle1: tuple
cycle2: tuple

def __str__(self):
def __str__(self) -> str:
return f"GBL_c1({', '.join(self.cycle1)}) | GBL_c2({', '.join(self.cycle2)})"

def to_c(self, _static=True):
Expand Down Expand Up @@ -4402,7 +4393,10 @@ def add_other(self, f3d, other: SPSetOtherMode):
def to_binary(self, f3d, segments):
data = 0
for flag in self.flagList:
data |= getattr(f3d, str(flag), flag)
if hasattr(flag, "to_binary"):
data |= flag.to_binary(f3d)
else:
data |= getattr(f3d, str(flag), flag)
cmd = getattr(f3d, str(self.cmd), self.cmd)
sft = getattr(f3d, str(self.sft), self.sft)
return gsSPSetOtherMode(cmd, sft, self.length, data, f3d)
Expand Down Expand Up @@ -4604,11 +4598,12 @@ def GBL_c2(m1a, m1b, m2a, m2b):
class DPSetRenderMode(GbiMacro):
flagList: set[str]
blender: Optional[RendermodeBlender] = None
# bl0-3 are string for each blender enum

@property
def use_preset(self):
return self.blender is None
# bl0-3 are string for each blender enum
def __init__(self, flagList, blender: Optional[RendermodeBlender] = None):
self.flagList = flagList
self.use_preset = blender is None
self.blender = blender

def to_binary(self, f3d, segments):
flagWord = renderFlagListToWord(self.flagList, f3d)
Expand Down
Loading