Skip to content

Commit

Permalink
Sort of fixed level loading in Battalion Wars 2.
Browse files Browse the repository at this point in the history
  • Loading branch information
MeltyPlayer committed Oct 23, 2023
1 parent dec3db1 commit edfcaa8
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 34 deletions.
16 changes: 12 additions & 4 deletions FinModelUtility/Formats/Modl/Modl/src/api/ModlModelReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,19 @@ public async Task<IModel> ImportModelAsync(
finBonesByIdentifier);
}

var levelDir = modlFile.AssertGetParent();
var baseLevelDir = levelDir.AssertGetParent();
var textureDictionary = new LazyDictionary<string, Task<ITexture>>(
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<Gtxd>()
Expand Down
3 changes: 1 addition & 2 deletions FinModelUtility/Formats/Modl/Modl/src/api/OutModelReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public bool Parse4RotationValuesFrom3UShorts_(IBinaryReader br,
Span<double> outValues) {
Span<ushort> shorts = stackalloc ushort[3];
br.ReadUInt16s(shorts);

var first_ushort = shorts[0];
var second_ushort = shorts[1];
var third_ushort = shorts[2];
Expand Down
29 changes: 16 additions & 13 deletions FinModelUtility/Formats/Modl/Modl/src/schema/anim/bw2/Bw2Anim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,18 @@ public void Read(IBinaryReader br) {
var animBoneFrames = new AnimBoneFrames();
this.AnimBoneFrames.Add(animBoneFrames);

Span<double> 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]));
}

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;
Expand All @@ -110,38 +112,40 @@ public void Read(IBinaryReader br) {
public void Parse3PositionValuesFrom2UShorts_(
IBwAnimBone animBone,
SchemaBinaryReader br,
out double[] outValues) {
Span<double> 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<double> outValues) {
Span<ushort> 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;
Expand Down Expand Up @@ -186,7 +190,6 @@ public bool Parse4RotationValuesFrom4UShorts_(IBinaryReader br,
outW = -outW;
}

outValues = new double[4];
outValues[0] = outX;
outValues[1] = outY;
outValues[2] = outZ;
Expand Down
23 changes: 15 additions & 8 deletions FinModelUtility/Formats/Modl/Modl/src/schema/xml/LevelXmlParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,12 @@ private void AddObjects_(ISceneArea sceneArea,
GameVersion gameVersion,
IBwTerrain bwTerrain,
IDictionary<string, IBwObject> 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"))
Expand Down Expand Up @@ -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(
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Wit>();
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}\"");
});
}
}
Expand Down

0 comments on commit edfcaa8

Please sign in to comment.