// File: /workspace/github_c_makefile_star2_O0/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
subq $0xd0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
movl $0x0, -0x24(%rbp)
cmpl $0x13, -0x24(%rbp)
jge 0x6eca
movq -0xa0(%rbp), %rax
movslq -0x24(%rbp), %rcx
movb $0x0, 0x5c(%rax,%rcx)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x6ea9
movq -0xa0(%rbp), %rdi
movl $0x5, %esi
callq 0x6440
movq -0xa0(%rbp), %rdi
addq $0x101, %rax            # imm = 0x101
movw %ax, 0x70(%rdi)
movl $0x5, %esi
callq 0x6440
movq -0xa0(%rbp), %rdi
addq $0x1, %rax
movb %al, 0x72(%rdi)
movl $0x4, %esi
callq 0x6440
addq $0x4, %rax
movb %al, -0x25(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movzbl -0x25(%rbp), %ecx
cmpl %ecx, %eax
jge 0x6f66
movq -0xa0(%rbp), %rdi
movl $0x3, %esi
callq 0x6440
movq %rax, %rcx
movq -0xa0(%rbp), %rax
movb %cl, -0x2d(%rbp)
movb -0x2d(%rbp), %dl
movslq -0x2c(%rbp), %rsi
leaq 0x94cd(%rip), %rcx      # 0x10420
movzbl (%rcx,%rsi), %ecx
movb %dl, 0x5c(%rax,%rcx)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x6f1c
movq -0xa0(%rbp), %rdi
movq %rsp, %rax
leaq -0x38(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x34(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x2e(%rbp), %rcx
movq %rcx, (%rax)
movl $0x13, %edx
movl $0x2, %r8d
movl $0x7, %r9d
movl %r8d, %esi
movl %r8d, %ecx
callq 0x73d0
jmp 0x6fa5
movq -0xa0(%rbp), %rax
cmpq $0x0, 0x78(%rax)
je 0x7015
movq -0xa0(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
je 0x6fd7
movq -0xa8(%rbp), %rdi
callq 0x2280
movq -0xa0(%rbp), %rax
movq $0x0, 0x78(%rax)
jmp 0x7015
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rdi
callq 0x20b0
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
callq 0x2320
jmp 0x73b5
movl $0x7fff8, %edi          # imm = 0x7FFF8
callq 0x2030
movq %rax, -0xb0(%rbp)
jmp 0x7028
movq -0xa0(%rbp), %rax
movq -0xb0(%rbp), %rcx
movq %rcx, 0x78(%rax)
movl $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq -0xa0(%rbp), %rdx
movl -0x48(%rbp), %eax
movzwl 0x70(%rdx), %ecx
movzbl 0x72(%rdx), %edx
addl %edx, %ecx
cmpl %ecx, %eax
jge 0x72ab
movq -0xa0(%rbp), %rax
cmpq $0xfffffff, 0x80(%rax) # imm = 0xFFFFFFF
jbe 0x708c
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x73b5
movq -0xa0(%rbp), %rdi
movq 0x80(%rdi), %rax
addq $0x1, %rax
movq %rax, 0x80(%rdi)
movl -0x34(%rbp), %esi
callq 0x6530
movq %rax, -0x58(%rbp)
movslq -0x38(%rbp), %rax
addq -0x58(%rbp), %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jbe 0x70d4
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x73b5
movq -0xa0(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x38(%rbp), %rdx
addq -0x58(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movq (%rcx), %rcx
movl %ecx, -0x5c(%rbp)
cmpq $0x800000, 0x48(%rax)   # imm = 0x800000
jb 0x7111
movq -0x20(%rbp), %rax
movl $0x0, (%rax)
movb $0x0, -0x1(%rbp)
jmp 0x73b5
movq -0xa0(%rbp), %rdi
movl -0x5c(%rbp), %esi
callq 0x6440
movq -0xa0(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x38(%rbp), %rdx
addq -0x58(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movq 0x10(%rcx), %rcx
movq %rcx, -0x68(%rbp)
movq 0x28(%rax), %rax
movslq -0x38(%rbp), %rcx
addq -0x58(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0xc(%rax)
jne 0x72a6
cmpq $0x10, -0x68(%rbp)
jae 0x7193
movq -0xa0(%rbp), %rax
movq -0x68(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movq -0x68(%rbp), %rdx
movq 0x78(%rax), %rax
movslq -0x48(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x72a4
cmpq $0x10, -0x68(%rbp)
jne 0x71f1
movq -0xa0(%rbp), %rdi
movl $0x2, %esi
callq 0x6440
addq $0x3, %rax
movl %eax, -0x6c(%rbp)
movl $0x0, -0x70(%rbp)
movl -0x70(%rbp), %eax
cmpl -0x6c(%rbp), %eax
jge 0x71ec
movq -0xa0(%rbp), %rax
movq -0x50(%rbp), %rdx
movq 0x78(%rax), %rax
movslq -0x48(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x71b9
jmp 0x72a2
cmpq $0x11, -0x68(%rbp)
jne 0x724c
movq -0xa0(%rbp), %rdi
movl $0x3, %esi
callq 0x6440
addq $0x3, %rax
movl %eax, -0x74(%rbp)
movl $0x0, -0x78(%rbp)
movl -0x78(%rbp), %eax
cmpl -0x74(%rbp), %eax
jge 0x724a
movq -0xa0(%rbp), %rax
movq 0x78(%rax), %rax
movslq -0x48(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x7217
jmp 0x72a0
movq -0xa0(%rbp), %rdi
movl $0x7, %esi
callq 0x6440
addq $0xb, %rax
movl %eax, -0x7c(%rbp)
movl $0x0, -0x80(%rbp)
movl -0x80(%rbp), %eax
cmpl -0x7c(%rbp), %eax
jge 0x729e
movq -0xa0(%rbp), %rax
movq 0x78(%rax), %rax
movslq -0x48(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x726b
jmp 0x72a0
jmp 0x72a2
jmp 0x72a4
jmp 0x72a6
jmp 0x7049
movq -0xa0(%rbp), %rdi
movq %rsp, %rax
leaq -0x90(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x88(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x81(%rbp), %rcx
movq %rcx, (%rax)
movl $0x3, %esi
movl $0x101, %edx            # imm = 0x101
xorl %r8d, %r8d
movl $0x9, %r9d
movl %r8d, %ecx
callq 0x73d0
jmp 0x72f2
movq -0xa0(%rbp), %rdi
movq %rsp, %rax
leaq -0x94(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x8c(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x82(%rbp), %rcx
movq %rcx, (%rax)
movl $0x4, %esi
xorl %edx, %edx
movl $0x1, %r8d
movl $0x6, %r9d
movl %r8d, %ecx
callq 0x73d0
jmp 0x7339
movq -0xa0(%rbp), %rdi
movl -0x90(%rbp), %esi
movl -0x94(%rbp), %edx
movl -0x88(%rbp), %ecx
movl -0x8c(%rbp), %r8d
movq -0x18(%rbp), %r9
movq -0x20(%rbp), %r10
movq %rsp, %rax
movq %r10, (%rax)
callq 0x8380
jmp 0x736e
movq -0xa0(%rbp), %rax
cmpq $0x0, 0x78(%rax)
je 0x73af
movq -0xa0(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0xb8(%rbp)
cmpq $0x0, %rax
je 0x73a0
movq -0xb8(%rbp), %rdi
callq 0x2280
movq -0xa0(%rbp), %rax
movq $0x0, 0x78(%rax)
jmp 0x73b1
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)