From edc901fbb8de4ee7388542549f24df1313b57321 Mon Sep 17 00:00:00 2001
From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
Date: Wed, 18 Dec 2024 19:29:13 +0000
Subject: [PATCH 1/3] SplitTools Cleanup
---
.../AnimJSONConverter.csproj | 1 -
CommandLine/ArchiveTool/ArchiveTool.csproj | 1 -
CommandLine/BuildEvent/BuildEvent.csproj | 1 -
CommandLine/BuildMDL/BuildMDL.csproj | 1 -
CommandLine/BuildMTN/BuildMTN.csproj | 1 -
.../BuildShapeMotion/BuildShapeMotion.csproj | 1 -
.../LevelConverter/LevelConverter.csproj | 1 -
.../ModelConverter/ModelConverter.csproj | 1 -
CommandLine/ModelFixes/ModelFixes.csproj | 1 -
.../ModelRelabeler/ModelRelabeler.csproj | 1 -
CommandLine/OptimizeAnim/OptimizeAnim.csproj | 1 -
CommandLine/PAKtool/PAKtool.csproj | 1 -
.../SplitShapeMotion/SplitShapeMotion.csproj | 1 -
CommandLine/TextureRemap/TextureRemap.csproj | 1 -
.../WeldConverter/WeldConverter.csproj | 1 -
CommandLine/buildSATools/buildSATools.csproj | 1 -
CommandLine/split/split.csproj | 1 -
CommandLine/splitEvent/Program.cs | 39 +-
CommandLine/splitEvent/splitEvent.csproj | 1 -
CommandLine/splitMDL/splitMDL.csproj | 1 -
CommandLine/splitMTN/Program.cs | 16 +-
CommandLine/splitMTN/splitMTN.csproj | 1 -
DataToolbox/DataToolbox.csproj | 1 -
Libraries/ArchiveLib/ArchiveLib.csproj | 1 -
.../FraGag.Compression.Prs.csproj | 1 -
.../NvTriStripDotNet/NvTriStripDotNet.csproj | 1 -
.../SAEditorCommon/SAEditorCommon.csproj | 1 -
.../SAModel.Direct3D/SAModel.Direct3D.csproj | 1 -
Libraries/SAModel/SAModel.csproj | 2 -
Libraries/SplitTools/HelperFunctions.cs | 950 +++++++++++-------
Libraries/SplitTools/IniData.cs | 1 -
Libraries/SplitTools/IniData_SplitDLL.cs | 1 -
Libraries/SplitTools/SplitBinary.cs | 1 -
Libraries/SplitTools/SplitDLL.cs | 1 -
Libraries/SplitTools/SplitEventCyclone.cs | 108 +-
Libraries/SplitTools/SplitEventExtra.cs | 227 ++++-
Libraries/SplitTools/SplitMTN.cs | 5 +-
Libraries/SplitTools/SplitMiniEvent.cs | 116 ++-
Libraries/SplitTools/SplitTools.csproj | 5 -
Libraries/VrSharp/VrSharp.csproj | 1 -
SA1Tools/PLTool/PLTool.csproj | 1 -
.../SADXObjectDefinitions.csproj | 1 -
SA1Tools/SADXTweaker2/SADXTweaker2.csproj | 1 -
SA1Tools/SADXsndSharp/SADXsndSharp.csproj | 1 -
SA1Tools/SASave/SASave.csproj | 1 -
SA1Tools/VMSEditor/VMSEditor.csproj | 1 -
.../SA2CutsceneTextEditor.csproj | 1 -
SA2Tools/SA2EventViewer/SA2EventViewer.csproj | 1 -
.../SA2MessageFileEditor.csproj | 1 -
.../SA2ObjectDefinitions.csproj | 1 -
.../SA2StageSelEdit/SA2StageSelEdit.csproj | 1 -
SAFontEdit/SAFontEdit.csproj | 1 -
SALVL/SALVL.csproj | 1 -
SAMDL/SAMDL.csproj | 1 -
SAToolsHub/SAToolsHub.csproj | 1 -
TextureEditor/TextureEditor.csproj | 1 -
56 files changed, 1006 insertions(+), 509 deletions(-)
diff --git a/CommandLine/AnimJSONConverter/AnimJSONConverter.csproj b/CommandLine/AnimJSONConverter/AnimJSONConverter.csproj
index e12aa5d1..89ece23b 100644
--- a/CommandLine/AnimJSONConverter/AnimJSONConverter.csproj
+++ b/CommandLine/AnimJSONConverter/AnimJSONConverter.csproj
@@ -9,7 +9,6 @@
false
false
embedded
- x64;x86
diff --git a/CommandLine/ArchiveTool/ArchiveTool.csproj b/CommandLine/ArchiveTool/ArchiveTool.csproj
index a3b0a779..e8133777 100644
--- a/CommandLine/ArchiveTool/ArchiveTool.csproj
+++ b/CommandLine/ArchiveTool/ArchiveTool.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/BuildEvent/BuildEvent.csproj b/CommandLine/BuildEvent/BuildEvent.csproj
index 311d3a79..590c87b5 100644
--- a/CommandLine/BuildEvent/BuildEvent.csproj
+++ b/CommandLine/BuildEvent/BuildEvent.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/BuildMDL/BuildMDL.csproj b/CommandLine/BuildMDL/BuildMDL.csproj
index 311d3a79..590c87b5 100644
--- a/CommandLine/BuildMDL/BuildMDL.csproj
+++ b/CommandLine/BuildMDL/BuildMDL.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/BuildMTN/BuildMTN.csproj b/CommandLine/BuildMTN/BuildMTN.csproj
index 311d3a79..590c87b5 100644
--- a/CommandLine/BuildMTN/BuildMTN.csproj
+++ b/CommandLine/BuildMTN/BuildMTN.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/BuildShapeMotion/BuildShapeMotion.csproj b/CommandLine/BuildShapeMotion/BuildShapeMotion.csproj
index 284b2119..3895960e 100644
--- a/CommandLine/BuildShapeMotion/BuildShapeMotion.csproj
+++ b/CommandLine/BuildShapeMotion/BuildShapeMotion.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/LevelConverter/LevelConverter.csproj b/CommandLine/LevelConverter/LevelConverter.csproj
index 9be7fc0b..a091bcaa 100644
--- a/CommandLine/LevelConverter/LevelConverter.csproj
+++ b/CommandLine/LevelConverter/LevelConverter.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/ModelConverter/ModelConverter.csproj b/CommandLine/ModelConverter/ModelConverter.csproj
index d18b0e70..4883bc28 100644
--- a/CommandLine/ModelConverter/ModelConverter.csproj
+++ b/CommandLine/ModelConverter/ModelConverter.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/ModelFixes/ModelFixes.csproj b/CommandLine/ModelFixes/ModelFixes.csproj
index d1f0e832..64e5e9f5 100644
--- a/CommandLine/ModelFixes/ModelFixes.csproj
+++ b/CommandLine/ModelFixes/ModelFixes.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/ModelRelabeler/ModelRelabeler.csproj b/CommandLine/ModelRelabeler/ModelRelabeler.csproj
index 50d63fad..8a3b7145 100644
--- a/CommandLine/ModelRelabeler/ModelRelabeler.csproj
+++ b/CommandLine/ModelRelabeler/ModelRelabeler.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/OptimizeAnim/OptimizeAnim.csproj b/CommandLine/OptimizeAnim/OptimizeAnim.csproj
index e12aa5d1..89ece23b 100644
--- a/CommandLine/OptimizeAnim/OptimizeAnim.csproj
+++ b/CommandLine/OptimizeAnim/OptimizeAnim.csproj
@@ -9,7 +9,6 @@
false
false
embedded
- x64;x86
diff --git a/CommandLine/PAKtool/PAKtool.csproj b/CommandLine/PAKtool/PAKtool.csproj
index cfc3440f..95c0b9e3 100644
--- a/CommandLine/PAKtool/PAKtool.csproj
+++ b/CommandLine/PAKtool/PAKtool.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/SplitShapeMotion/SplitShapeMotion.csproj b/CommandLine/SplitShapeMotion/SplitShapeMotion.csproj
index 284b2119..3895960e 100644
--- a/CommandLine/SplitShapeMotion/SplitShapeMotion.csproj
+++ b/CommandLine/SplitShapeMotion/SplitShapeMotion.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/TextureRemap/TextureRemap.csproj b/CommandLine/TextureRemap/TextureRemap.csproj
index d1f0e832..64e5e9f5 100644
--- a/CommandLine/TextureRemap/TextureRemap.csproj
+++ b/CommandLine/TextureRemap/TextureRemap.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/WeldConverter/WeldConverter.csproj b/CommandLine/WeldConverter/WeldConverter.csproj
index 69ddb004..0b388d66 100644
--- a/CommandLine/WeldConverter/WeldConverter.csproj
+++ b/CommandLine/WeldConverter/WeldConverter.csproj
@@ -8,7 +8,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/buildSATools/buildSATools.csproj b/CommandLine/buildSATools/buildSATools.csproj
index 76053a17..e99afd84 100644
--- a/CommandLine/buildSATools/buildSATools.csproj
+++ b/CommandLine/buildSATools/buildSATools.csproj
@@ -7,6 +7,5 @@
embedded
false
false
- x64;x86
\ No newline at end of file
diff --git a/CommandLine/split/split.csproj b/CommandLine/split/split.csproj
index 66c02ba1..37438af0 100644
--- a/CommandLine/split/split.csproj
+++ b/CommandLine/split/split.csproj
@@ -8,7 +8,6 @@
false
false
embedded
- x64;x86
diff --git a/CommandLine/splitEvent/Program.cs b/CommandLine/splitEvent/Program.cs
index ad2b4c8a..c1973d32 100644
--- a/CommandLine/splitEvent/Program.cs
+++ b/CommandLine/splitEvent/Program.cs
@@ -7,23 +7,14 @@ namespace splitEvent
{
static class Program
{
- public class Wildcard : Regex
+ private class Wildcard : Regex
{
- ///
- /// Initializes a wildcard with the given search pattern.
- ///
- /// The wildcard pattern to match.
- public Wildcard(string pattern)
- : base(WildcardToRegex(pattern))
- {
- }
-
///
/// Initializes a wildcard with the given search pattern and options.
///
/// The wildcard pattern to match.
/// A combination of one or more
- /// .
+ /// .
public Wildcard(string pattern, RegexOptions options)
: base(WildcardToRegex(pattern), options)
{
@@ -45,19 +36,23 @@ static void Main(string[] args)
{
string fullpath_out;
string fullpath_bin;
+
if (args.Length == 0)
{
Console.Write("Filename: ");
- args = new string[] { Console.ReadLine().Trim('"') };
+ args = [Console.ReadLine().Trim('"')];
}
+
fullpath_bin = Path.GetFullPath(args[0]);
string name = Path.GetFileName(fullpath_bin);
+
Wildcard evwcard = new Wildcard("e*", RegexOptions.IgnoreCase);
Wildcard mevwcard = new Wildcard("me*", RegexOptions.IgnoreCase);
Wildcard evxwcard = new Wildcard("e*_*", RegexOptions.IgnoreCase);
Wildcard mevxwcard = new Wildcard("me*_*", RegexOptions.IgnoreCase);
Wildcard exfwcard = new Wildcard("e*_*.*", RegexOptions.IgnoreCase);
Wildcard mexfwcard = new Wildcard("me*_*.*", RegexOptions.IgnoreCase);
+
if (!name.EndsWith("texlist.prs", StringComparison.OrdinalIgnoreCase))
{
if (mevwcard.IsMatch(name))
@@ -111,22 +106,40 @@ static void Main(string[] args)
if (args.Length > 1)
{
fullpath_out = args[1];
- if (fullpath_out[fullpath_out.Length - 1] != '/') fullpath_out = string.Concat(fullpath_out, '/');
+ if (fullpath_out[fullpath_out.Length - 1] != '/')
+ {
+ fullpath_out = string.Concat(fullpath_out, '/');
+ }
+
fullpath_out = Path.GetFullPath(fullpath_out);
}
+
Console.WriteLine("Output folder: {0}", fullpath_out);
+
if (name.Contains("tailsplain", StringComparison.OrdinalIgnoreCase))
+ {
sa2EventTailsPlane.Split(fullpath_bin, fullpath_out);
+ }
else if (name.EndsWith("texlist.prs", StringComparison.OrdinalIgnoreCase))
+ {
SA2Event.SplitExternalTexList(fullpath_bin, fullpath_out);
+ }
else if (mexfwcard.IsMatch(name))
+ {
sa2EventExtra.SplitMini(fullpath_bin, fullpath_out);
+ }
else if (exfwcard.IsMatch(name))
+ {
sa2EventExtra.Split(fullpath_bin, fullpath_out);
+ }
else if (name.StartsWith("me", StringComparison.OrdinalIgnoreCase))
+ {
SA2MiniEvent.Split(fullpath_bin, fullpath_out);
+ }
else
+ {
SA2Event.Split(fullpath_bin, fullpath_out);
+ }
}
}
}
\ No newline at end of file
diff --git a/CommandLine/splitEvent/splitEvent.csproj b/CommandLine/splitEvent/splitEvent.csproj
index 311d3a79..590c87b5 100644
--- a/CommandLine/splitEvent/splitEvent.csproj
+++ b/CommandLine/splitEvent/splitEvent.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/CommandLine/splitMDL/splitMDL.csproj b/CommandLine/splitMDL/splitMDL.csproj
index 4d0f26a4..bf2a411f 100644
--- a/CommandLine/splitMDL/splitMDL.csproj
+++ b/CommandLine/splitMDL/splitMDL.csproj
@@ -9,7 +9,6 @@
false
en
embedded
- x64;x86
diff --git a/CommandLine/splitMTN/Program.cs b/CommandLine/splitMTN/Program.cs
index 4546f06b..1a3a42c8 100644
--- a/CommandLine/splitMTN/Program.cs
+++ b/CommandLine/splitMTN/Program.cs
@@ -4,24 +4,26 @@
namespace splitMTN
{
- class Program
+ internal static class Program
{
- static void Main(string[] args)
+ private static void Main(string[] args)
{
- Queue argq = new Queue(args);
+ var argQueue = new Queue(args);
+
string filename;
- if (argq.Count > 0)
+
+ if (argQueue.Count > 0)
{
- filename = argq.Dequeue();
+ filename = argQueue.Dequeue();
Console.WriteLine("File: {0}", filename);
- SA2MTN.Split(filename);
}
else
{
Console.Write("File: ");
filename = Console.ReadLine();
- SA2MTN.Split(filename);
}
+
+ SA2MTN.Split(filename);
}
}
}
\ No newline at end of file
diff --git a/CommandLine/splitMTN/splitMTN.csproj b/CommandLine/splitMTN/splitMTN.csproj
index 311d3a79..590c87b5 100644
--- a/CommandLine/splitMTN/splitMTN.csproj
+++ b/CommandLine/splitMTN/splitMTN.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/DataToolbox/DataToolbox.csproj b/DataToolbox/DataToolbox.csproj
index 4b4167be..9e6c449f 100644
--- a/DataToolbox/DataToolbox.csproj
+++ b/DataToolbox/DataToolbox.csproj
@@ -8,7 +8,6 @@
false
en
embedded
- x64;x86
datatoolbox.ico
diff --git a/Libraries/ArchiveLib/ArchiveLib.csproj b/Libraries/ArchiveLib/ArchiveLib.csproj
index 1d944151..2d482a87 100644
--- a/Libraries/ArchiveLib/ArchiveLib.csproj
+++ b/Libraries/ArchiveLib/ArchiveLib.csproj
@@ -8,7 +8,6 @@
false
false
embedded
- x64;x86
diff --git a/Libraries/FraGag.Compression.Prs/FraGag.Compression.Prs.csproj b/Libraries/FraGag.Compression.Prs/FraGag.Compression.Prs.csproj
index a5458afa..c35fdacd 100644
--- a/Libraries/FraGag.Compression.Prs/FraGag.Compression.Prs.csproj
+++ b/Libraries/FraGag.Compression.Prs/FraGag.Compression.Prs.csproj
@@ -7,6 +7,5 @@
embedded
false
false
- x64;x86
\ No newline at end of file
diff --git a/Libraries/NvTriStripDotNet/NvTriStripDotNet.csproj b/Libraries/NvTriStripDotNet/NvTriStripDotNet.csproj
index 212bda9e..6ec30dad 100644
--- a/Libraries/NvTriStripDotNet/NvTriStripDotNet.csproj
+++ b/Libraries/NvTriStripDotNet/NvTriStripDotNet.csproj
@@ -7,7 +7,6 @@
false
false
true
- x64;x86
diff --git a/Libraries/SAEditorCommon/SAEditorCommon.csproj b/Libraries/SAEditorCommon/SAEditorCommon.csproj
index 6a1c4300..a3c3b7b5 100644
--- a/Libraries/SAEditorCommon/SAEditorCommon.csproj
+++ b/Libraries/SAEditorCommon/SAEditorCommon.csproj
@@ -9,7 +9,6 @@
false
false
embedded
- x64;x86
diff --git a/Libraries/SAModel.Direct3D/SAModel.Direct3D.csproj b/Libraries/SAModel.Direct3D/SAModel.Direct3D.csproj
index 1f5ae635..221c2ab0 100644
--- a/Libraries/SAModel.Direct3D/SAModel.Direct3D.csproj
+++ b/Libraries/SAModel.Direct3D/SAModel.Direct3D.csproj
@@ -8,7 +8,6 @@
embedded
false
false
- x64;x86
diff --git a/Libraries/SAModel/SAModel.csproj b/Libraries/SAModel/SAModel.csproj
index 9e252940..887665b0 100644
--- a/Libraries/SAModel/SAModel.csproj
+++ b/Libraries/SAModel/SAModel.csproj
@@ -1,6 +1,5 @@
-
net8.0-windows7.0
Library
true
@@ -8,7 +7,6 @@
en
false
false
- x64;x86
diff --git a/Libraries/SplitTools/HelperFunctions.cs b/Libraries/SplitTools/HelperFunctions.cs
index 8579fc0c..6cd570c5 100644
--- a/Libraries/SplitTools/HelperFunctions.cs
+++ b/Libraries/SplitTools/HelperFunctions.cs
@@ -1,8 +1,11 @@
using SAModel;
using System;
-using System.Collections.Generic;
+using System.Buffers;
+using System.Buffers.Binary;
using System.Globalization;
using System.IO;
+using System.Linq;
+using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
@@ -10,42 +13,201 @@ namespace SplitTools
{
public static class HelperFunctions
{
- // X86 SACompGC
- [DllImport("SACompGC_x86.dll", EntryPoint = "GetDecompressedSize", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
- private static extern uint GetDecompressedSizeX86(IntPtr InputBuffer);
- [DllImport("SACompGC_x86.dll", EntryPoint = "DecompressBuffer", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
- private static extern void DecompressBufferX86(IntPtr InputBuffer, IntPtr OutputBuffer);
- // X64 SACompGC
- [DllImport("SACompGC_x64.dll", EntryPoint = "GetDecompressedSize", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
- private static extern uint GetDecompressedSizeX64(IntPtr InputBuffer);
- [DllImport("SACompGC_x64.dll", EntryPoint = "DecompressBuffer", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
- private static extern void DecompressBufferX64(IntPtr InputBuffer, IntPtr OutputBuffer);
+ private static T ReadAs(Span span, int byteIndex) where T : unmanaged
+ {
+ return MemoryMarshal.Read(span[byteIndex..]);
+ }
+
+ private static uint SACompGC_GetData(uint numBits, ref SACompGCStatus data)
+ {
+ uint retVal;
+
+ if (data.BitBufferRemaining < numBits)
+ {
+ var v6 = (int)(numBits - data.BitBufferRemaining);
+ retVal = data.BitBuffer << (int)(numBits - data.BitBufferRemaining);
+
+ if (data.ReadOffset != 0 || data.ChunkCount != 0)
+ {
+ var v9 = BinaryPrimitives.ReverseEndianness(ReadAs(data.InputBuffer, data.ReadHead + (int)data.ReadOffset));
+ data.ReadOffset += 4;
+
+ var clearBits = 32 - v6;
+ retVal |= v9 << clearBits >> clearBits;
+ data.BitBufferRemaining = (byte)clearBits;
+ data.BitBuffer = v9 >> v6;
+
+ if (data.ReadOffset == 0x8000)
+ {
+ data.ReadOffset = 0;
+ data.ReadHead += 0x8000;
+ if (data.ReadHead == data.EndOffset)
+ {
+ data.ReadHead = 0;
+ }
+ data.ChunkCount--;
+ }
+ }
+ }
+ else
+ {
+ var v4 = data.BitBuffer;
+ data.BitBufferRemaining -= (byte)numBits;
+ data.BitBuffer >>= (int)numBits;
+
+ var clearBits = (int)(32 - numBits);
+ retVal = v4 << clearBits >> clearBits;
+ }
+
+ return retVal;
+ }
+
+ private static void SACompGCStatus_Process(ref SACompGCStatus data)
+ {
+ while (true)
+ {
+ if (SACompGC_GetData(1, ref data) != 0)
+ {
+ data.OutputBuffer[data.WriteHead] = (byte)SACompGC_GetData(8, ref data);
+ data.WriteHead++;
+ data.LengthLeft--;
+
+ if (data.LengthLeft == 0)
+ {
+ return;
+ }
+
+ continue;
+ }
+
+ // Perform RLE lookback
+ var copyIdx = (int)SACompGC_GetData(data.CopyOffsetBits, ref data) + 1;
+ var numBytes = SACompGC_GetData(data.CopySizeBits, ref data) + 2;
+ data.LengthLeft -= numBytes;
+
+ var lookbackHead = data.WriteHead - copyIdx;
+
+ if (!((int)data.LengthLeft < 0 || lookbackHead < 0))
+ {
+ // Copies a slice from earlier in the output buffer to place at the head.
+ data.OutputBuffer.Slice(lookbackHead, (int)numBytes)
+ .CopyTo(data.OutputBuffer.Slice(data.WriteHead, (int)numBytes));
+
+ data.WriteHead += (int)numBytes;
+
+ if (data.LengthLeft == 0)
+ {
+ return;
+ }
+ }
+ else
+ {
+ // Invalid?
+ return;
+ }
+ }
+ }
+
+ private static uint SACompGC_GetDecompressedSize(byte[] inputBuffer, out byte[] dataStart)
+ {
+ var saCompGcData = MemoryMarshal.Cast(inputBuffer);
+
+ if (inputBuffer != null)
+ {
+ while (saCompGcData[0] != 0x6F436153)
+ {
+ saCompGcData = saCompGcData[1..];
+
+ // Do not read out of bounds
+ if (saCompGcData.Length == 0)
+ {
+ dataStart = null;
+ return 0;
+ }
+ }
+
+ dataStart = MemoryMarshal.Cast(saCompGcData).ToArray();
+
+ return BinaryPrimitives.ReverseEndianness(saCompGcData[2]) & 0x0FFFFFFF;
+ }
+
+ dataStart = null;
+ return 0;
+ }
+
+ private static byte[] SACompGC_DecompressBuffer(byte[] input)
+ {
+ if (input == null)
+ {
+ return [];
+ }
+
+ var size = SACompGC_GetDecompressedSize(input, out input);
+ var output = new byte[size];
+
+ if (size == 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(input), "Empty file!");
+ }
+
+ SACompGCStatus data = new()
+ {
+ CopyOffsetBits = input[12],
+ CopySizeBits = input[13],
+ Field0x2D = (byte)(input[8] >> 6),
+ ReadOffset = 16,
+ LengthLeft = size,
+ Length = size,
+ ChunkCount = 0xFF, // -1 as byte
+ OutputBuffer = output,
+ WriteHead = 0,
+ InputBuffer = input,
+ ReadHead = 0,
+ EndOffset = (int)((size + 47) & 0xFFFFFFE0)
+ };
+
+ SACompGCStatus_Process(ref data);
+
+ return output.ToArray();
+ }
+
public static uint? SetupEXE(ref byte[] exefile)
{
if (ByteConverter.ToUInt16(exefile, 0) != 0x5A4D)
+ {
return null;
- int ptr = ByteConverter.ToInt32(exefile, 0x3c);
- if (ByteConverter.ToInt32(exefile, (int)ptr) != 0x4550) //PE\0\0
+ }
+
+ var ptr = ByteConverter.ToInt32(exefile, 0x3c);
+
+ if (ByteConverter.ToInt32(exefile, ptr) != 0x4550) //PE\0\0
+ {
return null;
+ }
+
try
{
ptr += 4;
- UInt16 numsects = ByteConverter.ToUInt16(exefile, (int)ptr + 2);
+ var numSects = ByteConverter.ToUInt16(exefile, ptr + 2);
ptr += 0x14;
- int PEHead = ptr;
- uint imageBase = ByteConverter.ToUInt32(exefile, ptr + 28);
+
+ var imageBase = ByteConverter.ToUInt32(exefile, ptr + 28);
+
if (imageBase != 0x82000000) // SADX X360 EXE doesn't like this
{
- byte[] result = new byte[ByteConverter.ToUInt32(exefile, ptr + 56)];
+ var result = new byte[ByteConverter.ToUInt32(exefile, ptr + 56)];
Array.Copy(exefile, result, ByteConverter.ToUInt32(exefile, ptr + 60));
ptr += 0xe0;
- for (int i = 0; i < numsects; i++)
+
+ for (var i = 0; i < numSects; i++)
{
Array.Copy(exefile, ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.FAddr), result, ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.VAddr), ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.FSize));
ptr += (int)SectOffs.Size;
}
+
exefile = result;
}
+
return imageBase;
}
catch
@@ -53,162 +215,92 @@ public static class HelperFunctions
return null;
}
}
-
- public static uint GetNewSectionAddress(byte[] exefile)
- {
- int ptr = ByteConverter.ToInt32(exefile, 0x3c);
- ptr += 4;
- UInt16 numsects = ByteConverter.ToUInt16(exefile, (int)ptr + 2);
- ptr += 0x14;
- ptr += 0xe0;
- ptr += (int)SectOffs.Size * (numsects - 1);
- return HelperFunctions.Align(ByteConverter.ToUInt32(exefile, ptr + (int)SectOffs.VAddr) + ByteConverter.ToUInt32(exefile, ptr + (int)SectOffs.VSize));
- }
-
- public static void CreateNewSection(ref byte[] exefile, string name, byte[] data, bool isCode)
+
+ public static void FixRELPointers(byte[] file, uint imageBase = 0)
{
- int ptr = ByteConverter.ToInt32(exefile, 0x3c);
- ptr += 4;
- UInt16 numsects = ByteConverter.ToUInt16(exefile, ptr + 2);
- int sectnumptr = ptr + 2;
- ptr += 0x14;
- int PEHead = ptr;
- ptr += 0xe0;
- int sectptr = ptr;
- ptr += (int)SectOffs.Size * numsects;
- ByteConverter.GetBytes((ushort)(numsects + 1)).CopyTo(exefile, sectnumptr);
- Array.Clear(exefile, ptr, 8);
- Encoding.ASCII.GetBytes(name).CopyTo(exefile, ptr);
- UInt32 vaddr = HelperFunctions.Align(ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.VAddr) + ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.VSize));
- ByteConverter.GetBytes(vaddr).CopyTo(exefile, ptr + (int)SectOffs.VAddr);
- UInt32 faddr = HelperFunctions.Align(ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.FAddr) + ByteConverter.ToUInt32(exefile, ptr - (int)SectOffs.Size + (int)SectOffs.FSize));
- ByteConverter.GetBytes(faddr).CopyTo(exefile, ptr + (int)SectOffs.FAddr);
- ByteConverter.GetBytes(isCode ? 0x60000020 : 0xC0000040).CopyTo(exefile, ptr + (int)SectOffs.Flags);
- int diff = (int)HelperFunctions.Align((uint)data.Length);
- ByteConverter.GetBytes(diff).CopyTo(exefile, ptr + (int)SectOffs.VSize);
- ByteConverter.GetBytes(diff).CopyTo(exefile, ptr + (int)SectOffs.FSize);
- if (isCode)
- ByteConverter.GetBytes(Convert.ToUInt32(ByteConverter.ToUInt32(exefile, PEHead + 4) + diff)).CopyTo(exefile, PEHead + 4);
- else
- ByteConverter.GetBytes(Convert.ToUInt32(ByteConverter.ToUInt32(exefile, PEHead + 8) + diff)).CopyTo(exefile, PEHead + 8);
- ByteConverter.GetBytes(Convert.ToUInt32(ByteConverter.ToUInt32(exefile, PEHead + 0x38) + diff)).CopyTo(exefile, PEHead + 0x38);
- Array.Resize(ref exefile, exefile.Length + diff);
- data.CopyTo(exefile, vaddr);
- }
+ var header = new OsModuleHeader(file, 0);
+ var sections = new OsSectionInfo[header.Info.NumSections];
+
+ for (var i = 0; i < header.Info.NumSections; i++)
+ {
+ sections[i] = new OsSectionInfo(file, (int)header.Info.SectionInfoOffset + (i * 8));
+ }
- public static void CompactEXE(ref byte[] exefile)
- {
- if (ByteConverter.ToUInt16(exefile, 0) != 0x5A4D)
- return;
- int ptr = ByteConverter.ToInt32(exefile, 0x3c);
- if (ByteConverter.ToInt32(exefile, (int)ptr) != 0x4550) //PE\0\0
- return;
- ptr += 4;
- UInt16 numsects = ByteConverter.ToUInt16(exefile, (int)ptr + 2);
- ptr += 0x14;
- int PEHead = ptr;
- uint imageBase = ByteConverter.ToUInt32(exefile, ptr + 28);
- byte[] result = new byte[ByteConverter.ToInt32(exefile, ptr + 0xe0 + ((int)SectOffs.Size * (numsects - 1)) + (int)SectOffs.FAddr) + ByteConverter.ToInt32(exefile, ptr + 0xe0 + ((int)SectOffs.Size * (numsects - 1)) + (int)SectOffs.FSize)];
- Array.Copy(exefile, result, ByteConverter.ToUInt32(exefile, ptr + 60));
- ptr += 0xe0;
- for (int i = 0; i < numsects; i++)
+ var imports = new OsImportInfo[header.ImpSize / 8];
+
+ for (var i = 0; i < imports.Length; i++)
{
- Array.Copy(exefile, ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.VAddr), result, ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.FAddr), ByteConverter.ToInt32(exefile, ptr + (int)SectOffs.FSize));
- ptr += (int)SectOffs.Size;
+ imports[i] = new OsImportInfo(file, (int)header.ImpOffset + (i * 8));
}
- exefile = result;
- }
- public static void FixRELPointers(byte[] file, uint imageBase = 0)
- {
- OSModuleHeader header = new OSModuleHeader(file, 0);
- OSSectionInfo[] sections = new OSSectionInfo[header.info.numSections];
- for (int i = 0; i < header.info.numSections; i++)
- sections[i] = new OSSectionInfo(file, (int)header.info.sectionInfoOffset + (i * 8));
- OSImportInfo[] imports = new OSImportInfo[header.impSize / 8];
- for (int i = 0; i < imports.Length; i++)
- imports[i] = new OSImportInfo(file, (int)header.impOffset + (i * 8));
- int reladdr = 0;
- for (int i = 0; i < imports.Length; i++)
- if (imports[i].id == header.info.id)
- {
- reladdr = (int)imports[i].offset;
- break;
- }
- OSRel rel = new OSRel(file, reladdr);
- int dataaddr = 0;
- unchecked
+ var relAddr = (from import in imports where import.Id == header.Info.Id select (int)import.Offset).FirstOrDefault();
+
+ var rel = new OsRel(file, relAddr);
+ var dataAddr = 0;
+
+ unchecked
+ {
+ while (rel.Type != (byte)RelocTypes.R_DOLPHIN_END)
{
- while (rel.type != (byte)RelocTypes.R_DOLPHIN_END)
+ dataAddr += rel.Offset;
+ var sectionBase = (uint)(sections[rel.Section].Offset & ~1);
+
+ switch (rel.Type)
{
- dataaddr += rel.offset;
- uint sectionbase = (uint)(sections[rel.section].offset & ~1);
- switch (rel.type)
- {
- case 0x01:
- ByteConverter.GetBytes(rel.addend + sectionbase + imageBase).CopyTo(file, dataaddr);
- break;
- case 0x02:
- ByteConverter.GetBytes((ByteConverter.ToUInt32(file, dataaddr) & 0xFC000003) | ((rel.addend + sectionbase) & 0x3FFFFFC) + imageBase).CopyTo(file, dataaddr);
- break;
- case 0x03:
- case 0x04:
- ByteConverter.GetBytes((ushort)(rel.addend + sectionbase) + imageBase).CopyTo(file, dataaddr);
- break;
- case 0x05:
- ByteConverter.GetBytes((ushort)((rel.addend + sectionbase) >> 16) + imageBase).CopyTo(file, dataaddr);
- break;
- case 0x06:
- ByteConverter.GetBytes((ushort)(((rel.addend + sectionbase) >> 16) + (((rel.addend + sectionbase) & 0x8000) == 0x8000 ? 1 : 0)) + imageBase).CopyTo(file, dataaddr);
- break;
- case 0x0A:
- ByteConverter.GetBytes((uint)((ByteConverter.ToUInt32(file, dataaddr) & 0xFC000003) | (((rel.addend + sectionbase) - dataaddr) & 0x3FFFFFC)) + imageBase).CopyTo(file, dataaddr);
- break;
- case 0x00:
- case (byte)RelocTypes.R_DOLPHIN_NOP:
- case (byte)RelocTypes.R_DOLPHIN_END:
- break;
- case (byte)RelocTypes.R_DOLPHIN_SECTION:
- dataaddr = (int)sectionbase;
- break;
- default:
- throw new NotImplementedException();
- }
- reladdr += 8;
- rel = new OSRel(file, reladdr);
+ case 0x01:
+ ByteConverter.GetBytes(rel.Addend + sectionBase + imageBase).CopyTo(file, dataAddr);
+ break;
+ case 0x02:
+ ByteConverter.GetBytes((ByteConverter.ToUInt32(file, dataAddr) & 0xFC000003) | ((rel.Addend + sectionBase) & 0x3FFFFFC) + imageBase).CopyTo(file, dataAddr);
+ break;
+ case 0x03:
+ case 0x04:
+ ByteConverter.GetBytes((ushort)(rel.Addend + sectionBase) + imageBase).CopyTo(file, dataAddr);
+ break;
+ case 0x05:
+ ByteConverter.GetBytes((ushort)((rel.Addend + sectionBase) >> 16) + imageBase).CopyTo(file, dataAddr);
+ break;
+ case 0x06:
+ ByteConverter.GetBytes((ushort)(((rel.Addend + sectionBase) >> 16) + (((rel.Addend + sectionBase) & 0x8000) == 0x8000 ? 1 : 0)) + imageBase).CopyTo(file, dataAddr);
+ break;
+ case 0x0A:
+ ByteConverter.GetBytes((uint)((ByteConverter.ToUInt32(file, dataAddr) & 0xFC000003) | (((rel.Addend + sectionBase) - dataAddr) & 0x3FFFFFC)) + imageBase).CopyTo(file, dataAddr);
+ break;
+ case 0x00:
+ case (byte)RelocTypes.R_DOLPHIN_NOP:
+ case (byte)RelocTypes.R_DOLPHIN_END:
+ break;
+ case (byte)RelocTypes.R_DOLPHIN_SECTION:
+ dataAddr = (int)sectionBase;
+ break;
+ default:
+ throw new NotImplementedException();
}
+ relAddr += 8;
+ rel = new OsRel(file, relAddr);
}
+ }
}
- public static void AlignCode(this List me)
- {
- while (me.Count % 0x10 > 0)
- me.Add(0x90);
- }
+ private static readonly System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
- public static uint Align(uint address)
+ public static string FileHash(string path, int rangeStart = 0, int rangeFinish = 0)
{
- if (address % 0x1000 == 0) return address;
- return ((address / 0x1000) + 1) * 0x1000;
+ return FileHash(File.ReadAllBytes(path), rangeStart, rangeFinish);
}
- static readonly System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
-
- public static string FileHash(string path, int rangeStart = 0, int rangeFinish = 0) { return FileHash(File.ReadAllBytes(path), rangeStart, rangeFinish); }
-
public static string FileHash(byte[] file, int rangeStart = 0, int rangeFinish = 0)
{
if (rangeStart != 0 || rangeFinish != 0)
{
- byte[] newfile = new byte[rangeFinish - rangeStart];
- Array.Copy(file, rangeStart, newfile, 0, newfile.Length);
- file = newfile;
+ var newFile = new byte[rangeFinish - rangeStart];
+ Array.Copy(file, rangeStart, newFile, 0, newFile.Length);
+ file = newFile;
}
+
file = md5.ComputeHash(file);
- string result = string.Empty;
- foreach (byte item in file)
- result += item.ToString("x2");
- return result;
+
+ return file.Aggregate(string.Empty, (current, item) => current + item.ToString("x2"));
}
private static readonly Encoding jpenc = Encoding.GetEncoding(932);
@@ -223,24 +315,17 @@ public static string FileHash(byte[] file, int rangeStart = 0, int rangeFinish =
public static Encoding GetEncoding(Game game, Languages language)
{
- switch (language)
+ return language switch
{
- case Languages.Japanese:
- return KoreanMode ? krenc : jpenc;
- case Languages.English:
- switch (game)
- {
- case Game.SA1:
- case Game.SADX:
- return KoreanMode ? krenc : jpenc;
- case Game.SA2:
- case Game.SA2B:
- return euenc;
- }
- throw new ArgumentOutOfRangeException("game");
- default:
- return euenc;
- }
+ Languages.Japanese => KoreanMode ? krenc : jpenc,
+ Languages.English => game switch
+ {
+ Game.SA1 or Game.SADX => KoreanMode ? krenc : jpenc,
+ Game.SA2 or Game.SA2B => euenc,
+ _ => throw new ArgumentOutOfRangeException(nameof(game))
+ },
+ _ => euenc
+ };
}
public static string GetCString(this byte[] file, int address)
@@ -250,29 +335,40 @@ public static string GetCString(this byte[] file, int address)
public static int GetPointer(this byte[] file, int address, uint imageBase)
{
- uint tmp = ByteConverter.ToUInt32(file, address);
- if (tmp == 0) return 0;
+ var tmp = ByteConverter.ToUInt32(file, address);
+
+ if (tmp == 0)
+ {
+ return 0;
+ }
+
return (int)(tmp - imageBase);
}
public static string UnescapeNewlines(this string line)
{
- StringBuilder sb = new StringBuilder(line.Length);
- for (int c = 0; c < line.Length; c++)
+ var sb = new StringBuilder(line.Length);
+
+ for (var c = 0; c < line.Length; c++)
+ {
switch (line[c])
{
- case '\\': // escape character
- if (c + 1 == line.Length) goto default;
+ case '\\': // Escape character
+ if (c + 1 == line.Length)
+ {
+ goto default;
+ }
+
c++;
switch (line[c])
{
- case 'n': // line feed
+ case 'n': // Line feed
sb.Append('\n');
break;
- case 'r': // carriage return
+ case 'r': // Carriage return
sb.Append('\r');
break;
- default: // literal character
+ default: // Literal character
sb.Append(line[c]);
break;
}
@@ -281,6 +377,8 @@ public static string UnescapeNewlines(this string line)
sb.Append(line[c]);
break;
}
+ }
+
return sb.ToString();
}
@@ -292,9 +390,11 @@ public static string EscapeNewlines(this string line)
public static string ToCHex(this ushort i)
{
if (i < 10)
+ {
return i.ToString(NumberFormatInfo.InvariantInfo);
- else
- return "0x" + i.ToString("X");
+ }
+
+ return "0x" + i.ToString("X");
}
public static string ToC(this string str) => str.ToC(Languages.Japanese);
@@ -303,40 +403,64 @@ public static string ToCHex(this ushort i)
public static string ToC(this string str, Game game, Languages language)
{
- if (str == null) return "NULL";
- Encoding enc = GetEncoding(game, language);
- StringBuilder result = new StringBuilder("\"");
- foreach (char item in str)
+ if (str == null)
{
- if (item == '\0')
- result.Append(@"\0");
- else if (item == '\a')
- result.Append(@"\a");
- else if (item == '\b')
- result.Append(@"\b");
- else if (item == '\f')
- result.Append(@"\f");
- else if (item == '\n')
- result.Append(@"\n");
- else if (item == '\r')
- result.Append(@"\r");
- else if (item == '\t')
- result.Append(@"\t");
- else if (item == '\v')
- result.Append(@"\v");
- else if (item == '"')
- result.Append(@"\""");
- else if (item == '\\')
- result.Append(@"\\");
- else if (item < ' ')
- result.AppendFormat(@"\{0}", Convert.ToString((short)item, 8).PadLeft(3, '0'));
- else if (item > '\x7F')
- foreach (byte b in enc.GetBytes(item.ToString()))
- result.AppendFormat(@"\{0}", Convert.ToString(b, 8).PadLeft(3, '0'));
- else
- result.Append(item);
+ return "NULL";
}
- result.Append("\"");
+
+ var enc = GetEncoding(game, language);
+ var result = new StringBuilder("\"");
+
+ foreach (var item in str)
+ {
+ switch (item)
+ {
+ case '\0':
+ result.Append(@"\0");
+ break;
+ case '\a':
+ result.Append(@"\a");
+ break;
+ case '\b':
+ result.Append(@"\b");
+ break;
+ case '\f':
+ result.Append(@"\f");
+ break;
+ case '\n':
+ result.Append(@"\n");
+ break;
+ case '\r':
+ result.Append(@"\r");
+ break;
+ case '\t':
+ result.Append(@"\t");
+ break;
+ case '\v':
+ result.Append(@"\v");
+ break;
+ case '"':
+ result.Append(@"\""");
+ break;
+ case '\\':
+ result.Append(@"\\");
+ break;
+ case < ' ':
+ result.Append($@"\{Convert.ToString((short)item, 8).PadLeft(3, '0')}");
+ break;
+ case > '\x7F':
+ {
+ foreach (byte b in enc.GetBytes(item.ToString()))
+ result.Append($@"\{Convert.ToString(b, 8).PadLeft(3, '0')}");
+ break;
+ }
+ default:
+ result.Append(item);
+ break;
+ }
+ }
+
+ result.Append('"');
return result.ToString();
}
@@ -345,38 +469,59 @@ public static string ToComment(this string str)
return "/* " + str.ToCNoEncoding().Replace("*/", @"*\/") + " */";
}
- public static string ToCNoEncoding(this string str)
+ private static string ToCNoEncoding(this string str)
{
- if (str == null) return "NULL";
- StringBuilder result = new StringBuilder("\"");
- foreach (char item in str)
+ if (str == null)
{
- if (item == '\0')
- result.Append(@"\0");
- else if (item == '\a')
- result.Append(@"\a");
- else if (item == '\b')
- result.Append(@"\b");
- else if (item == '\f')
- result.Append(@"\f");
- else if (item == '\n')
- result.Append(@"\n");
- else if (item == '\r')
- result.Append(@"\r");
- else if (item == '\t')
- result.Append(@"\t");
- else if (item == '\v')
- result.Append(@"\v");
- else if (item == '"')
- result.Append(@"\""");
- else if (item == '\\')
- result.Append(@"\\");
- else if (item < ' ')
- result.AppendFormat(@"\{0}", Convert.ToString((short)item, 8).PadLeft(3, '0'));
- else
- result.Append(item);
+ return "NULL";
+ }
+
+ var result = new StringBuilder("\"");
+
+ foreach (var item in str)
+ {
+ switch (item)
+ {
+ case '\0':
+ result.Append(@"\0");
+ break;
+ case '\a':
+ result.Append(@"\a");
+ break;
+ case '\b':
+ result.Append(@"\b");
+ break;
+ case '\f':
+ result.Append(@"\f");
+ break;
+ case '\n':
+ result.Append(@"\n");
+ break;
+ case '\r':
+ result.Append(@"\r");
+ break;
+ case '\t':
+ result.Append(@"\t");
+ break;
+ case '\v':
+ result.Append(@"\v");
+ break;
+ case '"':
+ result.Append(@"\""");
+ break;
+ case '\\':
+ result.Append(@"\\");
+ break;
+ case < ' ':
+ result.Append($@"\{Convert.ToString((short)item, 8).PadLeft(3, '0')}");
+ break;
+ default:
+ result.Append(item);
+ break;
+ }
}
- result.Append("\"");
+
+ result.Append('"');
return result.ToString();
}
@@ -386,56 +531,72 @@ public static string ToC(this T item)
return item.ToC(typeof(T).Name);
}
- public static string ToC(this T item, string enumname)
+ public static string ToC(this T item, string enumName)
where T : Enum
{
- Type type = typeof(T);
+ var type = typeof(T);
if (type.GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0)
+ {
if (Enum.IsDefined(typeof(T), item))
- return enumname + "_" + item.ToString();
- else
- return item.ToString();
- else
+ {
+ return enumName + "_" + item;
+ }
+
+ return item.ToString();
+ }
+
+ var num = Convert.ToUInt64(item);
+ var values = Array.ConvertAll((T[])Enum.GetValues(type), (a) => Convert.ToUInt64(a));
+ var num2 = values.Length - 1;
+ var stringBuilder = new StringBuilder();
+ var flag = true;
+ var num3 = num;
+
+ while (num2 >= 0 && (num2 != 0 || values[num2] != 0uL))
{
- ulong num = Convert.ToUInt64(item);
- ulong[] values = Array.ConvertAll((T[])Enum.GetValues(type), (a) => Convert.ToUInt64(a));
- int num2 = values.Length - 1;
- StringBuilder stringBuilder = new StringBuilder();
- bool flag = true;
- ulong num3 = num;
- while (num2 >= 0 && (num2 != 0 || values[num2] != 0uL))
+ if ((num & values[num2]) == values[num2])
{
- if ((num & values[num2]) == values[num2])
+ num -= values[num2];
+ if (!flag)
{
- num -= values[num2];
- if (!flag)
- stringBuilder.Insert(0, " | ");
- stringBuilder.Insert(0, enumname + "_" + Enum.GetName(type, values[num2]));
- flag = false;
+ stringBuilder.Insert(0, " | ");
}
- num2--;
+
+ stringBuilder.Insert(0, enumName + "_" + Enum.GetName(type, values[num2]));
+ flag = false;
}
- if (num != 0uL)
+ num2--;
+ }
+
+ if (num != 0uL)
+ {
+ if (flag)
{
- if (flag)
- return item.ToString();
- else
- return stringBuilder.ToString() + " | " + item.ToString();
+ return item.ToString();
}
- if (num3 != 0uL)
- return stringBuilder.ToString();
- if (values.Length > 0 && values[0] == 0uL)
- return enumname + "_" + Enum.GetName(type, 0);
- return "0";
+
+ return stringBuilder + " | " + item;
}
+
+ if (num3 != 0uL)
+ {
+ return stringBuilder.ToString();
+ }
+
+ if (values.Length > 0 && values[0] == 0uL)
+ {
+ return enumName + "_" + Enum.GetName(type, 0);
+ }
+
+ return "0";
}
public static bool CheckBigEndianInt16(byte[] file, int address)
{
- bool bigEndState = ByteConverter.BigEndian;
+ var bigEndState = ByteConverter.BigEndian;
ByteConverter.BigEndian = true;
- bool isBigEndian = BitConverter.ToUInt16(file, address) > ByteConverter.ToUInt16(file, address);
+ var isBigEndian = BitConverter.ToUInt16(file, address) > ByteConverter.ToUInt16(file, address);
ByteConverter.BigEndian = bigEndState;
@@ -443,10 +604,10 @@ public static bool CheckBigEndianInt16(byte[] file, int address)
}
public static bool CheckBigEndianInt32(byte[] file, int address)
{
- bool bigEndState = ByteConverter.BigEndian;
+ var bigEndState = ByteConverter.BigEndian;
ByteConverter.BigEndian = true;
- bool isBigEndian = BitConverter.ToUInt32(file, address) > ByteConverter.ToUInt32(file, address);
+ var isBigEndian = BitConverter.ToUInt32(file, address) > ByteConverter.ToUInt32(file, address);
ByteConverter.BigEndian = bigEndState;
@@ -456,11 +617,12 @@ public static bool CheckBigEndianInt32(byte[] file, int address)
public static byte[] DecompressREL(byte[] file)
{
// Scan the array for the last instance of the "SaCompGC" string because there are some files with redundant headers
- int start = 0;
- bool isCompressed = false;
- bool bigend = ByteConverter.BigEndian;
+ var start = 0;
+ var isCompressed = false;
+ var bigEndian = ByteConverter.BigEndian;
ByteConverter.BigEndian = true;
- for (int u = file.Length - 8; u >= 0; u--)
+
+ for (var u = file.Length - 8; u >= 0; u--)
{
if (ByteConverter.ToUInt32(file, u) == 0x5361436F)// && BitConverter.ToUInt32(file, u + 4) == 0x4347706D)
{
@@ -469,33 +631,42 @@ public static byte[] DecompressREL(byte[] file)
break;
}
}
- if (!isCompressed) return file;
- byte[] input = new byte[file.Length - start];
+
+ if (!isCompressed)
+ {
+ return file;
+ }
+
+ var input = new byte[file.Length - start];
Array.Copy(file, start, input, 0, input.Length);
- // Process the new array
- IntPtr pnt_input = Marshal.AllocHGlobal(input.Length);
- Marshal.Copy(input, 0, pnt_input, input.Length);
- int size_output;
- if (Environment.Is64BitProcess)
- size_output = (int)GetDecompressedSizeX64(pnt_input);
- else
- size_output = (int)GetDecompressedSizeX86(pnt_input);
- IntPtr pnt_output = Marshal.AllocHGlobal(size_output);
- if (Environment.Is64BitProcess)
- DecompressBufferX64(pnt_input, pnt_output);
- else
- DecompressBufferX86(pnt_input, pnt_output);
- byte[] decompbuf = new byte[size_output];
- Marshal.Copy(pnt_output, decompbuf, 0, size_output);
- Marshal.FreeHGlobal(pnt_output);
- Marshal.FreeHGlobal(pnt_input);
- ByteConverter.BigEndian = bigend;
- return decompbuf;
+ var decompBuf = SACompGC_DecompressBuffer(input);
+
+ ByteConverter.BigEndian = bigEndian;
+ return decompBuf;
}
}
-
+ ref struct SACompGCStatus
+ {
+ public uint LengthLeft;
+ public uint Length;
+ public uint ReadOffset; // 0x8
+ public uint BitBuffer; // 0xc
+ public Span OutputBuffer;
+ public int ReadHead;
+ public Span InputBuffer;
+ public int EndOffset; // 0x1c
+ public int WriteHead; // byte offset instead of pointer
+
+ public byte ChunkCount; // 0x28
+ public byte BitBufferRemaining; // 0x29
+ public byte CopyOffsetBits; //0x2a
+ public byte CopySizeBits; //0x2b
+ // special note: missing 0x2c for some reason. bad decomp?
+ public byte Field0x2D;
+ }
+
enum SectOffs
{
VSize = 8,
@@ -561,7 +732,7 @@ public enum SA1Characters : byte
MetalSonic = 8
}
- [Flags()]
+ [Flags]
public enum SA1CharacterFlags
{
Sonic = 1 << SA1Characters.Sonic,
@@ -711,8 +882,7 @@ public enum SA2DCLevelIDs : byte
ChaoWorld = 90,
Invalid = 91
}
-
-
+
public enum SA2Characters
{
Sonic = 0,
@@ -739,7 +909,7 @@ public enum SA2KartCharacters
Rouge = 7
}
- [Flags()]
+ [Flags]
public enum SA2CharacterFlags
{
Sonic = 1 << SA2Characters.Sonic,
@@ -764,149 +934,147 @@ public enum Languages
public enum ChaoItemCategory
{
- ChaoItemCategory_Egg = 1,
- ChaoItemCategory_Fruit = 3,
- ChaoItemCategory_Seed = 7,
- ChaoItemCategory_Hat = 9,
- ChaoItemCategory_MenuTheme = 0x10
+ Egg = 1,
+ Fruit = 3,
+ Seed = 7,
+ Hat = 9,
+ MenuTheme = 0x10
}
- class OSModuleLink
+ internal class OsModuleLink
{
- public uint next;
- public uint prev;
+ public uint Next;
+ public uint Prev;
- public OSModuleLink(byte[] file, int address)
+ public OsModuleLink(byte[] file, int address)
{
- next = ByteConverter.ToUInt32(file, address);
- prev = ByteConverter.ToUInt32(file, address + 4);
+ Next = ByteConverter.ToUInt32(file, address);
+ Prev = ByteConverter.ToUInt32(file, address + 4);
}
}
- class OSModuleInfo
+ internal class OsModuleInfo
{
- public uint id; // unique identifier for the module
- public OSModuleLink link; // doubly linked list of modules
- public uint numSections; // # of sections
- public uint sectionInfoOffset; // offset to section info table
- public uint nameOffset; // offset to module name
- public uint nameSize; // size of module name
- public uint version; // version number
-
- public OSModuleInfo(byte[] file, int address)
+ public uint Id; // Unique identifier for the module
+ public OsModuleLink Link; // Doubly linked list of modules
+ public uint NumSections; // # of sections
+ public uint SectionInfoOffset; // Offset to section info table
+ public uint NameOffset; // Offset to module name
+ public uint NameSize; // Size of module name
+ public uint Version; // Version number
+
+ public OsModuleInfo(byte[] file, int address)
{
- id = ByteConverter.ToUInt32(file, address);
+ Id = ByteConverter.ToUInt32(file, address);
address += 4;
- link = new OSModuleLink(file, address);
+ Link = new OsModuleLink(file, address);
address += 8;
- numSections = ByteConverter.ToUInt32(file, address);
+ NumSections = ByteConverter.ToUInt32(file, address);
address += 4;
- sectionInfoOffset = ByteConverter.ToUInt32(file, address);
+ SectionInfoOffset = ByteConverter.ToUInt32(file, address);
address += 4;
- nameOffset = ByteConverter.ToUInt32(file, address);
+ NameOffset = ByteConverter.ToUInt32(file, address);
address += 4;
- nameSize = ByteConverter.ToUInt32(file, address);
+ NameSize = ByteConverter.ToUInt32(file, address);
address += 4;
- version = ByteConverter.ToUInt32(file, address);
+ Version = ByteConverter.ToUInt32(file, address);
}
}
- class OSModuleHeader
+ internal class OsModuleHeader
{
- // CAUTION: info must be the 1st member
- public OSModuleInfo info;
+ // CAUTION: Info must be the 1st member
+ public OsModuleInfo Info;
// OS_MODULE_VERSION == 1
- public uint bssSize; // total size of bss sections in bytes
- public uint relOffset;
- public uint impOffset;
- public uint impSize; // size in bytes
- public byte prologSection; // section # for prolog function
- public byte epilogSection; // section # for epilog function
- public byte unresolvedSection; // section # for unresolved function
- public byte padding0;
- public uint prolog; // prolog function offset
- public uint epilog; // epilog function offset
- public uint unresolved; // unresolved function offset
+ public uint BssSize; // Total size of bss sections in bytes
+ public uint RelOffset;
+ public uint ImpOffset;
+ public uint ImpSize; // Size in bytes
+ public byte PrologSection; // Section # for prolog function
+ public byte EpilogSection; // Section # for epilog function
+ public byte UnresolvedSection; // Section # for unresolved function
+ public byte Padding0;
+ public uint Prolog; // Prolog function offset
+ public uint Epilog; // Epilog function offset
+ public uint Unresolved; // Unresolved function offset
// OS_MODULE_VERSION == 2
- public uint align; // module alignment constraint
- public uint bssAlign; // bss alignment constraint
+ public uint Align; // Module alignment constraint
+ public uint BssAlign; // Bss alignment constraint
- public OSModuleHeader(byte[] file, int address)
+ public OsModuleHeader(byte[] file, int address)
{
- info = new OSModuleInfo(file, address);
+ Info = new OsModuleInfo(file, address);
address += 0x20;
- bssSize = ByteConverter.ToUInt32(file, address);
+ BssSize = ByteConverter.ToUInt32(file, address);
address += 4;
- relOffset = ByteConverter.ToUInt32(file, address);
+ RelOffset = ByteConverter.ToUInt32(file, address);
address += 4;
- impOffset = ByteConverter.ToUInt32(file, address);
+ ImpOffset = ByteConverter.ToUInt32(file, address);
address += 4;
- impSize = ByteConverter.ToUInt32(file, address);
+ ImpSize = ByteConverter.ToUInt32(file, address);
address += 4;
- prologSection = file[address++];
- epilogSection = file[address++];
- unresolvedSection = file[address++];
- padding0 = file[address++];
- prolog = ByteConverter.ToUInt32(file, address);
+ PrologSection = file[address++];
+ EpilogSection = file[address++];
+ UnresolvedSection = file[address++];
+ Padding0 = file[address++];
+ Prolog = ByteConverter.ToUInt32(file, address);
address += 4;
- epilog = ByteConverter.ToUInt32(file, address);
+ Epilog = ByteConverter.ToUInt32(file, address);
address += 4;
- unresolved = ByteConverter.ToUInt32(file, address);
+ Unresolved = ByteConverter.ToUInt32(file, address);
address += 4;
- align = ByteConverter.ToUInt32(file, address);
+ Align = ByteConverter.ToUInt32(file, address);
address += 4;
- bssAlign = ByteConverter.ToUInt32(file, address);
+ BssAlign = ByteConverter.ToUInt32(file, address);
}
}
- class OSSectionInfo
+ class OsSectionInfo
{
- public uint offset;
- public uint size;
+ public uint Offset;
+ public uint Size;
- public OSSectionInfo(byte[] file, int address)
+ public OsSectionInfo(byte[] file, int address)
{
- offset = ByteConverter.ToUInt32(file, address);
- size = ByteConverter.ToUInt32(file, address + 4);
+ Offset = ByteConverter.ToUInt32(file, address);
+ Size = ByteConverter.ToUInt32(file, address + 4);
}
}
- class OSImportInfo
+ class OsImportInfo
{
- public uint id; // external module id
- public uint offset; // offset to OSRel instructions
+ public uint Id; // External module id
+ public uint Offset; // Offset to OSRel instructions
- public OSImportInfo(byte[] file, int address)
+ public OsImportInfo(byte[] file, int address)
{
- id = ByteConverter.ToUInt32(file, address);
- offset = ByteConverter.ToUInt32(file, address + 4);
+ Id = ByteConverter.ToUInt32(file, address);
+ Offset = ByteConverter.ToUInt32(file, address + 4);
}
}
- class OSRel
+ class OsRel
{
- public ushort offset; // byte offset from the previous entry
- public byte type;
- public byte section;
- public uint addend;
+ public ushort Offset; // Byte offset from the previous entry
+ public byte Type;
+ public byte Section;
+ public uint Addend;
- public OSRel(byte[] file, int address)
+ public OsRel(byte[] file, int address)
{
- offset = ByteConverter.ToUInt16(file, address);
- type = file[address + 2];
- section = file[address + 3];
- addend = ByteConverter.ToUInt32(file, address + 4);
+ Offset = ByteConverter.ToUInt16(file, address);
+ Type = file[address + 2];
+ Section = file[address + 3];
+ Addend = ByteConverter.ToUInt32(file, address + 4);
}
}
enum RelocTypes
{
R_DOLPHIN_NOP = 201, // C9h current offset += OSRel.offset
- R_DOLPHIN_SECTION = 202, // CAh current section = OSRel.section
- R_DOLPHIN_END = 203 // CBh
+ R_DOLPHIN_SECTION = 202, // CAh current section = OSRel.section
+ R_DOLPHIN_END = 203 // CBh
}
-
-
}
diff --git a/Libraries/SplitTools/IniData.cs b/Libraries/SplitTools/IniData.cs
index ed038779..c94bcbc6 100644
--- a/Libraries/SplitTools/IniData.cs
+++ b/Libraries/SplitTools/IniData.cs
@@ -5,7 +5,6 @@
using System.Globalization;
using System.IO;
using System.Linq;
-using System.Runtime.CompilerServices;
using System.Text;
using ByteConverter = SAModel.ByteConverter;
diff --git a/Libraries/SplitTools/IniData_SplitDLL.cs b/Libraries/SplitTools/IniData_SplitDLL.cs
index e95509db..def69542 100644
--- a/Libraries/SplitTools/IniData_SplitDLL.cs
+++ b/Libraries/SplitTools/IniData_SplitDLL.cs
@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
-using SplitTools;
namespace SplitTools.SplitDLL
{
diff --git a/Libraries/SplitTools/SplitBinary.cs b/Libraries/SplitTools/SplitBinary.cs
index 452bcdf2..01a84962 100644
--- a/Libraries/SplitTools/SplitBinary.cs
+++ b/Libraries/SplitTools/SplitBinary.cs
@@ -4,7 +4,6 @@
using System.Globalization;
using System.IO;
using System.Linq;
-using SplitTools;
using SAModel;
using SAModel.GC;
diff --git a/Libraries/SplitTools/SplitDLL.cs b/Libraries/SplitTools/SplitDLL.cs
index f0360cef..47f465a1 100644
--- a/Libraries/SplitTools/SplitDLL.cs
+++ b/Libraries/SplitTools/SplitDLL.cs
@@ -5,7 +5,6 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
-using SplitTools;
using SAModel;
using SAModel.GC;
using SplitTools.Split;
diff --git a/Libraries/SplitTools/SplitEventCyclone.cs b/Libraries/SplitTools/SplitEventCyclone.cs
index b77abb06..394b8d01 100644
--- a/Libraries/SplitTools/SplitEventCyclone.cs
+++ b/Libraries/SplitTools/SplitEventCyclone.cs
@@ -3,23 +3,19 @@
using SAModel;
using System;
using System.Collections.Generic;
-using System.Diagnostics.Metrics;
using System.IO;
using System.Linq;
-using System.Reflection.Metadata;
using System.Text;
-using System.Web.Services.Description;
-using static System.Windows.Forms.Design.AxImporter;
namespace SplitTools.SAArc
{
public static class sa2EventTailsPlane
{
- static List nodenames = new List();
- static Dictionary modelfiles = new Dictionary();
- static Dictionary motionfiles = new Dictionary();
- static Dictionary camarrayfiles = new Dictionary();
- static Dictionary texanimfiles = new Dictionary();
+ static List nodenames = new();
+ static Dictionary modelfiles = new();
+ static Dictionary motionfiles = new();
+ static Dictionary camarrayfiles = new();
+ static Dictionary texanimfiles = new();
public static void Split(string filename, string outputPath, string labelFile = null)
{
@@ -28,49 +24,75 @@ public static void Split(string filename, string outputPath, string labelFile =
camarrayfiles.Clear();
motionfiles.Clear();
texanimfiles.Clear();
+
string dir = Environment.CurrentDirectory;
+
try
{
- if (outputPath[outputPath.Length - 1] != '/') outputPath = string.Concat(outputPath, "/");
+ if (outputPath[outputPath.Length - 1] != '/')
+ {
+ outputPath = string.Concat(outputPath, "/");
+ }
+
// get file name, read it from the console if nothing
string evfilename = filename;
evfilename = Path.GetFullPath(evfilename);
string EventFileName = Path.GetFileNameWithoutExtension(evfilename);
if (Path.GetExtension(evfilename).Equals(".bin", StringComparison.OrdinalIgnoreCase))
+ {
EventFileName += "_bin";
+ }
Console.WriteLine("Splitting file {0}...", evfilename);
byte[] fc;
if (Path.GetExtension(evfilename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
+ {
fc = Prs.Decompress(evfilename);
+ }
else
+ {
fc = File.ReadAllBytes(evfilename);
+ }
+
if (Path.GetExtension(evfilename).Equals(".bin", StringComparison.OrdinalIgnoreCase) && fc[0] == 0x0F && fc[1] == 0x81)
+ {
fc = Prs.Decompress(evfilename);
+ }
+
EventCycloneIniData ini = new EventCycloneIniData() { Name = Path.GetFileNameWithoutExtension(evfilename) };
if (outputPath.Length != 0)
{
if (!Directory.Exists(outputPath))
+ {
Directory.CreateDirectory(outputPath);
+ }
+
Environment.CurrentDirectory = outputPath;
}
else
+ {
Environment.CurrentDirectory = Path.GetDirectoryName(evfilename);
- Directory.CreateDirectory(EventFileName);
+ }
+
+ Directory.CreateDirectory(EventFileName);
// Metadata for SAMDL Project Mode
byte[] mlength = null;
Dictionary evsectionlist = new Dictionary();
Dictionary evsplitfilenames = new Dictionary();
- if (labelFile != null) labelFile = Path.GetFullPath(labelFile);
+ if (labelFile != null)
+ {
+ labelFile = Path.GetFullPath(labelFile);
+ }
+
if (File.Exists(labelFile))
{
evsplitfilenames = IniSerializer.Deserialize>(labelFile);
mlength = File.ReadAllBytes(labelFile);
}
string evname = Path.GetFileNameWithoutExtension(evfilename);
- string[] evmetadata = new string[0];
+ string[] evmetadata = [];
string evtexname = Path.Combine("EVENT", evname);
@@ -122,10 +144,15 @@ public static void Split(string filename, string outputPath, string labelFile =
{
EntityName = modelfiles[ini.Model].MetaName;
if (battle)
+ {
outResult += modelfiles[ini.Model].MetaName + "|" + $"{evtexname}TEX";
-
+ }
+
else
+ {
outResult += modelfiles[ini.Model].MetaName + "|" + $"{evtexname}";
+ }
+
evsectionlist[modelfiles[ini.Model].Filename] = outResult;
}
}
@@ -191,10 +218,17 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
string dir = Environment.CurrentDirectory;
try
{
- if (fileOutputPath[fileOutputPath.Length - 1] != '/') fileOutputPath = string.Concat(fileOutputPath, "/");
+ if (fileOutputPath[fileOutputPath.Length - 1] != '/')
+ {
+ fileOutputPath = string.Concat(fileOutputPath, "/");
+ }
+
filename = Path.GetFullPath(filename);
if (Directory.Exists(filename))
+ {
filename += ".prs";
+ }
+
Environment.CurrentDirectory = Path.GetDirectoryName(filename);
string path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename));
JsonSerializer js = new JsonSerializer();
@@ -204,9 +238,14 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
evinfo = js.Deserialize(jtr);
uint gamekey;
if (!isBigEndian.HasValue)
+ {
ByteConverter.BigEndian = evinfo.BigEndian;
+ }
else
+ {
ByteConverter.BigEndian = isBigEndian.Value;
+ }
+
List evfile = new List();
List databytes = new List();
Dictionary animaddrs = new Dictionary();
@@ -214,9 +253,14 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
Dictionary panimaddrs = new Dictionary();
Dictionary labels = new Dictionary();
if (evinfo.BigEndian == true)
+ {
gamekey = 0x8162FE60;
+ }
else
+ {
gamekey = 0xCB00000;
+ }
+
uint imageBase = gamekey + 0x10;
uint tlsstart = gamekey + 0x10;
NJS_TEXLIST tex = NJS_TEXLIST.Load(Path.Combine(path, "tailsPlain.satex"));
@@ -286,7 +330,10 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
if (fileOutputPath.Length != 0)
{
if (!Directory.Exists(fileOutputPath))
+ {
Directory.CreateDirectory(fileOutputPath);
+ }
+
filename = Path.Combine(fileOutputPath, Path.GetFileName(filename));
}
@@ -294,10 +341,14 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
{
FraGag.Compression.Prs.Compress(evfile.ToArray(), filename);
if (!File.Exists(filename))
+ {
File.Create(filename);
+ }
}
else
+ {
File.WriteAllBytes(filename, evfile.ToArray());
+ }
}
finally
{
@@ -320,7 +371,10 @@ private static string GetModel(byte[] fc, int address, uint key, string fn, stri
List names = new List(obj.GetObjects().Select((o) => o.Name));
foreach (string s in names)
if (modelfiles.ContainsKey(s))
+ {
modelfiles.Remove(s);
+ }
+
nodenames.AddRange(names);
modelfiles.Add(obj.Name, new ModelInfo(fn, obj, ModelFormat.Chunk, meta));
}
@@ -332,7 +386,9 @@ private static string GetMotion(byte[] fc, int address, uint key, string fn, Lis
{
NJS_MOTION mtn = null;
if (motions != null)
+ {
mtn = motions[ByteConverter.ToInt32(fc, address)];
+ }
else
{
int ptr3 = fc.GetPointer(address, key);
@@ -343,9 +399,16 @@ private static string GetMotion(byte[] fc, int address, uint key, string fn, Lis
mtn.OptimizeShape();
}
}
- if (mtn == null) return null;
+ if (mtn == null)
+ {
+ return null;
+ }
+
if (!motionfiles.ContainsKey(mtn.Name) || motionfiles[mtn.Name].Filename == null)
+ {
motionfiles[mtn.Name] = new MotionInfo(fn, mtn);
+ }
+
return mtn.Name;
}
@@ -386,7 +449,9 @@ private static string GetCamData(byte[] fc, int address, uint key, string fn, Li
{
NJS_CAMERA ncam = null;
if (ncams != null)
+ {
ncam = ncams[ByteConverter.ToInt32(fc, address + 0xC)];
+ }
else
{
int ptr3 = fc.GetPointer(address, key);
@@ -395,9 +460,16 @@ private static string GetCamData(byte[] fc, int address, uint key, string fn, Li
ncam = new NJS_CAMERA(fc, ptr3 + 0xC, key);
}
}
- if (ncam == null) return null;
+ if (ncam == null)
+ {
+ return null;
+ }
+
if (!camarrayfiles.ContainsKey(ncam.Name) || camarrayfiles[ncam.Name].Filename == null)
+ {
camarrayfiles[ncam.Name] = new CameraInfo(fn, ncam);
+ }
+
return ncam.Name;
}
}
@@ -413,7 +485,7 @@ public string GameString
set { Game = (Game)Enum.Parse(typeof(Game), value); }
}
public bool BigEndian { get; set; }
- public Dictionary Files { get; set; } = new Dictionary();
+ public Dictionary Files { get; set; } = new();
public string Texlist { get; set; }
public string Model { get; set; }
public string Animation { get; set; }
diff --git a/Libraries/SplitTools/SplitEventExtra.cs b/Libraries/SplitTools/SplitEventExtra.cs
index 5e4b5e39..94ff5577 100644
--- a/Libraries/SplitTools/SplitEventExtra.cs
+++ b/Libraries/SplitTools/SplitEventExtra.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Text;
namespace SplitTools.SAArc
@@ -16,7 +15,11 @@ public static void Split(string filename, string outputPath)
string dir = Environment.CurrentDirectory;
try
{
- if (outputPath[outputPath.Length - 1] != '/') outputPath = string.Concat(outputPath, "/");
+ if (outputPath[outputPath.Length - 1] != '/')
+ {
+ outputPath = string.Concat(outputPath, "/");
+ }
+
// get file name, read it from the console if nothing
string evfilename = filename;
@@ -24,18 +27,29 @@ public static void Split(string filename, string outputPath)
Console.WriteLine("Splitting file {0}...", filename);
byte[] fc;
if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
+ {
fc = Prs.Decompress(filename);
+ }
else
+ {
fc = File.ReadAllBytes(filename);
+ }
+
EventExtraIniData ini = new EventExtraIniData() { Name = Path.GetFileNameWithoutExtension(filename) };
if (outputPath.Length != 0)
{
if (!Directory.Exists(outputPath))
+ {
Directory.CreateDirectory(outputPath);
+ }
+
Environment.CurrentDirectory = outputPath;
}
else
+ {
Environment.CurrentDirectory = Path.GetDirectoryName(evfilename);
+ }
+
Directory.CreateDirectory(Path.GetFileNameWithoutExtension(evfilename));
bool battle;
bool beta;
@@ -81,7 +95,10 @@ public static void Split(string filename, string outputPath)
ini.LanguageOnly = false;
}
if (lang)
+ {
Console.WriteLine("File only contains audio/subtitle timings.");
+ }
+
int address = 0;
int subcount = 0;
int timestamps = 0;
@@ -91,20 +108,35 @@ public static void Split(string filename, string outputPath)
SubtitleInfo subs = new SubtitleInfo();
subs.FrameStart = ByteConverter.ToInt32(fc, address);
if (subs.FrameStart != 0)
+ {
subcount++;
+ }
+
if (subs.FrameStart == -1)
+ {
timestamps++;
+ }
+
subs.VisibleTime = ByteConverter.ToUInt32(fc, address + 4);
ini.Subtitles.Add(subs);
}
if (subcount != 0)
+ {
Console.WriteLine("Event contains {0} active subtitle entr{1}.", subcount, subcount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use subtitles.");
+ }
+
if (timestamps != 0)
+ {
Console.WriteLine("Event contains {0} opening text screen entr{1}.", timestamps, timestamps == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not have an opening text screen.");
+ }
int audiocount = 0;
for (int i = 0; i < 512; i++)
@@ -113,7 +145,10 @@ public static void Split(string filename, string outputPath)
AudioInfo audio = new AudioInfo();
audio.FrameStart = ByteConverter.ToInt32(fc, address);
if (audio.FrameStart != 0)
+ {
audiocount++;
+ }
+
audio.SFXInit = fc[address + 4];
// Sets the credits scroll speed. Higher values equal slower speeds.
audio.CreditsControl = fc[address + 5];
@@ -124,9 +159,13 @@ public static void Split(string filename, string outputPath)
ini.AudioInfo.Add(audio);
}
if (audiocount != 0)
+ {
Console.WriteLine("Event contains {0} active audio entr{1}.", audiocount, audiocount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not contain active audio entries.");
+ }
if (fc.Length > 0x9900)
{
@@ -137,7 +176,10 @@ public static void Split(string filename, string outputPath)
ScreenEffects screen = new ScreenEffects();
screen.FrameStart = ByteConverter.ToInt32(fc, address);
if (screen.FrameStart != 0)
+ {
screencount++;
+ }
+
screen.Type = fc[address + 4];
if (battle)
{
@@ -163,9 +205,13 @@ public static void Split(string filename, string outputPath)
ini.ScreenEffects.Add(screen);
}
if (screencount != 0)
+ {
Console.WriteLine("Event contains {0} active screen effect entr{1}.", screencount, screencount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use screen effects.");
+ }
int particlecount = 0;
for (int i = 0; i < 2048; i++)
@@ -174,7 +220,10 @@ public static void Split(string filename, string outputPath)
ParticleEffects particle = new ParticleEffects();
particle.FrameStart = ByteConverter.ToInt32(fc, address);
if (particle.FrameStart != 0)
+ {
particlecount++;
+ }
+
particle.ParticleID = fc[address + 4];
particle.MotionID = fc[address + 5];
particle.TextureID = ByteConverter.ToSingle(fc, address + 0x8);
@@ -184,9 +233,13 @@ public static void Split(string filename, string outputPath)
ini.ParticleEffects.Add(particle);
}
if (particlecount != 0)
+ {
Console.WriteLine("Event contains {0} active standard particle effect entr{1}.", particlecount, particlecount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use standard particle effects.");
+ }
int lightcount = 0;
if (beta)
@@ -196,16 +249,28 @@ public static void Split(string filename, string outputPath)
address = 0x26800 + (0x44 * i);
LightingInfo light = new LightingInfo();
if (i < 64)
+ {
light.LightSet = "Light1";
+ }
else if (i < 128)
+ {
light.LightSet = "Light2";
+ }
else if (i < 192)
+ {
light.LightSet = "Light3";
+ }
else
+ {
light.LightSet = "Light4";
+ }
+
light.FrameStart = ByteConverter.ToInt32(fc, address);
if (light.FrameStart != 0)
+ {
lightcount++;
+ }
+
light.FadeType = ByteConverter.ToInt32(fc, address + 4);
light.LightDirection = new Vertex(fc, address + 8);
light.Color = new Vertex(fc, address + 0x14);
@@ -214,9 +279,13 @@ public static void Split(string filename, string outputPath)
ini.Lighting.Add(light);
}
if (lightcount != 0)
+ {
Console.WriteLine("Event contains {0} active lighting entr{1}.", lightcount, lightcount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use lighting.");
+ }
int blurcount = 0;
for (int i = 0; i < 64; i++)
@@ -225,7 +294,10 @@ public static void Split(string filename, string outputPath)
BlurInfo blur = new BlurInfo();
blur.FrameStart = ByteConverter.ToInt32(fc, address);
if (blur.FrameStart != 0)
+ {
blurcount++;
+ }
+
blur.Duration = ByteConverter.ToInt32(fc, address + 4);
blur.BlurModelID1 = fc[address + 8];
blur.BlurModelID2 = fc[address + 9];
@@ -237,9 +309,13 @@ public static void Split(string filename, string outputPath)
ini.BlurInfo.Add(blur);
}
if (blurcount != 0)
+ {
Console.WriteLine("Event contains {0} active blur entr{1}.", blurcount, blurcount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use blur effects.");
+ }
int particle2count = 0;
for (int i = 0; i < 64; i++)
@@ -254,7 +330,10 @@ public static void Split(string filename, string outputPath)
particle2.Unk6 = ByteConverter.ToInt16(fc, address + 0x1E);
particle2.FrameStart = ByteConverter.ToInt32(fc, address + 0x20);
if (particle2.FrameStart != 0)
+ {
particle2count++;
+ }
+
particle2.Spread = new Vertex(fc, address + 0x24);
particle2.Count = ByteConverter.ToInt32(fc, address + 0x30);
particle2.Unk9 = ByteConverter.ToInt32(fc, address + 0x34);
@@ -263,9 +342,13 @@ public static void Split(string filename, string outputPath)
ini.ParticleGenerators.Add(particle2);
}
if (particle2count != 0)
+ {
Console.WriteLine("Event contains {0} active particle generator entr{1}.", particle2count, particle2count == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use particle generators.");
+ }
int videocount = 0;
for (int i = 0; i < 64; i++)
@@ -274,7 +357,10 @@ public static void Split(string filename, string outputPath)
VideoInfo video = new VideoInfo();
video.FrameStart = ByteConverter.ToInt32(fc, address);
if (video.FrameStart != 0)
+ {
videocount++;
+ }
+
video.PosX = ByteConverter.ToInt16(fc, address + 0x4);
video.PosY = ByteConverter.ToInt16(fc, address + 0x6);
video.Depth = ByteConverter.ToSingle(fc, address + 0x8);
@@ -284,9 +370,13 @@ public static void Split(string filename, string outputPath)
ini.VideoInfo.Add(video);
}
if (videocount != 0)
+ {
Console.WriteLine("Event contains {0} active video entr{1}.", videocount, videocount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use video effects.");
+ }
}
else
{
@@ -295,16 +385,28 @@ public static void Split(string filename, string outputPath)
address = 0x26800 + (0x44 * i);
LightingInfo light = new LightingInfo();
if (i < 256)
+ {
light.LightSet = "Light1";
+ }
else if (i < 512)
+ {
light.LightSet = "Light2";
+ }
else if (i < 768)
+ {
light.LightSet = "Light3";
+ }
else
+ {
light.LightSet = "Light4";
+ }
+
light.FrameStart = ByteConverter.ToInt32(fc, address);
if (light.FrameStart != 0)
+ {
lightcount++;
+ }
+
light.FadeType = ByteConverter.ToInt32(fc, address + 4);
light.LightDirection = new Vertex(fc, address + 8);
light.Color = new Vertex(fc, address + 0x14);
@@ -313,9 +415,13 @@ public static void Split(string filename, string outputPath)
ini.Lighting.Add(light);
}
if (lightcount != 0)
+ {
Console.WriteLine("Event contains {0} active lighting entr{1}.", lightcount, lightcount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use lighting.");
+ }
int blurcount = 0;
for (int i = 0; i < 64; i++)
@@ -324,7 +430,10 @@ public static void Split(string filename, string outputPath)
BlurInfo blur = new BlurInfo();
blur.FrameStart = ByteConverter.ToInt32(fc, address);
if (blur.FrameStart != 0)
+ {
blurcount++;
+ }
+
blur.Duration = ByteConverter.ToInt32(fc, address + 4);
blur.BlurModelID1 = fc[address + 8];
blur.BlurModelID2 = fc[address + 9];
@@ -336,9 +445,13 @@ public static void Split(string filename, string outputPath)
ini.BlurInfo.Add(blur);
}
if (blurcount != 0)
+ {
Console.WriteLine("Event contains {0} active blur entr{1}.", blurcount, blurcount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use blur effects.");
+ }
int particle2count = 0;
for (int i = 0; i < 64; i++)
@@ -353,7 +466,10 @@ public static void Split(string filename, string outputPath)
particle2.Unk6 = ByteConverter.ToInt16(fc, address + 0x1E);
particle2.FrameStart = ByteConverter.ToInt32(fc, address + 0x20);
if (particle2.FrameStart != 0)
+ {
particle2count++;
+ }
+
particle2.Spread = new Vertex(fc, address + 0x24);
particle2.Count = ByteConverter.ToInt32(fc, address + 0x30);
particle2.Unk9 = ByteConverter.ToInt32(fc, address + 0x34);
@@ -362,9 +478,13 @@ public static void Split(string filename, string outputPath)
ini.ParticleGenerators.Add(particle2);
}
if (particle2count != 0)
+ {
Console.WriteLine("Event contains {0} active particle generator entr{1}.", particle2count, particle2count == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use particle generators.");
+ }
int videocount = 0;
for (int i = 0; i < 64; i++)
@@ -373,7 +493,10 @@ public static void Split(string filename, string outputPath)
VideoInfo video = new VideoInfo();
video.FrameStart = ByteConverter.ToInt32(fc, address);
if (video.FrameStart != 0)
+ {
videocount++;
+ }
+
video.PosX = ByteConverter.ToInt16(fc, address + 0x4);
video.PosY = ByteConverter.ToInt16(fc, address + 0x6);
video.Depth = ByteConverter.ToSingle(fc, address + 0x8);
@@ -383,9 +506,13 @@ public static void Split(string filename, string outputPath)
ini.VideoInfo.Add(video);
}
if (videocount != 0)
+ {
Console.WriteLine("Event contains {0} active video entr{1}.", videocount, videocount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Event does not use video effects.");
+ }
}
}
JsonSerializer js = new JsonSerializer
@@ -407,7 +534,11 @@ public static void SplitMini(string filename, string outputPath)
string dir = Environment.CurrentDirectory;
try
{
- if (outputPath[outputPath.Length - 1] != '/') outputPath = string.Concat(outputPath, "/");
+ if (outputPath[outputPath.Length - 1] != '/')
+ {
+ outputPath = string.Concat(outputPath, "/");
+ }
+
// get file name, read it from the console if nothing
string evfilename = filename;
@@ -415,18 +546,29 @@ public static void SplitMini(string filename, string outputPath)
Console.WriteLine("Splitting file {0}...", filename);
byte[] fc;
if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
+ {
fc = Prs.Decompress(filename);
+ }
else
+ {
fc = File.ReadAllBytes(filename);
+ }
+
MiniEventExtraIniData ini = new MiniEventExtraIniData() { Name = Path.GetFileNameWithoutExtension(filename) };
if (outputPath.Length != 0)
{
if (!Directory.Exists(outputPath))
+ {
Directory.CreateDirectory(outputPath);
+ }
+
Environment.CurrentDirectory = outputPath;
}
else
+ {
Environment.CurrentDirectory = Path.GetDirectoryName(evfilename);
+ }
+
Directory.CreateDirectory(Path.GetFileNameWithoutExtension(evfilename));
if (fc[4] > 0 || fc[8] > 0 || fc[0x100] > 0)
{
@@ -450,14 +592,21 @@ public static void SplitMini(string filename, string outputPath)
SubtitleInfo subs = new SubtitleInfo();
subs.FrameStart = ByteConverter.ToInt32(fc, addr);
if (subs.FrameStart != 0)
+ {
subcount++;
+ }
+
subs.VisibleTime = ByteConverter.ToUInt32(fc, addr + 4);
ini.Subtitles.Add(subs);
}
if (subcount != 0)
+ {
Console.WriteLine("Mini-Event contains {0} active subtitle entr{1}.", subcount, subcount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Mini-Event does not use subtitles.");
+ }
int effectcount = 0;
for (int i = 0; i < 64; i++)
@@ -467,7 +616,10 @@ public static void SplitMini(string filename, string outputPath)
int frame = fc.GetPointer(addr, 0);
fx.FrameStart = ByteConverter.ToUInt32(fc, addr);
if (frame != 0)
+ {
effectcount++;
+ }
+
fx.FadeType = fc[addr + 4];
fx.SFXEntry1 = fc[addr + 5];
fx.SFXEntry2 = fc[addr + 6];
@@ -478,9 +630,14 @@ public static void SplitMini(string filename, string outputPath)
ini.Effects.Add(fx);
}
if (effectcount != 0)
+ {
Console.WriteLine("Mini-Event contains {0} active effect entr{1}.", effectcount, effectcount == 1 ? "y" : "ies");
+ }
else
+ {
Console.WriteLine("Mini-Event does not use additional effects.");
+ }
+
int misccount = 0;
for (int i = 0; i < 1; i++)
{
@@ -492,13 +649,20 @@ public static void SplitMini(string filename, string outputPath)
int unkdata2 = fc.GetPointer(addr + 0x10, 0);
misc.Unk3 = new Vertex(fc, addr + 0x10);
if (unkdata1 != 0 || unkdata2 != 0)
+ {
misccount++;
+ }
+
ini.Unknown.Add(misc);
}
if (misccount != 0)
+ {
Console.WriteLine("Mini-Event contains an unknown effect entry.");
+ }
else
+ {
Console.WriteLine("Mini-Event does not use unknown effects.");
+ }
JsonSerializer js = new JsonSerializer
{
@@ -518,7 +682,11 @@ public static void Build(bool? isBigEndian, bool? isLanguageFile, string filenam
string dir = Environment.CurrentDirectory;
try
{
- if (fileOutputPath[fileOutputPath.Length - 1] != '/') fileOutputPath = string.Concat(fileOutputPath, "/");
+ if (fileOutputPath[fileOutputPath.Length - 1] != '/')
+ {
+ fileOutputPath = string.Concat(fileOutputPath, "/");
+ }
+
string path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename));
JsonSerializer js = new JsonSerializer();
EventExtraIniData ini;
@@ -537,22 +705,35 @@ public static void Build(bool? isBigEndian, bool? isLanguageFile, string filenam
{
ByteConverter.BigEndian = isBigEndian.Value;
if (ByteConverter.BigEndian == true)
+ {
battle = true;
+ }
else
+ {
battle = false;
-
+ }
}
if (!isLanguageFile.HasValue)
+ {
language = ini.LanguageOnly;
+ }
else
+ {
language = isLanguageFile.Value;
+ }
+
List extradata = new List();
foreach (SubtitleInfo subs in ini.Subtitles)
{
if (subs.FrameStart != -1)
- extradata.AddRange(ByteConverter.GetBytes(subs.FrameStart));
+ {
+ extradata.AddRange(ByteConverter.GetBytes(subs.FrameStart));
+ }
else
+ {
extradata.AddRange(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF });
+ }
+
extradata.AddRange(ByteConverter.GetBytes(subs.VisibleTime));
}
foreach (AudioInfo audio in ini.AudioInfo)
@@ -564,9 +745,13 @@ public static void Build(bool? isBigEndian, bool? isLanguageFile, string filenam
foreach (ScreenEffects screen in ini.ScreenEffects)
{
if (battle)
+ {
extradata.AddRange(screen.GetBytesGC());
+ }
else
+ {
extradata.AddRange(screen.GetBytesDC());
+ }
}
foreach (ParticleEffects particle in ini.ParticleEffects)
@@ -594,17 +779,24 @@ public static void Build(bool? isBigEndian, bool? isLanguageFile, string filenam
if (fileOutputPath.Length != 0)
{
if (!Directory.Exists(fileOutputPath))
+ {
Directory.CreateDirectory(fileOutputPath);
+ }
+
filename = Path.Combine(fileOutputPath, Path.GetFileName(filename));
}
if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
{
FraGag.Compression.Prs.Compress(extradata.ToArray(), filename);
if (!File.Exists(filename))
+ {
File.Create(filename);
+ }
}
else
+ {
File.WriteAllBytes(filename, extradata.ToArray());
+ }
}
finally
{
@@ -616,7 +808,11 @@ public static void BuildMini(bool? isBigEndian, string filename, string fileOutp
string dir = Environment.CurrentDirectory;
try
{
- if (fileOutputPath[fileOutputPath.Length - 1] != '/') fileOutputPath = string.Concat(fileOutputPath, "/");
+ if (fileOutputPath[fileOutputPath.Length - 1] != '/')
+ {
+ fileOutputPath = string.Concat(fileOutputPath, "/");
+ }
+
string path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename));
JsonSerializer js = new JsonSerializer();
MiniEventExtraIniData ini;
@@ -624,9 +820,14 @@ public static void BuildMini(bool? isBigEndian, string filename, string fileOutp
using (JsonTextReader jtr = new JsonTextReader(tr))
ini = js.Deserialize(jtr);
if (!isBigEndian.HasValue)
+ {
ByteConverter.BigEndian = ini.BigEndian;
+ }
else
+ {
ByteConverter.BigEndian = isBigEndian.Value;
+ }
+
List extradata = new List();
foreach (SubtitleInfo subs in ini.Subtitles)
{
@@ -644,17 +845,24 @@ public static void BuildMini(bool? isBigEndian, string filename, string fileOutp
if (fileOutputPath.Length != 0)
{
if (!Directory.Exists(fileOutputPath))
+ {
Directory.CreateDirectory(fileOutputPath);
+ }
+
filename = Path.Combine(fileOutputPath, Path.GetFileName(filename));
}
if (Path.GetExtension(filename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
{
FraGag.Compression.Prs.Compress(extradata.ToArray(), filename);
if (!File.Exists(filename))
+ {
File.Create(filename);
+ }
}
else
+ {
File.WriteAllBytes(filename, extradata.ToArray());
+ }
}
finally
{
@@ -927,9 +1135,14 @@ public byte[] GetBytes()
result.AddRange(new byte[2]);
// Some files are cute and have leftover text in them. This ensures the strings aren't too long.
if (VideoName.Length < 0x30)
+ {
result.AddRange(Encoding.ASCII.GetBytes(VideoName));
+ }
else
+ {
result.AddRange(Encoding.ASCII.GetBytes(VideoName.Remove(0x30)));
+ }
+
result.Align(0x40);
return result.ToArray();
}
diff --git a/Libraries/SplitTools/SplitMTN.cs b/Libraries/SplitTools/SplitMTN.cs
index 0c637634..664493ed 100644
--- a/Libraries/SplitTools/SplitMTN.cs
+++ b/Libraries/SplitTools/SplitMTN.cs
@@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
-using System.Windows.Forms;
namespace SplitTools.SAArc
{
@@ -117,9 +116,7 @@ public static void Build(bool? isBigEndian, string mtnFilename)
{
if (!animParts.TryGetValue(item.Value, out short animPart))
{
- var msgError = "Error, The animation \"" + item.Value + "\" is missing. Please check your ini file and make sure the animation name matches.";
- MessageBox.Show(msgError, "Missing Anim File");
- return;
+ throw new ArgumentOutOfRangeException(nameof(mtnFilename), $"The animation {item.Value} is missing. Please check your .ini file and make sure the animation name matches.");
}
mtnFile.AddRange(ByteConverter.GetBytes(item.Key));
diff --git a/Libraries/SplitTools/SplitMiniEvent.cs b/Libraries/SplitTools/SplitMiniEvent.cs
index 2a470ad5..efebbf94 100644
--- a/Libraries/SplitTools/SplitMiniEvent.cs
+++ b/Libraries/SplitTools/SplitMiniEvent.cs
@@ -1,21 +1,19 @@
using FraGag.Compression;
using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
using SAModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Web.Services.Description;
namespace SplitTools.SAArc
{
public static class SA2MiniEvent
{
- static List nodenames = new List();
- static Dictionary modelfiles = new Dictionary();
- static Dictionary motionfiles = new Dictionary();
- static Dictionary camarrayfiles = new Dictionary();
+ static List nodenames = new();
+ static Dictionary modelfiles = new();
+ static Dictionary motionfiles = new();
+ static Dictionary camarrayfiles = new();
public static void Split(string filename, string outputPath, string labelFile = null)
{
@@ -26,7 +24,11 @@ public static void Split(string filename, string outputPath, string labelFile =
string dir = Environment.CurrentDirectory;
try
{
- if (outputPath[outputPath.Length - 1] != '/') outputPath = string.Concat(outputPath, "/");
+ if (outputPath[outputPath.Length - 1] != '/')
+ {
+ outputPath = string.Concat(outputPath, "/");
+ }
+
// get file name, read it from the console if nothing
string evfilename = filename;
evfilename = Path.GetFullPath(evfilename);
@@ -34,24 +36,39 @@ public static void Split(string filename, string outputPath, string labelFile =
Console.WriteLine("Splitting file {0}...", evfilename);
byte[] fc;
if (Path.GetExtension(evfilename).Equals(".prs", StringComparison.OrdinalIgnoreCase))
+ {
fc = Prs.Decompress(evfilename);
+ }
else
+ {
fc = File.ReadAllBytes(evfilename);
+ }
+
MiniEventIniData ini = new MiniEventIniData() { Name = Path.GetFileNameWithoutExtension(evfilename) };
if (outputPath.Length != 0)
{
if (!Directory.Exists(outputPath))
+ {
Directory.CreateDirectory(outputPath);
+ }
+
Environment.CurrentDirectory = outputPath;
}
else
+ {
Environment.CurrentDirectory = Path.GetDirectoryName(evfilename);
+ }
+
Directory.CreateDirectory(Path.GetFileNameWithoutExtension(evfilename));
// Metadata for SAMDL Project Mode
byte[] mlength = null;
Dictionary evsectionlist = new Dictionary();
Dictionary evsplitfilenames = new Dictionary();
- if (labelFile != null) labelFile = Path.GetFullPath(labelFile);
+ if (labelFile != null)
+ {
+ labelFile = Path.GetFullPath(labelFile);
+ }
+
if (File.Exists(labelFile))
{
evsplitfilenames = IniSerializer.Deserialize>(labelFile);
@@ -185,10 +202,16 @@ public static void Split(string filename, string outputPath, string labelFile =
{
parts.Anims = GetMotion(fc, address2 + 4, key, $"{chnm}\\{prnm}.saanim", motions, modelfiles[parts.Model].Model.CountAnimated(), $"{evname} {chnm} EV {partmetaname} Animation");
if (parts.Anims != null)
+ {
modelfiles[parts.Model].Motions.Add($"{prnm}.saanim");
+ }
+
parts.ShapeMotions = GetMotion(fc, address2 + 8, key, $"{chnm}\\{prnm}Shape.saanim", motions, modelfiles[parts.Model].Model.CountMorph(), $"{evname} {chnm} EV {partmetaname} Shape Motion");
if (parts.ShapeMotions != null)
+ {
modelfiles[parts.Model].Motions.Add($"{prnm}Shape.saanim");
+ }
+
// populating metadata file
string outResult = null;
// checks if the source ini is a placeholder
@@ -207,7 +230,9 @@ public static void Split(string filename, string outputPath, string labelFile =
data.Parts.Add(parts);
}
else
+ {
data.Parts.Add(null);
+ }
}
ini.MainData.Add(data);
}
@@ -225,7 +250,10 @@ public static void Split(string filename, string outputPath, string labelFile =
ini.NinjaCamera = GetCamData(fc, 4, key, "CameraAttributes.ini", ncams);
}
else
+ {
Console.WriteLine("Mini-Event does not contain a camera.");
+ }
+
ini.CharacterFlags = (SA2CharacterFlags)ByteConverter.ToInt32(fc, 0);
foreach (var item in motionfiles.Values)
{
@@ -278,10 +306,17 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
string dir = Environment.CurrentDirectory;
try
{
- if (fileOutputPath[fileOutputPath.Length - 1] != '/') fileOutputPath = string.Concat(fileOutputPath, "/");
+ if (fileOutputPath[fileOutputPath.Length - 1] != '/')
+ {
+ fileOutputPath = string.Concat(fileOutputPath, "/");
+ }
+
filename = Path.GetFullPath(filename);
if (Directory.Exists(filename))
+ {
filename += ".prs";
+ }
+
Environment.CurrentDirectory = Path.GetDirectoryName(filename);
string path = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(filename)), Path.GetFileNameWithoutExtension(filename));
JsonSerializer js = new JsonSerializer();
@@ -291,9 +326,14 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
evinfo = js.Deserialize(jtr);
uint gamekey;
if (!isBigEndian.HasValue)
+ {
ByteConverter.BigEndian = evinfo.BigEndian;
+ }
else
+ {
ByteConverter.BigEndian = isBigEndian.Value;
+ }
+
List evfile = new List();
List databytes = new List();
Dictionary animaddrs = new Dictionary();
@@ -303,9 +343,14 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
Dictionary pshapeaddrs = new Dictionary();
Dictionary labels = new Dictionary();
if (ByteConverter.BigEndian)
+ {
gamekey = 0x816DFE60;
+ }
else
+ {
gamekey = 0xCB00000;
+ }
+
uint imageBase = gamekey + 0x2C;
// Character flags
evfile.AddRange(ByteConverter.GetBytes(Convert.ToUInt32(evinfo.CharacterFlags)));
@@ -404,7 +449,9 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
imageBase += 0x34;
}
else
+ {
evfile.AddRange(new byte[4]);
+ }
}
evfile.AddRange(new byte[4]);
// Raw data goes here
@@ -426,16 +473,27 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
{
evfile.AddRange(ByteConverter.GetBytes(mdladdrs[constant + p]));
if (part.Anims != null)
+ {
evfile.AddRange(ByteConverter.GetBytes(panimaddrs[constant + p]));
+ }
else
+ {
evfile.AddRange(new byte[4]);
+ }
+
if (part.ShapeMotions != null)
+ {
evfile.AddRange(ByteConverter.GetBytes(pshapeaddrs[constant + p]));
+ }
else
+ {
evfile.AddRange(new byte[4]);
+ }
}
else
+ {
evfile.AddRange(new byte[0xC]);
+ }
}
}
}
@@ -444,7 +502,10 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
if (fileOutputPath.Length != 0)
{
if (!Directory.Exists(fileOutputPath))
+ {
Directory.CreateDirectory(fileOutputPath);
+ }
+
filename = Path.Combine(fileOutputPath, Path.GetFileName(filename));
}
@@ -452,10 +513,14 @@ public static void Build(bool? isBigEndian, string filename, string fileOutputPa
{
FraGag.Compression.Prs.Compress(evfile.ToArray(), filename);
if (!File.Exists(filename))
+ {
File.Create(filename);
+ }
}
else
+ {
File.WriteAllBytes(filename, evfile.ToArray());
+ }
}
finally
{
@@ -478,7 +543,10 @@ private static string GetModel(byte[] fc, int address, uint key, string fn, stri
List names = new List(obj.GetObjects().Select((o) => o.Name));
foreach (string s in names)
if (modelfiles.ContainsKey(s))
+ {
modelfiles.Remove(s);
+ }
+
nodenames.AddRange(names);
modelfiles.Add(obj.Name, new ModelInfo(fn, obj, ModelFormat.Chunk, meta));
}
@@ -490,7 +558,9 @@ private static string GetMotion(byte[] fc, int address, uint key, string fn, Lis
{
NJS_MOTION mtn = null;
if (motions != null)
+ {
mtn = motions[ByteConverter.ToInt32(fc, address)];
+ }
else
{
int ptr3 = fc.GetPointer(address, key);
@@ -501,9 +571,16 @@ private static string GetMotion(byte[] fc, int address, uint key, string fn, Lis
mtn.OptimizeShape();
}
}
- if (mtn == null) return null;
+ if (mtn == null)
+ {
+ return null;
+ }
+
if (!motionfiles.ContainsKey(mtn.Name) || motionfiles[mtn.Name].Filename == null)
+ {
motionfiles[mtn.Name] = new MotionInfo(fn, mtn, meta);
+ }
+
return mtn.Name;
}
@@ -511,7 +588,9 @@ private static string GetCamData(byte[] fc, int address, uint key, string fn, Li
{
NJS_CAMERA ncam = null;
if (ncams != null)
+ {
ncam = ncams[ByteConverter.ToInt32(fc, address)];
+ }
else
{
int ptr3 = fc.GetPointer(address, key);
@@ -520,9 +599,16 @@ private static string GetCamData(byte[] fc, int address, uint key, string fn, Li
ncam = new NJS_CAMERA(fc, ptr3 + 0xC, key);
}
}
- if (ncam == null) return null;
+ if (ncam == null)
+ {
+ return null;
+ }
+
if (!camarrayfiles.ContainsKey(ncam.Name) || camarrayfiles[ncam.Name].Filename == null)
+ {
camarrayfiles[ncam.Name] = new CameraInfo(fn, ncam);
+ }
+
return ncam.Name;
}
}
@@ -539,7 +625,7 @@ public string GameString
set { Game = (Game)Enum.Parse(typeof(Game), value); }
}
public bool BigEndian { get; set; }
- public Dictionary Files { get; set; } = new Dictionary();
+ public Dictionary Files { get; set; } = new();
[JsonIgnore]
public SA2CharacterFlags CharacterFlags { get; set; }
[JsonProperty(PropertyName = "CharacterFlags")]
@@ -550,8 +636,8 @@ public string CharFlagString
}
public string Camera { get; set; }
public string NinjaCamera { get; set; }
- public Dictionary MainDataAddrs { get; set; } = new Dictionary();
- public List MainData { get; set; } = new List();
+ public Dictionary MainDataAddrs { get; set; } = new();
+ public List MainData { get; set; } = new();
}
public class MiniEventMaster
@@ -559,7 +645,7 @@ public class MiniEventMaster
public string Name { get; set; }
public string Character { get; set; }
public string BodyAnims { get; set; }
- public List Parts { get; set; } = new List();
+ public List Parts { get; set; } = new();
}
public class MiniEventParts
diff --git a/Libraries/SplitTools/SplitTools.csproj b/Libraries/SplitTools/SplitTools.csproj
index f387d37a..5a9edf35 100644
--- a/Libraries/SplitTools/SplitTools.csproj
+++ b/Libraries/SplitTools/SplitTools.csproj
@@ -2,13 +2,11 @@
net8.0-windows7.0
Library
- true
en
false
false
..\..\build\lib\
embedded
- x64;x86
@@ -21,7 +19,4 @@
-
-
-
\ No newline at end of file
diff --git a/Libraries/VrSharp/VrSharp.csproj b/Libraries/VrSharp/VrSharp.csproj
index ae0ec1fa..6a87f486 100644
--- a/Libraries/VrSharp/VrSharp.csproj
+++ b/Libraries/VrSharp/VrSharp.csproj
@@ -7,7 +7,6 @@
..\..\build\lib\
false
false
- x64;x86
diff --git a/SA1Tools/PLTool/PLTool.csproj b/SA1Tools/PLTool/PLTool.csproj
index cd2889c6..960b220f 100644
--- a/SA1Tools/PLTool/PLTool.csproj
+++ b/SA1Tools/PLTool/PLTool.csproj
@@ -7,7 +7,6 @@
en
false
false
- x64;x86
PLTool_100.ico
diff --git a/SA1Tools/SADXObjectDefinitions/SADXObjectDefinitions.csproj b/SA1Tools/SADXObjectDefinitions/SADXObjectDefinitions.csproj
index 17738659..558b26be 100644
--- a/SA1Tools/SADXObjectDefinitions/SADXObjectDefinitions.csproj
+++ b/SA1Tools/SADXObjectDefinitions/SADXObjectDefinitions.csproj
@@ -7,7 +7,6 @@
embedded
false
false
- x64;x86
diff --git a/SA1Tools/SADXTweaker2/SADXTweaker2.csproj b/SA1Tools/SADXTweaker2/SADXTweaker2.csproj
index 4e1bba33..dbbb5408 100644
--- a/SA1Tools/SADXTweaker2/SADXTweaker2.csproj
+++ b/SA1Tools/SADXTweaker2/SADXTweaker2.csproj
@@ -7,7 +7,6 @@
en
false
false
- x64;x86
sadxtweaker.ico
diff --git a/SA1Tools/SADXsndSharp/SADXsndSharp.csproj b/SA1Tools/SADXsndSharp/SADXsndSharp.csproj
index 24e48b96..3e1a4477 100644
--- a/SA1Tools/SADXsndSharp/SADXsndSharp.csproj
+++ b/SA1Tools/SADXsndSharp/SADXsndSharp.csproj
@@ -9,7 +9,6 @@
false
false
embedded
- x64;x86
diff --git a/SA1Tools/SASave/SASave.csproj b/SA1Tools/SASave/SASave.csproj
index 42d3d0e7..38f86a85 100644
--- a/SA1Tools/SASave/SASave.csproj
+++ b/SA1Tools/SASave/SASave.csproj
@@ -9,7 +9,6 @@
false
false
embedded
- x64;x86
diff --git a/SA1Tools/VMSEditor/VMSEditor.csproj b/SA1Tools/VMSEditor/VMSEditor.csproj
index 8be18816..2c29f22b 100644
--- a/SA1Tools/VMSEditor/VMSEditor.csproj
+++ b/SA1Tools/VMSEditor/VMSEditor.csproj
@@ -10,7 +10,6 @@
embedded
false
false
- x64;x86
diff --git a/SA2Tools/SA2CutsceneTextEditor/SA2CutsceneTextEditor.csproj b/SA2Tools/SA2CutsceneTextEditor/SA2CutsceneTextEditor.csproj
index cc2bdad0..169aaf46 100644
--- a/SA2Tools/SA2CutsceneTextEditor/SA2CutsceneTextEditor.csproj
+++ b/SA2Tools/SA2CutsceneTextEditor/SA2CutsceneTextEditor.csproj
@@ -9,7 +9,6 @@
embedded
false
false
- x64;x86
true
diff --git a/SA2Tools/SA2EventViewer/SA2EventViewer.csproj b/SA2Tools/SA2EventViewer/SA2EventViewer.csproj
index 05669803..e7713a89 100644
--- a/SA2Tools/SA2EventViewer/SA2EventViewer.csproj
+++ b/SA2Tools/SA2EventViewer/SA2EventViewer.csproj
@@ -5,7 +5,6 @@
true
..\..\build\tools\
en
- x64;x86
icon_sa2EvView.ico
diff --git a/SA2Tools/SA2MessageFileEditor/SA2MessageFileEditor.csproj b/SA2Tools/SA2MessageFileEditor/SA2MessageFileEditor.csproj
index 64937dd9..410ce2eb 100644
--- a/SA2Tools/SA2MessageFileEditor/SA2MessageFileEditor.csproj
+++ b/SA2Tools/SA2MessageFileEditor/SA2MessageFileEditor.csproj
@@ -9,7 +9,6 @@
embedded
false
false
- x64;x86
true
diff --git a/SA2Tools/SA2ObjectDefinitions/SA2ObjectDefinitions.csproj b/SA2Tools/SA2ObjectDefinitions/SA2ObjectDefinitions.csproj
index 1fb70ad8..65f3569a 100644
--- a/SA2Tools/SA2ObjectDefinitions/SA2ObjectDefinitions.csproj
+++ b/SA2Tools/SA2ObjectDefinitions/SA2ObjectDefinitions.csproj
@@ -8,7 +8,6 @@
embedded
false
false
- x64;x86
true
diff --git a/SA2Tools/SA2StageSelEdit/SA2StageSelEdit.csproj b/SA2Tools/SA2StageSelEdit/SA2StageSelEdit.csproj
index 935799df..20190d76 100644
--- a/SA2Tools/SA2StageSelEdit/SA2StageSelEdit.csproj
+++ b/SA2Tools/SA2StageSelEdit/SA2StageSelEdit.csproj
@@ -9,7 +9,6 @@
embedded
false
false
- x64;x86
diff --git a/SAFontEdit/SAFontEdit.csproj b/SAFontEdit/SAFontEdit.csproj
index d835494e..b5eed019 100644
--- a/SAFontEdit/SAFontEdit.csproj
+++ b/SAFontEdit/SAFontEdit.csproj
@@ -8,7 +8,6 @@
false
en
embedded
- x64;x86
true
sadxfontedit.ico
diff --git a/SALVL/SALVL.csproj b/SALVL/SALVL.csproj
index 55280f9f..f0708cf0 100644
--- a/SALVL/SALVL.csproj
+++ b/SALVL/SALVL.csproj
@@ -10,7 +10,6 @@
false
icon_dxLvl2.ico
embedded
- x64;x86
diff --git a/SAMDL/SAMDL.csproj b/SAMDL/SAMDL.csproj
index 48ce3b1e..e48fc2e1 100644
--- a/SAMDL/SAMDL.csproj
+++ b/SAMDL/SAMDL.csproj
@@ -10,7 +10,6 @@
false
ico_samdl.ico
embedded
- x64;x86
TRACE
diff --git a/SAToolsHub/SAToolsHub.csproj b/SAToolsHub/SAToolsHub.csproj
index b0e059c4..20b34110 100644
--- a/SAToolsHub/SAToolsHub.csproj
+++ b/SAToolsHub/SAToolsHub.csproj
@@ -8,7 +8,6 @@
false
false
embedded
- x64;x86
Resources\ToolsHub_ico.ico
diff --git a/TextureEditor/TextureEditor.csproj b/TextureEditor/TextureEditor.csproj
index 3885c191..fc6f954c 100644
--- a/TextureEditor/TextureEditor.csproj
+++ b/TextureEditor/TextureEditor.csproj
@@ -10,7 +10,6 @@
icon_TexEdit.ico
embedded
True
- x64;x86
true
From 9773d986da7f1c1d61c21a7506b605a636104ddd Mon Sep 17 00:00:00 2001
From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
Date: Thu, 19 Dec 2024 14:38:13 +0000
Subject: [PATCH 2/3] Remove SACompGC DLLs
---
Dependencies/SACompGC_x64.dll | Bin 13824 -> 0 bytes
Dependencies/SACompGC_x86.dll | Bin 10240 -> 0 bytes
2 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 Dependencies/SACompGC_x64.dll
delete mode 100644 Dependencies/SACompGC_x86.dll
diff --git a/Dependencies/SACompGC_x64.dll b/Dependencies/SACompGC_x64.dll
deleted file mode 100644
index c32f263903ec9e7d17f70479aa52a09d4ac3f52a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 13824
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
From e9ba4e1d5c9597749595bea0dedf20d29292b13c Mon Sep 17 00:00:00 2001
From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
Date: Thu, 19 Dec 2024 15:23:51 +0000
Subject: [PATCH 3/3] Remove SACompGC BuildEvent
---
SAToolsHub/SAToolsHub.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SAToolsHub/SAToolsHub.csproj b/SAToolsHub/SAToolsHub.csproj
index 20b34110..b74d18a7 100644
--- a/SAToolsHub/SAToolsHub.csproj
+++ b/SAToolsHub/SAToolsHub.csproj
@@ -41,6 +41,6 @@
-
+
\ No newline at end of file