Skip to content

Commit

Permalink
+Added early support for M&L Paper Jam MSBT files.
Browse files Browse the repository at this point in the history
+Added an early BG4 explorer UI. (Not currently accessible.)
~Simplified the BG4 extraction class.
  • Loading branch information
IcySon55 committed Dec 24, 2015
1 parent 8362161 commit 81713d6
Show file tree
Hide file tree
Showing 12 changed files with 470 additions and 366 deletions.
31 changes: 16 additions & 15 deletions BG4.cs
Expand Up @@ -20,9 +20,14 @@ public int CompareTo(FileEntry rhs)
}
}

class InvalidBG4Exception : Exception
{
public InvalidBG4Exception(string message) : base(message) { }
}

class BG4
{
public string Extract(string filename, string path, bool overwrite = true)
public static string Extract(string filename, string path, bool overwrite = true)
{
string result = "Files successfully extracted.";

Expand All @@ -40,14 +45,12 @@ public string Extract(string filename, string path, bool overwrite = true)

// TODO: Decipher header values

while (br.ReadUInt32() != 0xFFFFFFFF) { } // Jump to the end of the entry
while (br.ReadUInt32() != 0xFFFFFFFF) { } // Jump to the end of the header
br.ReadBytes(2); // 00 00

// Loop through file details
bool eoh = false;

List<FileEntry> entries = new List<FileEntry>();
List<string> filenames = new List<string>();
FileEntry entry = new FileEntry();

while (!eoh)
Expand All @@ -72,6 +75,7 @@ public string Extract(string filename, string path, bool overwrite = true)
entry = new FileEntry();
}

// File entry closer
if (br.PeekString() == Encoding.ASCII.GetString(new byte[] { 0x00, 0x00, 0x00, 0x80 }))
br.ReadBytes(4); // 00 00 00 80
}
Expand All @@ -81,11 +85,16 @@ public string Extract(string filename, string path, bool overwrite = true)
}
}

// Sort the file entries into NameIndex order
entries.Sort();

// Filenames
bool eofn = false;
List<string> filenames = new List<string>();

while (!eofn)
{
if (filenames.Count == entries.Count)
if (br.PeekString(2) == Encoding.ASCII.GetString(new byte[] { 0xFF, 0xFF }))
eofn = true;
else
{
Expand All @@ -106,9 +115,6 @@ public string Extract(string filename, string path, bool overwrite = true)
}
}

// Arrange the file entries in NameIndex order
entries.Sort();

// Extract!
for (int i = 0; i < entries.Count; i++)
{
Expand Down Expand Up @@ -142,14 +148,9 @@ public string Extract(string filename, string path, bool overwrite = true)
return result;
}

public void Pack(string filename, string path)
public static void Pack(string filename, string path)
{

throw new NotImplementedException();
}
}

class InvalidBG4Exception : Exception
{
public InvalidBG4Exception(string message) : base(message) { }
}
}
87 changes: 56 additions & 31 deletions MSBT.cs
Expand Up @@ -70,7 +70,7 @@ class TXT2
class Entry
{
public UInt32 Length;
public List<byte[]> Values = new List<byte[]>();
public List<Value> Values = new List<Value>();
public byte[] Value;
public Int32 ID;

Expand All @@ -79,6 +79,13 @@ public override string ToString()
return (Length > 0 ? Encoding.ASCII.GetString(Value) : (ID + 1).ToString());
}
}

class Value
{
public byte[] Data;
public bool Editable = true;
public bool NullTerminated = true;
}

class MSBT
{
Expand All @@ -93,7 +100,7 @@ class MSBT
public TXT2 TXT2 = new TXT2();
public List<string> SectionOrder = new List<string>();

byte paddingChar = 0xAB;
private byte paddingChar = 0xAB;

public MSBT(string filename)
{
Expand Down Expand Up @@ -170,18 +177,8 @@ private void ReadLBL1(BinaryReaderX br)
LBL1.SectionSize = br.ReadUInt32();
LBL1.Unknown1 = br.ReadBytes(8);
LBL1.Unknown2 = br.ReadBytes(8);
uint startOfLabels = (uint)br.BaseStream.Position + sizeof(UInt32);
while (!eoi)
{
uint temp = br.ReadUInt32();
if (temp > 2)
{
startOfLabels = temp + (uint)offset + (uint)LBL1.Unknown1.Length + (uint)LBL1.Unknown2.Length;
eoi = true;
}
}
br.BaseStream.Seek(-sizeof(UInt32), SeekOrigin.Current);
LBL1.Unknown3 = br.ReadBytes((int)startOfLabels - (int)br.BaseStream.Position);
uint startOfLabels = 0x35C; // Magic LBL1 label start position
LBL1.Unknown3 = br.ReadBytes((int)(startOfLabels - br.BaseStream.Position));

while (br.BaseStream.Position < (offset + LBL1.Identifier.Length + sizeof(UInt32) + LBL1.Unknown1.Length + LBL1.SectionSize))
{
Expand Down Expand Up @@ -256,27 +253,48 @@ private void ReadTXT2(BinaryReaderX br)
{
byte[] unichar = br.ReadBytes(2);

if (unichar[0] == paddingChar && unichar[1] == paddingChar)
break;

if (Header.ByteOrderMark[0] == 0xFE)
Array.Reverse(unichar);

if (unichar[0] != 0x0 || unichar[1] != 0x0)
result.AddRange(unichar);
else
{
entry.Values.Add(result.ToArray());
Value val = new Value();
val.Data = result.ToArray();

if (result.Count == 0)
val.Editable = false;

entry.Values.Add(val);
result.Clear();
}
}
}

// Strange extended string without null termination
if (result.Count > 1)
{
Value finalVal = new Value();
finalVal.Data = result.ToArray();
finalVal.Editable = false;
finalVal.NullTerminated = false;
entry.Values.Add(finalVal);
}

entry.ID = i;
TXT2.OriginalEntries.Add(entry);

// Duplicate entries for editing
Entry entryEdited = new Entry();
foreach (byte[] value in entry.Values)
entryEdited.Values.Add(value);
foreach (Value value in entry.Values)
{
Value val = new Value();
val.Data = value.Data;
val.Editable = value.Editable;
val.NullTerminated = value.NullTerminated;
entryEdited.Values.Add(val);
}
entryEdited.Value = entry.Value;
entryEdited.ID = entry.ID;
TXT2.Entries.Add(entryEdited);
Expand All @@ -289,7 +307,11 @@ private void PaddingSeek(BinaryReaderX br)
{
long remainder = br.BaseStream.Position % 16;
if (remainder > 0)
{
paddingChar = br.ReadByte();
br.BaseStream.Seek(-1, SeekOrigin.Current);
br.BaseStream.Seek(16 - remainder, SeekOrigin.Current);
}
}

public bool Save()
Expand Down Expand Up @@ -461,9 +483,9 @@ private bool WriteTXT2(BinaryWriterX bw)

for (int i = 0; i < TXT2.NumberOfStrings; i++)
{
foreach (byte[] value in TXT2.Entries[i].Values)
foreach (Value value in TXT2.Entries[i].Values)
{
newSize += (UInt32)(value.Length + 2);
newSize += (UInt32)(value.Data.Length + (value.NullTerminated ? 2 : 0));
}
}

Expand All @@ -479,8 +501,8 @@ private bool WriteTXT2(BinaryWriterX bw)
for (int i = 0; i < TXT2.NumberOfStrings; i++)
{
offsets.Add(offsetsLength + runningTotal);
foreach (byte[] value in TXT2.Entries[i].Values)
runningTotal += ((UInt32)value.Length) + 2;
foreach (Value value in TXT2.Entries[i].Values)
runningTotal += (UInt32)(value.Data.Length + (value.NullTerminated ? 2 : 0));
}
for (int i = 0; i < TXT2.NumberOfStrings; i++)
bw.Write(offsets[i]);
Expand All @@ -489,18 +511,21 @@ private bool WriteTXT2(BinaryWriterX bw)
for (int j = 0; j < TXT2.Entries[i].Values.Count; j++)
TXT2.OriginalEntries[i].Values[j] = TXT2.Entries[i].Values[j];

foreach (byte[] value in TXT2.Entries[i].Values)
foreach (Value value in TXT2.Entries[i].Values)
{
if (Header.ByteOrderMark[0] == 0xFF)
bw.Write(value);
bw.Write(value.Data);
else
for (int j = 0; j < value.Length; j += 2)
for (int j = 0; j < value.Data.Length; j += 2)
{
bw.Write(value[j + 1]);
bw.Write(value[j]);
bw.Write(value.Data[j + 1]);
bw.Write(value.Data[j]);
}
bw.Write('\0');
bw.Write('\0');
if (value.NullTerminated)
{
bw.Write('\0');
bw.Write('\0');
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions MsbtEditor.csproj
Expand Up @@ -58,6 +58,12 @@
<ItemGroup>
<Compile Include="BG4.cs" />
<Compile Include="BinaryTools.cs" />
<Compile Include="frmBG4.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="frmBG4.Designer.cs">
<DependentUpon>frmBG4.cs</DependentUpon>
</Compile>
<Compile Include="frmMain.cs">
<SubType>Form</SubType>
</Compile>
Expand All @@ -68,6 +74,9 @@
<Compile Include="MSBT.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="frmBG4.resx">
<DependentUpon>frmBG4.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="frmMain.resx">
<DependentUpon>frmMain.cs</DependentUpon>
<SubType>Designer</SubType>
Expand Down
2 changes: 1 addition & 1 deletion Properties/AssemblyInfo.cs
Expand Up @@ -31,4 +31,4 @@
//
// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
// usando l'asterisco '*' come illustrato di seguito:
[assembly: AssemblyVersion("0.8.*")]
[assembly: AssemblyVersion("0.8.0.0")]
10 changes: 10 additions & 0 deletions Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Properties/Resources.resx
Expand Up @@ -160,6 +160,9 @@
<data name="menu_up" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\images\menu-up.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="msbteditor" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\images\msbteditor.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="tab_class" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\images\tab-class.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
Expand Down

0 comments on commit 81713d6

Please sign in to comment.