Skip to content

Instantly share code, notes, and snippets.

@heinermann
Forked from ogarvey/Decompress.cpp
Last active March 6, 2024 14:22
Show Gist options
  • Save heinermann/146c89cc78f2236c131827c4699516fd to your computer and use it in GitHub Desktop.
Save heinermann/146c89cc78f2236c131827c4699516fd to your computer and use it in GitHub Desktop.
Decompiled Tetris Decompress method
#define g_p_BOLTcursor (*(byte **)(unaff_A5 + -0x15f0))
#define g_BOLT_bytes_available (*(int *)(unaff_A5 + -0x15f8))
#define NEXT_BYTE(r) nBytesAvailable--;\
if (nBytesAvailable < 0) { NextBlock(); pData = g_p_BOLTcursor; nBytesAvailable = g_BOLT_bytes_available; }\
r = *pData++;
byte * Decompress(byte *pResult, uint result_filesize, ushort flags)
{
ushort uVar2;
uint uVar1;
int nBytesAvailable;
byte bVar4;
uint uVar5;
uint uVar6;
ushort uVar7;
byte *pData;
byte *pbVar9;
byte *pbVar10;
byte *pOutputPtr;
int unaff_A5;
byte next_byte;
if (!pResult) {
pResult = (byte *)SysBOLTAlloc(result_filesize);
if (!pResult) return NULL;
}
pData = g_p_BOLTcursor;
nBytesAvailable = g_BOLT_bytes_available;
pOutputPtr = pResult;
if ((flags & 8) == 0) { // compressed
while ((int)result_filesize >= 1) {
NEXT_BYTE(bytevalue);
switch((bytevalue & 0xf0) >> 4) {
case 0x0:
case 0x1:
uVar5 = (uint)(bytevalue & 0x1f);
result_filesize -= uVar5 + 1;
if ((int)uVar5 < nBytesAvailable) {
nBytesAvailable -= uVar5 + 1;
do {
*pOutputPtr++ = *pData++;
uVar5--;
} while (uVar5 != -1);
}
else {
do {
NEXT_BYTE(*pOutputPtr);
pOutputPtr++;
uVar5--;
} while (uVar5 != -1);
}
continue;
case 0x2:
uVar7 = bytevalue & 0xf;
bVar4 = 0;
goto LAB_00009076;
case 0x3:
NEXT_BYTE(bVar4);
uVar7 = (bytevalue & 0xf) + 2;
LAB_00009076:
result_filesize -= uVar7 + 1;
do {
*pOutputPtr++ = bVar4;
uVar7--;
} while (uVar7 != -1);
continue;
case 0x4:
case 0x5:
case 0x6:
case 0x7:
uVar6 = (uint)(ushort)((bytevalue & 7) + 1);
pbVar10 = pOutputPtr - (int)(short)((bytevalue >> 3 & 7) + 1);
break;
case 0x8:
NEXT_BYTE(next_byte);
uVar6 = (uint)(ushort)((next_byte & 0x3f) + 2);
pbVar10 = pOutputPtr - (int)(short)((CONCAT11(bytevalue,next_byte) >> 6 & 0x3f) + 1);
break;
case 0x9:
NEXT_BYTE(next_byte);
uVar6 = (uint)(ushort)((next_byte & 3) + 2);
pbVar10 = pOutputPtr - (int)(short)((CONCAT11(bytevalue,next_byte) >> 2 & 0x3ff) + 1);
break;
case 0xA:
NEXT_BYTE(next_byte);
uVar2 = (ushort)next_byte << 8;
NEXT_BYTE(next_byte);
uVar6 = (uint)(ushort)((uVar2 & 0xff00 | (ushort)next_byte) - 1);
pbVar10 = pOutputPtr - (int)(short)((bytevalue & 0xf) + 1);
break;
case 0xB:
NEXT_BYTE(next_byte);
uVar1 = (uint)next_byte << 8;
NEXT_BYTE(next_byte);
uVar6 = (uint)(ushort)(((ushort)uVar1 & 0x300 | (ushort)next_byte) + 3);
pbVar10 = pOutputPtr - (int)(short)(((ushort)((uVar1 & 0xff00 | bytevalue << 0x10) >> 10) & 0x3ff) + 1);
break;
case 0xC:
case 0xD:
uVar6 = (uint)(ushort)((bytevalue & 3) + 1);
pbVar10 = pOutputPtr - (int)(short)(bytevalue >> 2 & 7);
goto LAB_000091d4;
case 0xE:
NEXT_BYTE(next_byte);
uVar6 = (uint)(ushort)((next_byte & 0x3f) + 2);
pbVar10 = pOutputPtr - (int)(short)(CONCAT11(bytevalue,next_byte) >> 6 & 0x3f );
goto LAB_000091d4;
case 0xF:
NEXT_BYTE(next_byte);
uVar1 = (uint)next_byte << 8;
NEXT_BYTE(next_byte);
uVar6 = (uint)(ushort)(((ushort)uVar1 & 0x300 | (ushort)next_byte) + 3) ;
pbVar10 = pOutputPtr - (int)(short)((ushort)((uVar1 & 0xff00 | bytevalue << 0x10) >> 10) & 0x3ff);
LAB_000091d4:
result_filesize -= uVar6 + 1;
do {
pbVar10--;
*pOutputPtr++ = *pbVar10;
uVar6--;
} while (uVar6 != -1);
continue;
}
result_filesize -= uVar6 + 1;
do {
*pOutputPtr++ = *pbVar10++;
uVar6--;
} while (uVar6 != -1);
}
}
else {
// uncompressed
while ((uVar7 = (short)result_filesize - 1,
result_filesize = result_filesize & 0xffff0000 | (uint)uVar7, uVar7 != 0xffff ||
(result_filesize = result_filesize - 0x10000, -1 < (int)result_filesize))) {
NEXT_BYTE(next_byte);
*pOutputPtr = next_byte;
pOutputPtr++;
}
}
g_BOLT_bytes_available = nBytesAvailable;
g_p_BOLTcursor = pData;
return pResult;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment