// File: /workspace/github_c_makefile_star2_O0/DavidSM64[P]DKR-Decompressor/GECompression.cpp
// Function: GECompression::OutputDecompressedBuffer(int&, int&)
unsigned char* GECompression::OutputDecompressedBuffer(int& fileSize, int& compressedSize)
{
	compressedSize = 0;
	if ((compressedBuffer == NULL) || (compressedBufferSize < 3))
		return NULL;


	if ((((compressedBuffer[0] << 8) | compressedBuffer[1]) != 0x1172) && (((compressedBuffer[0] << 8) | compressedBuffer[1]) != 0x1173) && (((compressedBuffer[0] << 8) | compressedBuffer[1]) != 0x68DE)&& (((compressedBuffer[0] << 8) | compressedBuffer[1]) != 0x789C) && (((compressedBuffer[0] << 8) | compressedBuffer[1]) != 0x78DA) && (((compressedBuffer[0] << 24) | (compressedBuffer[1]<<16) | (compressedBuffer[2]<<8) | (compressedBuffer[3])) != 0x1F8B0800) && (((compressedBuffer[0] << 24) | (compressedBuffer[1]<<16) | (compressedBuffer[2]<<8) | (compressedBuffer[3])) != 0x1F8B0808) && (game != BLASTCORPS) && (game != BANJOTOOIE) && (game != CONKER)  && (game != TOPGEARRALLY) && (game != JFG) && (game != DKR) && (game != JFGKIOSK) && (game != MICKEYSPEEDWAY) && (game != ZLB))
	{
		//MessageBox(NULL, "Not 1172/1173/1F8B0800/1F8B0808 Compressed", "Error", NULL);
        std::cout << "Error: Not 1172/1173/1F8B0800/1F8B0808 Compressed" << std::endl;
		return NULL;
	}

	bitsCache = 0;
	bitsRemain = 0;
	if ((game == GOLDENEYE) || (game == KILLERINSTINCT) || (game == MILO) || (game == STUNTRACER64) || (game == RESIDENTEVIL2))
		bytesIndex = 2;
	else if (game == PD)
		bytesIndex = 5;
	else if (game == BANJOKAZOOIE)
		bytesIndex = 6;
	else if ((game == DONKEYKONG64) || (game == DONKEYKONG64KIOSK) || (game == BLASTCORPS))
		bytesIndex = 0xA;
	else if ((game == BANJOTOOIE))
		bytesIndex = 0x2;
	else if (game == CONKER)
		bytesIndex = 4;
	else if (game == TOPGEARRALLY)
		bytesIndex = 0xE;
	else if ((game == JFG) || (game == JFGKIOSK) || (game == DKR) || (game == MICKEYSPEEDWAY))
		bytesIndex = 0x5;
	else if (game == ZLB)
		bytesIndex = 0x12;


	if (((game == DONKEYKONG64) || (game == DONKEYKONG64KIOSK) || (game == BLASTCORPS)) && (((compressedBuffer[0] << 24) | (compressedBuffer[1]<<16) | (compressedBuffer[2]<<8) | (compressedBuffer[3])) == 0x1F8B0808))
	{
		while (compressedBuffer[bytesIndex] != 0)
			bytesIndex++;
		bytesIndex++;
	}
	unpackTableIndex = 0;
	for (int x = 0; x < 0xFFFF; x++)
	{
		unpackTable[x].bits = 0;
		unpackTable[x].flags = 0;
		unpackTable[x].nextIndex = 0;
		unpackTable[x].wordValue = 0;
	}

	unsigned char* returnBuffer;
	returnBuffer = new unsigned char[maxByteSize];


	bool done = false;
	unsigned char compressionType;
	fileSize = 0;

	iterationCounter = 0;

	do
	{
		if (iterationCounter > 268435455)
		{
			fileSize = 0;
			if (returnBuffer != NULL)
				delete [] returnBuffer;
			return NULL;
		}
		iterationCounter++;
		done = GetNBits(1);
		if (bytesIndex >= maxByteSize)
		{
			fileSize = 0;
			if (returnBuffer != NULL)
				delete [] returnBuffer;
			return NULL;
		}
		compressionType = GetNBits(2);
		if (compressionType == 0)
		{
			if (!UncompressType0(returnBuffer, fileSize))
			{
				fileSize = 0;
				if (returnBuffer != NULL)
					delete [] returnBuffer;
				return NULL;
			}
		}
		else if (compressionType == 1)
		{
			if (!UncompressType1(returnBuffer, fileSize))
			{
				fileSize = 0;
				if (returnBuffer != NULL)
					delete [] returnBuffer;
				return NULL;
			}
		}
		else if (compressionType == 2)
		{
			if (!UncompressType2(returnBuffer, fileSize))
			{
				fileSize = 0;
				if (returnBuffer != NULL)
					delete [] returnBuffer;
				return NULL;
			}
		}
		else
		{
			fileSize = 0;
				if (returnBuffer != NULL)
					delete [] returnBuffer;
				return NULL;
		}
	} while (done != 1);

	compressedSize = bytesIndex;
	return returnBuffer;	
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rcx
movl $0x0, (%rcx)
cmpq $0x0, 0x50(%rax)
je 0x6637
movq -0x40(%rbp), %rax
cmpl $0x3, 0x58(%rax)
jge 0x6644
movq $0x0, -0x8(%rbp)
jmp 0x6caa
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x8, %eax
movq 0x50(%rcx), %rcx
movzbl 0x1(%rcx), %ecx
orl %ecx, %eax
cmpl $0x1172, %eax           # imm = 0x1172
je 0x67ed
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x8, %eax
movq 0x50(%rcx), %rcx
movzbl 0x1(%rcx), %ecx
orl %ecx, %eax
cmpl $0x1173, %eax           # imm = 0x1173
je 0x67ed
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x8, %eax
movq 0x50(%rcx), %rcx
movzbl 0x1(%rcx), %ecx
orl %ecx, %eax
cmpl $0x68de, %eax           # imm = 0x68DE
je 0x67ed
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x8, %eax
movq 0x50(%rcx), %rcx
movzbl 0x1(%rcx), %ecx
orl %ecx, %eax
cmpl $0x789c, %eax           # imm = 0x789C
je 0x67ed
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x8, %eax
movq 0x50(%rcx), %rcx
movzbl 0x1(%rcx), %ecx
orl %ecx, %eax
cmpl $0x78da, %eax           # imm = 0x78DA
je 0x67ed
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x18, %eax
movq 0x50(%rcx), %rdx
movzbl 0x1(%rdx), %edx
shll $0x10, %edx
orl %edx, %eax
movq 0x50(%rcx), %rdx
movzbl 0x2(%rdx), %edx
shll $0x8, %edx
orl %edx, %eax
movq 0x50(%rcx), %rcx
movzbl 0x3(%rcx), %ecx
orl %ecx, %eax
cmpl $0x1f8b0800, %eax       # imm = 0x1F8B0800
je 0x67ed
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x18, %eax
movq 0x50(%rcx), %rdx
movzbl 0x1(%rdx), %edx
shll $0x10, %edx
orl %edx, %eax
movq 0x50(%rcx), %rdx
movzbl 0x2(%rdx), %edx
shll $0x8, %edx
orl %edx, %eax
movq 0x50(%rcx), %rcx
movzbl 0x3(%rcx), %ecx
orl %ecx, %eax
cmpl $0x1f8b0808, %eax       # imm = 0x1F8B0808
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0x5, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0x6, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0x8, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0x9, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0xb, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0xc, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0xd, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0xe, (%rax)
je 0x67ed
movq -0x40(%rbp), %rax
cmpl $0x11, (%rax)
je 0x67ed
movq 0x980b(%rip), %rdi      # 0xffd0
leaq 0x5a01(%rip), %rsi      # 0xc1cd
callq 0x21c0
movq %rax, %rdi
movq 0x97e5(%rip), %rsi      # 0xffc0
callq 0x21f0
movq $0x0, -0x8(%rbp)
jmp 0x6caa
movq -0x40(%rbp), %rax
movq $0x0, 0x38(%rax)
movl $0x0, 0x40(%rax)
cmpl $0x0, (%rax)
je 0x6829
movq -0x40(%rbp), %rax
cmpl $0x3, (%rax)
je 0x6829
movq -0x40(%rbp), %rax
cmpl $0xa, (%rax)
je 0x6829
movq -0x40(%rbp), %rax
cmpl $0x10, (%rax)
je 0x6829
movq -0x40(%rbp), %rax
cmpl $0x12, (%rax)
jne 0x683a
movq -0x40(%rbp), %rax
movq $0x2, 0x48(%rax)
jmp 0x6936
movq -0x40(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x6854
movq -0x40(%rbp), %rax
movq $0x5, 0x48(%rax)
jmp 0x6934
movq -0x40(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x686e
movq -0x40(%rbp), %rax
movq $0x6, 0x48(%rax)
jmp 0x6932
movq -0x40(%rbp), %rax
cmpl $0x4, (%rax)
je 0x6889
movq -0x40(%rbp), %rax
cmpl $0x7, (%rax)
je 0x6889
movq -0x40(%rbp), %rax
cmpl $0x5, (%rax)
jne 0x689a
movq -0x40(%rbp), %rax
movq $0xa, 0x48(%rax)
jmp 0x6930
movq -0x40(%rbp), %rax
cmpl $0x6, (%rax)
jne 0x68b1
movq -0x40(%rbp), %rax
movq $0x2, 0x48(%rax)
jmp 0x692e
movq -0x40(%rbp), %rax
cmpl $0x8, (%rax)
jne 0x68c8
movq -0x40(%rbp), %rax
movq $0x4, 0x48(%rax)
jmp 0x692c
movq -0x40(%rbp), %rax
cmpl $0x9, (%rax)
jne 0x68df
movq -0x40(%rbp), %rax
movq $0xe, 0x48(%rax)
jmp 0x692a
movq -0x40(%rbp), %rax
cmpl $0xb, (%rax)
je 0x6903
movq -0x40(%rbp), %rax
cmpl $0xd, (%rax)
je 0x6903
movq -0x40(%rbp), %rax
cmpl $0xc, (%rax)
je 0x6903
movq -0x40(%rbp), %rax
cmpl $0xe, (%rax)
jne 0x6911
movq -0x40(%rbp), %rax
movq $0x5, 0x48(%rax)
jmp 0x6928
movq -0x40(%rbp), %rax
cmpl $0x11, (%rax)
jne 0x6926
movq -0x40(%rbp), %rax
movq $0x12, 0x48(%rax)
jmp 0x6928
jmp 0x692a
jmp 0x692c
jmp 0x692e
jmp 0x6930
jmp 0x6932
jmp 0x6934
jmp 0x6936
movq -0x40(%rbp), %rax
cmpl $0x4, (%rax)
je 0x6951
movq -0x40(%rbp), %rax
cmpl $0x7, (%rax)
je 0x6951
movq -0x40(%rbp), %rax
cmpl $0x5, (%rax)
jne 0x69c3
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movzbl (%rax), %eax
shll $0x18, %eax
movq 0x50(%rcx), %rdx
movzbl 0x1(%rdx), %edx
shll $0x10, %edx
orl %edx, %eax
movq 0x50(%rcx), %rdx
movzbl 0x2(%rdx), %edx
shll $0x8, %edx
orl %edx, %eax
movq 0x50(%rcx), %rcx
movzbl 0x3(%rcx), %ecx
orl %ecx, %eax
cmpl $0x1f8b0808, %eax       # imm = 0x1F8B0808
jne 0x69c3
jmp 0x698c
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rax
movq 0x48(%rcx), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0x69b3
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x48(%rax)
jmp 0x698c
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x48(%rax)
movq -0x40(%rbp), %rax
movl $0x0, 0x30(%rax)
movl $0x0, -0x24(%rbp)
cmpl $0xffff, -0x24(%rbp)    # imm = 0xFFFF
jge 0x6a43
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x24(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movq $0x0, (%rcx)
movq 0x28(%rax), %rcx
movslq -0x24(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movb $0x0, 0x8(%rcx)
movq 0x28(%rax), %rcx
movslq -0x24(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movl $0x0, 0xc(%rcx)
movq 0x28(%rax), %rax
movslq -0x24(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq $0x0, 0x10(%rax)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x69d5
movl $0x800000, %edi         # imm = 0x800000
callq 0x2030
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, -0x30(%rbp)
movb $0x0, -0x31(%rbp)
movq -0x18(%rbp), %rcx
movl $0x0, (%rcx)
movq $0x0, 0x80(%rax)
movq -0x40(%rbp), %rax
cmpq $0xfffffff, 0x80(%rax) # imm = 0xFFFFFFF
jbe 0x6ab9
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
cmpq $0x0, -0x30(%rbp)
je 0x6aac
movq -0x30(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, %rax
je 0x6aaa
movq -0x48(%rbp), %rdi
callq 0x2280
jmp 0x6aac
movq $0x0, -0x8(%rbp)
jmp 0x6caa
movq -0x40(%rbp), %rdi
movq 0x80(%rdi), %rax
addq $0x1, %rax
movq %rax, 0x80(%rdi)
movl $0x1, %esi
callq 0x6440
movq %rax, %rcx
movq -0x40(%rbp), %rax
cmpq $0x0, %rcx
setne %cl
andb $0x1, %cl
movb %cl, -0x31(%rbp)
cmpq $0x800000, 0x48(%rax)   # imm = 0x800000
jb 0x6b2e
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
cmpq $0x0, -0x30(%rbp)
je 0x6b21
movq -0x30(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, %rax
je 0x6b1f
movq -0x50(%rbp), %rdi
callq 0x2280
jmp 0x6b21
movq $0x0, -0x8(%rbp)
jmp 0x6caa
movq -0x40(%rbp), %rdi
movl $0x2, %esi
callq 0x6440
movb %al, -0x32(%rbp)
movzbl -0x32(%rbp), %eax
cmpl $0x0, %eax
jne 0x6b99
movq -0x40(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x6cc0
testb $0x1, %al
jne 0x6b94
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
cmpq $0x0, -0x30(%rbp)
je 0x6b87
movq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
je 0x6b85
movq -0x58(%rbp), %rdi
callq 0x2280
jmp 0x6b87
movq $0x0, -0x8(%rbp)
jmp 0x6caa
jmp 0x6c7f
movzbl -0x32(%rbp), %eax
cmpl $0x1, %eax
jne 0x6bf3
movq -0x40(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x6dd0
testb $0x1, %al
jne 0x6bee
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
cmpq $0x0, -0x30(%rbp)
je 0x6be1
movq -0x30(%rbp), %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, %rax
je 0x6bdf
movq -0x60(%rbp), %rdi
callq 0x2280
jmp 0x6be1
movq $0x0, -0x8(%rbp)
jmp 0x6caa
jmp 0x6c7d
movzbl -0x32(%rbp), %eax
cmpl $0x2, %eax
jne 0x6c47
movq -0x40(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x6e80
testb $0x1, %al
jne 0x6c45
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
cmpq $0x0, -0x30(%rbp)
je 0x6c3b
movq -0x30(%rbp), %rax
movq %rax, -0x68(%rbp)
cmpq $0x0, %rax
je 0x6c39
movq -0x68(%rbp), %rdi
callq 0x2280
jmp 0x6c3b
movq $0x0, -0x8(%rbp)
jmp 0x6caa
jmp 0x6c7b
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
cmpq $0x0, -0x30(%rbp)
je 0x6c71
movq -0x30(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, %rax
je 0x6c6f
movq -0x70(%rbp), %rdi
callq 0x2280
jmp 0x6c71
movq $0x0, -0x8(%rbp)
jmp 0x6caa
jmp 0x6c7d
jmp 0x6c7f
jmp 0x6c81
movb -0x31(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x6a71
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rax
movl %eax, %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)