Skip to content

Commit

Permalink
GOB: Implement an unpackData() extension used in some games
Browse files Browse the repository at this point in the history
This extension allows larger strings to be copied from the LZ77-sliding window when unpacking.
  • Loading branch information
sdelamarre committed Aug 30, 2023
1 parent 68396c1 commit 9b0d1f7
Showing 1 changed file with 26 additions and 6 deletions.
32 changes: 26 additions & 6 deletions engines/gob/extract_gob_stk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,18 +319,33 @@ void ExtractGobStk::extractChunks(Common::Filename &outpath, Common::File &stk)
byte *ExtractGobStk::unpackData(byte *src, uint32 &size) {
uint32 counter;
uint16 cmd;
byte tmpBuf[4114];
byte tmpBuf[4370]; // 4096 + (256 + 18) = 4096 + (max string length)
int16 off;
byte len;
int16 len;
uint16 tmpIndex;

counter = size = READ_LE_UINT32(src);
src += 4;
uint16 magic1 = READ_LE_UINT16(src);
src += 2;
uint16 magic2 = READ_LE_UINT16(src);
src += 2;

for (int i = 0; i < 4078; i++)
tmpBuf[i] = 0x20;
tmpIndex = 4078;
int16 extendedLenCmd;
if ((magic1 == 0x1234) && (magic2 == 0x5678)) {
// Extended format allowing to copy larger strings
// from the window (up to 256 + 18 = 274 bytes).
extendedLenCmd = 18;
tmpIndex = 273;
} else {
// Standard format allowing to copy short strings
// (up to 18 bytes) from the window.
extendedLenCmd = 100; // Cannot be matched
tmpIndex = 4078;
src -= 4;
}

src += 4;
memset(tmpBuf, 0x20, tmpIndex); // Fill initial window with spaces

byte *unpacked = new byte[size];
byte *dest = unpacked;
Expand Down Expand Up @@ -358,6 +373,11 @@ byte *ExtractGobStk::unpackData(byte *src, uint32 &size) {
len = (*src & 0x0F) + 3;
src++;

if (len == extendedLenCmd) {
len = *src + 18;
src++;
}

for (int i = 0; i < len; i++) {
*dest++ = tmpBuf[(off + i) % 4096];
if (--counter == 0)
Expand Down

0 comments on commit 9b0d1f7

Please sign in to comment.