// File: /workspace/github_c_makefile_star2_O0/AMGarkin[P]BDOcrypt/BDO_decrypt.c
// Function: main
int main(int argc, char **argv)
{
	if (argc != 3){
		printf("BDO_decrypt <source file> <output file>");
		return 1;
	}

	char* srcFileName = argv[1];
	char* outFileName = argv[2];

	FILE* srcFile = fopen(srcFileName, "rb");
	if (srcFile == NULL){
		printf("File not found: %s", srcFileName);
		return -1;
	}
	FILE* tmpFile = tmpfile();
	FILE* outFile = fopen(outFileName, "wb");

	///Decompress source to temporary file
	unsigned long compressedSize = 0;
	unsigned long uncompressedSize = 0;

	fseek(srcFile, 0, SEEK_END);
	compressedSize = ftell(srcFile) - 4; // 1st 4 bytes holds information about uncompressed data size
	rewind(srcFile);

	fread(&uncompressedSize, 4, 1, srcFile);

	unsigned char *pCompressedData = (unsigned char *) calloc(compressedSize, sizeof(unsigned char));
	unsigned char *pUncompressedData = (unsigned char *) calloc(uncompressedSize, sizeof(unsigned char));

	fread(pCompressedData, 1, compressedSize, srcFile);

	int result = uncompress(pUncompressedData, &uncompressedSize, pCompressedData, compressedSize);

	if (result == Z_OK) {
		fwrite(pUncompressedData, 1, uncompressedSize, tmpFile);

		///Convert .bss data from temporary file to text file
		unsigned long strSize;
		unsigned long strType;
		unsigned long strID1;
		unsigned short strID2;
		unsigned char strID3;
		unsigned char strID4;
		int a, b;
		wchar_t tmp;
		wchar_t strBuff[MAX_BUFF_SIZE];

		rewind(tmpFile);

		//write BOM (byte order mark) 0xFEFF = UTF-16 little-endian
		fwrite(&BOM_UTF16LE, 2, 1, outFile);

		while (1){
			if (fread(&strSize, 4, 1, tmpFile) != 1) break;
			if (fread(&strType, 4, 1, tmpFile) != 1) break;
			if (fread(&strID1, 4, 1, tmpFile) != 1) break;
			if (fread(&strID2, 2, 1, tmpFile) != 1) break;
			if (fread(&strID3, 1, 1, tmpFile) != 1) break;
			if (fread(&strID4, 1, 1, tmpFile) != 1) break;
			b = 0;
			for (a = 0; a < strSize + 2; a++) {
				if (fread(&tmp, 2, 1, tmpFile) != 1) break;
				if (tmp == CHAR_LF) {
					strBuff[b] = L'\\';
					b++;
					strBuff[b] = L'n';
					b++;
				} else {
					strBuff[b] = tmp;
					b++;
				}
			}

			fwprintf(outFile, L"%u\t%u\t%u\t%u\t%u\t\"%s\"\r\n", strType, strID1, strID2, strID3, strID4, strBuff);
		}
	} else if (result == Z_MEM_ERROR) {
		printf("ERROR: Not enough memory.");
	} else if (result == Z_BUF_ERROR) {
		printf("ERROR: Output buffer is too small.");
	} else if (result == Z_DATA_ERROR) {
		printf("ERROR: Input data are corrupted or incomplete.");
	}

	fclose(srcFile);
	fclose(tmpFile);
	fclose(outFile);

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40a0, %rsp           # imm = 0x40A0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x3, -0x8(%rbp)
je 0x4017e9
leaq 0x9e82e(%rip), %rdi     # 0x4a0004
movb $0x0, %al
callq 0x411fe0
movl $0x1, -0x4(%rbp)
jmp 0x401b7a
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
leaq 0x9e820(%rip), %rsi     # 0x4a002c
callq 0x419800
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x40183a
movq -0x18(%rbp), %rsi
leaq 0x9e808(%rip), %rdi     # 0x4a002f
movb $0x0, %al
callq 0x411fe0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x401b7a
callq 0x412170
movq %rax, -0x30(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x9e7f4(%rip), %rsi     # 0x4a0042
callq 0x419800
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x41d5b0
movq -0x28(%rbp), %rdi
callq 0x419a00
subq $0x4, %rax
movq %rax, -0x40(%rbp)
movq -0x28(%rbp), %rdi
callq 0x41d690
movq -0x28(%rbp), %rcx
leaq -0x48(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x419900
movq -0x40(%rbp), %rdi
movl $0x1, %esi
callq 0x42a0c0
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
movl $0x1, %esi
callq 0x42a0c0
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
movq -0x40(%rbp), %rdx
movq -0x28(%rbp), %rcx
movl $0x1, %esi
callq 0x419900
movq -0x58(%rbp), %rdi
movq -0x50(%rbp), %rdx
movq -0x40(%rbp), %rcx
leaq -0x48(%rbp), %rsi
callq 0x401d40
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
jne 0x401b12
movq -0x58(%rbp), %rdi
movq -0x48(%rbp), %rdx
movq -0x30(%rbp), %rcx
movl $0x1, %esi
callq 0x419b50
movq -0x30(%rbp), %rdi
callq 0x41d690
movq -0x38(%rbp), %rcx
leaq 0x9e784(%rip), %rdi     # 0x4a00b4
movl $0x2, %esi
movl $0x1, %edx
callq 0x419b50
movq -0x30(%rbp), %rcx
leaq -0x68(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x419900
cmpq $0x1, %rax
je 0x401961
jmp 0x401b10
movq -0x30(%rbp), %rcx
leaq -0x70(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x419900
cmpq $0x1, %rax
je 0x401983
jmp 0x401b10
movq -0x30(%rbp), %rcx
leaq -0x78(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x419900
cmpq $0x1, %rax
je 0x4019a5
jmp 0x401b10
movq -0x30(%rbp), %rcx
leaq -0x7a(%rbp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x419900
cmpq $0x1, %rax
je 0x4019c7
jmp 0x401b10
movq -0x30(%rbp), %rcx
leaq -0x7b(%rbp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x419900
cmpq $0x1, %rax
je 0x4019e7
jmp 0x401b10
movq -0x30(%rbp), %rcx
leaq -0x7c(%rbp), %rdi
movl $0x1, %edx
movq %rdx, %rsi
callq 0x419900
cmpq $0x1, %rax
je 0x401a07
jmp 0x401b10
movl $0x0, -0x84(%rbp)
movl $0x0, -0x80(%rbp)
movslq -0x80(%rbp), %rax
movq -0x68(%rbp), %rcx
addq $0x2, %rcx
cmpq %rcx, %rax
jae 0x401ad2
movq -0x30(%rbp), %rcx
leaq -0x88(%rbp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x419900
cmpq $0x1, %rax
je 0x401a52
jmp 0x401ad2
cmpl $0xa, -0x88(%rbp)
jne 0x401a9f
movslq -0x84(%rbp), %rax
movl $0x5c, -0x4090(%rbp,%rax,4)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
movslq -0x84(%rbp), %rax
movl $0x6e, -0x4090(%rbp,%rax,4)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x401ac2
movl -0x88(%rbp), %ecx
movslq -0x84(%rbp), %rax
movl %ecx, -0x4090(%rbp,%rax,4)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x401ac4
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x401a18
movq -0x38(%rbp), %rdi
movq -0x70(%rbp), %rdx
movq -0x78(%rbp), %rcx
movzwl -0x7a(%rbp), %r8d
movzbl -0x7b(%rbp), %r9d
movzbl -0x7c(%rbp), %r10d
leaq -0x4090(%rbp), %rax
leaq 0x9e5bd(%rip), %rsi     # 0x4a00b8
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x41a140
jmp 0x40193f
jmp 0x401b58
cmpl $-0x4, -0x5c(%rbp)
jne 0x401b28
leaq 0x9e526(%rip), %rdi     # 0x4a0045
movb $0x0, %al
callq 0x411fe0
jmp 0x401b56
cmpl $-0x5, -0x5c(%rbp)
jne 0x401b3e
leaq 0x9e52a(%rip), %rdi     # 0x4a005f
movb $0x0, %al
callq 0x411fe0
jmp 0x401b54
cmpl $-0x3, -0x5c(%rbp)
jne 0x401b52
leaq 0x9e537(%rip), %rdi     # 0x4a0082
movb $0x0, %al
callq 0x411fe0
jmp 0x401b54
jmp 0x401b56
jmp 0x401b58
movq -0x28(%rbp), %rdi
callq 0x4190d0
movq -0x30(%rbp), %rdi
callq 0x4190d0
movq -0x38(%rbp), %rdi
callq 0x4190d0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40a0, %rsp           # imm = 0x40A0
popq %rbp
retq
nopw %cs:(%rax,%rax)