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

[OoT] Fix latest decomp issues #366

Merged
merged 16 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 14 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
25 changes: 16 additions & 9 deletions fast64_internal/f3d/f3d_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1979,6 +1979,8 @@ def parseVertexData(dlData: str, vertexDataName: str, f3dContext: F3DContext):
pathMatch = re.search(r'\#include\s*"([^"]*)"', data)
if pathMatch is not None:
path = pathMatch.group(1)
if bpy.context.scene.gameEditorMode == "OOT":
path = f"{bpy.context.scene.fast64.oot.get_extracted_path()}/{path}"
data = readFile(f3dContext.getVTXPathFromInclude(path))

f3d = f3dContext.f3d
Expand Down Expand Up @@ -2081,6 +2083,8 @@ def parseTextureData(dlData, textureName, f3dContext, imageFormat, imageSize, wi
pathMatch = re.search(r'\#include\s*"(.*?)"', data, re.DOTALL)
if pathMatch is not None:
path = pathMatch.group(1)
if bpy.context.scene.gameEditorMode == "OOT":
path = f"{bpy.context.scene.fast64.oot.get_extracted_path()}/{path}"
originalImage = bpy.data.images.load(f3dContext.getImagePathFromInclude(path))
image = originalImage.copy()
image.pack()
Expand Down Expand Up @@ -2268,18 +2272,21 @@ def importMeshC(
f3dContext: F3DContext,
callClearMaterial: bool = True,
) -> bpy.types.Object:
mesh = bpy.data.meshes.new(name + "_mesh")
obj = bpy.data.objects.new(name + "_mesh", mesh)
bpy.context.collection.objects.link(obj)
if bpy.context.scene.gameEditorMode == "OOT":
mesh = bpy.data.meshes.new(name + "_mesh")
obj = bpy.data.objects.new(name + "_mesh", mesh)
bpy.context.collection.objects.link(obj)

f3dContext.mat().draw_layer.oot = drawLayer
transformMatrix = mathutils.Matrix.Scale(1 / scale, 4)
f3dContext.mat().draw_layer.oot = drawLayer
transformMatrix = mathutils.Matrix.Scale(1 / scale, 4)

parseF3D(data, name, transformMatrix, name, name, "oot", drawLayer, f3dContext, True)
f3dContext.createMesh(obj, removeDoubles, importNormals, callClearMaterial)
parseF3D(data, name, transformMatrix, name, name, "oot", drawLayer, f3dContext, True)
f3dContext.createMesh(obj, removeDoubles, importNormals, callClearMaterial)

applyRotation([obj], math.radians(-90), "X")
return obj
applyRotation([obj], math.radians(-90), "X")
return obj
else:
raise PluginError("ERROR: This function has not been implemented yet for this game.")


class F3D_ImportDL(bpy.types.Operator):
Expand Down
2 changes: 1 addition & 1 deletion fast64_internal/oot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ To be able to actually watch your cutscene you need to have a way to trigger it,
- ``ENTR_SPOT00_3`` is the Hyrule Field entrance from Lost Woods, see ``entrance_table.h`` to view/add entrances
- ``2`` means this cutscene can be watched as child AND as adult
- ``EVENTCHKINF_A0`` is the flag set in the ``event_chk_inf`` table, this is a macro but you can use raw hex: ``0xA0``
- ``gHyruleFieldIntroCs`` is the name of the array with the cutscene commands, as defined in ``assets/scenes/overworld/spot00_scene.c``, ``CutsceneData gHyruleFieldIntroCs[]``
- ``gHyruleFieldIntroCs`` is the name of the array with the cutscene commands, as defined in ``extracted/VERSION/assets/scenes/overworld/spot00_scene.c``, ``CutsceneData gHyruleFieldIntroCs[]``
4. Compile the game again and use the entrance you chose for ``sEntranceCutsceneTable`` and your cutscene should play.

Alternatively, you can use the map select to watch your cutscene, though note that this won't make it watchable during normal gameplay:
Expand Down
22 changes: 22 additions & 0 deletions fast64_internal/oot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@
oot_operator_unregister,
)

oot_versions_items = [
("Custom", "Custom", "Custom"),
("gc-jp", "gc-jp", "gc-jp"),
("gc-jp-mq", "gc-jp-mq", "gc-jp-mq"),
("gc-jp-ce", "gc-jp-ce", "gc-jp-ce"),
("gc-us", "gc-us", "gc-us"),
("gc-us-mq", "gc-us-mq", "gc-us-mq"),
("gc-eu", "gc-eu", "gc-eu"),
("gc-eu-mq", "gc-eu-mq", "gc-eu-mq"),
("gc-eu-mq-dbg", "gc-eu-mq-dbg", "gc-eu-mq-dbg"),
("hackeroot-mq", "HackerOoT", "hackeroot-mq"), # TODO: force this value if HackerOoT features are enabled?
("legacy", "Legacy", "Older Decomp Version"),
]


class OOT_Properties(bpy.types.PropertyGroup):
"""Global OOT Scene Properties found under scene.fast64.oot"""
Expand All @@ -75,6 +89,14 @@ class OOT_Properties(bpy.types.PropertyGroup):
animExportSettings: bpy.props.PointerProperty(type=OOTAnimExportSettingsProperty)
animImportSettings: bpy.props.PointerProperty(type=OOTAnimImportSettingsProperty)
collisionExportSettings: bpy.props.PointerProperty(type=OOTCollisionExportSettings)
oot_version: bpy.props.EnumProperty(name="OoT Version", items=oot_versions_items, default="gc-eu-mq-dbg")
oot_version_custom: bpy.props.StringProperty(name="Custom Version")

def get_extracted_path(self):
if self.oot_version == "legacy":
return "."
else:
return f"extracted/{self.oot_version if self.oot_version != 'Custom' else self.oot_version_custom}"

useDecompFeatures: bpy.props.BoolProperty(
name="Use decomp for export", description="Use names and macros from decomp when exporting", default=True
Expand Down
16 changes: 11 additions & 5 deletions fast64_internal/oot/animation/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

def exportAnimationC(armatureObj: bpy.types.Object, settings: OOTAnimExportSettingsProperty):
path = bpy.path.abspath(settings.customPath)
exportPath = ootGetObjectPath(settings.isCustom, path, settings.folderName)
exportPath = ootGetObjectPath(settings.isCustom, path, settings.folderName, False)

checkEmptyName(settings.folderName)
checkEmptyName(armatureObj.name)
Expand Down Expand Up @@ -66,7 +66,7 @@ def exportAnimationC(armatureObj: bpy.types.Object, settings: OOTAnimExportSetti
ootAnim = ootExportNonLinkAnimation(armatureObj, convertTransformMatrix, name)

ootAnimC = ootAnim.toC()
path = ootGetPath(exportPath, settings.isCustom, "assets/objects/", settings.folderName, False, False)
path = ootGetPath(exportPath, settings.isCustom, "assets/objects/", settings.folderName, True, False)
writeCData(ootAnimC, os.path.join(path, filename + ".h"), os.path.join(path, filename + ".c"))

if not settings.isCustom:
Expand All @@ -79,13 +79,19 @@ def ootImportAnimationC(
actorScale: float,
):
importPath = bpy.path.abspath(settings.customPath)
filepath = ootGetObjectPath(settings.isCustom, importPath, settings.folderName)
filepath = ootGetObjectPath(settings.isCustom, importPath, settings.folderName, True)
if settings.isLink:
numLimbs = 21
if not settings.isCustom:
basePath = bpy.path.abspath(bpy.context.scene.ootDecompPath)
animFilepath = os.path.join(basePath, "assets/misc/link_animetion/link_animetion.c")
animHeaderFilepath = os.path.join(basePath, "assets/objects/gameplay_keep/gameplay_keep.c")
animFilepath = os.path.join(
basePath,
f"{bpy.context.scene.fast64.oot.get_extracted_path()}/assets/misc/link_animetion/link_animetion.c",
)
animHeaderFilepath = os.path.join(
basePath,
f"{bpy.context.scene.fast64.oot.get_extracted_path()}/assets/objects/gameplay_keep/gameplay_keep.c",
)
else:
animFilepath = filepath
animHeaderFilepath = filepath
Expand Down
2 changes: 1 addition & 1 deletion fast64_internal/oot/collision/exporter/to_c/collision.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def exportCollisionToC(
name = toAlnum(originalObj.name)
isCustomExport = exportSettings.customExport
folderName = exportSettings.folder
exportPath = ootGetObjectPath(isCustomExport, bpy.path.abspath(exportSettings.exportPath), folderName)
exportPath = ootGetObjectPath(isCustomExport, bpy.path.abspath(exportSettings.exportPath), folderName, False)

collision = OOTCollision(name)
collision.cameraData = OOTCameraData(name)
Expand Down
8 changes: 4 additions & 4 deletions fast64_internal/oot/f3d/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,21 +119,21 @@ def execute(self, context):
flipbookUses2DArray = settings.flipbookUses2DArray
flipbookArrayIndex2D = settings.flipbookArrayIndex2D if flipbookUses2DArray else None

paths = [ootGetObjectPath(isCustomImport, importPath, folderName)]
data = getImportData(paths)
paths = [ootGetObjectPath(isCustomImport, importPath, folderName, True)]
filedata = getImportData(paths)
f3dContext = OOTF3DContext(get_F3D_GBI(), [name], basePath)

scale = getOOTScale(settings.actorScale)
if not isCustomImport:
data = ootGetIncludedAssetData(basePath, paths, data) + data
filedata = ootGetIncludedAssetData(basePath, paths, filedata) + filedata

if overlayName is not None:
ootReadTextureArrays(basePath, overlayName, name, f3dContext, False, flipbookArrayIndex2D)
if settings.autoDetectActorScale:
scale = ootReadActorScale(basePath, overlayName, False)

obj = importMeshC(
data,
filedata,
name,
scale,
removeDoubles,
Expand Down
2 changes: 2 additions & 0 deletions fast64_internal/oot/f3d/properties.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import bpy

from bpy.types import PropertyGroup, Object, World, Material, UILayout
from bpy.props import PointerProperty, StringProperty, BoolProperty, EnumProperty, IntProperty, FloatProperty
from bpy.utils import register_class, unregister_class
Expand Down
5 changes: 5 additions & 0 deletions fast64_internal/oot/file_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ def draw(self, context):
prop_split(col, context.scene, "ootBlenderScale", "OOT Scene Scale")

prop_split(col, context.scene, "ootDecompPath", "Decomp Path")

prop_split(col, context.scene.fast64.oot, "oot_version", "OoT Version")
if context.scene.fast64.oot.oot_version == "Custom":
prop_split(col, context.scene.fast64.oot, "oot_version_custom", "Custom Version")

col.prop(context.scene.fast64.oot, "headerTabAffectsVisibility")
col.prop(context.scene.fast64.oot, "hackerFeaturesEnabled")

Expand Down
15 changes: 11 additions & 4 deletions fast64_internal/oot/oot_level_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def parseScene(
subfolder = None
else:
if option == "Custom":
subfolder = "assets/scenes/" + settings.subFolder + "/"
subfolder = f"{bpy.context.scene.fast64.oot.get_extracted_path()}/assets/scenes/{settings.subFolder}/"
else:
sceneName = sceneNameFromID(option)
subfolder = None
Expand All @@ -214,9 +214,16 @@ def parseScene(
if settings.isCustomDest is not None:
importSubdir = subfolder
if not settings.isCustomDest and subfolder is None:
importSubdir = os.path.dirname(getSceneDirFromLevelName(sceneName)) + "/"

sceneFolderPath = ootGetPath(importPath, settings.isCustomDest, importSubdir, sceneName, False, True)
importSubdir = os.path.dirname(getSceneDirFromLevelName(sceneName, True)) + "/"

sceneFolderPath = ootGetPath(
f"{importPath}/{bpy.context.scene.fast64.oot.get_extracted_path()}/",
settings.isCustomDest,
importSubdir,
sceneName,
False,
True,
)
filePath = os.path.join(sceneFolderPath, f"{sceneName}_scene.c")
sceneData = readFile(filePath)

Expand Down
26 changes: 20 additions & 6 deletions fast64_internal/oot/oot_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def isPathObject(obj: bpy.types.Object) -> bool:
"testroom",
]

# NOTE: the "extracted/VERSION/" part is added in ``getSceneDirFromLevelName`` when needed
ootSceneDirs = {
"assets/scenes/dungeons/": ootSceneDungeons,
"assets/scenes/indoors/": ootSceneIndoors,
Expand Down Expand Up @@ -243,10 +244,11 @@ def addIncludeFilesExtension(objectName, objectPath, assetName, extension):
saveDataToFile(path, data)


def getSceneDirFromLevelName(name):
def getSceneDirFromLevelName(name: str, include_extracted: bool = False):
extracted = bpy.context.scene.fast64.oot.get_extracted_path() if include_extracted else "."
for sceneDir, dirLevels in ootSceneDirs.items():
if name in dirLevels:
return sceneDir + name
return f"{extracted}/" + sceneDir + name
return None


Expand Down Expand Up @@ -458,22 +460,34 @@ def checkEmptyName(name):
raise PluginError("No name entered for the exporter.")


def ootGetObjectPath(isCustomExport: bool, exportPath: str, folderName: str) -> str:
def ootGetObjectPath(isCustomExport: bool, exportPath: str, folderName: str, include_extracted: bool) -> str:
extracted = bpy.context.scene.fast64.oot.get_extracted_path() if include_extracted else "."

if isCustomExport:
filepath = exportPath
else:
filepath = os.path.join(
ootGetPath(exportPath, isCustomExport, "assets/objects/", folderName, False, False), folderName + ".c"
ootGetPath(
exportPath,
isCustomExport,
f"{extracted}/assets/objects/",
folderName,
False,
False,
),
folderName + ".c",
)
return filepath


def ootGetObjectHeaderPath(isCustomExport: bool, exportPath: str, folderName: str) -> str:
def ootGetObjectHeaderPath(isCustomExport: bool, exportPath: str, folderName: str, include_extracted: bool) -> str:
extracted = bpy.context.scene.fast64.oot.get_extracted_path() if include_extracted else "."
if isCustomExport:
filepath = exportPath
else:
filepath = os.path.join(
ootGetPath(exportPath, isCustomExport, "assets/objects/", folderName, False, False), folderName + ".h"
ootGetPath(exportPath, isCustomExport, f"{extracted}/assets/objects/", folderName, False, False),
folderName + ".h",
)
return filepath

Expand Down
8 changes: 4 additions & 4 deletions fast64_internal/oot/scene/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,21 +222,21 @@ class OOT_RemoveScene(Operator):

def execute(self, context):
settings = context.scene.ootSceneRemoveSettings # Type: OOTRemoveSceneSettingsProperty
levelName = settings.name
option = settings.option

if settings.customExport:
self.report({"ERROR"}, "You can only remove scenes from your decomp path.")
return {"FINISHED"}

if option == "Custom":
subfolder = "assets/scenes/" + settings.subFolder + "/"
levelName = settings.name
subfolder = f"assets/scenes/{settings.subFolder}/"
else:
levelName = sceneNameFromID(option)
subfolder = None
removeInfo = RemoveInfo(abspath(context.scene.ootDecompPath), subfolder, levelName)

Files.remove_scene(removeInfo)
# the scene files will be removed from `assets` if it's present
Files.remove_scene(RemoveInfo(abspath(context.scene.ootDecompPath), subfolder, levelName))

self.report({"INFO"}, "Success!")
return {"FINISHED"}
Expand Down
15 changes: 2 additions & 13 deletions fast64_internal/oot/scene/panels.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import bpy
import os

from bpy.types import UILayout
from bpy.utils import register_class, unregister_class
from ...utility import customExportWarning, prop_split
from ...panels import OOT_Panel
from ..oot_constants import ootEnumSceneID
from ..oot_utility import getEnumName
Expand All @@ -10,7 +11,6 @@
OOTImportSceneSettingsProperty,
OOTRemoveSceneSettingsProperty,
OOTBootupSceneOptions,
OOTSceneCommon,
)

from .operators import (
Expand Down Expand Up @@ -80,17 +80,6 @@ def draw(self, context):
removeRow = removeBox.row()
removeRow.operator(OOT_RemoveScene.bl_idname, text="Remove Scene")

if removeSettings.option == "Custom":
exportPath = (
context.scene.ootDecompPath + f"assets/scenes/{removeSettings.subFolder}/{removeSettings.name}/"
)

if not os.path.exists(exportPath):
removeRow.enabled = False
removeBox.label(text="This path doesn't exist.")
else:
removeRow.enabled = True


classes = (OOT_ExportScenePanel,)

Expand Down
4 changes: 2 additions & 2 deletions fast64_internal/oot/skeleton/exporter/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def ootProcessBone(
def ootConvertArmatureToSkeleton(
originalArmatureObj,
convertTransformMatrix,
fModel,
fModel: OOTModel,
name,
convertTextureData,
skeletonOnly,
Expand Down Expand Up @@ -280,7 +280,7 @@ def ootConvertArmatureToC(
else:
data.source += "\n"

path = ootGetPath(exportPath, isCustomExport, "assets/objects/", folderName, False, True)
path = ootGetPath(exportPath, isCustomExport, "assets/objects/", folderName, True, True)
includeDir = settings.customAssetIncludeDir if settings.isCustom else f"assets/objects/{folderName}"
exportData = fModel.to_c(
TextureExportSettings(False, savePNG, includeDir, path), OOTGfxFormatter(ScrollMethod.Vertex)
Expand Down
6 changes: 3 additions & 3 deletions fast64_internal/oot/skeleton/importer/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from ....utility import hexOrDecInt, applyRotation, PluginError
from ...oot_f3d_writer import ootReadActorScale
from ...oot_model_classes import OOTF3DContext, ootGetIncludedAssetData
from ...oot_utility import ootGetObjectPath, getOOTScale, ootGetObjectHeaderPath, ootGetEnums, ootStripComments
from ...oot_utility import OOTEnum, ootGetObjectPath, getOOTScale, ootGetObjectHeaderPath, ootGetEnums, ootStripComments
from ...oot_texture_array import ootReadTextureArrays
from ..constants import ootSkeletonImportDict
from ..properties import OOTSkeletonImportSettings
Expand Down Expand Up @@ -259,8 +259,8 @@ def ootImportSkeletonC(basePath: str, importSettings: OOTSkeletonImportSettings)
restPoseData = None

filepaths = [
ootGetObjectPath(isCustomImport, importPath, folderName),
ootGetObjectHeaderPath(isCustomImport, importPath, folderName),
ootGetObjectPath(isCustomImport, importPath, folderName, True),
ootGetObjectHeaderPath(isCustomImport, importPath, folderName, True),
]

removeDoubles = importSettings.removeDoubles
Expand Down
4 changes: 3 additions & 1 deletion fast64_internal/oot/skeleton/properties.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from bpy.types import Armature, PropertyGroup, Object, Bone, UILayout
import bpy

from bpy.types import PropertyGroup, Object, Bone, UILayout
from bpy.props import EnumProperty, PointerProperty, StringProperty, FloatProperty, BoolProperty, IntProperty
from bpy.utils import register_class, unregister_class
from ...f3d.f3d_material import ootEnumDrawLayers
Expand Down
Loading