// File: /workspace/github_c_makefile_star2_O3/Joy-Division[P]tools-mgs/dat-extract_enc.c
// Function: main
int main( int argc, char **argv ) {
	
	unsigned char datheader[3*4] = {0};
	unsigned char datheaderbig[3*4] = {0};
	char execpath[4096] = {0}, stagename[32];
	unsigned char *stagelist = NULL;
	char builddatestring[32];
	char builddatestringbig[32];
	time_t buildtime;
	struct tm *buildstruct = NULL;
	
	uint16_t overridegame = 0;
	
	unsigned int i = 0;
	unsigned int flags = 0;
	
	tocDatHeader *dathead = NULL;
	tocDatHeader *datheadbig = NULL;
	stageinfo *infolist = NULL;
	tocStageEntry *stages = NULL;
	tocStageEntrySmall *smallstages = NULL;
	tocStageEntryBig *bigstages = NULL;
	
	uint32_t *headvals = NULL;
	
	if ( argc < 2 ) {
		printf("Not enough args!\nUse: %s DAT-file [id-override]\n", argv[0]);
		return 1;
	}
	if( argc == 3 ) {
		overridegame = strtoul(argv[2], NULL, 16);
	}
	
	if(strlen(argv[0]) > 4096) BREAK("Path to executable exceeds 4096 chars!\n")
	strcpy(execpath, argv[0]);
	if(strrchr(execpath, '/') || strrchr(execpath, '\\')) cleanExecPath(execpath);
	else sprintf(execpath, "./");
	
	FILE *f = NULL;
	/* needed for debugging purposes */
	FILE *o = NULL;
	
	if( !(f = fopen( argv[1], "rb" ))) {
		printf("Couldnt open file %s\n", argv[1]);
		return 1;
	}
	
	fread( &initialkey, 4, 1, f );
	initialkeybig = bswap_32(initialkey);
	
	
	fread( datheader, 0x0C, 1, f );
	headvals = (uint32_t *)datheader;
	
	/* the trial edition does bullshit here, meh */
	if(initialkey == 0x00000001) {
		
		flags |= (GAME_MGS2|TRIALSTAGE);
		
		getDictionary(&commondic, &numcommondic, execpath, "common-trial2", flags);
		
		dathead = malloc(sizeof(tocDatHeader));
		
		buildtime = headvals[0];
		buildstruct = gmtime(&buildtime);
		strftime(builddatestring, 32, dateTimeString, buildstruct);
		
		printf("DAT Header info (endianess: little - Trial mode):\n");
		printf("builddate %s (%08x) - numstages %03d (%08x) - headersize %08x\n", builddatestring, headvals[0], headvals[1], headvals[1], headvals[2]);
		dathead->numStages = headvals[1] & 0xFFFF;
	}
	else {
		dathead = (tocDatHeader *)datheader;
		datheadbig = (tocDatHeader *)datheaderbig;
		
		/* decrypt header in BE mode */
		decryptHeader(datheader, 3, GAME_MGS4);
		
		datheadbig->version = bswap_16(dathead->version);
		datheadbig->numblocks = bswap_16(dathead->numblocks);
		datheadbig->numStages = bswap_16(dathead->numStages);
		datheadbig->game = bswap_16(dathead->game);
		datheadbig->unknownhash = bswap_32(dathead->unknownhash);
		
		/* encrypt header in BE mode */
		decryptHeader(datheader, 3, GAME_MGS4);
		/* decrypt header in LE mode */
		decryptHeader(datheader, 3, 0);
		
		buildtime = initialkey;
		buildstruct = gmtime(&buildtime);
		strftime(builddatestring, 32, dateTimeString, buildstruct);
		
		buildtime = initialkeybig;
		buildstruct = gmtime(&buildtime);
		strftime(builddatestringbig, 32, dateTimeString, buildstruct);
		
		if(((dathead->version >> 8) || (dathead->numblocks >> 8)) && ((datheadbig->version != 1))) {
			printf("unencrypted fiel\n");
			/* "encrypt" header in LE mode to turn the "decrypted" data back into usable data, as it never was encrypted */
			decryptHeader(datheader, 3, 0);
			if(!(dathead->unknownhash & 0xFF)) {
				printf("reassigning datheadbig values\n");
				datheadbig->version = bswap_16(dathead->version);
				datheadbig->numblocks = bswap_16(dathead->numblocks);
				datheadbig->numStages = bswap_16(dathead->numStages);
				datheadbig->game = bswap_16(dathead->game);
				datheadbig->unknownhash = bswap_32(dathead->unknownhash);
				dathead = datheadbig;
				flags |= GAME_TTS; /* doing this because TTS is the only BE game with unencrypted data */
			}
		}
		
		else flags |= ENCRYPTED;
		
		if((datheadbig->game == 0x0000) && (datheadbig->version == 1)) {
			dathead = datheadbig;
			flags |= GAME_MGS4;
		}
		
		printf("DAT Header info (endianness %s):\n", (flags & IS_BIGENDIAN)?"BE":"LE");
		printf(datHeaderInfoString, (flags & IS_BIGENDIAN)?builddatestringbig:builddatestring, initialkey, dathead->version, dathead->numblocks, dathead->numStages, dathead->numStages, dathead->game, dathead->unknownhash);
		
		if(!overridegame) overridegame = dathead->game;
		else printf("WARNING: overriding game from file with passed value %04x\n", overridegame);
		
		switch(overridegame) {
			case 0xCCCC: { /* TTS uses 0xCCCC as "game" magic, which conveniently works when interpreted as either LE or BE 16bit value */
				printf("TTS DAT detected based on game hash\n");
				dathead = datheadbig;
				flags |= (GAME_TTS|GAME_MGS2|COMPRESSED);
				
				getDictionary(&commondic, &numcommondic, execpath, "common-tts", flags);
				
				break;
			}
			case 0x4010:
			case 0x4016:
			case 0x610A:
			case 0x2ABB: {
				printf("MGS2 DAT detected based on game hash\n");
				flags |= (GAME_MGS2 | ((flags & ENCRYPTED) ? COMPRESSED : 0));
				
				getDictionary(&commondic, &numcommondic, execpath, "common-mgs2", flags);
				break;
			}
			case 0x0000:	/* THIS MAY EXPLODE HORRIBLY POSSIBLY EVENTUALLY
					   WHO THOUGHT THIS WAS A GOOD IDEA */
					/* AS EXPECTED IT EXPLODED HORRIBLY AND ATE KITTENS */
				if(!(flags & IS_BIGENDIAN)) flags |= GAME_MGS3S;
			case 0x0025:
			case 0x0063:
			case 0x4015:
			case 0x4212: { // FOR THIS ONE AS WELL... (see below)
				if(flags & ENCRYPTED) {
					if(flags & IS_BIGENDIAN) { /* BE thing for MGS4 */
						if(datheadbig->version != 1) BREAK("unexpected version, not 1\n");
						flags |= (GAME_MGS4|COMPRESSED);
						
						getDictionary(&commondic, &numcommondic, execpath, "common-mgs4", flags);
					}
					else { /* LE thing for MGS3, see comment for case 0x0000 */
						printf("MGS3 DAT detected based on game hash\n");
						flags |= (GAME_MGS3|COMPRESSED);
						
						getDictionary(&commondic, &numcommondic, execpath, "common-mgs3", flags);
					}
				}
				else { // WHY DOES THE XBOX ONE SHARE AN ID WITH MGS3 >:(
					printf("MGS2 DAT detected based on game hash\n");
					flags |= GAME_MGS2;
					
					getDictionary(&commondic, &numcommondic, execpath, "common-mgs2", flags);
				}
				break;
			}
			case 0x0806: {
				printf("ZOE2 DAT detected based on game hash\n");
				flags |= (GAME_ZOE2|COMPRESSED);
				
				getDictionary(&commondic, &numcommondic, execpath, "common-zoe2", flags);
				break;
			}
			default: {
				/* change this back, just in case something goes really bad */
				dathead = (tocDatHeader *)datheader;
				printf("DAT Header info:\n");
				printf(datHeaderInfoString, builddatestring, initialkey, dathead->version, dathead->numblocks, dathead->numStages, dathead->numStages, dathead->game, dathead->unknownhash);
				
				printf("DAT Header info BE:\n");
				printf(datHeaderInfoString, builddatestringbig, initialkeybig, datheadbig->version, datheadbig->numblocks, datheadbig->numStages, datheadbig->numStages, datheadbig->game, datheadbig->unknownhash);
				printf("overridegame was %04x\n", overridegame);
				printf("unknown game hash, aborting\n");
				fclose(f);
				return 0;
			}
		}
	}
	
	printf("Flags raw %08x\n", flags);
	printf("Current flags:\n%s%s%s%s%s%s%s%s%s\n", (flags & GAME_MGS2) ? "GAME_MGS2 " : "", (flags & GAME_MGS3) ? "GAME_MGS3 " : "", (flags & GAME_MGS4) ? "GAME_MGS4 " : "", (flags & GAME_ZOE2) ? "GAME_ZOE2 " : "", (flags & GAME_TTS) ? "GAME_TTS " : "", (flags & GAME_MGS3S) ? "GAME_MGS3S " : "", (flags & TRIALSTAGE) ? "TRIALSTAGE " : "", (flags & ENCRYPTED) ? "ENCRYPTED " : "", (flags & COMPRESSED) ? "COMPRESSED " : "");
	
	if(flags & IS_BIGSTAGE) {
		
		stagelist = malloc((3*4)+(sizeof(tocStageEntryBig)*dathead->numStages));
		stages = malloc(sizeof(tocStageEntry)*dathead->numStages);
		bigstages = (tocStageEntryBig *)(stagelist+(3*4));
		fseek(f, 4, SEEK_SET);
		fread( stagelist, (3*4)+(sizeof(tocStageEntryBig)*dathead->numStages), 1, f );
		
		if(flags & ENCRYPTED) decryptHeader(stagelist, 3+(dathead->numStages*5), flags);
		
		for(i = 0; i < dathead->numStages; i++) {
			stages[i].name = bigstages[i].name;
			stages[i].offset = (flags & IS_BIGENDIAN) ? bswap_32(bigstages[i].offset) : bigstages[i].offset;
		}
		/* dumps the stagelist for debugging purposes */
		printf("DAMPSTAGEBIG\n");
		o = fopen("stagedampbig.bin", "wb");
		fwrite(stagelist, (3*4)+(sizeof(tocStageEntryBig)*dathead->numStages), 1, o);
		fclose(o); 
	}
	else {
		stagelist = malloc((3*4)+(sizeof(tocStageEntrySmall)*dathead->numStages));
		stages = malloc(sizeof(tocStageEntry)*dathead->numStages);
		smallstages = (flags & TRIALSTAGE) ? ((tocStageEntrySmall *)stagelist) : ((tocStageEntrySmall *)(stagelist+(3*4)));
		fseek(f, (flags & TRIALSTAGE) ? 0x10 : 4, SEEK_SET); /* trial has its stage list at a different offset */
		fread( stagelist, (3*4)+(sizeof(tocStageEntrySmall)*dathead->numStages), 1, f );
		
		if(flags & ENCRYPTED) decryptHeader(stagelist, 3+(dathead->numStages*3), flags);
		
		for(i = 0; i < dathead->numStages; i++) {
			stages[i].name = smallstages[i].name;
			stages[i].offset = (flags & IS_BIGENDIAN) ? bswap_32(smallstages[i].offset) : smallstages[i].offset;
		}
		/* dumps the stagelist for debugging purposes */
		printf("DAMPSTAGESMALL\n");
		o = fopen("stagedampsmall.bin", "wb");
		fwrite(stagelist, (3*4)+(sizeof(tocStageEntrySmall)*dathead->numStages), 1, o);
		fclose(o);
	}
	
	printf("Stagelist:\n");
	for(i = 0; i < dathead->numStages; i++) printf("idx %04x Name %s - offset %08x(%08x)\n", i, stages[i].name, stages[i].offset, stages[i].offset * 0x800);
	
	infolist = processStages(f, stages, dathead->numStages, flags);
	
	for(i = 0; i < dathead->numStages; i++) {
		createDirectory(stages[i].name);
		if(flags & TRIALSTAGE) strcpy(stagename, "trial2-");
		else if(flags & GAME_TTS) strcpy(stagename, "tts-");
		else if(flags & GAME_MGS2) strcpy(stagename, "mgs2-");
		else if(flags & GAME_MGS3) strcpy(stagename, "mgs3-");
		else if(flags & GAME_MGS4) strcpy(stagename, "mgs4-");
		else if(flags & GAME_ZOE2) strcpy(stagename, "zoe2-");
		strcat(stagename, stages[i].name);
		getDictionary(&stagedic, &numstagedic, execpath, stagename, flags);
		
		processInfoWithStage(f, infolist[i], stages[i], flags);
		if(stagedic) free(stagedic);
		stagedic = NULL;
		if(numstagedic > 0) numdicentries -= numstagedic;
		numstagedic = 0;
	}
	
	for(i = 0; i < dathead->numStages; i++) free(infolist[i].data);
	free(stagelist);
	free(infolist);
	free(stages);
	if(flags & TRIALSTAGE) free(dathead);
	
	if(commondic) free(commondic);
	
	printf("Done.\n");
	
	fclose(f);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10d8, %rsp           # imm = 0x10D8
movq %rsi, %rbx
movl %edi, %ebp
xorl %eax, %eax
movl %eax, 0x10(%rsp)
movq %rax, 0x8(%rsp)
movl %eax, 0x30(%rsp)
movq %rax, 0x28(%rsp)
leaq 0xd0(%rsp), %rdi
movl $0x1000, %edx           # imm = 0x1000
xorl %esi, %esi
callq 0x5100
cmpl $0x1, %ebp
jg 0x6894
movq (%rbx), %rsi
leaq 0x1eb1(%rip), %rdi      # 0x873c
xorl %eax, %eax
callq 0x50c0
jmp 0x68d0
cmpl $0x3, %ebp
jne 0x68ae
movq 0x10(%rbx), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x5200
movq %rax, %r13
jmp 0x68b1
xorl %r13d, %r13d
movq (%rbx), %r14
movq %r14, %rdi
callq 0x50b0
cmpq $0x1001, %rax           # imm = 0x1001
jb 0x68eb
leaq 0x2290(%rip), %rdi      # 0x8b5b
callq 0x5070
movl $0x1, %r14d
movl %r14d, %eax
addq $0x10d8, %rsp           # imm = 0x10D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xd0(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x5050
movq %r15, %rdi
movl $0x2f, %esi
callq 0x50f0
movq %rax, %r14
testq %rax, %rax
jne 0x692e
leaq 0xd0(%rsp), %rdi
movl $0x5c, %esi
callq 0x50f0
testq %rax, %rax
je 0x6d1f
movb $0x0, (%r14)
movq 0x8(%rbx), %rdi
leaq 0x1e33(%rip), %rsi      # 0x8770
callq 0x51c0
testq %rax, %rax
je 0x6a5a
movq %rax, %r12
leaq 0x591b(%rip), %rdi      # 0xc270
movl $0x4, %esi
movl $0x1, %edx
movq %rax, %rcx
callq 0x5080
movl 0x5903(%rip), %eax      # 0xc270
bswapl %eax
movl %eax, 0x58ff(%rip)      # 0xc274
leaq 0x8(%rsp), %rdi
movl $0xc, %esi
movl $0x1, %edx
movq %rdi, 0x38(%rsp)
movq %r12, %rcx
callq 0x5080
movl 0x58d9(%rip), %eax      # 0xc270
cmpq $0x1, %rax
movq %r12, 0x40(%rsp)
jne 0x6a6a
leaq 0x58cb(%rip), %rdi      # 0xc278
leaq 0x1dbf(%rip), %rdx      # 0x8773
leaq -0x1659(%rip), %r8      # 0x5362
leaq 0xd0(%rsp), %rsi
movl $0xa, %ecx
callq 0x53d8
movl %eax, 0x58b5(%rip)      # 0xc288
testl %eax, %eax
jle 0x69dd
addl %eax, 0x58b3(%rip)      # 0xc290
movl $0xc, %edi
callq 0x5170
movq %rax, %r13
movl 0x8(%rsp), %ebx
leaq 0x88(%rsp), %rdi
movq %rbx, (%rdi)
callq 0x51f0
movq 0x5823(%rip), %rdx      # 0xc228
leaq 0x90(%rsp), %r14
movl $0x20, %esi
movq %r14, %rdi
movq %rax, %rcx
callq 0x51b0
leaq 0x20d8(%rip), %rdi      # 0x8afc
callq 0x5070
movl 0xc(%rsp), %ebp
movl 0x10(%rsp), %r9d
leaq 0x1d48(%rip), %rdi      # 0x8781
movq %r14, %rsi
movl %ebx, %edx
movl %ebp, %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x50c0
movw %bp, 0x4(%r13)
movl $0x41, %r14d
jmp 0x6f5c
movq 0x8(%rbx), %rsi
leaq 0x1c14(%rip), %rdi      # 0x8679
jmp 0x688b
movl 0x5804(%rip), %edx      # 0xc274
movl 0x46ba(%rip), %ecx      # 0xb130
movl %edx, %esi
xorl $0xf0f0, %esi           # imm = 0xF0F0
xorl %edi, %edi
movl %edx, %r8d
movl %ecx, %r9d
imull %r8d, %r9d
xorl %r8d, 0x8(%rsp,%rdi,4)
addl %esi, %r9d
incq %rdi
movl %r9d, %r8d
cmpq $0x3, %rdi
jne 0x6a83
movzwl 0x8(%rsp), %ebp
movl %ebp, %edi
rolw $0x8, %di
movzwl 0xa(%rsp), %r8d
rolw $0x8, %r8w
movw %di, 0x20(%rsp)
movw %di, 0x28(%rsp)
movw %r8w, 0x14(%rsp)
movw %r8w, 0x2a(%rsp)
movzwl 0xc(%rsp), %r14d
movl %r14d, %edi
rolw $0x8, %di
movw %di, 0x18(%rsp)
movw %di, 0x2c(%rsp)
movzwl 0xe(%rsp), %r15d
movl %r15d, %edi
rolw $0x8, %di
movw %di, 0x16(%rsp)
movw %di, 0x2e(%rsp)
movl 0x10(%rsp), %edi
bswapl %edi
movq %rdi, 0x78(%rsp)
movl %edi, 0x30(%rsp)
xorl %edi, %edi
xorl %edx, 0x8(%rsp,%rdi,4)
imull %ecx, %edx
addl %esi, %edx
incq %rdi
cmpq $0x3, %rdi
jne 0x6b09
movl %eax, %edx
xorl $0xf0f0, %edx           # imm = 0xF0F0
xorl %esi, %esi
movl %eax, %r8d
movl %eax, %edi
imull %ecx, %edi
xorl %r8d, 0x8(%rsp,%rsi,4)
addl %edx, %edi
incq %rsi
movl %edi, %r8d
cmpq $0x3, %rsi
jne 0x6b2a
leaq 0x88(%rsp), %rbx
movq %rax, (%rbx)
movq %rbx, %rdi
callq 0x51f0
movq 0x56ce(%rip), %rdx      # 0xc228
leaq 0x90(%rsp), %rdi
movl $0x20, %esi
movq %rax, %rcx
callq 0x51b0
movl 0x56ff(%rip), %eax      # 0xc274
movq %rax, (%rbx)
movq %rbx, %rdi
callq 0x51f0
movq 0x56a1(%rip), %rdx      # 0xc228
leaq 0xb0(%rsp), %r12
movl $0x20, %esi
movq %r12, %rdi
movq %rax, %rcx
callq 0x51b0
movl $0x100, %esi            # imm = 0x100
cmpl %esi, %ebp
setb %cl
movzwl 0xa(%rsp), %ebx
movzwl %bx, %edi
cmpl %esi, %edi
setb %dl
movl $0x80, %eax
cmpl %esi, %ebp
movq %r14, 0x80(%rsp)
movl %edi, 0x4c(%rsp)
je 0x6c6c
andb %dl, %cl
jne 0x6c6c
leaq 0x1e01(%rip), %rdi      # 0x89df
callq 0x5070
movl 0x5687(%rip), %esi      # 0xc270
movl 0x4541(%rip), %eax      # 0xb130
movl %esi, %ecx
xorl $0xf0f0, %ecx           # imm = 0xF0F0
xorl %edx, %edx
movl %eax, %edi
imull %esi, %edi
xorl %esi, 0x8(%rsp,%rdx,4)
addl %ecx, %edi
incq %rdx
movl %edi, %esi
cmpq $0x3, %rdx
jne 0x6bf9
movl 0x10(%rsp), %r14d
xorl %eax, %eax
testb %r14b, %r14b
jne 0x6c6c
leaq 0x1dce(%rip), %rdi      # 0x89f0
callq 0x5070
leaq 0x28(%rsp), %rax
movzwl 0x20(%rsp), %ecx
movw %cx, (%rax)
rolw $0x8, %bx
movw %bx, 0x2(%rax)
movzwl 0x18(%rsp), %ecx
movw %cx, 0x4(%rax)
movzwl 0x16(%rsp), %ecx
movw %cx, 0x6(%rax)
bswapl %r14d
movq %rax, 0x38(%rsp)
movl %r14d, 0x8(%rax)
movl $0x10, %eax
movl %r14d, %ecx
movq %rcx, 0x78(%rsp)
movw %bx, 0x14(%rsp)
movl %ebp, 0x48(%rsp)
movl %ebp, %ecx
xorl $0x100, %ecx            # imm = 0x100
movl %eax, %edx
orl $0x4, %edx
movq %r15, %rbp
orw %r15w, %cx
cmovnel %eax, %edx
leaq 0x28(%rsp), %rax
movq 0x38(%rsp), %rbx
cmoveq %rax, %rbx
movq %rdx, %r14
testb $0x14, %dl
leaq 0x1b43(%rip), %rax      # 0x87e5
leaq 0x1b39(%rip), %rsi      # 0x87e2
cmoveq %rax, %rsi
leaq 0x90(%rsp), %rax
cmoveq %rax, %r12
leaq 0x1b00(%rip), %rdi      # 0x87c0
xorl %eax, %eax
callq 0x50c0
movq 0x5562(%rip), %rdi      # 0xc230
movl 0x559c(%rip), %edx      # 0xc270
movzwl (%rbx), %ecx
movzwl 0x2(%rbx), %r8d
movzwl 0x4(%rbx), %r9d
movzwl 0x6(%rbx), %r10d
movl 0x8(%rbx), %r11d
subq $0x8, %rsp
movq %r12, %rsi
xorl %eax, %eax
pushq %r11
pushq %r10
pushq %r9
callq 0x50c0
addq $0x20, %rsp
testw %r13w, %r13w
je 0x6d36
movq %rbx, %r15
movzwl %r13w, %esi
leaq 0x1ad2(%rip), %rdi      # 0x87e8
xorl %eax, %eax
callq 0x50c0
jmp 0x6d3e
movb $0x0, 0xd2(%rsp)
movw $0x2f2e, 0xd0(%rsp)     # imm = 0x2F2E
jmp 0x6932
movq %rbx, %r15
movzwl 0x6(%rbx), %r13d
movq 0x40(%rsp), %r12
movzwl %r13w, %ebx
cmpl $0x400f, %ebx           # imm = 0x400F
movq %r14, %r8
jle 0x6d86
cmpl $0x4211, %ebx           # imm = 0x4211
movq %r15, %r13
jg 0x6db4
cmpl $0x4010, %ebx           # imm = 0x4010
je 0x6e12
cmpl $0x4015, %ebx           # imm = 0x4015
je 0x6f1b
cmpl $0x4016, %ebx           # imm = 0x4016
je 0x6e12
jmp 0x6e41
cmpl $0x62, %ebx
movq %r15, %r13
jle 0x6e30
cmpl $0x63, %ebx
je 0x6f1b
cmpl $0x806, %ebx            # imm = 0x806
je 0x74fe
cmpl $0x2abb, %ebx           # imm = 0x2ABB
je 0x6e12
jmp 0x6e41
cmpl $0x4212, %ebx           # imm = 0x4212
je 0x6f1b
cmpl $0x610a, %ebx           # imm = 0x610A
je 0x6e12
cmpl $0xcccc, %ebx           # imm = 0xCCCC
jne 0x6e41
leaq 0x1cc0(%rip), %rdi      # 0x8a97
callq 0x5070
orl $0x111, %r14d           # imm = 0x111
leaq 0x548e(%rip), %rdi      # 0xc278
leaq 0x5497(%rip), %rsi      # 0xc288
leaq 0x1a2b(%rip), %rcx      # 0x8823
leaq 0xd0(%rsp), %rdx
movl %r14d, %r8d
callq 0x56dc
leaq 0x28(%rsp), %r13
jmp 0x6f5c
leaq 0x1c59(%rip), %rdi      # 0x8a72
callq 0x5070
movl %r14d, %eax
andl $-0x80, %eax
leal (%r14,%rax,2), %r14d
incl %r14d
jmp 0x6f37
testl %ebx, %ebx
je 0x6f0a
cmpl $0x25, %ebx
je 0x6f1b
leaq 0x1c73(%rip), %rdi      # 0x8abb
callq 0x5070
movq 0x53dc(%rip), %rdi      # 0xc230
movl 0x5416(%rip), %edx      # 0xc270
movl 0x10(%rsp), %r10d
subq $0x8, %rsp
xorl %r14d, %r14d
leaq 0x98(%rsp), %rsi
movl 0x50(%rsp), %ecx
movl 0x54(%rsp), %r8d
movq 0x88(%rsp), %r9
xorl %eax, %eax
pushq %r10
pushq %rbp
pushq %r9
callq 0x50c0
addq $0x20, %rsp
leaq 0x1c36(%rip), %rdi      # 0x8acc
callq 0x5070
movq 0x538e(%rip), %rdi      # 0xc230
movl 0x53cc(%rip), %edx      # 0xc274
movzwl 0x20(%rsp), %ecx
movzwl 0x14(%rsp), %r8d
movzwl 0x18(%rsp), %r9d
movzwl 0x16(%rsp), %r10d
subq $0x8, %rsp
leaq 0xb8(%rsp), %rsi
xorl %eax, %eax
pushq 0x80(%rsp)
pushq %r10
pushq %r9
callq 0x50c0
addq $0x20, %rsp
leaq 0x1976(%rip), %rdi      # 0x885e
movl %ebx, %esi
xorl %eax, %eax
callq 0x50c0
leaq 0x1be8(%rip), %rdi      # 0x8ae0
callq 0x5070
movq %r12, %rdi
callq 0x5090
jmp 0x68d6
movl %r8d, %eax
orl $0x20, %eax
testb $0x14, %r8b
cmovnel %r8d, %eax
movl %eax, %r8d
testb %r8b, %r8b
js 0x74be
leaq 0x1b47(%rip), %rdi      # 0x8a72
movq %r8, %r14
callq 0x5070
orl $0x1, %r14d
leaq 0x533a(%rip), %rdi      # 0xc278
leaq 0x5343(%rip), %rsi      # 0xc288
leaq 0x18e2(%rip), %rcx      # 0x882e
leaq 0xd0(%rsp), %rdx
movl %r14d, %r8d
callq 0x56dc
leaq 0x1912(%rip), %rdi      # 0x8875
movl %r14d, %esi
xorl %eax, %eax
movq %r14, %r15
callq 0x50c0
testb $0x1, %r15b
leaq 0x10c6(%rip), %rax      # 0x8041
leaq 0x1926(%rip), %rsi      # 0x88a8
cmoveq %rax, %rsi
testb $0x2, %r15b
leaq 0x1922(%rip), %rdx      # 0x88b3
cmoveq %rax, %rdx
testb $0x4, %r15b
leaq 0x191e(%rip), %rcx      # 0x88be
cmoveq %rax, %rcx
testb $0x8, %r15b
leaq 0x191a(%rip), %r8       # 0x88c9
cmoveq %rax, %r8
testb $0x10, %r15b
leaq 0x1916(%rip), %r9       # 0x88d4
cmoveq %rax, %r9
testb $0x20, %r15b
leaq 0x1911(%rip), %r10      # 0x88de
cmoveq %rax, %r10
testb $0x40, %r15b
leaq 0x190e(%rip), %r11      # 0x88ea
cmoveq %rax, %r11
testb %r15b, %r15b
leaq 0x190c(%rip), %rbx      # 0x88f6
cmovnsq %rax, %rbx
btl $0x8, %r15d
leaq 0x1907(%rip), %r14      # 0x8901
cmovaeq %rax, %r14
leaq 0x1880(%rip), %rdi      # 0x8885
xorl %eax, %eax
pushq %r14
pushq %rbx
pushq %r11
pushq %r10
callq 0x50c0
addq $0x20, %rsp
movzwl 0x4(%r13), %eax
movl %eax, %ebx
shll $0x4, %ebx
testb $0x2c, %r15b
movq %r15, 0x20(%rsp)
je 0x7139
leaq (%rax,%rax,4), %rax
leaq 0xc(,%rax,4), %rdi
callq 0x5170
movq %rax, %r14
movq %rbx, %rdi
callq 0x5170
movq %rax, %rbp
movl $0x4, %esi
movq %r12, %rdi
xorl %edx, %edx
callq 0x51a0
movzwl 0x4(%r13), %eax
leaq (%rax,%rax,4), %rax
leaq 0xc(,%rax,4), %rsi
movl $0x1, %edx
movq %r14, %rdi
movq %r12, %rcx
callq 0x5080
movzwl 0x4(%r13), %eax
testb %r15b, %r15b
jns 0x70d9
testb $0x14, %r15b
leaq 0x51e0(%rip), %rcx      # 0xc274
leaq 0x51d5(%rip), %rdx      # 0xc270
cmoveq %rdx, %rcx
movl (%rcx), %r8d
movl 0x4088(%rip), %ecx      # 0xb130
movl %r8d, %edx
xorl $0xf0f0, %edx           # imm = 0xF0F0
leaq (%rax,%rax,4), %rsi
leaq 0xc(,%rsi,4), %rsi
xorl %edi, %edi
movl %ecx, %r9d
imull %r8d, %r9d
xorl %r8d, (%r14,%rdi)
addl %edx, %r9d
addq $0x4, %rdi
movl %r9d, %r8d
cmpq %rdi, %rsi
jne 0x70bf
movq %r14, 0x18(%rsp)
movl $0x14, %r14d
leaq 0x1822(%rip), %rbx      # 0x890d
leaq 0x1a4b(%rip), %rdi      # 0x8b3d
testq %rax, %rax
je 0x7243
movq 0x18(%rsp), %rcx
addq $0x1c, %rcx
shll $0x4, %eax
xorl %edx, %edx
leaq -0x10(%rcx), %rsi
testb $0x14, %r15b
movq %rsi, (%rbp,%rdx)
movl (%rcx), %esi
movl %esi, %r8d
bswapl %r8d
cmovel %esi, %r8d
movl %r8d, 0x8(%rbp,%rdx)
addq $0x14, %rcx
addq $0x10, %rdx
cmpq %rdx, %rax
jne 0x7109
jmp 0x7243
leaq (%rax,%rax,2), %rax
leaq 0xc(,%rax,4), %rdi
callq 0x5170
movq %rax, %r14
movq %rbx, %rdi
callq 0x5170
movq %rax, %rbp
movq %r12, %rbx
leaq 0xc(%r14), %r12
testb $0x40, %r15b
cmovneq %r14, %r12
movl $0x4, %eax
movl $0x10, %esi
cmoveq %rax, %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x51a0
movzwl 0x4(%r13), %eax
leaq (%rax,%rax,2), %rax
leaq 0xc(,%rax,4), %rsi
movl $0x1, %edx
movq %r14, %rdi
movq %rbx, %rcx
callq 0x5080
movzwl 0x4(%r13), %eax
testb %r15b, %r15b
jns 0x71fa
testb $0x10, %r15b
leaq 0x50bf(%rip), %rcx      # 0xc274
leaq 0x50b4(%rip), %rdx      # 0xc270
cmoveq %rdx, %rcx
movl (%rcx), %r8d
movl 0x3f67(%rip), %ecx      # 0xb130
movl %r8d, %edx
xorl $0xf0f0, %edx           # imm = 0xF0F0
leaq (%rax,%rax,2), %rsi
leaq 0xc(,%rsi,4), %rsi
xorl %edi, %edi
movl %ecx, %r9d
imull %r8d, %r9d
xorl %r8d, (%r14,%rdi)
addl %edx, %r9d
addq $0x4, %rdi
movl %r9d, %r8d
cmpq %rdi, %rsi
jne 0x71e0
movq %r14, 0x18(%rsp)
movl $0xc, %r14d
leaq 0x1712(%rip), %rbx      # 0x891e
leaq 0x191b(%rip), %rdi      # 0x8b2e
testq %rax, %rax
je 0x7243
shll $0x4, %eax
xorl %ecx, %ecx
testb $0x10, %r15b
movq %r12, (%rbp,%rcx)
movl 0x8(%r12), %edx
movl %edx, %esi
bswapl %esi
cmovel %edx, %esi
movl %esi, 0x8(%rbp,%rcx)
addq $0xc, %r12
addq $0x10, %rcx
cmpq %rcx, %rax
jne 0x721d
callq 0x5070
leaq 0x13fb(%rip), %rsi      # 0x864a
movq %rbx, %rdi
callq 0x51c0
movq %rax, %rbx
movzwl 0x4(%r13), %esi
imulq %r14, %rsi
addq $0xc, %rsi
movl $0x1, %edx
movq 0x18(%rsp), %rdi
movq %rax, %rcx
callq 0x5230
movq %rbx, %rdi
callq 0x5090
leaq 0x18c2(%rip), %rdi      # 0x8b4a
callq 0x5070
cmpw $0x0, 0x4(%r13)
je 0x72d3
leaq 0x8(%rbp), %r12
leaq 0x1691(%rip), %rbx      # 0x8931
xorl %r14d, %r14d
movq -0x8(%r12), %rdx
movl (%r12), %ecx
movl %ecx, %r8d
shll $0xb, %r8d
movq %rbx, %rdi
movl %r14d, %esi
xorl %eax, %eax
callq 0x50c0
incq %r14
movzwl 0x4(%r13), %edx
addq $0x10, %r12
cmpq %rdx, %r14
jb 0x72a3
jmp 0x72d5
xorl %edx, %edx
movq 0x40(%rsp), %rdi
movq %rbp, %rsi
movq 0x20(%rsp), %rcx
callq 0x5ccf
movq %rax, %r12
cmpw $0x0, 0x4(%r13)
je 0x7463
movq %r13, 0x38(%rsp)
xorl %r14d, %r14d
leaq 0x50(%rsp), %rbx
xorl %r13d, %r13d
movq 0x20(%rsp), %r15
movq (%rbp,%r14), %rdi
movl $0x1ff, %esi            # imm = 0x1FF
callq 0x5060
movq 0x20(%rsp), %rax
testb $0x40, %al
jne 0x7348
testb $0x10, %al
jne 0x7359
testb $0x1, %al
jne 0x7368
testb $0x2, %al
jne 0x7379
testb $0x4, %al
jne 0x738a
testb $0x8, %al
je 0x7399
movw $0x2d, 0x54(%rsp)
movl $0x32656f7a, 0x50(%rsp) # imm = 0x32656F7A
jmp 0x7399
movabsq $0x2d326c61697274, %rax # imm = 0x2D326C61697274
movq %rax, 0x50(%rsp)
jmp 0x7399
movb $0x0, 0x54(%rsp)
movl $0x2d737474, 0x50(%rsp) # imm = 0x2D737474
jmp 0x7399
movw $0x2d, 0x54(%rsp)
movl $0x3273676d, 0x50(%rsp) # imm = 0x3273676D
jmp 0x7399
movw $0x2d, 0x54(%rsp)
movl $0x3373676d, 0x50(%rsp) # imm = 0x3373676D
jmp 0x7399
movw $0x2d, 0x54(%rsp)
movl $0x3473676d, 0x50(%rsp) # imm = 0x3473676D
movq (%rbp,%r14), %rsi
movq %rbx, %rdi
callq 0x5210
leaq 0x4ed3(%rip), %rdi      # 0xc280
leaq 0x4ed8(%rip), %rsi      # 0xc28c
leaq 0xd0(%rsp), %rdx
movq %rbx, %rcx
movl %r15d, %r8d
callq 0x56dc
movl (%r12,%r14), %esi
movq 0x8(%r12,%r14), %rdx
movq (%rbp,%r14), %rcx
movl 0x8(%rbp,%r14), %r8d
movq 0x40(%rsp), %rdi
movl %r15d, %r9d
callq 0x5e70
movq 0x4e92(%rip), %rdi      # 0xc280
testq %rdi, %rdi
je 0x73f8
callq 0x5030
movq $0x0, 0x4e7d(%rip) # 0xc280
movl 0x4e83(%rip), %eax      # 0xc28c
testl %eax, %eax
jle 0x7413
subl %eax, 0x4e7d(%rip)      # 0xc290
movl $0x0, 0x4e6f(%rip)      # 0xc28c
incq %r13
movq 0x38(%rsp), %rax
movzwl 0x4(%rax), %eax
addq $0x10, %r14
cmpq %rax, %r13
jb 0x730b
testw %ax, %ax
movq 0x38(%rsp), %r13
je 0x7463
movq %r12, %rbx
addq $0x8, %rbx
xorl %r14d, %r14d
movq (%rbx), %rdi
callq 0x5030
incq %r14
movzwl 0x4(%r13), %eax
addq $0x10, %rbx
cmpq %rax, %r14
jb 0x744a
movq 0x18(%rsp), %rdi
callq 0x5030
movq %r12, %rdi
callq 0x5030
movq %rbp, %rdi
callq 0x5030
testb $0x40, 0x20(%rsp)
je 0x748c
movq %r13, %rdi
callq 0x5030
movq 0x4de5(%rip), %rdi      # 0xc278
testq %rdi, %rdi
movq 0x40(%rsp), %rbx
je 0x74a2
callq 0x5030
leaq 0x16ac(%rip), %rdi      # 0x8b55
callq 0x5070
movq %rbx, %rdi
callq 0x5090
xorl %r14d, %r14d
jmp 0x68d6
testb $0x14, %r8b
je 0x752b
cmpl $0x100, 0x48(%rsp)      # imm = 0x100
jne 0x755b
orl $0x104, %r8d            # imm = 0x104
leaq 0x4d98(%rip), %rdi      # 0xc278
leaq 0x4da1(%rip), %rsi      # 0xc288
leaq 0x134c(%rip), %rcx      # 0x883a
leaq 0xd0(%rsp), %rdx
movq %r8, %r14
jmp 0x6f57
leaq 0x1509(%rip), %rdi      # 0x8a0e
callq 0x5070
orl $0x108, %r14d           # imm = 0x108
leaq 0x4d60(%rip), %rdi      # 0xc278
leaq 0x4d69(%rip), %rsi      # 0xc288
leaq 0x132c(%rip), %rcx      # 0x8852
jmp 0x6f4c
leaq 0x1501(%rip), %rdi      # 0x8a33
movq %r8, %r14
callq 0x5070
orl $0x102, %r14d           # imm = 0x102
leaq 0x4d30(%rip), %rdi      # 0xc278
leaq 0x4d39(%rip), %rsi      # 0xc288
leaq 0x12f0(%rip), %rcx      # 0x8846
jmp 0x6f4c
leaq 0x14f6(%rip), %rdi      # 0x8a58
jmp 0x68cb