Some LM3 adjustments

This commit is contained in:
KillzXGaming 2019-11-10 09:45:39 -05:00
parent ddfdbdc724
commit ee82fb1218
6 changed files with 164 additions and 101 deletions

View file

@ -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();

View file

@ -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;
} }

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -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
{ {