Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SM64/F3D] Fix and update Ui Image Exporter #452

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 7 additions & 2 deletions fast64_internal/f3d/f3d_gbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3262,6 +3262,10 @@ class FImage:
isLargeTexture: bool = field(init=False, compare=False, default=False)
converted: bool = field(init=False, compare=False, default=False)

@property
def aligner_name(self):
return f"{self.name}_aligner"

def size(self):
return len(self.data)

Expand All @@ -3280,7 +3284,7 @@ def to_c_helper(self, texData, bitsPerValue):

# This is to force 8 byte alignment
if bitsPerValue != 64:
code.source = f"Gfx {self.name}_aligner[] = {{gsSPEndDisplayList()}};\n"
code.source = f"Gfx {self.aligner_name}[] = {{gsSPEndDisplayList()}};\n"
code.source += f"u{str(bitsPerValue)} {self.name}[] = {{\n\t"
code.source += texData
code.source += "\n};\n\n"
Expand Down Expand Up @@ -3399,7 +3403,8 @@ def to_c(self, static=True):
if static:
return f"g{'s'*static}{type(self).__name__}({', '.join( self.getargs(static) )})"
else:
return f"g{'s'*static}{type(self).__name__}(glistp++, {', '.join( self.getargs(static) )})"
args = ["glistp++"] + list(self.getargs(static))
return f"g{'s'*static}{type(self).__name__}({', '.join( args )})"

def size(self, f3d):
return GFX_SIZE
Expand Down
17 changes: 14 additions & 3 deletions fast64_internal/f3d/f3d_material.py
Original file line number Diff line number Diff line change
Expand Up @@ -2143,9 +2143,9 @@ def get_textlut_mode(f3d_mat: "F3DMaterialProperty", inherit_from_tex: bool = Fa
use_dict = all_combiner_uses(f3d_mat)
textures = [f3d_mat.tex0] if use_dict["Texture 0"] and f3d_mat.tex0.tex_set else []
textures += [f3d_mat.tex1] if use_dict["Texture 1"] and f3d_mat.tex1.tex_set else []
tlut_modes = [tex.ci_format if tex.tex_format.startswith("CI") else "NONE" for tex in textures]
tlut_modes = [tex.tlut_mode for tex in textures]
if tlut_modes and tlut_modes[0] == tlut_modes[-1]:
return "G_TT_" + tlut_modes[0]
return tlut_modes[0]
return None if inherit_from_tex else f3d_mat.rdp_settings.g_mdsft_textlut


Expand Down Expand Up @@ -2858,6 +2858,15 @@ class TextureProperty(PropertyGroup):
)
tile_scroll: bpy.props.PointerProperty(type=SetTileSizeScrollProperty)

@property
def is_ci(self):
self.tex_format: str
return self.tex_format.startswith("CI")

@property
def tlut_mode(self):
return f"G_TT_{self.ci_format if self.is_ci else 'NONE'}"

def get_tex_size(self) -> list[int]:
if self.tex or self.use_tex_reference:
if self.tex is not None:
Expand Down Expand Up @@ -2919,6 +2928,7 @@ def ui_image(
textureProp: TextureProperty,
name: str,
showCheckBox: bool,
hide_lowhigh=False,
):
inputGroup = layout.box().column()

Expand Down Expand Up @@ -3025,7 +3035,8 @@ def ui_image(
shift = prop_input.row()
shift.prop(textureProp.S, "shift", text="Shift S")
shift.prop(textureProp.T, "shift", text="Shift T")

if hide_lowhigh:
return
low = prop_input.row()
low.prop(textureProp.S, "low", text="S Low")
low.prop(textureProp.T, "low", text="T Low")
Expand Down
57 changes: 54 additions & 3 deletions fast64_internal/f3d/f3d_texture_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,10 @@ def fromMat(self, index: int, f3dMat: F3DMaterialProperty) -> bool:
texProp = getattr(f3dMat, "tex" + str(index))
return self.fromProp(texProp, index)

def fromProp(self, texProp: TextureProperty, index: int) -> bool:
def fromProp(self, texProp: TextureProperty, index: int, ignore_tex_set=False) -> bool:
self.indexInMat = index
self.texProp = texProp
if not texProp.tex_set:
if not texProp.tex_set and not ignore_tex_set:
return True

self.useTex = True
Expand Down Expand Up @@ -463,6 +463,34 @@ def fromProp(self, texProp: TextureProperty, index: int) -> bool:

return True

def materialless_setup(self) -> None:
"""moreSetupFromModel equivalent that does not handle material properties like OOT flipbooks"""
if not self.useTex:
return

if self.isTexCI:
self.imDependencies, self.flipbook, self.pal = (
[] if self.texProp.tex is None else [self.texProp.tex],
None,
None,
)
if self.isTexRef:
self.palLen = self.texProp.pal_reference_size
else:
assert self.flipbook is None
self.pal = getColorsUsedInImage(self.texProp.tex, self.palFormat)
self.palLen = len(self.pal)
if self.palLen > (16 if self.texFormat == "CI4" else 256):
raise PluginError(
f"Error in Texture {self.indexInMat} uses too many unique colors to fit in format {self.texFormat}."
)
else:
self.imDependencies = [] if self.texProp.tex is None else [self.texProp.tex]
self.flipbook = None

self.isPalRef = self.isTexRef and self.flipbook is None
self.palDependencies = self.imDependencies

def moreSetupFromModel(
self,
material: bpy.types.Material,
Expand Down Expand Up @@ -504,6 +532,26 @@ def getPaletteName(self):
return self.flipbook.name
return getImageName(self.texProp.tex)

def setup_single_tex(self, is_ci: bool, use_large_tex: bool):
is_large = False
tmem_size = 256 if is_ci else 512
if is_ci:
assert self.useTex # should this be here?
if self.useTex:
self.loadPal = True
self.palBaseName = self.getPaletteName()
if self.tmemSize > tmem_size:
if use_large_tex:
self.doTexLoad = False
return True
elif not bpy.context.scene.ignoreTextureRestrictions:
raise PluginError(
"Textures are too big. Max TMEM size is 4k "
"bytes, ex. 2 32x32 RGBA 16 bit textures.\n"
"Note that texture width will be internally padded to 64 bit boundaries."
)
return is_large

def writeAll(
self,
fMaterial: FMaterial,
Expand All @@ -514,7 +562,7 @@ def writeAll(
return
assert (
self.imDependencies is not None
) # Must be set manually if didn't use moreSetupFromModel, e.g. ti.imDependencies = [tex]
), "self.imDependencies is None, either moreSetupFromModel or materialless_setup must be called beforehand"

# Get definitions
imageKey, fImage = saveOrGetTextureDefinition(
Expand Down Expand Up @@ -551,6 +599,9 @@ def writeAll(
fModel.writeTexRefNonCITextures(self.flipbook, self.texFormat)
else:
if self.isTexCI:
assert (
self.pal is not None
), "self.pal is None, either moreSetupFromModel or materialless_setup must be called beforehand"
writeCITextureData(self.texProp.tex, fImage, self.pal, self.palFormat, self.texFormat)
else:
writeNonCITextureData(self.texProp.tex, fImage, self.texFormat)
Expand Down
Loading
Loading