1
0
mirror of synced 2025-01-19 09:17:30 +01:00

More LM2 archive improvements

This commit is contained in:
KillzXGaming 2019-07-21 20:08:16 -04:00
parent 571dad0776
commit 131af671bf
8 changed files with 136 additions and 29 deletions

Binary file not shown.

View File

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox.Library.IO;
namespace FirstPlugin
{
//Table consists of 2 chunk entry lists that define how the .data reads sections
public class LM2_ChunkTable
{
private const int ChunkInfoIdenfier = 0x2001301;
//I am uncertain how these chunk lists work. There is first a list with an identifier and one extra unknown
//The second list can contain the same entries as the other list, however it may include more chunks
//Example, the first list may have image headers, while the second include both image headers and image blocks
public List<ChunkEntry> ChunkEntries = new List<ChunkEntry>();
public List<ChunkSubEntry> ChunkSubEntries = new List<ChunkSubEntry>();
public class ChunkEntry
{
public uint Unknown1;
public uint ChunkOffset;
public uint ChunkType;
public uint Unknown2;
public uint Unknown3;
}
public class ChunkSubEntry
{
public uint ChunkOffset;
public uint ChunkType;
public uint Unknown;
}
public void Read(FileReader tableReader)
{
//Each data type has chunk info. There is no counter so keep checking idenfier
while (tableReader.ReadUInt32() == ChunkInfoIdenfier)
{
ChunkEntry entry = new ChunkEntry();
ChunkEntries.Add(entry);
entry.Unknown1 = tableReader.ReadUInt32(); //8
entry.ChunkOffset = tableReader.ReadUInt32(); //The chunk offset in the file. Relative to the first chunk position in the file
entry.ChunkType = tableReader.ReadUInt32(); //The type of chunk. 0x8701B5 for example for texture info
entry.Unknown2 = tableReader.ReadUInt32();
//This increases by 2 each chunk info, however the starting value is not 0
//Note the last entry does not have this
entry.Unknown3 = tableReader.ReadUInt32();
}
if (ChunkEntries.Count > 0)
ChunkEntries.LastOrDefault<ChunkEntry>().Unknown3 = 0;
tableReader.Seek(-4); //Seek 4 back as the last entry lacks unkown 4
//Check the chunk types
//This time it includes more chunks (like image blocks)
//Read to the end of the file as the rest of the table are types, offsets, and an unknown value
while (!tableReader.EndOfStream && tableReader.Position <= tableReader.BaseStream.Length - 12)
{
ChunkSubEntry subEntry = new ChunkSubEntry();
subEntry.ChunkType = tableReader.ReadUInt32(); //The type of chunk. 0x8701B5 for example for texture info
subEntry.Unknown = tableReader.ReadUInt32(); //This seems to be the same value as the other Unknown2 in the last section
subEntry.ChunkOffset = tableReader.ReadUInt32(); //The chunk offset in the file. Relative to the first chunk position in the file
ChunkSubEntries.Add(subEntry);
}
}
}
}

View File

@ -13,7 +13,7 @@ using System.Drawing;
namespace FirstPlugin
{
//Parse info based on https://github.com/TheFearsomeDzeraora/LM2L
public class LM2_DICT : TreeNodeFile, IFileFormat
public class LM2_DICT : TreeNodeFile, IFileFormat, IArchiveFile
{
public FileType FileType { get; set; } = FileType.Archive;
@ -48,9 +48,14 @@ namespace FirstPlugin
}
public List<FileEntry> files = new List<FileEntry>();
public IEnumerable<ArchiveFileInfo> Files => files;
public void ClearFiles() { files.Clear(); }
public bool IsCompressed = false;
public LM2_ChunkTable ChunkTable;
public void Load(System.IO.Stream stream)
{
using (var reader = new FileReader(stream))
@ -65,15 +70,46 @@ namespace FirstPlugin
reader.SeekBegin(0x2C);
byte[] Unknowns = reader.ReadBytes((int)FileCount);
long FileTablePos = reader.Position;
for (int i = 0; i < FileCount; i++)
{
var file = new FileEntry(this);
file.Read(reader);
if (file.FileType != 0)
//Skip the file table entries as those are not needed to be loaded
if (file.FileType != 0 && i > 1)
{
file.Text = $"File {i} (Unknowns {file.FileType} {file.Unknown2} {file.Unknown3})";
file.FileName = $"File {i} (FileType: ({file.FileType}) Unknowns: {file.Unknown2} {file.Unknown3})";
files.Add(file);
}
//The first file stores a chunk layout
//The second one seems to be a duplicate?
if (i == 0)
{
using (var tableReader = new FileReader(file.FileData))
{
ChunkTable = new LM2_ChunkTable();
ChunkTable.Read(tableReader);
TreeNode debugFolder = new TreeNode("DEBUG TABLE INFO");
Nodes.Add(debugFolder);
TreeNode list1 = new TreeNode("Entry List 1");
TreeNode list2 = new TreeNode("Entry List 2 ");
debugFolder.Nodes.Add(list1);
debugFolder.Nodes.Add(list2);
foreach (var chunk in ChunkTable.ChunkEntries)
{
list1.Nodes.Add($"ChunkOffset {chunk.ChunkOffset} ChunkType {chunk.ChunkType.ToString("X")} Unknown1 {chunk.Unknown1} Unknown2 {chunk.Unknown2} Unknown3 {chunk.Unknown3}");
}
foreach (var chunk in ChunkTable.ChunkSubEntries)
{
list2.Nodes.Add($"ChunkOffset {chunk.ChunkOffset} ChunkType {chunk.ChunkType.ToString("X")} Unknown {chunk.Unknown}");
}
}
}
}
//Now go through each file and format and connect the headers and blocks
@ -85,13 +121,14 @@ namespace FirstPlugin
for (int i = 0; i < files.Count; i++)
{
if (files[i].FileType == FileEntry.FileDataType.Texture)
if (files[i].FileType == FileEntry.DataType.Texture)
{
if (files[i].Unknown3 == 1) //Info
{
//Read the info
using (var textureReader = new FileReader(files[i].FileData))
{
int headerIndex = 0;
while (textureReader.ReadUInt32() == TexturePOWE.Identifier)
{
var texture = new TexturePOWE();
@ -99,7 +136,7 @@ namespace FirstPlugin
texture.SelectedImageKey = texture.ImageKey;
texture.Index = ImageIndex;
texture.Read(textureReader);
texture.Text = $"Texture {ImageIndex}";
texture.Text = $"Texture {headerIndex++}";
textureFolder.Nodes.Add(texture);
Textures.Add(texture);
}
@ -120,8 +157,6 @@ namespace FirstPlugin
ImageIndex++;
}
}
else
Nodes.Add(files[i]);
}
if (textureFolder.Nodes.Count > 0)
@ -231,23 +266,23 @@ namespace FirstPlugin
}
}
public class FileEntry : TreeNodeCustom
public class FileEntry : ArchiveFileInfo
{
public LM2_DICT ParentDictionary { get; set; }
public uint Offset;
public uint DecompressedSize;
public uint CompressedSize;
public FileDataType FileType;
public DataType FileType;
public byte Unknown2;
public byte Unknown3; //Possibly the effect? 0 for image block, 1 for info
public enum FileDataType : ushort
public enum DataType : ushort
{
Texture = 0x80,
}
public byte[] FileData
public override byte[] FileData
{
get { return GetData(); }
set
@ -256,18 +291,6 @@ namespace FirstPlugin
}
}
public override void OnClick(TreeView treeview)
{
HexEditor editor = (HexEditor)LibraryGUI.GetActiveContent(typeof(HexEditor));
if (editor == null)
{
editor = new HexEditor();
LibraryGUI.LoadEditor(editor);
}
editor.Dock = DockStyle.Fill;
editor.LoadData(FileData);
}
public FileEntry(LM2_DICT dict)
{
ParentDictionary = dict;
@ -278,7 +301,7 @@ namespace FirstPlugin
Offset = reader.ReadUInt32();
DecompressedSize = reader.ReadUInt32();
CompressedSize = reader.ReadUInt32();
FileType = reader.ReadEnum<FileDataType>(false);
FileType = reader.ReadEnum<DataType>(false);
Unknown2 = reader.ReadByte();
Unknown3 = reader.ReadByte();
}

View File

@ -1403,6 +1403,12 @@ namespace Bfres.Structs
vert.Data = weights.ToArray();
vert.Format = att.Format;
atrib.Add(vert);
for (int i = 0; i < weights.Count; i++)
{
Console.WriteLine($"w {i} {weights[i]}");
}
}
if (att.Name == "_i0")
{

View File

@ -264,7 +264,7 @@ namespace FirstPlugin
break;
}
if (objects[0].weightsT.Count != objects[0].vertices.Count)
if (objects[0].weightsT.Count > 0 && objects[0].weightsT.Count != objects[0].vertices.Count)
throw new Exception("Incorrect vertex amount");
foreach (STGenericObject obj in objects)
@ -277,16 +277,20 @@ namespace FirstPlugin
foreach (float f in obj.weightsT[v])
obj.vertices[v].boneWeights.Add(f);
}
int vID = 0;
foreach (Vertex v in obj.vertices)
{
if (v.boneNames.Count == 1)
Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]}");
Console.WriteLine($"{vID} {v.boneNames[0]} {v.boneWeights[0]}");
if (v.boneNames.Count == 2)
Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]}");
Console.WriteLine($"{vID} {v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]}");
if (v.boneNames.Count == 3)
Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]} {v.boneNames[2]} {v.boneWeights[2]}");
Console.WriteLine($"{vID} {v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]} {v.boneNames[2]} {v.boneWeights[2]}");
if (v.boneNames.Count == 4)
Console.WriteLine($"{v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]} {v.boneNames[2]} {v.boneWeights[2]} {v.boneNames[3]} {v.boneWeights[3]}");
Console.WriteLine($"{vID} {v.boneNames[0]} {v.boneWeights[0]} {v.boneNames[1]} {v.boneWeights[1]} {v.boneNames[2]} {v.boneWeights[2]} {v.boneNames[3]} {v.boneWeights[3]}");
vID++;
}
}

View File

@ -204,6 +204,7 @@
<Compile Include="FileFormats\Archives\ARC.cs" />
<Compile Include="FileFormats\Archives\GFA.cs" />
<Compile Include="FileFormats\Archives\IGA_PAK.cs" />
<Compile Include="FileFormats\Archives\LM2\LM2_ChunkTable.cs" />
<Compile Include="FileFormats\Archives\LM2\LM2_DICT.cs" />
<Compile Include="FileFormats\Archives\LZARC.cs" />
<Compile Include="FileFormats\Archives\ME01.cs" />