Skip to content

Commit c51e462

Browse files
authored
[SM64/F3D] Fix and update Ui Image Exporter (#452)
* [SM64/F3D] Fix and update Ui Image Exporter Fixes #451 Missing: Load and set commands and pallets (currently relying on multitex manager, will have to be changed somehow) Updated: Tex prop is now drawn using ui_image, ui_image has been updated to optionally hide low and high props (are handled by size cmd, does not exist for texrect) materialless_setup func for TexInfo, equivelant to moreSetupFromModel for bpy material-less contexts, obviously cannot handle flipbooks ignore_tex_set bool for fromProp Use only fromProp and updated writeAll Some basic ui reordering to match other panels * Fix noted issues, clean up code to be consistent, add tlut mode * use world defaults and saveModeSetting to remove revert code, remove extra syncs * close to being finished * refresh 13 memes * automatically pick 1 cycle instead of copy mode * Rasky confirmed ia16 tlut works for copy mode, cool * Revert "Rasky confirmed ia16 tlut works for copy mode, cool" This reverts commit 7fe981c. * [SM64/F3D] Fix and update Ui Image Exporter Updated: Tex prop is now drawn using ui_image, ui_image has been updated to optionally hide low and high props (are handled by size cmd, does not exist for texture rectangles) materialless_setup func for TexInfo, equivelant to moreSetupFromModel for bpy material-less contexts, obviously cannot handle flipbooks setup_single_tex func for TexInfo, sets up a single texture without the context of the multi texture manager ignore_tex_set bool for fromProp Use only fromProp and updated writeAll Use saveModeSetting (and world defaults) instead of manullay appending each DP command (except for blend color) Removed syncs except for the sync after the texrect cmd to do the reverts Removed deprecated arg for png exporting in save_textures (assumed from fimage) Removed the ) part of the delimiter checked when exporting "Menu", refresh 13 made it (void) instead of () Some basic ui reordering to match other panels Added 1 cycle variant for non rgba16 exports Fix dynamic dls * fix dsdx and dsdy * fix overwrite data issues could not deal with aligner and palletes, now can! * sauren nitpicks * fix first test * Update f3d_texture_writer.py * make the regex allow even more whitespace * fix extra new lines
1 parent a139743 commit c51e462

File tree

5 files changed

+156
-100
lines changed

5 files changed

+156
-100
lines changed

fast64_internal/f3d/f3d_gbi.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,6 +3285,10 @@ class FImage:
32853285
isLargeTexture: bool = field(init=False, compare=False, default=False)
32863286
converted: bool = field(init=False, compare=False, default=False)
32873287

3288+
@property
3289+
def aligner_name(self):
3290+
return f"{self.name}_aligner"
3291+
32883292
def size(self):
32893293
return len(self.data)
32903294

@@ -3303,7 +3307,7 @@ def to_c_helper(self, texData, bitsPerValue):
33033307

33043308
# This is to force 8 byte alignment
33053309
if bitsPerValue != 64:
3306-
code.source = f"Gfx {self.name}_aligner[] = {{gsSPEndDisplayList()}};\n"
3310+
code.source = f"Gfx {self.aligner_name}[] = {{gsSPEndDisplayList()}};\n"
33073311
code.source += f"u{str(bitsPerValue)} {self.name}[] = {{\n\t"
33083312
code.source += texData
33093313
code.source += "\n};\n\n"
@@ -3422,7 +3426,8 @@ def to_c(self, static=True):
34223426
if static:
34233427
return f"g{'s'*static}{type(self).__name__}({', '.join( self.getargs(static) )})"
34243428
else:
3425-
return f"g{'s'*static}{type(self).__name__}(glistp++, {', '.join( self.getargs(static) )})"
3429+
args = ["glistp++"] + list(self.getargs(static))
3430+
return f"g{'s'*static}{type(self).__name__}({', '.join( args )})"
34263431

34273432
def size(self, f3d):
34283433
return GFX_SIZE

fast64_internal/f3d/f3d_material.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,9 +2276,9 @@ def get_textlut_mode(f3d_mat: "F3DMaterialProperty", inherit_from_tex: bool = Fa
22762276
use_dict = all_combiner_uses(f3d_mat)
22772277
textures = [f3d_mat.tex0] if use_dict["Texture 0"] and f3d_mat.tex0.tex_set else []
22782278
textures += [f3d_mat.tex1] if use_dict["Texture 1"] and f3d_mat.tex1.tex_set else []
2279-
tlut_modes = [tex.ci_format if tex.tex_format.startswith("CI") else "NONE" for tex in textures]
2279+
tlut_modes = [tex.tlut_mode for tex in textures]
22802280
if tlut_modes and tlut_modes[0] == tlut_modes[-1]:
2281-
return "G_TT_" + tlut_modes[0]
2281+
return tlut_modes[0]
22822282
return None if inherit_from_tex else f3d_mat.rdp_settings.g_mdsft_textlut
22832283

22842284

@@ -2991,6 +2991,15 @@ class TextureProperty(PropertyGroup):
29912991
)
29922992
tile_scroll: bpy.props.PointerProperty(type=SetTileSizeScrollProperty)
29932993

2994+
@property
2995+
def is_ci(self):
2996+
self.tex_format: str
2997+
return self.tex_format.startswith("CI")
2998+
2999+
@property
3000+
def tlut_mode(self):
3001+
return f"G_TT_{self.ci_format if self.is_ci else 'NONE'}"
3002+
29943003
def get_tex_size(self) -> list[int]:
29953004
if self.tex or self.use_tex_reference:
29963005
if self.tex is not None:
@@ -3052,6 +3061,7 @@ def ui_image(
30523061
textureProp: TextureProperty,
30533062
name: str,
30543063
showCheckBox: bool,
3064+
hide_lowhigh=False,
30553065
):
30563066
inputGroup = layout.box().column()
30573067

@@ -3158,7 +3168,8 @@ def ui_image(
31583168
shift = prop_input.row()
31593169
shift.prop(textureProp.S, "shift", text="Shift S")
31603170
shift.prop(textureProp.T, "shift", text="Shift T")
3161-
3171+
if hide_lowhigh:
3172+
return
31623173
low = prop_input.row()
31633174
low.prop(textureProp.S, "low", text="S Low")
31643175
low.prop(textureProp.T, "low", text="T Low")

fast64_internal/f3d/f3d_texture_writer.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,10 @@ def fromMat(self, index: int, f3dMat: F3DMaterialProperty) -> bool:
420420
texProp = getattr(f3dMat, "tex" + str(index))
421421
return self.fromProp(texProp, index)
422422

423-
def fromProp(self, texProp: TextureProperty, index: int) -> bool:
423+
def fromProp(self, texProp: TextureProperty, index: int, ignore_tex_set=False) -> bool:
424424
self.indexInMat = index
425425
self.texProp = texProp
426-
if not texProp.tex_set:
426+
if not texProp.tex_set and not ignore_tex_set:
427427
return True
428428

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

464464
return True
465465

466+
def materialless_setup(self) -> None:
467+
"""moreSetupFromModel equivalent that does not handle material properties like OOT flipbooks"""
468+
if not self.useTex:
469+
return
470+
471+
if self.isTexCI:
472+
self.imDependencies, self.flipbook, self.pal = (
473+
[] if self.texProp.tex is None else [self.texProp.tex],
474+
None,
475+
None,
476+
)
477+
if self.isTexRef:
478+
self.palLen = self.texProp.pal_reference_size
479+
else:
480+
assert self.flipbook is None
481+
self.pal = getColorsUsedInImage(self.texProp.tex, self.palFormat)
482+
self.palLen = len(self.pal)
483+
if self.palLen > (16 if self.texFormat == "CI4" else 256):
484+
raise PluginError(
485+
f"Error in Texture {self.indexInMat} uses too many unique colors to fit in format {self.texFormat}."
486+
)
487+
else:
488+
self.imDependencies = [] if self.texProp.tex is None else [self.texProp.tex]
489+
self.flipbook = None
490+
491+
self.isPalRef = self.isTexRef and self.flipbook is None
492+
self.palDependencies = self.imDependencies
493+
466494
def moreSetupFromModel(
467495
self,
468496
material: bpy.types.Material,
@@ -504,6 +532,26 @@ def getPaletteName(self):
504532
return self.flipbook.name
505533
return getImageName(self.texProp.tex)
506534

535+
def setup_single_tex(self, is_ci: bool, use_large_tex: bool):
536+
is_large = False
537+
tmem_size = 256 if is_ci else 512
538+
if is_ci:
539+
assert self.useTex # should this be here?
540+
if self.useTex:
541+
self.loadPal = True
542+
self.palBaseName = self.getPaletteName()
543+
if self.tmemSize > tmem_size:
544+
if use_large_tex:
545+
self.doTexLoad = False
546+
return True
547+
elif not bpy.context.scene.ignoreTextureRestrictions:
548+
raise PluginError(
549+
"Textures are too big. Max TMEM size is 4k "
550+
"bytes, ex. 2 32x32 RGBA 16 bit textures.\n"
551+
"Note that texture width will be internally padded to 64 bit boundaries."
552+
)
553+
return is_large
554+
507555
def writeAll(
508556
self,
509557
fMaterial: FMaterial,
@@ -514,7 +562,7 @@ def writeAll(
514562
return
515563
assert (
516564
self.imDependencies is not None
517-
) # Must be set manually if didn't use moreSetupFromModel, e.g. ti.imDependencies = [tex]
565+
), "self.imDependencies is None, either moreSetupFromModel or materialless_setup must be called beforehand"
518566

519567
# Get definitions
520568
imageKey, fImage = saveOrGetTextureDefinition(
@@ -551,6 +599,9 @@ def writeAll(
551599
fModel.writeTexRefNonCITextures(self.flipbook, self.texFormat)
552600
else:
553601
if self.isTexCI:
602+
assert (
603+
self.pal is not None
604+
), "self.pal is None, either moreSetupFromModel or materialless_setup must be called beforehand"
554605
writeCITextureData(self.texProp.tex, fImage, self.pal, self.palFormat, self.texFormat)
555606
else:
556607
writeNonCITextureData(self.texProp.tex, fImage, self.texFormat)

0 commit comments

Comments
 (0)