[SM64] Bring more props to combined and merge level enums (#512)

There is only one level enum (which I took the time to organize), binary will simply error out with Custom (tho it is not fully out of the possibility to support custom levels in binary in the future), upgrade code added.
Dl and animation now share props with combined, animation rework actually uses these but for now both just redraw the prop to keep the ui the same.
Imports and address converter left untouched besides enum change, these should not be per scene.
Convert to str in getPathAndLevel to avoid issues with posix paths -> abspath

Alternatively, should this be just a pr for level enums?
Closes #498
This commit is contained in:
Lila
2025-08-15 14:17:25 -04:00
committed by GitHub
parent 6dd14a0d8b
commit aff23e0ef5
12 changed files with 224 additions and 264 deletions
+27 -11
View File
@@ -7,8 +7,15 @@ from bpy.path import abspath
from bpy.utils import register_class, unregister_class
from ...render_settings import on_update_render_settings
from ...utility import directory_path_checks, directory_ui_warnings, prop_split, set_prop_if_in_data, upgrade_old_prop
from ..sm64_constants import defaultExtendSegment4
from ...utility import (
directory_path_checks,
directory_ui_warnings,
prop_split,
set_prop_if_in_data,
upgrade_old_prop,
get_first_set_prop,
)
from ..sm64_constants import defaultExtendSegment4, OLD_BINARY_LEVEL_ENUMS
from ..sm64_objects import SM64_CombinedObjectProperties
from ..sm64_utility import export_rom_ui_warnings, import_rom_ui_warnings
from ..tools import SM64_AddrConvProperties
@@ -33,7 +40,7 @@ class SM64_Properties(PropertyGroup):
"""Global SM64 Scene Properties found under scene.fast64.sm64"""
version: IntProperty(name="SM64_Properties Version", default=0)
cur_version = 4 # version after property migration
cur_version = 5 # version after property migration
# UI Selection
show_importing_menus: BoolProperty(name="Show Importing Menus", default=False)
@@ -114,16 +121,22 @@ class SM64_Properties(PropertyGroup):
"exportType": "export_type",
}
old_export_props_to_new = {
"custom_group_name": {"geoLevelName", "colLevelName", "animLevelName"},
"custom_export_path": {"geoExportPath", "colExportPath", "animExportPath"},
"custom_level_name": {"levelName", "geoLevelName", "colLevelName", "animLevelName", "DLLevelName"},
"custom_export_path": {"geoExportPath", "colExportPath", "animExportPath", "DLExportPath"},
"object_name": {"geoName", "colName", "animName"},
"group_name": {"geoGroupName", "colGroupName", "animGroupName"},
"level_name": {"levelOption", "geoLevelOption", "colLevelOption", "animLevelOption"},
"custom_level_name": {"levelName", "geoLevelName", "colLevelName", "animLevelName"},
"group_name": {"geoGroupName", "colGroupName", "animGroupName", "DLGroupName"},
"level_name": {"levelOption", "geoLevelOption", "colLevelOption", "animLevelOption", "DLLevelOption"},
"non_decomp_level": {"levelCustomExport"},
"export_header_type": {"geoExportHeaderType", "colExportHeaderType", "animExportHeaderType"},
"custom_include_directory": {"geoTexDir"},
"export_header_type": {
"geoExportHeaderType",
"colExportHeaderType",
"animExportHeaderType",
"DLExportHeaderType",
},
"custom_include_directory": {"geoTexDir", "DLTexDir"},
}
binary_level_names = {"levelAnimExport", "colExportLevel", "levelDLExport", "levelGeoExport"}
old_custom_props = {"animCustomExport", "colCustomExport", "geoCustomExport", "DLCustomExport"}
for scene in bpy.data.scenes:
sm64_props: SM64_Properties = scene.fast64.sm64
sm64_props.address_converter.upgrade_changed_props(scene)
@@ -144,9 +157,12 @@ class SM64_Properties(PropertyGroup):
upgrade_old_prop(sm64_props, new, scene, old)
upgrade_old_prop(sm64_props, "show_importing_menus", sm64_props, "showImportingMenus")
combined_props = scene.fast64.sm64.combined_export
combined_props: SM64_CombinedObjectProperties = sm64_props.combined_export
for new, old in old_export_props_to_new.items():
upgrade_old_prop(combined_props, new, scene, old)
if get_first_set_prop(combined_props, old_custom_props):
combined_props.export_header_type = "Custom"
upgrade_old_prop(combined_props, "level_name", scene, binary_level_names, old_enum=OLD_BINARY_LEVEL_ENUMS)
sm64_props.version = SM64_Properties.cur_version
def to_repo_settings(self):
+30 -42
View File
@@ -2,7 +2,7 @@ from pathlib import Path
import bpy, os, copy, shutil, mathutils, math
from bpy.utils import register_class, unregister_class
from ..panels import SM64_Panel
from .sm64_level_parser import parseLevelAtPointer
from .sm64_level_parser import parse_level_binary
from .sm64_rom_tweaks import ExtendBank0x04
from .sm64_geolayout_bone import animatableBoneTypes
@@ -33,15 +33,12 @@ from ..utility import (
makeWriteInfoBox,
writeBoxExportType,
stashActionInArmature,
enumExportHeaderType,
)
from .sm64_constants import (
bank0Segment,
insertableBinaryTypes,
level_pointers,
defaultExtendSegment4,
level_enums,
enumLevelNames,
marioAnimations,
)
@@ -706,6 +703,7 @@ class SM64_ExportAnimMario(bpy.types.Operator):
def execute(self, context):
romfileOutput = None
tempROM = None
props = context.scene.fast64.sm64.combined_export
try:
if len(context.selected_objects) == 0 or not isinstance(
context.selected_objects[0].data, bpy.types.Armature
@@ -726,21 +724,21 @@ class SM64_ExportAnimMario(bpy.types.Operator):
if context.scene.fast64.sm64.export_type == "C":
exportPath, levelName = getPathAndLevel(
context.scene.animCustomExport,
context.scene.animExportPath,
context.scene.animLevelName,
context.scene.animLevelOption,
props.is_actor_custom_export,
props.actor_custom_path,
props.export_level_name,
props.level_name,
)
if not context.scene.animCustomExport:
if not props.is_actor_custom_export:
applyBasicTweaks(exportPath)
exportAnimationC(
armatureObj,
context.scene.loopAnimation,
exportPath,
bpy.context.scene.animName,
bpy.context.scene.animGroupName,
context.scene.animCustomExport,
context.scene.animExportHeaderType,
props.actor_group_name,
props.is_actor_custom_export,
props.export_header_type,
levelName,
)
self.report({"INFO"}, "Success!")
@@ -761,7 +759,7 @@ class SM64_ExportAnimMario(bpy.types.Operator):
romfileOutput = open(bpy.path.abspath(tempROM), "rb+")
# Note actual level doesn't matter for Mario, since he is in all of them
levelParsed = parseLevelAtPointer(romfileOutput, level_pointers[context.scene.levelAnimExport])
levelParsed = parse_level_binary(romfileOutput, props.level_name)
segmentData = levelParsed.segmentData
if context.scene.fast64.sm64.extend_bank_4:
ExtendBank0x04(romfileOutput, segmentData, defaultExtendSegment4)
@@ -855,34 +853,36 @@ class SM64_ExportAnimPanel(SM64_Panel):
# called every frame
def draw(self, context):
col = self.layout.column()
props = context.scene.fast64.sm64.combined_export
propsAnimExport = col.operator(SM64_ExportAnimMario.bl_idname)
col.prop(context.scene, "loopAnimation")
if context.scene.fast64.sm64.export_type == "C":
col.prop(context.scene, "animCustomExport")
if context.scene.animCustomExport:
prop_split(col, props, "export_header_type", "Export Type")
if props.is_actor_custom_export:
col.prop(context.scene, "animExportPath")
prop_split(col, context.scene, "animName", "Name")
customExportWarning(col)
else:
prop_split(col, context.scene, "animExportHeaderType", "Export Type")
prop_split(col, context.scene, "animName", "Name")
if context.scene.animExportHeaderType == "Actor":
prop_split(col, context.scene, "animGroupName", "Group Name")
elif context.scene.animExportHeaderType == "Level":
prop_split(col, context.scene, "animLevelOption", "Level")
if context.scene.animLevelOption == "Custom":
prop_split(col, context.scene, "animLevelName", "Level Name")
if props.export_header_type == "Actor":
prop_split(col, props, "group_name", "Group")
if props.group_name == "Custom":
prop_split(col, props, "custom_group_name", "Group Name")
elif props.export_header_type == "Level":
prop_split(col, props, "level_name", "Level")
if props.level_name == "Custom":
prop_split(col, props, "custom_level_name", "Level Name")
decompFolderMessage(col)
writeBox = makeWriteInfoBox(col)
writeBoxExportType(
writeBox,
context.scene.animExportHeaderType,
props.export_header_type,
context.scene.animName,
context.scene.animLevelName,
context.scene.animLevelOption,
props.export_level_name,
props.level_name,
)
elif context.scene.fast64.sm64.export_type == "Insertable Binary":
@@ -903,7 +903,7 @@ class SM64_ExportAnimPanel(SM64_Panel):
col.prop(context.scene, "overwrite_0x28")
if context.scene.overwrite_0x28:
prop_split(col, context.scene, "addr_0x28", "28 Command Address")
col.prop(context.scene, "levelAnimExport")
prop_split(col, props, "level_name", "Level")
col.separator()
prop_split(col, context.scene, "animExportStart", "Start Address")
prop_split(col, context.scene, "animExportEnd", "End Address")
@@ -925,7 +925,7 @@ class SM64_ImportAnimMario(bpy.types.Operator):
raisePluginError(self, e)
return {"CANCELLED"}
try:
levelParsed = parseLevelAtPointer(romfileSrc, level_pointers[context.scene.levelAnimImport])
levelParsed = parse_level_binary(romfileSrc, context.scene.levelAnimImport)
segmentData = levelParsed.segmentData
animStart = int(context.scene.animStartImport, 16)
@@ -1049,8 +1049,9 @@ def sm64_anim_register():
bpy.types.Scene.isDMAExport = bpy.props.BoolProperty(name="Is DMA Animation")
bpy.types.Scene.DMAEntryAddress = bpy.props.StringProperty(name="DMA Entry Address", default="4EC008")
bpy.types.Scene.DMAStartAddress = bpy.props.StringProperty(name="DMA Start Address", default="4EC000")
bpy.types.Scene.levelAnimImport = bpy.props.EnumProperty(items=level_enums, name="Level", default="IC")
bpy.types.Scene.levelAnimExport = bpy.props.EnumProperty(items=level_enums, name="Level", default="IC")
bpy.types.Scene.levelAnimImport = bpy.props.EnumProperty(
items=enumLevelNames, name="Level", default="castle_inside"
)
bpy.types.Scene.loopAnimation = bpy.props.BoolProperty(name="Loop Animation", default=True)
bpy.types.Scene.setAnimListIndex = bpy.props.BoolProperty(name="Set Anim List Entry", default=True)
bpy.types.Scene.overwrite_0x28 = bpy.props.BoolProperty(name="Overwrite 0x28 behaviour command", default=True)
@@ -1064,14 +1065,7 @@ def sm64_anim_register():
bpy.types.Scene.animListIndexImport = bpy.props.IntProperty(name="Anim List Index", min=0, max=255)
bpy.types.Scene.animListIndexExport = bpy.props.IntProperty(name="Anim List Index", min=0, max=255)
bpy.types.Scene.animName = bpy.props.StringProperty(name="Name", default="mario")
bpy.types.Scene.animGroupName = bpy.props.StringProperty(name="Group Name", default="group0")
bpy.types.Scene.animWriteHeaders = bpy.props.BoolProperty(name="Write Headers For Actor", default=True)
bpy.types.Scene.animCustomExport = bpy.props.BoolProperty(name="Custom Export Path")
bpy.types.Scene.animExportHeaderType = bpy.props.EnumProperty(
items=enumExportHeaderType, name="Header Export", default="Actor"
)
bpy.types.Scene.animLevelName = bpy.props.StringProperty(name="Level", default="bob")
bpy.types.Scene.animLevelOption = bpy.props.EnumProperty(items=enumLevelNames, name="Level", default="bob")
def sm64_anim_unregister():
@@ -1082,7 +1076,6 @@ def sm64_anim_unregister():
del bpy.types.Scene.animExportStart
del bpy.types.Scene.animExportEnd
del bpy.types.Scene.levelAnimImport
del bpy.types.Scene.levelAnimExport
del bpy.types.Scene.isDMAImport
del bpy.types.Scene.isDMAExport
del bpy.types.Scene.DMAStartAddress
@@ -1100,9 +1093,4 @@ def sm64_anim_unregister():
del bpy.types.Scene.animListIndexImport
del bpy.types.Scene.animListIndexExport
del bpy.types.Scene.animName
del bpy.types.Scene.animGroupName
del bpy.types.Scene.animWriteHeaders
del bpy.types.Scene.animCustomExport
del bpy.types.Scene.animExportHeaderType
del bpy.types.Scene.animLevelName
del bpy.types.Scene.animLevelOption
+5 -19
View File
@@ -2,16 +2,10 @@ from pathlib import Path
import bpy, shutil, os, math, mathutils
from bpy.utils import register_class, unregister_class
from io import BytesIO
from .sm64_constants import (
level_enums,
level_pointers,
enumLevelNames,
insertableBinaryTypes,
defaultExtendSegment4,
)
from .sm64_constants import insertableBinaryTypes, defaultExtendSegment4
from .sm64_utility import export_rom_checks, to_include_descriptor, update_actor_includes, write_or_delete_if_found
from .sm64_objects import SM64_Area, start_process_sm64_objects
from .sm64_level_parser import parseLevelAtPointer
from .sm64_level_parser import parse_level_binary
from .sm64_rom_tweaks import ExtendBank0x04
from ..panels import SM64_Panel
@@ -33,11 +27,6 @@ from ..utility import (
tempName,
bytesToHex,
applyRotation,
customExportWarning,
decompFolderMessage,
makeWriteInfoBox,
writeBoxExportType,
enumExportHeaderType,
selectSingleObject,
)
@@ -529,7 +518,7 @@ class SM64_ExportCollision(bpy.types.Operator):
romfileExport.close()
romfileOutput = open(bpy.path.abspath(tempROM), "rb+")
levelParsed = parseLevelAtPointer(romfileOutput, level_pointers[context.scene.colExportLevel])
levelParsed = parse_level_binary(romfileOutput, props.level_name)
segmentData = levelParsed.segmentData
if context.scene.fast64.sm64.extend_bank_4:
@@ -598,6 +587,7 @@ class SM64_ExportCollisionPanel(SM64_Panel):
def draw(self, context):
col = self.layout.column()
propsColE = col.operator(SM64_ExportCollision.bl_idname)
props = context.scene.fast64.sm64.combined_export
col.prop(context.scene, "colIncludeChildren")
if context.scene.fast64.sm64.export_type == "Insertable Binary":
@@ -605,7 +595,7 @@ class SM64_ExportCollisionPanel(SM64_Panel):
else:
prop_split(col, context.scene, "colStartAddr", "Start Address")
prop_split(col, context.scene, "colEndAddr", "End Address")
prop_split(col, context.scene, "colExportLevel", "Level Used By Collision")
prop_split(col, props, "level_name", "Level")
col.prop(context.scene, "set_addr_0x2A")
if context.scene.set_addr_0x2A:
prop_split(col, context.scene, "addr_0x2A", "0x2A Behaviour Command Address")
@@ -634,9 +624,6 @@ def sm64_col_register():
register_class(cls)
# Collision
bpy.types.Scene.colExportLevel = bpy.props.EnumProperty(
items=level_enums, name="Level Used By Collision", default="WF"
)
bpy.types.Scene.addr_0x2A = bpy.props.StringProperty(name="0x2A Behaviour Command Address", default="21A9CC")
bpy.types.Scene.set_addr_0x2A = bpy.props.BoolProperty(name="Overwrite 0x2A Behaviour Command")
bpy.types.Scene.colStartAddr = bpy.props.StringProperty(name="Start Address", default="11D8930")
@@ -665,7 +652,6 @@ def sm64_col_register():
def sm64_col_unregister():
# Collision
del bpy.types.Scene.colExportLevel
del bpy.types.Scene.addr_0x2A
del bpy.types.Scene.set_addr_0x2A
del bpy.types.Scene.colStartAddr
+102 -97
View File
@@ -38,75 +38,78 @@ commonGeolayoutPointers = {
}
level_enums = [
("HH", "Big Boo's Haunt", "HH"), # Originally Haunted House
("CCM", "Cool Cool Mountain", "CCM"),
("IC", "Inside Castle", "IC"),
("HMC", "Hazy Maze Cave", "HMC"),
("SSL", "Shifting Sand Land", "SSL"),
("BOB", "Bob-Omb's Battlefield", "BOB"),
("SML", "Snow Man's land", "SML"),
("WDW", "Wet Dry World", "WDW"),
("JRB", "Jolly Roger Bay", "JRB"),
("THI", "Tiny Huge Island", "THI"),
("TTC", "Tick Tock Clock", "TTC"),
("RR", "Rainbow Ride", "RR"),
("CG", "Castle Grounds", "CG"),
("BFC", "Bowser First Course", "BFC"),
("VC", "Vanish Cap", "VC"),
("BFS", "Bowser's Fire Sea", "BFS"),
("SA", "Secret Aquarium", "SA"),
("BTC", "Bowser Third Course", "BTC"),
("LLL", "Lethal Lava Land", "LLL"),
("DDD", "Dire Dire Docks", "DDD"),
("WF", "Whomp's Fortress", "WF"),
("PIC", "Picture at the end", "PIC"),
("CC", "Castle Courtyard", "CC"),
("PSS", "Peach's Secret Slide", "PSS"),
("MC", "Metal Cap", "MC"),
("WC", "Wing Cap", "WC"),
("BFB", "Bowser First Battle", "BFB"),
("RC", "Rainbow Clouds", "RC"),
("BSB", "Bowser Second Battle", "BSB"),
("BTB", "Bowser Third Battle", "BTB"),
("TTM", "Tall Tall Mountain", "TTM"),
OLD_BINARY_LEVEL_ENUMS = [
"bbh", # Big Boo's Haunt
"ccm", # Cool Cool Mountain
"castle_inside", # Inside Castle
"hmc", # Hazy Maze Cave
"ssl", # Shifting Sand Land
"bob", # Bob-Omb's Battlefield
"sl", # Snow Man's Land
"wdw", # Wet Dry World
"jrb", # Jolly Roger Bay
"thi", # Tiny Huge Island
"ttc", # Tick Tock Clock
"rr", # Rainbow Ride
"castle_grounds", # Castle Grounds
"bitdw", # Bowser In The Dark World
"vcutm", # Vanish Cap
"bitfs", # Bowser's Fire Sea
"sa", # Secret Aquarium
"bits", # Bowser In The Sky
"lll", # Lethal Lava Land
"ddd", # Dire Dire Docks
"wf", # Whomp's Fortress
"ending", # Picture at the end
"castle_courtyard", # Castle Courtyard
"pss", # Peach's Secret Slide
"cotmc", # Cavern Of The Metal Cap
"totwc", # Tower Of The Wing Cap
"bowser_1", # Bowser Battle 1
"wmotr", # Wing Mario Over The Rainbow
"bowser_2", # Bowser Battle 2
"bowser_3", # Bowser Battle 3
"ttm", # Tall Tall Mountain
]
enumLevelNames = [
("Custom", "Custom", "Custom"),
("bbh", "Big Boo's Haunt", "Big Boo's Haunt"),
("bitdw", "Bowser In The Dark World", "Bowser In The Dark World"),
("bitfs", "Bowser In The Fire Sea", "Bowser In The Fire Sea"),
("bits", "Bowser In The Sky", "Bowser In The Sky"),
("bob", "Bob-omb Battlefield", "Bob-omb Battlefield"),
("bowser_1", "Bowser 1", "Bowser 1"),
("bowser_2", "Bowser 2", "Bowser 2"),
("bowser_3", "Bowser 3", "Bowser 3"),
("castle_courtyard", "Castle Courtyard", "Castle Courtyard"),
("castle_grounds", "Castle Grounds", "Castle Grounds"),
("castle_inside", "Castle Inside", "Castle Inside"),
("ccm", "Cool Cool Mountain", "Cool Cool Mountain"),
("cotmc", "Cavern Of The Metal Cap", "Cavern Of The Metal Cap"),
("ddd", "Dire Dire Docks", "Dire Dire Docks"),
("ending", "Ending", "Ending"),
("hmc", "Hazy Maze Cave", "Hazy Maze Cave"),
("intro", "Intro", "Intro"),
("jrb", "Jolly Roger Bay", "Jolly Roger Bay"),
("lll", "Lethal Lava Land", "Lethal Lava Land"),
("menu", "Menu", "Menu"),
("pss", "Peach's Secret Slide", "Peach's Secret Slide"),
("rr", "Rainbow Ride", "Rainbow Ride"),
("sa", "Secret Aquarium", "Secret Aquarium"),
("sl", "Snowman's Land", "Snowman's Land"),
("ssl", "Shifting Sand Land", "Shifting Sand Land"),
("thi", "Tiny Huge Island", "Tiny Huge Island"),
("totwc", "Tower Of The Wing Cap", "Tower Of The Wing Cap"),
("ttc", "Tick Tock Clock", "Tick Tock Clock"),
("ttm", "Tall Tall Mountain", "Tall Tall Mountain"),
("vcutm", "Vanish Cap Under The Moat", "Vanish Cap Under The Moat"),
("wdw", "Wet Dry World", "Wet Dry World"),
("wf", "Whomp's Fortress", "Whomp's Fortress"),
("wmotr", "Wing Mario Over The Rainbow", "Wing Mario Over The Rainbow"),
("bob", "Bob-omb Battlefield", "Bob-omb Battlefield", 5),
("wf", "Whomp's Fortress", "Whomp's Fortress", 32),
("jrb", "Jolly Roger Bay", "Jolly Roger Bay", 18),
("ccm", "Cool Cool Mountain", "Cool Cool Mountain", 12),
("bbh", "Big Boo's Haunt", "Big Boo's Haunt", 1),
("hmc", "Hazy Maze Cave", "Hazy Maze Cave", 16),
("lll", "Lethal Lava Land", "Lethal Lava Land", 19),
("ssl", "Shifting Sand Land", "Shifting Sand Land", 25),
("ddd", "Dire Dire Docks", "Dire Dire Docks", 14),
("sl", "Snowman's Land", "Snowman's Land", 24),
("wdw", "Wet Dry World", "Wet Dry World", 31),
("ttm", "Tall Tall Mountain", "Tall Tall Mountain", 29),
("thi", "Tiny Huge Island", "Tiny Huge Island", 26),
("ttc", "Tick Tock Clock", "Tick Tock Clock", 28),
("rr", "Rainbow Ride", "Rainbow Ride", 22),
("", "Castle", "", 34),
("castle_courtyard", "Castle Courtyard", "Castle Courtyard", 9),
("castle_grounds", "Castle Grounds", "Castle Grounds", 10),
("castle_inside", "Castle Inside", "Castle Inside", 11),
("", "Extra Courses", "", 35),
("totwc", "Tower Of The Wing Cap", "Tower Of The Wing Cap", 27),
("cotmc", "Cavern Of The Metal Cap", "Cavern Of The Metal Cap", 13),
("vcutm", "Vanish Cap Under The Moat", "Vanish Cap Under The Moat", 30),
("pss", "Peach's Secret Slide", "Peach's Secret Slide", 21),
("sa", "Secret Aquarium", "Secret Aquarium", 23),
("wmotr", "Wing Mario Over The Rainbow", "Wing Mario Over The Rainbow", 33),
("bitdw", "Bowser In The Dark World", "Bowser In The Dark World", 2),
("bowser_1", "Bowser Battle 1", "Bowser Battle 1", 6),
("bitfs", "Bowser In The Fire Sea", "Bowser In The Fire Sea", 3),
("bowser_2", "Bowser Battle 2", "Bowser Battle 2", 7),
("bits", "Bowser In The Sky", "Bowser In The Sky", 4),
("bowser_3", "Bowser Battle 3", "Bowser Battle 3", 8),
("", "Special", "", 36),
("Custom", "Custom", "Custom", 0),
("intro", "Intro", "Intro", 17),
("menu", "Menu", "Menu", 20),
("ending", "Picture at the end", "Cake screen", 15),
]
levelIDNames = {
@@ -264,37 +267,39 @@ sm64_character_data = {
}
level_pointers = {
"HH": 0x2AC094,
"CCM": 0x2AC0A8,
"IC": 0x2AC0BC,
"HMC": 0x2AC0D0,
"SSL": 0x2AC0E4,
"BOB": 0x2AC0F8,
"SML": 0x2AC10C,
"WDW": 0x2AC120,
"JRB": 0x2AC134,
"THI": 0x2AC148,
"TTC": 0x2AC15C,
"RR": 0x2AC170,
"CG": 0x2AC184,
"BFC": 0x2AC198,
"VC": 0x2AC1AC,
"BFS": 0x2AC1C0,
"SA": 0x2AC1D4,
"BTC": 0x2AC1E8,
"LLL": 0x2AC1FC,
"DDD": 0x2AC210,
"WF": 0x2AC224,
"PIC": 0x2AC238,
"CC": 0x2AC24C,
"PSS": 0x2AC260,
"MC": 0x2AC274,
"WC": 0x2AC288,
"BFB": 0x2AC29C,
"RC": 0x2AC2B0,
"BSB": 0x2AC2C4,
"BTB": 0x2AC2D8,
"TTM": 0x2AC2EC,
"bbh": 0x2AC094,
"ccm": 0x2AC0A8,
"castle_inside": 0x2AC0BC,
"hmc": 0x2AC0D0,
"ssl": 0x2AC0E4,
"bob": 0x2AC0F8,
"sl": 0x2AC10C,
"wdw": 0x2AC120,
"jrb": 0x2AC134,
"thi": 0x2AC148,
"ttc": 0x2AC15C,
"rr": 0x2AC170,
"castle_grounds": 0x2AC184,
"bitdw": 0x2AC198,
"vcutm": 0x2AC1AC,
"bitfs": 0x2AC1C0,
"sa": 0x2AC1D4,
"bits": 0x2AC1E8,
"lll": 0x2AC1FC,
"ddd": 0x2AC210,
"wf": 0x2AC224,
"ending": 0x2AC238,
"castle_courtyard": 0x2AC24C,
"pss": 0x2AC260,
"cotmc": 0x2AC274,
"totwc": 0x2AC288,
"bowser_1": 0x2AC29C,
"wmotr": 0x2AC2B0,
"bowser_2": 0x2AC2C4,
"bowser_3": 0x2AC2D8,
"ttm": 0x2AC2EC,
"menu": 0x2A6130,
"intro": 0x269EB0,
}
insertableBinaryTypes = {"Display List": 0, "Geolayout": 1, "Animation": 2, "Collision": 3}
+4 -4
View File
@@ -7,9 +7,9 @@ from bpy.ops import object
from bpy.props import StringProperty, EnumProperty, BoolProperty
from ..panels import SM64_Panel
from ..f3d.f3d_parser import F3DtoBlenderObject
from .sm64_constants import level_enums, level_pointers
from .sm64_constants import enumLevelNames
from .sm64_utility import import_rom_checks
from .sm64_level_parser import parseLevelAtPointer
from .sm64_level_parser import parse_level_binary
from ..utility import (
PluginError,
@@ -40,7 +40,7 @@ class SM64_ImportDL(Operator):
try:
import_rom_checks(abspath(context.scene.fast64.sm64.import_rom))
romfileSrc = open(abspath(context.scene.fast64.sm64.import_rom), "rb")
levelParsed = parseLevelAtPointer(romfileSrc, level_pointers[context.scene.levelDLImport])
levelParsed = parse_level_binary(romfileSrc, context.scene.levelDLImport)
segmentData = levelParsed.segmentData
start = (
decodeSegmentedAddr(int(context.scene.DLImportStart, 16).to_bytes(4, "big"), segmentData)
@@ -102,7 +102,7 @@ def sm64_dl_parser_register():
register_class(cls)
Scene.DLImportStart = StringProperty(name="Start Address", default="A3BE1C")
Scene.levelDLImport = EnumProperty(items=level_enums, name="Level", default="CG")
Scene.levelDLImport = EnumProperty(items=enumLevelNames, name="Level", default="castle_grounds")
Scene.isSegmentedAddrDLImport = BoolProperty(name="Is Segmented Address", default=False)
+32 -60
View File
@@ -24,9 +24,9 @@ from .sm64_utility import (
write_or_delete_if_found,
write_material_headers,
)
from .sm64_level_parser import parseLevelAtPointer
from .sm64_level_parser import parse_level_binary
from .sm64_rom_tweaks import ExtendBank0x04
from typing import Tuple, Union, Iterable
from typing import Tuple
from ..f3d.f3d_bleed import BleedGraphics
@@ -43,7 +43,6 @@ from ..f3d.f3d_gbi import (
GfxMatWriteMethod,
ScrollMethod,
DLFormat,
SPDisplayList,
GfxList,
GfxListTag,
FTexRect,
@@ -57,11 +56,8 @@ from ..f3d.f3d_gbi import (
SPTexture,
SPEndDisplayList,
TextureExportSettings,
FSetTileSizeScrollField,
FImageKey,
vertexScrollTemplate,
get_tile_scroll_code,
GFX_SIZE,
)
from ..utility import (
@@ -88,18 +84,10 @@ from ..utility import (
decompFolderMessage,
makeWriteInfoBox,
writeBoxExportType,
enumExportHeaderType,
create_or_get_world,
)
from .sm64_constants import (
level_enums,
enumLevelNames,
level_pointers,
defaultExtendSegment4,
bank0Segment,
insertableBinaryTypes,
)
from .sm64_constants import defaultExtendSegment4, bank0Segment, insertableBinaryTypes
enumHUDExportLocation = [
@@ -589,6 +577,7 @@ class SM64_ExportDL(bpy.types.Operator):
def execute(self, context):
romfileOutput = None
tempROM = None
props = context.scene.fast64.sm64.combined_export
try:
if context.mode != "OBJECT":
raise PluginError("Operator can only be used in object mode.")
@@ -610,27 +599,27 @@ class SM64_ExportDL(bpy.types.Operator):
applyRotation([obj], radians(90), "X")
if context.scene.fast64.sm64.export_type == "C":
exportPath, levelName = getPathAndLevel(
context.scene.DLCustomExport,
context.scene.DLExportPath,
context.scene.DLLevelName,
context.scene.DLLevelOption,
props.is_actor_custom_export,
props.actor_custom_path,
props.export_level_name,
props.level_name,
)
if not context.scene.DLCustomExport:
if not props.is_actor_custom_export:
applyBasicTweaks(exportPath)
fileStatus = sm64ExportF3DtoC(
exportPath,
obj,
DLFormat.Static if context.scene.DLExportisStatic else DLFormat.Dynamic,
finalTransform,
bpy.context.scene.DLTexDir,
props.custom_include_directory,
bpy.context.scene.saveTextures,
bpy.context.scene.DLSeparateTextureDef,
bpy.context.scene.DLincludeChildren,
bpy.context.scene.DLName,
levelName,
context.scene.DLGroupName,
context.scene.DLCustomExport,
context.scene.DLExportHeaderType,
props.actor_group_name,
props.is_actor_custom_export,
props.export_header_type,
)
starSelectWarning(self, fileStatus)
@@ -652,7 +641,7 @@ class SM64_ExportDL(bpy.types.Operator):
romfileExport.close()
romfileOutput = open(bpy.path.abspath(tempROM), "rb+")
levelParsed = parseLevelAtPointer(romfileOutput, level_pointers[context.scene.levelDLExport])
levelParsed = parse_level_binary(romfileOutput, props.level_name)
segmentData = levelParsed.segmentData
if context.scene.fast64.sm64.extend_bank_4:
ExtendBank0x04(romfileOutput, segmentData, defaultExtendSegment4)
@@ -733,27 +722,28 @@ class SM64_ExportDLPanel(SM64_Panel):
def draw(self, context):
col = self.layout.column()
propsDLE = col.operator(SM64_ExportDL.bl_idname)
props = context.scene.fast64.sm64.combined_export
if context.scene.fast64.sm64.export_type == "C":
col.prop(context.scene, "DLExportisStatic")
col.prop(context.scene, "DLCustomExport")
if context.scene.DLCustomExport:
col.prop(context.scene, "DLExportPath")
prop_split(col, context.scene, "DLName", "Name")
prop_split(col, props, "export_header_type", "Export Type")
prop_split(col, context.scene, "DLName", "Name")
if props.is_actor_custom_export:
prop_split(col, props, "custom_export_path", "Custom Path")
if context.scene.saveTextures:
prop_split(col, context.scene, "DLTexDir", "Texture Include Path")
prop_split(col, props, "custom_include_directory", "Texture Include Path")
col.prop(context.scene, "DLSeparateTextureDef")
customExportWarning(col)
else:
prop_split(col, context.scene, "DLExportHeaderType", "Export Type")
prop_split(col, context.scene, "DLName", "Name")
if context.scene.DLExportHeaderType == "Actor":
prop_split(col, context.scene, "DLGroupName", "Group Name")
elif context.scene.DLExportHeaderType == "Level":
prop_split(col, context.scene, "DLLevelOption", "Level")
if context.scene.DLLevelOption == "Custom":
prop_split(col, context.scene, "DLLevelName", "Level Name")
if props.export_header_type == "Actor":
prop_split(col, props, "group_name", "Group")
if props.group_name == "Custom":
prop_split(col, props, "custom_group_name", "Group Name")
elif props.export_header_type == "Level":
prop_split(col, props, "level_name", "Level")
if props.level_name == "Custom":
prop_split(col, props, "custom_level_name", "Level Name")
if context.scene.saveTextures:
col.prop(context.scene, "DLSeparateTextureDef")
@@ -761,10 +751,10 @@ class SM64_ExportDLPanel(SM64_Panel):
writeBox = makeWriteInfoBox(col)
writeBoxExportType(
writeBox,
context.scene.DLExportHeaderType,
props.export_header_type,
context.scene.DLName,
context.scene.DLLevelName,
context.scene.DLLevelOption,
props.export_level_name,
props.level_name,
)
elif context.scene.fast64.sm64.export_type == "Insertable Binary":
@@ -776,7 +766,7 @@ class SM64_ExportDLPanel(SM64_Panel):
if context.scene.DLUseBank0:
prop_split(col, context.scene, "DLRAMAddr", "RAM Address")
else:
col.prop(context.scene, "levelDLExport")
col.prop(props, "level_name")
col.prop(context.scene, "overwriteGeoPtr")
if context.scene.overwriteGeoPtr:
prop_split(col, context.scene, "DLExportGeoPtr", "Geolayout Pointer")
@@ -1004,26 +994,16 @@ def sm64_dl_writer_register():
bpy.types.Scene.DLExportStart = bpy.props.StringProperty(name="Start", default="11D8930")
bpy.types.Scene.DLExportEnd = bpy.props.StringProperty(name="End", default="11FFF00")
bpy.types.Scene.levelDLExport = bpy.props.EnumProperty(items=level_enums, name="Level", default="WF")
bpy.types.Scene.DLExportGeoPtr = bpy.props.StringProperty(name="Geolayout Pointer", default="132AA8")
bpy.types.Scene.overwriteGeoPtr = bpy.props.BoolProperty(name="Overwrite geolayout pointer", default=False)
bpy.types.Scene.DLExportPath = bpy.props.StringProperty(name="Directory", subtype="FILE_PATH")
bpy.types.Scene.DLExportisStatic = bpy.props.BoolProperty(name="Static DL", default=True)
bpy.types.Scene.DLDefinePath = bpy.props.StringProperty(name="Definitions Filepath", subtype="FILE_PATH")
bpy.types.Scene.DLUseBank0 = bpy.props.BoolProperty(name="Use Bank 0")
bpy.types.Scene.DLRAMAddr = bpy.props.StringProperty(name="RAM Address", default="80000000")
bpy.types.Scene.DLTexDir = bpy.props.StringProperty(name="Include Path", default="levels/bob")
bpy.types.Scene.DLSeparateTextureDef = bpy.props.BoolProperty(name="Save texture.inc.c separately")
bpy.types.Scene.DLincludeChildren = bpy.props.BoolProperty(name="Include Children")
bpy.types.Scene.DLInsertableBinaryPath = bpy.props.StringProperty(name="Filepath", subtype="FILE_PATH")
bpy.types.Scene.DLName = bpy.props.StringProperty(name="Name", default="mario")
bpy.types.Scene.DLCustomExport = bpy.props.BoolProperty(name="Custom Export Path")
bpy.types.Scene.DLExportHeaderType = bpy.props.EnumProperty(
items=enumExportHeaderType, name="Header Export", default="Actor"
)
bpy.types.Scene.DLGroupName = bpy.props.StringProperty(name="Group Name", default="group0")
bpy.types.Scene.DLLevelName = bpy.props.StringProperty(name="Level", default="bob")
bpy.types.Scene.DLLevelOption = bpy.props.EnumProperty(items=enumLevelNames, name="Level", default="bob")
bpy.types.Scene.texrect = bpy.props.PointerProperty(type=TextureProperty)
bpy.types.Scene.texrectImageTexture = bpy.props.PointerProperty(type=bpy.types.ImageTexture)
@@ -1038,26 +1018,18 @@ def sm64_dl_writer_unregister():
for cls in reversed(sm64_dl_writer_classes):
unregister_class(cls)
del bpy.types.Scene.levelDLExport
del bpy.types.Scene.DLExportStart
del bpy.types.Scene.DLExportEnd
del bpy.types.Scene.DLExportGeoPtr
del bpy.types.Scene.overwriteGeoPtr
del bpy.types.Scene.DLExportPath
del bpy.types.Scene.DLExportisStatic
del bpy.types.Scene.DLDefinePath
del bpy.types.Scene.DLUseBank0
del bpy.types.Scene.DLRAMAddr
del bpy.types.Scene.DLTexDir
del bpy.types.Scene.DLSeparateTextureDef
del bpy.types.Scene.DLincludeChildren
del bpy.types.Scene.DLInsertableBinaryPath
del bpy.types.Scene.DLName
del bpy.types.Scene.DLCustomExport
del bpy.types.Scene.DLExportHeaderType
del bpy.types.Scene.DLGroupName
del bpy.types.Scene.DLLevelName
del bpy.types.Scene.DLLevelOption
del bpy.types.Scene.texrect
del bpy.types.Scene.TexRectExportPath
@@ -2,8 +2,8 @@ import bpy, mathutils, math, bmesh, copy
from bpy.utils import register_class, unregister_class
from ..f3d.f3d_parser import createBlankMaterial, parseF3DBinary
from ..panels import SM64_Panel
from .sm64_level_parser import parseLevelAtPointer
from .sm64_constants import level_pointers, level_enums
from .sm64_level_parser import parse_level_binary
from .sm64_constants import enumLevelNames
from .sm64_geolayout_bone import enumShadowType, animatableBoneTypes, enumBoneType
from .sm64_geolayout_constants import getGeoLayoutCmdLength, nodeGroupCmds, GEO_BRANCH_STORE
from .sm64_utility import import_rom_checks
@@ -1540,7 +1540,7 @@ class SM64_ImportGeolayout(bpy.types.Operator):
armatureObj = None
# Get segment data
levelParsed = parseLevelAtPointer(romfileSrc, level_pointers[levelGeoImport])
levelParsed = parse_level_binary(romfileSrc, levelGeoImport)
segmentData = levelParsed.segmentData
geoStart = int(geoImportAddr, 16)
if context.scene.geoIsSegPtr:
@@ -1634,7 +1634,7 @@ def sm64_geo_parser_register():
bpy.types.Scene.geoImportAddr = bpy.props.StringProperty(name="Start Address", default="1F1D60")
bpy.types.Scene.generateArmature = bpy.props.BoolProperty(name="Generate Armature?", default=True)
bpy.types.Scene.levelGeoImport = bpy.props.EnumProperty(items=level_enums, name="Level", default="HMC")
bpy.types.Scene.levelGeoImport = bpy.props.EnumProperty(items=enumLevelNames, name="Level", default="hmc")
bpy.types.Scene.ignoreSwitch = bpy.props.BoolProperty(name="Ignore Switch Nodes", default=True)
+6 -20
View File
@@ -13,7 +13,7 @@ from .sm64_geolayout_bone import getSwitchOptionBone, animatableBoneTypes
from .sm64_camera import saveCameraSettingsToGeolayout
from .sm64_f3d_writer import SM64Model, SM64GfxFormatter
from .sm64_texscroll import modifyTexScrollFiles, modifyTexScrollHeadersGroup
from .sm64_level_parser import parseLevelAtPointer
from .sm64_level_parser import parse_level_binary
from .sm64_rom_tweaks import ExtendBank0x04
from .sm64_utility import export_rom_checks, starSelectWarning, update_actor_includes, write_material_headers
@@ -51,11 +51,6 @@ from ..utility import (
tempName,
getAddressFromRAMAddress,
prop_split,
customExportWarning,
decompFolderMessage,
makeWriteInfoBox,
writeBoxExportType,
enumExportHeaderType,
geoNodeRotateOrder,
deselectAllObjects,
selectSingleObject,
@@ -101,7 +96,6 @@ from ..f3d.f3d_gbi import (
DLFormat,
SPEndDisplayList,
SPDisplayList,
FMaterial,
)
from .sm64_geolayout_classes import (
@@ -130,14 +124,7 @@ from .sm64_geolayout_classes import (
Geolayout,
)
from .sm64_constants import (
insertableBinaryTypes,
bank0Segment,
level_pointers,
defaultExtendSegment4,
level_enums,
enumLevelNames,
)
from .sm64_constants import insertableBinaryTypes, bank0Segment, defaultExtendSegment4
if typing.TYPE_CHECKING:
from .sm64_geolayout_bone import SM64_BoneProperties
@@ -2913,7 +2900,7 @@ class SM64_ExportGeolayoutObject(ObjectDataExporter):
romfileExport.close()
romfileOutput = open(bpy.path.abspath(tempROM), "rb+")
levelParsed = parseLevelAtPointer(romfileOutput, level_pointers[context.scene.levelGeoExport])
levelParsed = parse_level_binary(romfileOutput, props.level_name)
segmentData = levelParsed.segmentData
if context.scene.fast64.sm64.extend_bank_4:
@@ -3111,7 +3098,7 @@ class SM64_ExportGeolayoutArmature(bpy.types.Operator):
romfileExport.close()
romfileOutput = open(bpy.path.abspath(tempROM), "rb+")
levelParsed = parseLevelAtPointer(romfileOutput, level_pointers[context.scene.levelGeoExport])
levelParsed = parse_level_binary(romfileOutput, props.level_name)
segmentData = levelParsed.segmentData
if context.scene.fast64.sm64.extend_bank_4:
@@ -3215,6 +3202,7 @@ class SM64_ExportGeolayoutPanel(SM64_Panel):
col = self.layout.column()
propsGeoE = col.operator(SM64_ExportGeolayoutArmature.bl_idname)
propsGeoE = col.operator(SM64_ExportGeolayoutObject.bl_idname)
props = context.scene.fast64.sm64.combined_export
if context.scene.fast64.sm64.export_type == "Insertable Binary":
col.prop(context.scene, "geoInsertableBinaryPath")
else:
@@ -3225,7 +3213,7 @@ class SM64_ExportGeolayoutPanel(SM64_Panel):
if context.scene.geoUseBank0:
prop_split(col, context.scene, "geoRAMAddr", "RAM Address")
else:
col.prop(context.scene, "levelGeoExport")
prop_split(col, props, "level_name", "Level")
col.prop(context.scene, "overwriteModelLoad")
if context.scene.overwriteModelLoad:
@@ -3258,7 +3246,6 @@ def sm64_geo_writer_register():
for cls in sm64_geo_writer_classes:
register_class(cls)
bpy.types.Scene.levelGeoExport = bpy.props.EnumProperty(items=level_enums, name="Level", default="HMC")
bpy.types.Scene.geoExportStart = bpy.props.StringProperty(name="Start", default="11D8930")
bpy.types.Scene.geoExportEnd = bpy.props.StringProperty(name="End", default="11FFF00")
@@ -3291,7 +3278,6 @@ def sm64_geo_writer_unregister():
for cls in reversed(sm64_geo_writer_classes):
unregister_class(cls)
del bpy.types.Scene.levelGeoExport
del bpy.types.Scene.geoExportStart
del bpy.types.Scene.geoExportEnd
del bpy.types.Scene.overwriteModelLoad
@@ -41,6 +41,13 @@ from .sm64_level_constants import (
L_PLACE_MACRO_OBJECT,
L_JET_STREAM,
)
from .sm64_constants import level_pointers
def parse_level_binary(romfile, name: str):
if name == "Custom":
raise PluginError("Custom levels not supported for binary exports.")
return parseLevelAtPointer(romfile, level_pointers[name])
def parseLevelAtPointer(romfile, pointerAddress):
+4 -4
View File
@@ -10,9 +10,9 @@ from ...utility import PluginError, decodeSegmentedAddr, encodeSegmentedAddr, se
from ...f3d.f3d_material import getDefaultMaterialPreset, createF3DMat, add_f3d_mat_to_obj
from ...utility import parentObject, intToHex, bytesToHex
from ..sm64_constants import level_pointers, levelIDNames, level_enums
from ..sm64_constants import levelIDNames, enumLevelNames
from ..sm64_utility import import_rom_checks, int_from_str
from ..sm64_level_parser import parseLevelAtPointer
from ..sm64_level_parser import parse_level_binary
from ..sm64_geolayout_utility import createBoneGroups
from ..sm64_geolayout_parser import generateMetarig
@@ -31,7 +31,7 @@ class SM64_AddrConv(OperatorBase):
rom: StringProperty(name="ROM", subtype="FILE_PATH")
# Using an enum here looks cleaner when using this as an operator
option: EnumProperty(name="Conversion type", items=enum_address_conversion_options)
level: EnumProperty(items=level_enums, name="Level", default="IC")
level: EnumProperty(items=enumLevelNames, name="Level", default="castle_inside")
addr: StringProperty(name="Address")
clipboard: BoolProperty(name="Copy to clipboard", default=True)
result: StringProperty(name="Result")
@@ -41,7 +41,7 @@ class SM64_AddrConv(OperatorBase):
import_rom_path = abspath(self.rom)
import_rom_checks(import_rom_path)
with open(import_rom_path, "rb") as romfile:
level_parsed = parseLevelAtPointer(romfile, level_pointers[self.level])
level_parsed = parse_level_binary(romfile, self.level)
segment_data = level_parsed.segmentData
if self.option == "TO_VIR":
result = intToHex(decodeSegmentedAddr(addr.to_bytes(4, "big"), segment_data))
+2 -2
View File
@@ -7,7 +7,7 @@ from bpy.utils import register_class, unregister_class
from ...utility import prop_split, upgrade_old_prop
from ..sm64_utility import string_int_prop, import_rom_ui_warnings
from ..sm64_constants import level_enums
from ..sm64_constants import enumLevelNames
from .operators import SM64_AddrConv
@@ -18,7 +18,7 @@ class SM64_AddrConvProperties(PropertyGroup):
rom: StringProperty(name="Import ROM", subtype="FILE_PATH")
address: StringProperty(name="Address")
level: EnumProperty(items=level_enums, name="Level", default="IC")
level: EnumProperty(items=enumLevelNames, name="Level", default="castle_inside")
clipboard: BoolProperty(name="Copy to Clipboard", default=True)
def upgrade_changed_props(self, scene: Scene):
+1 -1
View File
@@ -444,7 +444,7 @@ def extendedRAMLabel(layout):
def getPathAndLevel(is_custom_export, custom_export_path, custom_level_name, level_enum):
if is_custom_export:
export_path = bpy.path.abspath(custom_export_path)
export_path = bpy.path.abspath(str(custom_export_path))
level_name = custom_level_name
else:
export_path = str(bpy.context.scene.fast64.sm64.abs_decomp_path)