mirror of
https://github.com/ApfelTeeSaft/lightspeed64.git
synced 2026-08-26 19:33:24 +00:00
[SM64] Rework actor load exports for level scripts (#564)
* seg 8 loading for yay0 and geo segments * update replaceScriptLoads to add new script loads if missing * change grid layout * add global write/don't write toggle for actor loads and 'None' option for individual segment loads * reappend any JUMP_LINK commands that do not contain 'script_func_global' * formatting lol * some code quality changes * move write actor loads to the correct place, clean up the UI a little (grid wasn´t even being used properly aha) * replace yay0 or mio0 equivelent commands to current compression method --------- Co-authored-by: Lila <[email protected]>
This commit is contained in:
@@ -2101,7 +2101,7 @@ groupsSeg5 = [
|
||||
("group9", "group9", "Haunted Objects (Boo, Mad Piano etc.)"),
|
||||
("group10", "group10", "Peach/Yoshi"),
|
||||
("group11", "group11", "THI Ojbects (Lakitu, Wiggler, Bubba)"),
|
||||
("Do Not Write", "Do Not Write", "Do Not Write"),
|
||||
("None", "None", "None"),
|
||||
("Custom", "Custom", "Custom"),
|
||||
]
|
||||
|
||||
@@ -2113,7 +2113,13 @@ groupsSeg6 = [
|
||||
("group15", "group15", "Castle Objects (MIPS, Toad etc.)"),
|
||||
("group16", "group16", "Ice Objects (Chill Bully, Moneybags)"),
|
||||
("group17", "group17", "Cave Objects (Swoop, Scuttlebug, Dorrie etc.)"),
|
||||
("Do Not Write", "Do Not Write", "Do Not Write"),
|
||||
("None", "None", "None"),
|
||||
("Custom", "Custom", "Custom"),
|
||||
]
|
||||
|
||||
groups_seg8 = [
|
||||
("common0", "common0", "Generic course objects (Goomba, Bob-ombs, Cannon etc.)"),
|
||||
("None", "None", "None"),
|
||||
("Custom", "Custom", "Custom"),
|
||||
]
|
||||
|
||||
|
||||
@@ -440,19 +440,25 @@ def parseZoomMasks(filepath):
|
||||
return ZoomOutMasks(zoomMacros, cameraData)
|
||||
|
||||
|
||||
def replaceSegmentLoad(levelscript, segmentName, command, changedSegment):
|
||||
def replace_segment_load(level: LevelScript, name: str, commands: list[str], new_segment: int):
|
||||
args = ["0x0{:X}".format(new_segment), name + "SegmentRomStart", name + "SegmentRomEnd"]
|
||||
changedLoad = None
|
||||
for segmentLoad in levelscript.segmentLoads:
|
||||
for i, segmentLoad in enumerate(level.segmentLoads):
|
||||
segmentString = segmentLoad[1][0].lower()
|
||||
segment = int(segmentString, 16 if "x" in segmentString else 10)
|
||||
if segmentLoad[0] == command and segment == changedSegment:
|
||||
segment = int(segmentString, 0)
|
||||
if segmentLoad[0] in commands and segment == new_segment:
|
||||
level.segmentLoads[i] = Macro(commands[0], args, segmentLoad[2])
|
||||
changedLoad = segmentLoad
|
||||
if changedLoad is None:
|
||||
changedLoad = Macro(command, [hex(changedSegment), "", ""], "")
|
||||
levelscript.segmentLoads.append(changedLoad)
|
||||
changedLoad = Macro(commands[0], args, "")
|
||||
level.segmentLoads.append(changedLoad)
|
||||
|
||||
changedLoad[1][1] = segmentName + "SegmentRomStart"
|
||||
changedLoad[1][2] = segmentName + "SegmentRomEnd"
|
||||
|
||||
def remove_segment_load(levelscript: LevelScript, segment_num: int):
|
||||
for segment_load in levelscript.segmentLoads:
|
||||
segment_string = segment_load[1][0].lower()
|
||||
if int(segment_string, 0) == segment_num:
|
||||
levelscript.segmentLoads.remove(segment_load)
|
||||
|
||||
|
||||
def replaceScriptLoads(levelscript, obj):
|
||||
@@ -462,19 +468,13 @@ def replaceScriptLoads(levelscript, obj):
|
||||
if "script_func_global_" not in target:
|
||||
newFuncs.append(jumpLink)
|
||||
continue
|
||||
scriptNum = int(re.findall(r"\d+", target)[-1])
|
||||
# this is common0
|
||||
if scriptNum == 1:
|
||||
newFuncs.append(jumpLink)
|
||||
continue
|
||||
if scriptNum < 13:
|
||||
newNum = obj.fast64.sm64.segment_loads.group5
|
||||
else:
|
||||
newNum = obj.fast64.sm64.segment_loads.group6
|
||||
if newNum == "Do Not Write":
|
||||
newFuncs.append(jumpLink)
|
||||
continue
|
||||
newFuncs.append(Macro("JUMP_LINK", [newNum], jumpLink.comment))
|
||||
|
||||
group_seg_loads = obj.fast64.sm64.segment_loads
|
||||
scriptFuncs = (group_seg_loads.group8, group_seg_loads.group5, group_seg_loads.group6)
|
||||
for func in scriptFuncs:
|
||||
if func is not None:
|
||||
newFuncs.append(Macro("JUMP_LINK", [func], ""))
|
||||
|
||||
levelscript.levelFunctions = newFuncs
|
||||
|
||||
|
||||
@@ -818,38 +818,49 @@ def export_area_c(
|
||||
|
||||
def export_level_script_c(obj, prev_level_script, level_name, level_data, level_dir, uses_env_fx):
|
||||
compressionFmt = bpy.context.scene.fast64.sm64.compression_format
|
||||
|
||||
def replace_compressed_segment_load(name: str, segment: int, add_compression_fmt=True):
|
||||
compression_fmts = [compressionFmt.upper()] + list({"MIO0", "YAY0", "RAW"} - {compressionFmt.upper()})
|
||||
valid_cmds = [f"LOAD_{fmt}" for fmt in compression_fmts]
|
||||
if add_compression_fmt:
|
||||
name += f"_{compressionFmt}"
|
||||
replace_segment_load(prev_level_script, f"_{name}", valid_cmds, segment)
|
||||
|
||||
# replace level loads
|
||||
replaceSegmentLoad(prev_level_script, f"_{level_name}_segment_7", f"LOAD_{compressionFmt.upper()}", 0x07)
|
||||
replace_compressed_segment_load(f"{level_name}_segment_7", 0x07, False)
|
||||
if uses_env_fx:
|
||||
replaceSegmentLoad(prev_level_script, f"_effect_{compressionFmt}", f"LOAD_{compressionFmt.upper()}", 0x0B)
|
||||
replace_compressed_segment_load("effect", 0x0B)
|
||||
if not obj.useBackgroundColor:
|
||||
if obj.background == "CUSTOM":
|
||||
segment = obj.fast64.sm64.level.backgroundSegment
|
||||
else:
|
||||
segment = f"{backgroundSegments[obj.background]}_skybox"
|
||||
replaceSegmentLoad(prev_level_script, f"_{segment}_{compressionFmt}", f"LOAD_{compressionFmt.upper()}", 0x0A)
|
||||
replace_compressed_segment_load(segment, 0x0A)
|
||||
|
||||
# replace actor loads
|
||||
group_seg_loads = obj.fast64.sm64.segment_loads
|
||||
if group_seg_loads.seg5_enum != "Do Not Write":
|
||||
replaceSegmentLoad(
|
||||
prev_level_script,
|
||||
f"_{group_seg_loads.seg5}_{compressionFmt}",
|
||||
f"LOAD_{compressionFmt.upper()}",
|
||||
0x05,
|
||||
)
|
||||
replaceSegmentLoad(prev_level_script, f"_{group_seg_loads.seg5}_geo", "LOAD_RAW", 0x0C)
|
||||
if group_seg_loads.seg6_enum != "Do Not Write":
|
||||
replaceSegmentLoad(
|
||||
prev_level_script,
|
||||
f"_{group_seg_loads.seg6}_{compressionFmt}",
|
||||
f"LOAD_{compressionFmt.upper()}",
|
||||
0x06,
|
||||
)
|
||||
replaceSegmentLoad(prev_level_script, f"_{group_seg_loads.seg6}_geo", "LOAD_RAW", 0x0D)
|
||||
if group_seg_loads.write_actor_loads:
|
||||
if group_seg_loads.seg5_enum != "None":
|
||||
replace_compressed_segment_load(group_seg_loads.seg5, 0x05)
|
||||
replace_segment_load(prev_level_script, f"_{group_seg_loads.seg5}_geo", ["LOAD_RAW"], 0x0C)
|
||||
else:
|
||||
remove_segment_load(prev_level_script, 0x05)
|
||||
remove_segment_load(prev_level_script, 0x0C)
|
||||
if group_seg_loads.seg6_enum != "None":
|
||||
replace_compressed_segment_load(group_seg_loads.seg6, 0x06)
|
||||
replace_segment_load(prev_level_script, f"_{group_seg_loads.seg6}_geo", ["LOAD_RAW"], 0x0D)
|
||||
else:
|
||||
remove_segment_load(prev_level_script, 0x06)
|
||||
remove_segment_load(prev_level_script, 0x0D)
|
||||
if group_seg_loads.seg8_enum != "None":
|
||||
replace_compressed_segment_load(group_seg_loads.seg8, 0x08)
|
||||
replace_segment_load(prev_level_script, f"_{group_seg_loads.seg8}_geo", ["LOAD_RAW"], 0x0F)
|
||||
else:
|
||||
remove_segment_load(prev_level_script, 0x08)
|
||||
remove_segment_load(prev_level_script, 0x0F)
|
||||
replaceScriptLoads(prev_level_script, obj)
|
||||
|
||||
# write data
|
||||
replaceScriptLoads(prev_level_script, obj)
|
||||
saveDataToFile(os.path.join(level_dir, "script.c"), prev_level_script.to_c(level_data.area_data))
|
||||
|
||||
return level_data
|
||||
|
||||
@@ -46,6 +46,7 @@ from .sm64_constants import (
|
||||
obj_group_enums,
|
||||
groupsSeg5,
|
||||
groupsSeg6,
|
||||
groups_seg8,
|
||||
groups_obj_export,
|
||||
)
|
||||
from .sm64_utility import convert_addr_to_func
|
||||
@@ -1254,8 +1255,7 @@ class SM64ObjectPanel(bpy.types.Panel):
|
||||
# box.box().label(text = 'Background IDs defined in include/geo_commands.h.')
|
||||
box.prop(obj, "actSelectorIgnore")
|
||||
box.prop(obj, "setAsStartLevel")
|
||||
grid = box.grid_flow(columns=2)
|
||||
obj.fast64.sm64.segment_loads.draw(grid)
|
||||
obj.fast64.sm64.segment_loads.draw_props(box)
|
||||
prop_split(box, obj, "acousticReach", "Acoustic Reach")
|
||||
obj.starGetCutscenes.draw(box)
|
||||
|
||||
@@ -2776,28 +2776,35 @@ class SM64_GameObjectProperties(bpy.types.PropertyGroup):
|
||||
|
||||
|
||||
class SM64_SegmentProperties(bpy.types.PropertyGroup):
|
||||
write_actor_loads: bpy.props.BoolProperty(name="Write Actor Loads")
|
||||
seg5_load_custom: bpy.props.StringProperty(name="Segment 5 Seg")
|
||||
seg5_group_custom: bpy.props.StringProperty(name="Segment 5 Group")
|
||||
seg6_load_custom: bpy.props.StringProperty(name="Segment 6 Seg")
|
||||
seg6_group_custom: bpy.props.StringProperty(name="Segment 6 Group")
|
||||
seg5_enum: bpy.props.EnumProperty(name="Segment 5 Group", default="Do Not Write", items=groupsSeg5)
|
||||
seg6_enum: bpy.props.EnumProperty(name="Segment 6 Group", default="Do Not Write", items=groupsSeg6)
|
||||
seg8_load_custom: bpy.props.StringProperty(name="Segment 8 Seg")
|
||||
seg8_group_custom: bpy.props.StringProperty(name="Segment 8 Group")
|
||||
seg5_enum: bpy.props.EnumProperty(name="Segment 5 Group", default="None", items=groupsSeg5)
|
||||
seg6_enum: bpy.props.EnumProperty(name="Segment 6 Group", default="None", items=groupsSeg6)
|
||||
seg8_enum: bpy.props.EnumProperty(name="Segment 8 Group", default="None", items=groups_seg8)
|
||||
|
||||
def draw(self, layout):
|
||||
def draw_props(self, layout):
|
||||
col = layout.column()
|
||||
prop_split(col, self, "seg5_enum", "Segment 5 Select")
|
||||
if self.seg5_enum == "Custom":
|
||||
prop_split(col, self, "seg5_load_custom", "Segment 5 Seg")
|
||||
prop_split(col, self, "seg5_group_custom", "Segment 5 Group")
|
||||
col = layout.column()
|
||||
prop_split(col, self, "seg6_enum", "Segment 6 Select")
|
||||
if self.seg6_enum == "Custom":
|
||||
prop_split(col, self, "seg6_load_custom", "Segment 6 Seg")
|
||||
prop_split(col, self, "seg6_group_custom", "Segment 6 Group")
|
||||
col.prop(self, "write_actor_loads")
|
||||
if not self.write_actor_loads:
|
||||
return
|
||||
|
||||
for seg in (5, 6, 8):
|
||||
prop_split(col, self, f"seg{seg}_enum", f"Segment {seg} Select")
|
||||
if getattr(self, f"seg{seg}_enum") == "Custom":
|
||||
prop_split(col, self, f"seg{seg}_load_custom", "Segment")
|
||||
prop_split(col, self, f"seg{seg}_group_custom", "Group")
|
||||
col.separator()
|
||||
|
||||
def jump_link_from_enum(self, grp):
|
||||
if grp == "Do Not Write":
|
||||
return grp
|
||||
if grp == "None":
|
||||
return None
|
||||
elif grp == "common0":
|
||||
return "script_func_global_1"
|
||||
num = int(grp.removeprefix("group")) + 1
|
||||
return f"script_func_global_{num}"
|
||||
|
||||
@@ -2815,6 +2822,13 @@ class SM64_SegmentProperties(bpy.types.PropertyGroup):
|
||||
else:
|
||||
return self.seg6_enum
|
||||
|
||||
@property
|
||||
def seg8(self):
|
||||
if self.seg8_enum == "Custom":
|
||||
return self.seg8_load_custom
|
||||
else:
|
||||
return self.seg8_enum
|
||||
|
||||
@property
|
||||
def group5(self):
|
||||
if self.seg5_enum == "Custom":
|
||||
@@ -2829,6 +2843,13 @@ class SM64_SegmentProperties(bpy.types.PropertyGroup):
|
||||
else:
|
||||
return self.jump_link_from_enum(self.seg6_enum)
|
||||
|
||||
@property
|
||||
def group8(self):
|
||||
if self.seg8_enum == "Custom":
|
||||
return self.seg8_group_custom
|
||||
else:
|
||||
return self.jump_link_from_enum(self.seg8_enum)
|
||||
|
||||
|
||||
class SM64_ObjectProperties(bpy.types.PropertyGroup):
|
||||
version: bpy.props.IntProperty(name="SM64_ObjectProperties Version", default=0)
|
||||
|
||||
Reference in New Issue
Block a user