// File: /workspace/github_c_makefile_star2_O2/DavidSM64[P]DKR-Decompressor/GECompression.cpp
// Function: GECompression::UncompressType2(unsigned char*, int&)
bool GECompression::UncompressType2(unsigned char* returnBuffer, int& fileSize)
{
	try
	{

	for (int x = 0; x < 0x13; x++)
	{
		variableTable[x] = 0;
	}

	tableSize = (GetNBits(5)+0x101);
	fiveBits = GetNBits(5)+0x1;
	unsigned char fourBits = GetNBits(4)+0x4;

	for (int index = 0; index < fourBits; index++)
	{
		unsigned char threeBits = GetNBits(3);
		variableTable[bt2Table1B[index]] = threeBits;
	}

	bool returnValue1;
	int numBits1;
	int startIndex1;

	CreateGlobalDecompressionTable(2, 0x13, 2, 2, 7, returnValue1, numBits1, startIndex1);

	if (wordTable != NULL)
	{
		delete [] wordTable;
		wordTable = NULL;
	}
	wordTable = new unsigned long[0xFFFF];

	int wordTableSpot = 0;

	unsigned long lastWritten = 0;
	while (wordTableSpot < (tableSize + fiveBits))
	{

		if (iterationCounter > 268435455)
		{
			fileSize = 0;
			return false;
		}
		iterationCounter++;

		unsigned long tableIndex = GetNBitsAndPreserve(numBits1);
		if ((startIndex1 + tableIndex) > 0xFFFF)
		{
			fileSize = 0;
			return false;
		}
		int numBits2 = unpackTable[startIndex1 + tableIndex].bits;
		if (bytesIndex >= maxByteSize)
		{
			fileSize = 0;
			return false;
		}
		GetNBits(numBits2);
		unsigned long wordValue = unpackTable[startIndex1 + tableIndex].wordValue;
		if (unpackTable[startIndex1 + tableIndex].nextIndex == 0)
		{
			if (wordValue < 0x10)
			{
				lastWritten = wordValue;
				wordTable[wordTableSpot] = wordValue;
				wordTableSpot++;
			}
			else if (wordValue == 0x10)
			{
				int repeatLen = (GetNBits(2) + 3);
				for (int index = 0; index < repeatLen; index++)
				{
					wordTable[wordTableSpot] = lastWritten;
					wordTableSpot++;
				}
			}
			else if (wordValue == 0x11)
			{
				int repeatLen = (GetNBits(3) + 3);
				for (int index = 0; index < repeatLen; index++)
				{
					wordTable[wordTableSpot] = 0;
					wordTableSpot++;					
				}
			}
			else
			{
				int repeatLen = (GetNBits(7) + 0xB);
				for (int index = 0; index < repeatLen; index++)
				{
					wordTable[wordTableSpot] = 0;
					wordTableSpot++;					
				}
			}
		}
	}
	bool returnValue2, returnValue3;
	int numBits2, numBits3;
	int startIndex2, startIndex3;

	CreateGlobalDecompressionTable(3, 0x101, 0, 0, 9, returnValue2, numBits2, startIndex2);

	CreateGlobalDecompressionTable(4, 0, 1, 1, 6, returnValue3, numBits3, startIndex3);
	DecompressBasedOnTable(startIndex2, startIndex3, numBits2, numBits3, returnBuffer, fileSize);
	if (wordTable != NULL)
	{
		delete [] wordTable;
		wordTable = NULL;
	}
	} catch (...)
	{
		fileSize = 0;
		return false;
	}
	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdx, -0x38(%rbp)
movq %rsi, -0x70(%rbp)
movq %rdi, %r14
pushq $0x5c
popq %rax
cmpq $0x6f, %rax
je 0x39f9
movb $0x0, (%r14,%rax)
incq %rax
jmp 0x39e9
pushq $0x5
popq %r15
movq %r14, %rdi
movl %r15d, %esi
callq 0x3530
addl $0x101, %eax            # imm = 0x101
movw %ax, 0x70(%r14)
movq %r14, %rdi
movl %r15d, %esi
callq 0x3530
incb %al
movb %al, 0x72(%r14)
pushq $0x4
popq %rsi
movq %r14, %rdi
callq 0x3530
addl $0x4, %eax
movzbl %al, %ebx
xorl %r15d, %r15d
pushq $0x3
popq %r12
leaq 0x696e(%rip), %r13      # 0xa3b0
cmpq %r15, %rbx
je 0x3a61
movq %r14, %rdi
movl %r12d, %esi
callq 0x3530
movzbl (%r15,%r13), %ecx
movb %al, 0x5c(%r14,%rcx)
incq %r15
jmp 0x3a42
subq $0x8, %rsp
leaq -0x50(%rbp), %rax
leaq -0x54(%rbp), %r8
leaq -0x2b(%rbp), %r10
pushq $0x13
popq %rdx
pushq $0x2
popq %rcx
pushq $0x7
popq %r9
movq %r14, %rdi
movl %ecx, %esi
pushq %rax
pushq %r8
pushq %r10
callq 0x3cec
addq $0x20, %rsp
movq 0x78(%r14), %rdi
testq %rdi, %rdi
je 0x3aa1
callq 0x21c0
andq $0x0, 0x78(%r14)
movl $0x7fff8, %edi          # imm = 0x7FFF8
callq 0x2030
movq %rax, 0x78(%r14)
movl -0x54(%rbp), %eax
movl %eax, -0x3c(%rbp)
movslq -0x50(%rbp), %rbx
imulq $0x18, %rbx, %rax
movq %rax, -0x60(%rbp)
xorl %eax, %eax
xorl %r12d, %r12d
movq %rax, -0x68(%rbp)
movzwl 0x70(%r14), %eax
movzbl 0x72(%r14), %ecx
addl %eax, %ecx
cmpl %ecx, %r12d
setge %r13b
jge 0x3c33
movq 0x80(%r14), %rax
cmpq $0x10000000, %rax       # imm = 0x10000000
jae 0x3c1a
incq %rax
movq %rax, 0x80(%r14)
movq %r14, %rdi
movl -0x3c(%rbp), %esi
callq 0x359e
movq %rax, %r15
addq %rbx, %rax
cmpq $0x10000, %rax          # imm = 0x10000
jae 0x3c1a
cmpq $0x800000, 0x48(%r14)   # imm = 0x800000
jae 0x3c1a
movq 0x28(%r14), %rcx
imulq $0x18, %rax, %rax
movl (%rcx,%rax), %esi
movq %r14, %rdi
callq 0x3530
imulq $0x18, %r15, %rax
addq 0x28(%r14), %rax
movq -0x60(%rbp), %rcx
cmpl $0x0, 0xc(%rcx,%rax)
jne 0x3aca
movq -0x60(%rbp), %rcx
movq 0x10(%rcx,%rax), %rax
cmpq $0xf, %rax
jbe 0x3c07
movslq %r12d, %r12
cmpq $0x11, %rax
je 0x3ba9
cmpq $0x10, %rax
movq -0x68(%rbp), %r15
jne 0x3bd8
movq %r14, %rdi
pushq $0x2
popq %rsi
callq 0x3530
addl $0x3, %eax
movq 0x78(%r14), %rcx
testl %eax, %eax
movl $0x0, %edx
cmovlel %edx, %eax
subl $0x1, %eax
jb 0x3aca
movq %r15, (%rcx,%r12,8)
incq %r12
jmp 0x3b97
movq %r14, %rdi
pushq $0x3
popq %rsi
callq 0x3530
addl $0x3, %eax
movq 0x78(%r14), %rcx
testl %eax, %eax
movl $0x0, %edx
cmovlel %edx, %eax
subl $0x1, %eax
jb 0x3aca
andq $0x0, (%rcx,%r12,8)
incq %r12
jmp 0x3bc5
movq %r14, %rdi
pushq $0x7
popq %rsi
callq 0x3530
addl $0xb, %eax
movq 0x78(%r14), %rcx
testl %eax, %eax
movl $0x0, %edx
cmovlel %edx, %eax
subl $0x1, %eax
jb 0x3aca
andq $0x0, (%rcx,%r12,8)
incq %r12
jmp 0x3bf4
movq 0x78(%r14), %rcx
movslq %r12d, %rdx
movq %rax, (%rcx,%rdx,8)
incl %r12d
jmp 0x3ac6
movq -0x38(%rbp), %rax
andl $0x0, (%rax)
movl %r13d, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
subq $0x8, %rsp
leaq -0x44(%rbp), %rax
leaq -0x4c(%rbp), %r8
leaq -0x2a(%rbp), %r10
pushq $0x3
popq %rsi
pushq $0x9
popq %r9
movq %r14, %rdi
movl $0x101, %edx            # imm = 0x101
xorl %ecx, %ecx
pushq %rax
pushq %r8
pushq %r10
callq 0x3cec
addq $0x20, %rsp
subq $0x8, %rsp
leaq -0x40(%rbp), %rax
leaq -0x48(%rbp), %r8
leaq -0x29(%rbp), %r10
pushq $0x4
popq %rsi
pushq $0x1
popq %rcx
pushq $0x6
popq %r9
movq %r14, %rdi
xorl %edx, %edx
pushq %rax
pushq %r8
pushq %r10
callq 0x3cec
addq $0x20, %rsp
movl -0x44(%rbp), %esi
movl -0x40(%rbp), %edx
movl -0x4c(%rbp), %ecx
movl -0x48(%rbp), %r8d
subq $0x8, %rsp
movq %r14, %rdi
movq -0x70(%rbp), %r9
pushq -0x38(%rbp)
callq 0x43f8
popq %rcx
popq %rdx
movq 0x78(%r14), %rdi
testq %rdi, %rdi
je 0x3c21
callq 0x21c0
andq $0x0, 0x78(%r14)
jmp 0x3c21
jmp 0x3ccf
movq %rax, %rdi
callq 0x20a0
movq -0x38(%rbp), %rax
andl $0x0, (%rax)
callq 0x2260
xorl %r13d, %r13d
jmp 0x3c21
nop