mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-26 14:30:26 +00:00
Some LM3 adjustments
This commit is contained in:
parent
ddfdbdc724
commit
ee82fb1218
6 changed files with 164 additions and 101 deletions
|
@ -57,7 +57,6 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
byte unk = tableReader.ReadByte();
|
byte unk = tableReader.ReadByte();
|
||||||
byte chunkFlags = tableReader.ReadByte();
|
byte chunkFlags = tableReader.ReadByte();
|
||||||
entry.ChunkSubCount = tableReader.ReadByte(); //Uncertain about this. 2 for textures (info + block). Some sections however use large numbers.
|
entry.ChunkSubCount = tableReader.ReadByte(); //Uncertain about this. 2 for textures (info + block). Some sections however use large numbers.
|
||||||
Console.WriteLine($"ChunkSubCount {entry.ChunkSubCount} {(entry.ChunkSubCount >> 4)}");
|
|
||||||
tableReader.ReadByte();
|
tableReader.ReadByte();
|
||||||
tableReader.ReadByte();
|
tableReader.ReadByte();
|
||||||
tableReader.ReadByte();
|
tableReader.ReadByte();
|
||||||
|
@ -83,8 +82,6 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
var chunkFlags = tableReader.ReadUInt16();
|
var chunkFlags = tableReader.ReadUInt16();
|
||||||
|
|
||||||
byte blockFlag = (byte)(chunkFlags >> 12);
|
byte blockFlag = (byte)(chunkFlags >> 12);
|
||||||
//Console.WriteLine($"blockFlag {chunkFlags >> 1} {chunkFlags >> 2} {chunkFlags >> 3} {chunkFlags >> 4} {chunkFlags >> 5} {chunkFlags >> 6} {chunkFlags >> 7} {chunkFlags >> 8}");
|
|
||||||
Console.WriteLine($"blockFlag {blockFlag} { subEntry.ChunkType}");
|
|
||||||
|
|
||||||
subEntry.ChunkSize = tableReader.ReadUInt32();
|
subEntry.ChunkSize = tableReader.ReadUInt32();
|
||||||
subEntry.ChunkOffset = tableReader.ReadUInt32();
|
subEntry.ChunkOffset = tableReader.ReadUInt32();
|
||||||
|
|
|
@ -99,31 +99,7 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
TreeNode materialNamesFolder = new TreeNode("Material Names");
|
TreeNode materialNamesFolder = new TreeNode("Material Names");
|
||||||
TreeNode chunkFolder = new TreeNode("Chunks");
|
TreeNode chunkFolder = new TreeNode("Chunks");
|
||||||
|
|
||||||
public static Dictionary<uint, string> HashNames = new Dictionary<uint, string>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public List<string> StringList = new List<string>();
|
public List<string> StringList = new List<string>();
|
||||||
public static void LoadHashes()
|
|
||||||
{
|
|
||||||
foreach (string hashStr in Properties.Resources.LM3_Hashes.Split('\n'))
|
|
||||||
{
|
|
||||||
string HashString = hashStr.TrimEnd();
|
|
||||||
|
|
||||||
uint hash = (uint)NLG_Common.StringToHash(HashString);
|
|
||||||
if (!HashNames.ContainsKey(hash))
|
|
||||||
HashNames.Add(hash, HashString);
|
|
||||||
|
|
||||||
string[] hashPaths = HashString.Split('/');
|
|
||||||
for (int i = 0; i < hashPaths?.Length; i++)
|
|
||||||
{
|
|
||||||
hash = (uint)NLG_Common.StringToHash(hashPaths[i]);
|
|
||||||
if (!HashNames.ContainsKey(hash))
|
|
||||||
HashNames.Add(hash, HashString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public System.IO.Stream GetFileBufferData()
|
public System.IO.Stream GetFileBufferData()
|
||||||
{
|
{
|
||||||
|
@ -144,7 +120,6 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
{
|
{
|
||||||
CanSave = false;
|
CanSave = false;
|
||||||
|
|
||||||
LoadHashes();
|
|
||||||
modelFolder = new LM3_ModelFolder(this);
|
modelFolder = new LM3_ModelFolder(this);
|
||||||
DrawableContainer.Name = FileName;
|
DrawableContainer.Name = FileName;
|
||||||
Renderer = new LM3_Renderer();
|
Renderer = new LM3_Renderer();
|
||||||
|
@ -291,7 +266,6 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
uint havokFileIndex = 0;
|
uint havokFileIndex = 0;
|
||||||
foreach (var chunk in ChunkTable.ChunkSubEntries)
|
foreach (var chunk in ChunkTable.ChunkSubEntries)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"chunk.ChunkType {chunk.ChunkType}");
|
|
||||||
var chunkEntry = new ChunkDataEntry(this, chunk);
|
var chunkEntry = new ChunkDataEntry(this, chunk);
|
||||||
chunkEntry.Text = $"{chunkId} {chunk.ChunkType.ToString("X")} {chunk.ChunkType} {chunk.ChunkOffset} {chunk.ChunkSize}";
|
chunkEntry.Text = $"{chunkId} {chunk.ChunkType.ToString("X")} {chunk.ChunkType} {chunk.ChunkOffset} {chunk.ChunkSize}";
|
||||||
|
|
||||||
|
@ -309,6 +283,7 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
using (var textureReader = new FileReader(chunkEntry.FileData, true))
|
using (var textureReader = new FileReader(chunkEntry.FileData, true))
|
||||||
{
|
{
|
||||||
currentTexture = new TexturePOWE();
|
currentTexture = new TexturePOWE();
|
||||||
|
currentTexture.HeaderOffset = chunk.ChunkOffset;
|
||||||
currentTexture.ImageKey = "texture";
|
currentTexture.ImageKey = "texture";
|
||||||
currentTexture.SelectedImageKey = currentTexture.ImageKey;
|
currentTexture.SelectedImageKey = currentTexture.ImageKey;
|
||||||
currentTexture.Index = ImageHeaderIndex;
|
currentTexture.Index = ImageHeaderIndex;
|
||||||
|
@ -318,8 +293,8 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
else
|
else
|
||||||
currentTexture.Text = $"Texture {currentTexture.ID2.ToString("X")}";
|
currentTexture.Text = $"Texture {currentTexture.ID2.ToString("X")}";
|
||||||
|
|
||||||
if (HashNames.ContainsKey(currentTexture.ID2))
|
if (NLG_Common.HashNames.ContainsKey(currentTexture.ID2))
|
||||||
currentTexture.Text = HashNames[currentTexture.ID2];
|
currentTexture.Text = NLG_Common.HashNames[currentTexture.ID2];
|
||||||
|
|
||||||
textureFolder.Nodes.Add(currentTexture);
|
textureFolder.Nodes.Add(currentTexture);
|
||||||
if (!Renderer.TextureList.ContainsKey(currentTexture.ID2.ToString("x")))
|
if (!Renderer.TextureList.ContainsKey(currentTexture.ID2.ToString("x")))
|
||||||
|
@ -335,7 +310,28 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
currentTexture.DataOffset = chunk.ChunkOffset;
|
currentTexture.DataOffset = chunk.ChunkOffset;
|
||||||
currentTexture.ImageData = chunkEntry.FileData.ToBytes();
|
currentTexture.ImageData = chunkEntry.FileData.ToBytes();
|
||||||
break;
|
break;
|
||||||
case SubDataType.ModelStart:
|
case SubDataType.ModelInfo:
|
||||||
|
chunkEntry.DataFile = File052Data;
|
||||||
|
|
||||||
|
uint numModels = chunk.ChunkSize / 12;
|
||||||
|
using (var dataReader = new FileReader(chunkEntry.FileData, true))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < numModels; i++)
|
||||||
|
{
|
||||||
|
uint hashID = dataReader.ReadUInt32();
|
||||||
|
uint numMeshes = dataReader.ReadUInt32();
|
||||||
|
dataReader.ReadUInt32(); //0
|
||||||
|
|
||||||
|
string text = hashID.ToString("X");
|
||||||
|
if (NLG_Common.HashNames.ContainsKey(hashID))
|
||||||
|
text = NLG_Common.HashNames[hashID];
|
||||||
|
|
||||||
|
|
||||||
|
currentModel.Text = text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SubDataType.MaterailData:
|
||||||
currentModelChunk = new TreeNode($"Model {modelIndex}");
|
currentModelChunk = new TreeNode($"Model {modelIndex}");
|
||||||
chunkFolder.Nodes.Add(currentModelChunk);
|
chunkFolder.Nodes.Add(currentModelChunk);
|
||||||
|
|
||||||
|
@ -347,8 +343,8 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
if (ModelHashes.Count > modelIndex)
|
if (ModelHashes.Count > modelIndex)
|
||||||
{
|
{
|
||||||
currentModel.Text = $"Model {modelIndex} {ModelHashes[(int)modelIndex].ToString("x")}";
|
currentModel.Text = $"Model {modelIndex} {ModelHashes[(int)modelIndex].ToString("x")}";
|
||||||
if (HashNames.ContainsKey(ModelHashes[(int)modelIndex]))
|
if (NLG_Common.HashNames.ContainsKey(ModelHashes[(int)modelIndex]))
|
||||||
currentModel.Text = HashNames[ModelHashes[(int)modelIndex]];
|
currentModel.Text = NLG_Common.HashNames[ModelHashes[(int)modelIndex]];
|
||||||
}
|
}
|
||||||
|
|
||||||
modelIndex++;
|
modelIndex++;
|
||||||
|
@ -366,8 +362,8 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
chunkEntry.DataFile = File052Data;
|
chunkEntry.DataFile = File052Data;
|
||||||
int MeshCount = (int)chunkEntry.FileData.Length / 0x40;
|
int MeshCount = (int)chunkEntry.FileData.Length / 0x40;
|
||||||
|
|
||||||
using (var vtxPtrReader = new FileReader(currentVertexPointerList.FileData))
|
using (var vtxPtrReader = new FileReader(currentVertexPointerList.FileData, true))
|
||||||
using (var meshReader = new FileReader(chunkEntry.FileData))
|
using (var meshReader = new FileReader(chunkEntry.FileData, true))
|
||||||
{
|
{
|
||||||
for (uint i = 0; i < MeshCount; i++)
|
for (uint i = 0; i < MeshCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -376,8 +372,6 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
mesh.Read(meshReader);
|
mesh.Read(meshReader);
|
||||||
currentModel.Meshes.Add(mesh);
|
currentModel.Meshes.Add(mesh);
|
||||||
|
|
||||||
Console.WriteLine($"mesh.Unknown3 {mesh.Unknown3 }");
|
|
||||||
|
|
||||||
var buffer = new LM3_Model.PointerInfo();
|
var buffer = new LM3_Model.PointerInfo();
|
||||||
buffer.Read(vtxPtrReader, mesh.Unknown3 != 4294967295);
|
buffer.Read(vtxPtrReader, mesh.Unknown3 != 4294967295);
|
||||||
currentModel.VertexBufferPointers.Add(buffer);
|
currentModel.VertexBufferPointers.Add(buffer);
|
||||||
|
@ -388,7 +382,7 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
break;
|
break;
|
||||||
case SubDataType.ModelTransform:
|
case SubDataType.ModelTransform:
|
||||||
chunkEntry.DataFile = File052Data;
|
chunkEntry.DataFile = File052Data;
|
||||||
using (var transformReader = new FileReader(chunkEntry.FileData))
|
using (var transformReader = new FileReader(chunkEntry.FileData, true))
|
||||||
{
|
{
|
||||||
//This is possibly very wrong
|
//This is possibly very wrong
|
||||||
//The data isn't always per mesh, but sometimes is
|
//The data isn't always per mesh, but sometimes is
|
||||||
|
@ -416,7 +410,7 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
if (chunk.ChunkSize > 0x40 && currentModel.Skeleton == null)
|
if (chunk.ChunkSize > 0x40 && currentModel.Skeleton == null)
|
||||||
{
|
{
|
||||||
chunkEntry.DataFile = File052Data;
|
chunkEntry.DataFile = File052Data;
|
||||||
using (var boneReader = new FileReader(chunkEntry.FileData))
|
using (var boneReader = new FileReader(chunkEntry.FileData, true))
|
||||||
{
|
{
|
||||||
currentModel.Skeleton = new STSkeleton();
|
currentModel.Skeleton = new STSkeleton();
|
||||||
DrawableContainer.Drawables.Add(currentModel.Skeleton);
|
DrawableContainer.Drawables.Add(currentModel.Skeleton);
|
||||||
|
@ -425,27 +419,38 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
for (int i = 0; i < numBones; i++)
|
for (int i = 0; i < numBones; i++)
|
||||||
{
|
{
|
||||||
boneReader.SeekBegin(i * 0x40);
|
boneReader.SeekBegin(i * 0x40);
|
||||||
uint hash = boneReader.ReadUInt32();
|
uint HashID = boneReader.ReadUInt32();
|
||||||
|
boneReader.ReadUInt32(); //unk
|
||||||
|
boneReader.ReadUInt32(); //unk
|
||||||
|
boneReader.ReadSingle(); //0
|
||||||
|
var Scale = new OpenTK.Vector3(
|
||||||
|
boneReader.ReadSingle(),
|
||||||
|
boneReader.ReadSingle(),
|
||||||
|
boneReader.ReadSingle());
|
||||||
|
boneReader.ReadSingle(); //0
|
||||||
|
var Rotate = new OpenTK.Vector3(
|
||||||
|
boneReader.ReadSingle(),
|
||||||
|
boneReader.ReadSingle(),
|
||||||
|
boneReader.ReadSingle());
|
||||||
|
boneReader.ReadSingle(); //0
|
||||||
|
var Position = new OpenTK.Vector3(
|
||||||
|
boneReader.ReadSingle(),
|
||||||
|
boneReader.ReadSingle(),
|
||||||
|
boneReader.ReadSingle());
|
||||||
|
float test = boneReader.ReadSingle(); //1
|
||||||
STBone bone = new STBone(currentModel.Skeleton);
|
STBone bone = new STBone(currentModel.Skeleton);
|
||||||
bone.Text = hash.ToString("x");
|
bone.Text = HashID.ToString("x");
|
||||||
if (HashNames.ContainsKey(hash))
|
// if (HashNames.ContainsKey(HashID))
|
||||||
bone.Text = HashNames[hash];
|
// bone.Text = HashNames[HashID];
|
||||||
bone.position = new float[3] { 0, 0, 0 };
|
// else
|
||||||
bone.rotation = new float[4] { 0, 0, 0, 1 };
|
// Console.WriteLine($"bone hash {HashID}");
|
||||||
|
|
||||||
|
bone.position = new float[3] { Position.X, Position.Z, Position.Y };
|
||||||
|
bone.rotation = new float[4] { Rotate.X, Rotate.Y, Rotate.Z, 1 };
|
||||||
bone.scale = new float[3] { 0.2f, 0.2f, 0.2f };
|
bone.scale = new float[3] { 0.2f, 0.2f, 0.2f };
|
||||||
|
|
||||||
|
|
||||||
boneReader.SeekBegin(48 + (i * 0x40));
|
|
||||||
var Position = new OpenTK.Vector3(boneReader.ReadSingle(), boneReader.ReadSingle(), boneReader.ReadSingle());
|
|
||||||
Position = OpenTK.Vector3.TransformPosition(Position, OpenTK.Matrix4.CreateRotationX(OpenTK.MathHelper.DegreesToRadians(90)));
|
|
||||||
bone.position[0] = Position.X;
|
|
||||||
bone.position[2] = Position.Y;
|
|
||||||
bone.position[1] = Position.Z;
|
|
||||||
|
|
||||||
|
|
||||||
bone.RotationType = STBone.BoneRotationType.Euler;
|
bone.RotationType = STBone.BoneRotationType.Euler;
|
||||||
// currentModel.Skeleton.bones.Add(bone);
|
currentModel.Skeleton.bones.Add(bone);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentModel.Skeleton.reset();
|
currentModel.Skeleton.reset();
|
||||||
|
@ -483,16 +488,14 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
break;*/
|
break;*/
|
||||||
case SubDataType.BoneHashList:
|
case SubDataType.BoneHashList:
|
||||||
chunkEntry.DataFile = File053Data;
|
chunkEntry.DataFile = File053Data;
|
||||||
Console.WriteLine("Model Check! " + currentModel.Text);
|
using (var chunkReader = new FileReader(chunkEntry.FileData, true))
|
||||||
|
|
||||||
using (var chunkReader = new FileReader(chunkEntry.FileData))
|
|
||||||
{
|
{
|
||||||
while (chunkReader.Position <= chunkReader.BaseStream.Length - 4)
|
while (chunkReader.Position <= chunkReader.BaseStream.Length - 4)
|
||||||
{
|
{
|
||||||
uint hash = chunkReader.ReadUInt32();
|
uint hash = chunkReader.ReadUInt32();
|
||||||
|
|
||||||
if (HashNames.ContainsKey(hash))
|
// if (HashNames.ContainsKey(hash))
|
||||||
Console.WriteLine("Hash Match! " + HashNames[hash]);
|
// Console.WriteLine("Hash Match! " + HashNames[hash]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -501,7 +504,8 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk.ChunkType == SubDataType.ModelStart ||
|
if (chunk.ChunkType == SubDataType.MaterailData ||
|
||||||
|
chunk.ChunkType == SubDataType.ModelInfo ||
|
||||||
chunk.ChunkType == SubDataType.MeshBuffers ||
|
chunk.ChunkType == SubDataType.MeshBuffers ||
|
||||||
chunk.ChunkType == SubDataType.MeshIndexTable ||
|
chunk.ChunkType == SubDataType.MeshIndexTable ||
|
||||||
chunk.ChunkType == SubDataType.SubmeshInfo ||
|
chunk.ChunkType == SubDataType.SubmeshInfo ||
|
||||||
|
@ -578,26 +582,52 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
for (int i = 0; i < fileEntries.Count; i++)
|
for (int i = 0; i < fileEntries.Count; i++)
|
||||||
{
|
{
|
||||||
uint offset = (uint)dataWriter.Position;
|
uint offset = (uint)dataWriter.Position;
|
||||||
var decomp = fileEntries[i].GetData();
|
var decompStream = fileEntries[i].GetData();
|
||||||
|
var mem = new System.IO.MemoryStream();
|
||||||
|
var decompSize = mem.Length;
|
||||||
|
|
||||||
if (i == 65)
|
if (i == 63)
|
||||||
{
|
{
|
||||||
using (var imageDataWriter = new FileWriter(decomp))
|
using (var imageDataWriter = new FileWriter(mem, true))
|
||||||
{
|
{
|
||||||
foreach (TexturePOWE image in textureFolder.Nodes) {
|
imageDataWriter.Write(decompStream.ToBytes());
|
||||||
|
foreach (TexturePOWE image in textureFolder.Nodes)
|
||||||
|
{
|
||||||
|
imageDataWriter.SeekBegin(image.HeaderOffset);
|
||||||
|
imageDataWriter.Write(image.ID2);
|
||||||
|
imageDataWriter.Write((ushort)image.Width);
|
||||||
|
imageDataWriter.Write((ushort)image.Height);
|
||||||
|
imageDataWriter.Write((ushort)image.Unknown);
|
||||||
|
imageDataWriter.Write((byte)image.ArrayCount);
|
||||||
|
imageDataWriter.Write((byte)image.Unknown2);
|
||||||
|
imageDataWriter.Write((byte)image.TexFormat);
|
||||||
|
imageDataWriter.Write((byte)image.Unknown3);
|
||||||
|
imageDataWriter.Write((ushort)image.Unknown4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (i == 65)
|
||||||
|
{
|
||||||
|
using (var imageDataWriter = new FileWriter(mem, true))
|
||||||
|
{
|
||||||
|
imageDataWriter.Write(decompStream.ToBytes());
|
||||||
|
foreach (TexturePOWE image in textureFolder.Nodes)
|
||||||
|
{
|
||||||
imageDataWriter.SeekBegin(image.DataOffset);
|
imageDataWriter.SeekBegin(image.DataOffset);
|
||||||
imageDataWriter.Write(image.ImageData);
|
imageDataWriter.Write(image.ImageData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mem = new System.IO.MemoryStream(decompStream.ToBytes());
|
||||||
|
|
||||||
var comp = STLibraryCompression.ZLIB.Compress(decomp.ToBytes());
|
var comp = STLibraryCompression.ZLIB.Compress(mem.ToBytes());
|
||||||
|
|
||||||
maxDataSize = Math.Max(maxDataSize, (uint)comp.Length);
|
maxDataSize = Math.Max(maxDataSize, (uint)comp.Length);
|
||||||
dataWriter.Write(comp);
|
dataWriter.Write(comp);
|
||||||
|
|
||||||
writer.Write(offset);
|
writer.Write(offset);
|
||||||
writer.Write((uint)decomp.Length);
|
writer.Write((uint)decompSize);
|
||||||
writer.Write((uint)comp.Length);
|
writer.Write((uint)comp.Length);
|
||||||
|
|
||||||
writer.Write(fileEntries[i].Unknown1);
|
writer.Write(fileEntries[i].Unknown1);
|
||||||
|
@ -615,13 +645,14 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
writer.Write(maxDataSize);
|
writer.Write(maxDataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataWriter.Close();
|
||||||
//After saving is done remove the existing file
|
|
||||||
System.IO.File.Delete(DataPath);
|
|
||||||
|
|
||||||
//Now move and rename our temp file to the new file path
|
|
||||||
System.IO.File.Move(TempPath, DataPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//After saving is done remove the existing file
|
||||||
|
System.IO.File.Delete(DataPath);
|
||||||
|
|
||||||
|
//Now move and rename our temp file to the new file path
|
||||||
|
System.IO.File.Move(TempPath, DataPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint GetLargestFileSize()
|
private uint GetLargestFileSize()
|
||||||
|
@ -762,9 +793,21 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
{
|
{
|
||||||
List<ToolStripItem> Items = new List<ToolStripItem>();
|
List<ToolStripItem> Items = new List<ToolStripItem>();
|
||||||
Items.Add(new STToolStipMenuItem("Export Raw Data", null, Export, Keys.Control | Keys.E));
|
Items.Add(new STToolStipMenuItem("Export Raw Data", null, Export, Keys.Control | Keys.E));
|
||||||
|
Items.Add(new STToolStipMenuItem("Replace Raw Data", null, Replace, Keys.Control | Keys.R));
|
||||||
return Items.ToArray();
|
return Items.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Replace(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
/* OpenFileDialog ofd = new OpenFileDialog();
|
||||||
|
ofd.FileName = Text;
|
||||||
|
ofd.Filter = "Raw Data (*.*)|*.*";
|
||||||
|
|
||||||
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
|
DataStream = new System.IO.FileStream(ofd.FileName, System.IO.FileMode.Open,
|
||||||
|
System.IO.FileAccess.ReadWrite, System.IO.FileShare.ReadWrite);*/
|
||||||
|
}
|
||||||
|
|
||||||
private void Export(object sender, EventArgs args)
|
private void Export(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
SaveFileDialog sfd = new SaveFileDialog();
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
@ -819,6 +862,8 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
return new SubStream(reader.BaseStream, Offset, DecompressedSize);
|
return new SubStream(reader.BaseStream, Offset, DecompressedSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Console.WriteLine("Path does not exist! " + DataFile);
|
||||||
|
|
||||||
return Data;
|
return Data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,11 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace FirstPlugin.LuigisMansion3
|
namespace FirstPlugin.LuigisMansion3
|
||||||
{
|
{
|
||||||
public enum DataType : uint
|
public enum DataType : ushort
|
||||||
{
|
{
|
||||||
Texture = 0xBA41B500,
|
Texture = 0xB500,
|
||||||
Model = 0x8101B000,
|
Model = 0xB000,
|
||||||
Unknown = 0x08C17000,
|
Unknown = 0x7000,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VertexDataFormat
|
public enum VertexDataFormat
|
||||||
|
@ -51,10 +51,11 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
{
|
{
|
||||||
TextureHeader = 0xB501,
|
TextureHeader = 0xB501,
|
||||||
TextureData = 0xB502,
|
TextureData = 0xB502,
|
||||||
ModelStart = 0xB006,
|
MaterailData = 0xB006, //Also marks start of model data
|
||||||
SubmeshInfo = 0xB003, //Or polygon groups?
|
SubmeshInfo = 0xB003, //Or polygon groups?
|
||||||
VertexStartPointers = 0xB004,
|
VertexStartPointers = 0xB004,
|
||||||
ModelTransform = 0xB001, //Matrix4x4. 0x40 in size
|
ModelTransform = 0xB001, //Matrix4x4. 0x40 in size
|
||||||
|
ModelInfo = 0xB002, //Contains mesh count and model hash
|
||||||
MeshBuffers = 0xB005, //vertex and index buffer
|
MeshBuffers = 0xB005, //vertex and index buffer
|
||||||
MaterialName = 0xB333,
|
MaterialName = 0xB333,
|
||||||
MeshIndexTable = 0xB007,
|
MeshIndexTable = 0xB007,
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
{
|
{
|
||||||
Nodes.Clear();
|
Nodes.Clear();
|
||||||
|
|
||||||
using (var reader = new FileReader(DataDictionary.GetFileBufferData()))
|
using (var reader = new FileReader(DataDictionary.GetFileBufferData(), true))
|
||||||
{
|
{
|
||||||
TreeNode texturesList = new TreeNode("Texture Maps");
|
TreeNode texturesList = new TreeNode("Texture Maps");
|
||||||
TreeNode skeletonNode = new TreeNode("Skeleton");
|
TreeNode skeletonNode = new TreeNode("Skeleton");
|
||||||
|
@ -249,8 +249,8 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
genericObj.Mesh = mesh;
|
genericObj.Mesh = mesh;
|
||||||
genericObj.Checked = true;
|
genericObj.Checked = true;
|
||||||
genericObj.Text = $"Mesh {i} {mesh.HashID.ToString("X")}";
|
genericObj.Text = $"Mesh {i} {mesh.HashID.ToString("X")}";
|
||||||
if (LM3_DICT.HashNames.ContainsKey(mesh.HashID))
|
if (NLG_Common.HashNames.ContainsKey(mesh.HashID))
|
||||||
genericObj.Text = LM3_DICT.HashNames[mesh.HashID];
|
genericObj.Text = NLG_Common.HashNames[mesh.HashID];
|
||||||
|
|
||||||
genericObj.SetMaterial(mesh.Material);
|
genericObj.SetMaterial(mesh.Material);
|
||||||
RenderedMeshes.Add(genericObj);
|
RenderedMeshes.Add(genericObj);
|
||||||
|
@ -474,6 +474,8 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
|
|
||||||
reader.Position = 0;
|
reader.Position = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
var meshSize = reader.BaseStream.Length / model.Meshes.Count;
|
var meshSize = reader.BaseStream.Length / model.Meshes.Count;
|
||||||
for (int i = 0; i < model.Meshes.Count; i++)
|
for (int i = 0; i < model.Meshes.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -628,10 +630,6 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
else
|
else
|
||||||
IndexFormat = IndexFormat.Index_16;
|
IndexFormat = IndexFormat.Index_16;
|
||||||
|
|
||||||
Console.WriteLine($"type {type} indexFlags {indexFlags} IndexCount {IndexCount}");
|
|
||||||
// IndexFormat = reader.ReadEnum<IndexFormat>(false);
|
|
||||||
// if (IndexFormat != (IndexFormat)0x8000 && IndexFormat != 0 && IndexFormat != IndexFormat.Index_16_0x2)
|
|
||||||
|
|
||||||
VertexCount = reader.ReadUInt32();
|
VertexCount = reader.ReadUInt32();
|
||||||
reader.ReadUInt32(); //unknown
|
reader.ReadUInt32(); //unknown
|
||||||
BufferPtrOffset = reader.ReadUInt16(); //I believe this might be for the buffer pointers. It shifts by 4 for each mesh
|
BufferPtrOffset = reader.ReadUInt16(); //I believe this might be for the buffer pointers. It shifts by 4 for each mesh
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
{
|
{
|
||||||
public class TexturePOWE : STGenericTexture
|
public class TexturePOWE : STGenericTexture
|
||||||
{
|
{
|
||||||
|
public long HeaderOffset;
|
||||||
public long DataOffset;
|
public long DataOffset;
|
||||||
|
|
||||||
public static readonly uint Identifier = 0xE977D350;
|
public static readonly uint Identifier = 0xE977D350;
|
||||||
|
@ -30,6 +31,14 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
[Browsable(false)]
|
[Browsable(false)]
|
||||||
public uint ID { get; set; }
|
public uint ID { get; set; }
|
||||||
|
|
||||||
|
public uint HashIDUint
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string HashID
|
public string HashID
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -72,9 +81,10 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
};
|
};
|
||||||
|
|
||||||
public byte TexFormat;
|
public byte TexFormat;
|
||||||
public byte Unknown;
|
public ushort Unknown;
|
||||||
public byte Unknown2;
|
public byte Unknown2;
|
||||||
public ushort Unknown3;
|
public byte Unknown3;
|
||||||
|
public ushort Unknown4;
|
||||||
|
|
||||||
public void Read(FileReader reader)
|
public void Read(FileReader reader)
|
||||||
{
|
{
|
||||||
|
@ -91,13 +101,14 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
ID2 = reader.ReadUInt32();
|
ID2 = reader.ReadUInt32();
|
||||||
Width = reader.ReadUInt16();
|
Width = reader.ReadUInt16();
|
||||||
Height = reader.ReadUInt16();
|
Height = reader.ReadUInt16();
|
||||||
var numMips = reader.ReadByte();
|
Unknown = reader.ReadUInt16();
|
||||||
var unk = reader.ReadByte(); //padding?
|
|
||||||
var numArray = reader.ReadByte();
|
var numArray = reader.ReadByte();
|
||||||
Unknown = reader.ReadByte();
|
|
||||||
TexFormat = reader.ReadByte();
|
|
||||||
Unknown2 = reader.ReadByte();
|
Unknown2 = reader.ReadByte();
|
||||||
Unknown3 = reader.ReadUInt16();
|
TexFormat = reader.ReadByte();
|
||||||
|
Unknown3 = reader.ReadByte();
|
||||||
|
Unknown4 = reader.ReadUInt16();
|
||||||
|
|
||||||
|
Console.WriteLine(ID2);
|
||||||
|
|
||||||
if (FormatTable.ContainsKey(TexFormat))
|
if (FormatTable.ContainsKey(TexFormat))
|
||||||
Format = FormatTable[TexFormat];
|
Format = FormatTable[TexFormat];
|
||||||
|
@ -110,11 +121,16 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
MipCount = 1;
|
MipCount = 1;
|
||||||
ArrayCount = numArray;
|
ArrayCount = numArray;
|
||||||
|
|
||||||
|
UpdateProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateProperties()
|
||||||
|
{
|
||||||
properties = new POWEProperties();
|
properties = new POWEProperties();
|
||||||
properties.ID = ID2;
|
properties.ID = ID2;
|
||||||
properties.Width = Width;
|
properties.Width = Width;
|
||||||
properties.Height = Height;
|
properties.Height = Height;
|
||||||
properties.NumMips = numMips;
|
properties.NumMips = (byte)MipCount;
|
||||||
properties.Format = Format;
|
properties.Format = Format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,17 +166,20 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
var surfacesNew = tex.GetSurfaces();
|
var surfacesNew = tex.GetSurfaces();
|
||||||
var surfaces = GetSurfaces();
|
var surfaces = GetSurfaces();
|
||||||
|
|
||||||
if (surfaces[0].mipmaps[0].Length != surfacesNew[0].mipmaps[0].Length)
|
if (surfaces[0].mipmaps[0].Length > surfacesNew[0].mipmaps[0].Length)
|
||||||
throw new Exception($"Image must be the same size! {surfaces[0].mipmaps[0].Length}");
|
throw new Exception($"Image must be the same size or smaller! {surfaces[0].mipmaps[0].Length}");
|
||||||
|
|
||||||
if (Width != tex.Texture.Width || Height != tex.Texture.Height)
|
|
||||||
throw new Exception("Image size must be the same!");
|
|
||||||
|
|
||||||
ImageData = tex.Texture.TextureData[0][0];
|
ImageData = tex.Texture.TextureData[0][0];
|
||||||
|
|
||||||
Width = tex.Texture.Width;
|
Width = tex.Texture.Width;
|
||||||
Height = tex.Texture.Height;
|
Height = tex.Texture.Height;
|
||||||
MipCount = tex.Texture.MipCount;
|
MipCount = tex.Texture.MipCount;
|
||||||
|
ArrayCount = tex.Texture.ArrayLength;
|
||||||
|
Format = tex.Format;
|
||||||
|
TexFormat = FormatTable.FirstOrDefault(x => x.Value == tex.Format).Key;
|
||||||
|
UpdateProperties();
|
||||||
|
|
||||||
|
Console.WriteLine($"TexFormat {TexFormat.ToString("X")}");
|
||||||
|
|
||||||
surfacesNew.Clear();
|
surfacesNew.Clear();
|
||||||
surfaces.Clear();
|
surfaces.Clear();
|
||||||
|
@ -204,6 +223,9 @@ namespace FirstPlugin.LuigisMansion3
|
||||||
GenerateMipsAndCompress(bitmap, MipCount, Format), MipCount);
|
GenerateMipsAndCompress(bitmap, MipCount, Format), MipCount);
|
||||||
|
|
||||||
ImageData = Utils.CombineByteArray(mipmaps.ToArray());
|
ImageData = Utils.CombineByteArray(mipmaps.ToArray());
|
||||||
|
ArrayCount = tex.ArrayLength;
|
||||||
|
TexFormat = FormatTable.FirstOrDefault(x => x.Value == Format).Key;
|
||||||
|
UpdateProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
|
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace FirstPlugin
|
||||||
{
|
{
|
||||||
public class NLG_Common
|
public class NLG_Common
|
||||||
{
|
{
|
||||||
private static Dictionary<uint, string> hashNames;
|
private static Dictionary<uint, string> hashNames = new Dictionary<uint, string>();
|
||||||
|
|
||||||
public static Dictionary<uint, string> HashNames
|
public static Dictionary<uint, string> HashNames
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue