all the code I find seems to be based on thakis code
too bad I just can't figure it out by myself, I'd rewrite it if I could. I'm pretty sure it's just one little stupid thing that makes it decode it incorrectly for sm3das
This commit is contained in:
@@ -33,36 +33,69 @@ namespace BMGEditor
|
||||
return;
|
||||
|
||||
Int32 decompSize = (data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]);
|
||||
byte[] output = new byte[decompSize];
|
||||
int Offs = 16;
|
||||
int dstoffs = 0;
|
||||
while (true)
|
||||
uint sourcePos = 16; //start at 0x10
|
||||
uint writePos = 0; //destination to write data to
|
||||
byte[] decodedData = new byte[decompSize + 1];
|
||||
byte groupHead = 0;
|
||||
byte lastGroupHead = 0;
|
||||
uint validBitCount = 0;
|
||||
|
||||
while (writePos < decompSize)
|
||||
{
|
||||
byte header = data[Offs++];
|
||||
for (int i = 0; i < 8; i++)
|
||||
//System.Windows.Forms.MessageBox.Show(groupHead.ToString("X") + "|" + validBitCount);
|
||||
if (validBitCount == 0) //new group header
|
||||
{
|
||||
if ((header & 0x80) != 0) output[dstoffs++] = data[Offs++];
|
||||
groupHead = data[sourcePos];
|
||||
lastGroupHead = groupHead;
|
||||
++sourcePos;
|
||||
validBitCount = 8; //reset count
|
||||
}
|
||||
if ((groupHead & 0x80) != 0) //straight copy as long as groupheader maintains left most bit as 1 (1000 0000)
|
||||
{
|
||||
decodedData[writePos] = data[sourcePos];
|
||||
writePos++;
|
||||
sourcePos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte b1 = data[sourcePos]; //byte 1
|
||||
byte b2 = data[sourcePos + 1]; //byte 2
|
||||
sourcePos += 2; //move past those two bytes
|
||||
uint dist = (uint)((b1 & 0xF) << 8) | b2; //distance
|
||||
if (Tests.isBE)
|
||||
dist = (UInt32)((dist >> 24) | ((dist & 0xFF0000) >> 8) | ((dist & 0xFF00) << 8) | (dist << 24));
|
||||
|
||||
uint copySource = writePos - (dist + 1); //copy
|
||||
uint numBytes = (uint)b1 >> 4; //how many bytes to copy
|
||||
|
||||
//if (sourcePos-2 > 0x13C0) //debug decode
|
||||
//System.Windows.Forms.MessageBox.Show("lastGroupHead: 0x" + lastGroupHead.ToString("X") + "\n" + "b1: 0x" + b1.ToString("X") + "\n" + "b2: 0x" + b2.ToString("X") + "\n" + "sourcePos: 0x" + sourcePos.ToString("X") + "\n" + "dist: " + dist + "\n" + "copySource: 0x" + copySource.ToString("X") + "\n" + "writePos: 0x" + writePos.ToString("X") + "\n" + "numBytes: " + numBytes);
|
||||
|
||||
if (numBytes == 0) //If the first 4 bits of the first byte is 0...
|
||||
{
|
||||
numBytes = data[sourcePos] + (uint)0x12;
|
||||
sourcePos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte b = data[Offs++];
|
||||
int offs = ((b & 0xF) << 8 | data[Offs++]) + 1;
|
||||
int length = (b >> 4) + 2;
|
||||
if (length == 2) length = data[Offs++] + 0x12;
|
||||
for (int j = 0; j < length; j++)
|
||||
{
|
||||
output[dstoffs] = output[dstoffs - offs];
|
||||
dstoffs++;
|
||||
}
|
||||
numBytes += 2;
|
||||
}
|
||||
if (dstoffs >= decompSize)
|
||||
for (int i = 0; i < numBytes; ++i)
|
||||
{
|
||||
Array.Resize(ref data, decompSize);
|
||||
output.CopyTo(data, 0);
|
||||
return;
|
||||
decodedData[writePos] = decodedData[copySource];
|
||||
copySource++;
|
||||
writePos++;
|
||||
}
|
||||
header <<= 1;
|
||||
}
|
||||
groupHead <<= 1; //left shift!!!
|
||||
validBitCount -= 1; //group header validation count of the binary position
|
||||
}
|
||||
|
||||
Array.Resize(ref data, decompSize + 1);
|
||||
decodedData.CopyTo(data, 0);
|
||||
FileStream test = File.OpenWrite("./test.bin");
|
||||
test.Write(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user