From b4f2ce301d564a6b1e84c58b90f4fbefc10bfffd Mon Sep 17 00:00:00 2001 From: Denis <93516910+Bussun@users.noreply.github.com> Date: Fri, 28 Jan 2022 22:58:37 +0100 Subject: [PATCH] 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 --- BMGEditor/FS/Yaz0Stream.cs | 75 +++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/BMGEditor/FS/Yaz0Stream.cs b/BMGEditor/FS/Yaz0Stream.cs index a49b916..b7b8b17 100644 --- a/BMGEditor/FS/Yaz0Stream.cs +++ b/BMGEditor/FS/Yaz0Stream.cs @@ -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; } } }