From edfcaa82f7ee3824b67eee7cc056b82c605647da Mon Sep 17 00:00:00 2001 From: MeltyPlayer Date: Mon, 23 Oct 2023 02:19:21 -0500 Subject: [PATCH] Sort of fixed level loading in Battalion Wars 2. --- .../Modl/Modl/src/api/ModlModelReader.cs | 16 +++++++--- .../Modl/Modl/src/api/OutModelReader.cs | 3 +- .../Modl/Modl/src/schema/anim/bw1/Bw1Anim.cs | 1 + .../Modl/Modl/src/schema/anim/bw2/Bw2Anim.cs | 29 ++++++++++--------- .../Modl/src/schema/xml/LevelXmlParser.cs | 23 ++++++++++----- .../src/platforms/wii/tools/Wit.cs | 16 +++++----- 6 files changed, 54 insertions(+), 34 deletions(-) diff --git a/FinModelUtility/Formats/Modl/Modl/src/api/ModlModelReader.cs b/FinModelUtility/Formats/Modl/Modl/src/api/ModlModelReader.cs index 5e03f365a..639307cda 100644 --- a/FinModelUtility/Formats/Modl/Modl/src/api/ModlModelReader.cs +++ b/FinModelUtility/Formats/Modl/Modl/src/api/ModlModelReader.cs @@ -106,11 +106,19 @@ public async Task ImportModelAsync( finBonesByIdentifier); } + var levelDir = modlFile.AssertGetParent(); + var baseLevelDir = levelDir.AssertGetParent(); var textureDictionary = new LazyDictionary>( - async textureName => { - var textureFile = - modlFile.AssertGetParent() - .AssertGetExistingFile($"{textureName}.texr"); + async textureNameWithoutExtension => { + var textureName = $"{textureNameWithoutExtension}.texr"; + IReadOnlyTreeFile textureFile; + if (!levelDir.TryToGetExistingFile( + textureName, + out textureFile)) { + textureFile = baseLevelDir + .GetFilesWithNameRecursive(textureName) + .First(); + } var texr = gameVersion == GameVersion.BW2 ? (ITexr) textureFile.ReadNew() diff --git a/FinModelUtility/Formats/Modl/Modl/src/api/OutModelReader.cs b/FinModelUtility/Formats/Modl/Modl/src/api/OutModelReader.cs index 1b6995eaa..a5956f6a3 100644 --- a/FinModelUtility/Formats/Modl/Modl/src/api/OutModelReader.cs +++ b/FinModelUtility/Formats/Modl/Modl/src/api/OutModelReader.cs @@ -44,8 +44,7 @@ public IModel ImportModel(IReadOnlyTreeFile outFile, var outDirectory = outFile.AssertGetParent() .GetExistingSubdirs() - .Single( - dir => dir.Name == outName + "_Level"); + .Single(dir => dir.Name.StartsWith(outName + "_L")); var allMapsDirectory = outDirectory.AssertGetParent(); return this.ImportModel(outFile, diff --git a/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw1/Bw1Anim.cs b/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw1/Bw1Anim.cs index f25328dcf..65674044c 100644 --- a/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw1/Bw1Anim.cs +++ b/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw1/Bw1Anim.cs @@ -130,6 +130,7 @@ public bool Parse4RotationValuesFrom3UShorts_(IBinaryReader br, Span outValues) { Span shorts = stackalloc ushort[3]; br.ReadUInt16s(shorts); + var first_ushort = shorts[0]; var second_ushort = shorts[1]; var third_ushort = shorts[2]; diff --git a/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw2/Bw2Anim.cs b/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw2/Bw2Anim.cs index dab23d4c6..4696689fe 100644 --- a/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw2/Bw2Anim.cs +++ b/FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw2/Bw2Anim.cs @@ -83,8 +83,10 @@ public void Read(IBinaryReader br) { var animBoneFrames = new AnimBoneFrames(); this.AnimBoneFrames.Add(animBoneFrames); + Span floats = stackalloc double[4]; + for (var p = 0; p < bone.PositionKeyframeCount; ++p) { - Parse3PositionValuesFrom2UShorts_(bone, ber, out var floats); + Parse3PositionValuesFrom2UShorts_(bone, ber, floats); animBoneFrames.PositionFrames.Add(((float) floats[0], (float) floats[1], (float) floats[2])); @@ -92,7 +94,7 @@ public void Read(IBinaryReader br) { for (var p = 0; p < bone.RotationKeyframeCount; ++p) { var flipSigns = - this.Parse4RotationValuesFrom4UShorts_(ber, out var floats); + this.Parse4RotationValuesFrom4UShorts_(ber, floats); if (flipSigns) { for (var f = 0; f < floats.Length; f++) { floats[f] *= -1; @@ -110,38 +112,40 @@ public void Read(IBinaryReader br) { public void Parse3PositionValuesFrom2UShorts_( IBwAnimBone animBone, SchemaBinaryReader br, - out double[] outValues) { + Span outValues) { var first_uint = br.ReadUInt32(); br.Position -= 2; var second_ushort = br.ReadUInt16(); - outValues = new double[3]; outValues[0] = (WeirdFloatMath.InterpretAsDouble( WeirdFloatMath.Concat44(0x43300000, (uint) (first_uint >> 0x15))) - - WeirdFloatMath.InterpretAsDouble(0x4330000000000000)) * + WeirdFloatMath.C_4503599627370496) * animBone.XPosDelta + animBone.XPosMin; outValues[1] = (WeirdFloatMath.InterpretAsDouble( WeirdFloatMath.Concat44(0x43300000, (uint) ((first_uint >> 10) & 0x7ff))) - - WeirdFloatMath.InterpretAsDouble(0x4330000000000000)) * + WeirdFloatMath.C_4503599627370496) * animBone.YPosDelta + animBone.YPosMin; outValues[2] = (WeirdFloatMath.InterpretAsDouble( WeirdFloatMath.Concat44(0x43300000, (uint) (second_ushort & 0x3ff))) - - WeirdFloatMath.InterpretAsDouble(0x4330000000000000)) * + WeirdFloatMath.C_4503599627370496) * animBone.ZPosDelta + animBone.ZPosMin; } public bool Parse4RotationValuesFrom4UShorts_(IBinaryReader br, - out double[] outValues) { - var first_ushort = br.ReadUInt16(); - var second_ushort = br.ReadUInt16(); - var third_ushort = br.ReadUInt16(); - var fourth_ushort = br.ReadUInt16(); + Span outValues) { + Span shorts = stackalloc ushort[4]; + br.ReadUInt16s(shorts); + + var first_ushort = shorts[0]; + var second_ushort = shorts[1]; + var third_ushort = shorts[2]; + var fourth_ushort = shorts[3]; const double DOUBLE_80600f40 = 4.503601774854144E15; const double FLOAT_80603708 = 3.0517578E-5; @@ -186,7 +190,6 @@ public bool Parse4RotationValuesFrom4UShorts_(IBinaryReader br, outW = -outW; } - outValues = new double[4]; outValues[0] = outX; outValues[1] = outY; outValues[2] = outZ; diff --git a/FinModelUtility/Formats/Modl/Modl/src/schema/xml/LevelXmlParser.cs b/FinModelUtility/Formats/Modl/Modl/src/schema/xml/LevelXmlParser.cs index 76666d0b0..10a401084 100644 --- a/FinModelUtility/Formats/Modl/Modl/src/schema/xml/LevelXmlParser.cs +++ b/FinModelUtility/Formats/Modl/Modl/src/schema/xml/LevelXmlParser.cs @@ -325,8 +325,12 @@ private void AddObjects_(ISceneArea sceneArea, GameVersion gameVersion, IBwTerrain bwTerrain, IDictionary objectMap) { + var parentDir = levelXmlFile.AssertGetParent(); var levelDirectory = - new FinDirectory(levelXmlFile.FullNameWithoutExtension); + parentDir.GetExistingSubdirs() + .Single( + subdir => subdir.FullPath.StartsWith( + levelXmlFile.FullNameWithoutExtension[..^4])); var modelFiles = levelDirectory .GetExistingFiles() .Where(file => file.Name.EndsWith(".modl")) @@ -456,10 +460,13 @@ await modlReader.ImportModelAsync( translation.X, translation.Z), translation.Z); - } else if (nextLinkId != null) { + } else if ( + nextLinkId != null && + levelObjMap.TryGetValue(nextLinkId, + out var positionObj)) { sceneObject.SetPosition( translation.X, - levelObjMap[nextLinkId].Position.Y, + positionObj.Position.Y, translation.Z); } else { sceneObject.SetPosition( @@ -470,16 +477,16 @@ await modlReader.ImportModelAsync( levelObjMap[levelObj.Id] = sceneObject; - if (nextLinkId != null) { - var nextLinkObj = levelObjMap[nextLinkId]; - - var nextLinkRotation = nextLinkObj.Rotation; + if (nextLinkId != null && + levelObjMap.TryGetValue(nextLinkId, + out var rotationAndLinkObj)) { + var nextLinkRotation = rotationAndLinkObj.Rotation; sceneObject.Rotation.SetDegrees( nextLinkRotation.XDegrees, nextLinkRotation.YDegrees, nextLinkRotation.ZDegrees); - var nextLinkScale = nextLinkObj.Scale; + var nextLinkScale = rotationAndLinkObj.Scale; sceneObject.SetScale(nextLinkScale.X, nextLinkScale.Y, nextLinkScale.Z); diff --git a/FinModelUtility/UniversalAssetTool/UniversalAssetTool/src/platforms/wii/tools/Wit.cs b/FinModelUtility/UniversalAssetTool/UniversalAssetTool/src/platforms/wii/tools/Wit.cs index 16a5e7bf5..0b1e5cc28 100644 --- a/FinModelUtility/UniversalAssetTool/UniversalAssetTool/src/platforms/wii/tools/Wit.cs +++ b/FinModelUtility/UniversalAssetTool/UniversalAssetTool/src/platforms/wii/tools/Wit.cs @@ -18,28 +18,30 @@ public bool Run(ISystemFile romFile, out IFileHierarchy hierarchy) { $"Cannot dump ROM because it does not exist: {romFile}"); var didChange = false; - if (ExtractorUtil.HasNotBeenExtractedYet(romFile, out var finalDirectory)) { + if (ExtractorUtil.HasNotBeenExtractedYet(romFile, + out var finalDirectory)) { didChange = true; - - this.DumpRom_(romFile); + this.DumpRom_(romFile, finalDirectory); Asserts.True(finalDirectory.Exists, $"Directory was not created: {finalDirectory}"); } - hierarchy = new FileHierarchy(romFile.NameWithoutExtension, finalDirectory); + hierarchy = + new FileHierarchy(romFile.NameWithoutExtension, finalDirectory); return didChange; } - private void DumpRom_(ISystemFile romFile) { + private void DumpRom_(ISystemFile romFile, ISystemDirectory outDirectory) { var logger = Logging.Create(); logger.LogInformation($"Dumping ROM {romFile}..."); + outDirectory.Delete(); Files.RunInDirectory( romFile.AssertGetParent()!, () => { - ProcessUtil.ExecuteBlockingSilently( + ProcessUtil.ExecuteBlocking( WiiToolsConstants.WIT_EXE, - $"extract \"{romFile.FullPath}\" \"./{romFile.NameWithoutExtension}\""); + $"extract \"{romFile.FullPath}\" \"{outDirectory.FullPath}\""); }); } }