// File: /workspace/github_c_makefile_star2_O1/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, 0x20(%rsp)
movq %rax, 0x18(%rsp)
leaq 0xd0(%rsp), %rdi
movl $0x1000, %edx           # imm = 0x1000
xorl %esi, %esi
callq 0x5100
cmpl $0x1, %ebp
jg 0x68c5
movq (%rbx), %rsi
leaq 0x1e80(%rip), %rdi      # 0x873c
xorl %eax, %eax
callq 0x50c0
jmp 0x6901
cmpl $0x3, %ebp
jne 0x68df
movq 0x10(%rbx), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x51f0
movq %rax, %r13
jmp 0x68e2
xorl %r13d, %r13d
movq (%rbx), %r14
movq %r14, %rdi
callq 0x50b0
cmpq $0x1001, %rax           # imm = 0x1001
jb 0x691c
leaq 0x225f(%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 0x695f
leaq 0xd0(%rsp), %rdi
movl $0x5c, %esi
callq 0x50f0
testq %rax, %rax
je 0x6d3c
movb $0x0, (%r14)
movq 0x8(%rbx), %rdi
leaq 0x1e02(%rip), %rsi      # 0x8770
callq 0x51b0
testq %rax, %rax
je 0x6a8b
movq %rax, %r12
leaq 0x58ea(%rip), %rdi      # 0xc270
movl $0x4, %esi
movl $0x1, %edx
movq %rax, %rcx
callq 0x5080
movl 0x58d2(%rip), %eax      # 0xc270
bswapl %eax
movl %eax, 0x58ce(%rip)      # 0xc274
leaq 0x8(%rsp), %rdi
movl $0xc, %esi
movl $0x1, %edx
movq %rdi, 0x38(%rsp)
movq %r12, %rcx
callq 0x5080
movl 0x58a8(%rip), %eax      # 0xc270
cmpq $0x1, %rax
movq %r12, 0x30(%rsp)
jne 0x6a9b
leaq 0x589a(%rip), %rdi      # 0xc278
leaq 0x1d8e(%rip), %rdx      # 0x8773
leaq -0x169a(%rip), %r8      # 0x5352
leaq 0xd0(%rsp), %rsi
movl $0xa, %ecx
callq 0x53c8
movl %eax, 0x5884(%rip)      # 0xc288
testl %eax, %eax
jle 0x6a0e
addl %eax, 0x5882(%rip)      # 0xc290
movl $0xc, %edi
callq 0x5160
movq %rax, %r13
movl 0x8(%rsp), %ebx
leaq 0x88(%rsp), %rdi
movq %rbx, (%rdi)
callq 0x51e0
movq 0x57f2(%rip), %rdx      # 0xc228
leaq 0x90(%rsp), %r14
movl $0x20, %esi
movq %r14, %rdi
movq %rax, %rcx
callq 0x51a0
leaq 0x20a7(%rip), %rdi      # 0x8afc
callq 0x5070
movl 0xc(%rsp), %ebp
movl 0x10(%rsp), %r9d
leaq 0x1d17(%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 0x6f7d
movq 0x8(%rbx), %rsi
leaq 0x1be3(%rip), %rdi      # 0x8679
jmp 0x68bc
movl 0x57d3(%rip), %edx      # 0xc274
movl 0x4689(%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 0x6ab4
movzwl 0x8(%rsp), %edi
movl %edi, 0x28(%rsp)
movl %edi, %r8d
rolw $0x8, %r8w
movzwl 0xa(%rsp), %edi
rolw $0x8, %di
movw %r8w, 0x40(%rsp)
movw %r8w, 0x18(%rsp)
movw %di, 0x1a(%rsp)
movzwl 0xc(%rsp), %r14d
movl %r14d, %r15d
rolw $0x8, %r15w
movw %r15w, 0x1c(%rsp)
movzwl 0xe(%rsp), %edi
movq %rdi, 0x78(%rsp)
movl %edi, %r12d
rolw $0x8, %r12w
movw %r12w, 0x1e(%rsp)
movl 0x10(%rsp), %edi
bswapl %edi
movl %edi, 0x20(%rsp)
xorl %edi, %edi
xorl %edx, 0x8(%rsp,%rdi,4)
imull %ecx, %edx
addl %esi, %edx
incq %rdi
cmpq $0x3, %rdi
jne 0x6b32
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 0x6b53
leaq 0x88(%rsp), %rbx
movq %rax, (%rbx)
movq %rbx, %rdi
callq 0x51e0
movq 0x56a5(%rip), %rdx      # 0xc228
leaq 0x90(%rsp), %rdi
movl $0x20, %esi
movq %rax, %rcx
callq 0x51a0
movl 0x56d6(%rip), %eax      # 0xc274
movq %rax, (%rbx)
movq %rbx, %rdi
callq 0x51e0
movq 0x5678(%rip), %rdx      # 0xc228
leaq 0xb0(%rsp), %rbp
movl $0x20, %esi
movq %rbp, %rdi
movq %rax, %rcx
callq 0x51a0
movl $0x100, %esi            # imm = 0x100
movl 0x28(%rsp), %edi
cmpl %esi, %edi
setb %cl
movzwl 0xa(%rsp), %ebx
movzwl %bx, %r8d
cmpl %esi, %r8d
setb %dl
movl $0x80, %eax
cmpl %esi, %edi
movq %r14, 0x80(%rsp)
movl %r8d, 0x4c(%rsp)
je 0x6c87
andb %dl, %cl
jne 0x6c87
leaq 0x1dd1(%rip), %rdi      # 0x89df
callq 0x5070
movl 0x5657(%rip), %esi      # 0xc270
movl 0x4511(%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 0x6c29
movl 0x10(%rsp), %r14d
xorl %eax, %eax
testb %r14b, %r14b
jne 0x6c87
leaq 0x1d9e(%rip), %rdi      # 0x89f0
callq 0x5070
leaq 0x18(%rsp), %rax
movzwl 0x40(%rsp), %ecx
movw %cx, (%rax)
rolw $0x8, %bx
movw %bx, 0x2(%rax)
movw %r15w, 0x4(%rax)
movw %r12w, 0x6(%rax)
bswapl %r14d
movq %rax, 0x38(%rsp)
movl %r14d, 0x8(%rax)
movl $0x10, %eax
leaq 0x18(%rsp), %rdi
movzwl 0x6(%rdi), %esi
movzwl (%rdi), %ebx
movl %ebx, %ecx
xorl $0x1, %ecx
movl %eax, %edx
orl $0x4, %edx
movq %rsi, 0x40(%rsp)
orw %si, %cx
cmovnel %eax, %edx
movq 0x38(%rsp), %r15
cmoveq %rdi, %r15
movq %rdx, %r14
testb $0x14, %dl
leaq 0x1b27(%rip), %rax      # 0x87e5
leaq 0x1b1d(%rip), %rsi      # 0x87e2
cmoveq %rax, %rsi
leaq 0x90(%rsp), %rax
cmoveq %rax, %rbp
leaq 0x1ae4(%rip), %rdi      # 0x87c0
xorl %eax, %eax
callq 0x50c0
movq 0x5546(%rip), %rdi      # 0xc230
movl 0x5580(%rip), %edx      # 0xc270
movzwl (%r15), %ecx
movzwl 0x2(%r15), %r8d
movzwl 0x4(%r15), %r9d
movzwl 0x6(%r15), %r10d
movl 0x8(%r15), %r11d
subq $0x8, %rsp
movq %rbp, %rsi
xorl %eax, %eax
pushq %r11
pushq %r10
pushq %r9
callq 0x50c0
addq $0x20, %rsp
testw %r13w, %r13w
je 0x6d53
movq %r15, %rbp
movzwl %r13w, %esi
leaq 0x1ab5(%rip), %rdi      # 0x87e8
xorl %eax, %eax
callq 0x50c0
jmp 0x6d5b
movb $0x0, 0xd2(%rsp)
movw $0x2f2e, 0xd0(%rsp)     # imm = 0x2F2E
jmp 0x6963
movq %r15, %rbp
movzwl 0x6(%r15), %r13d
movq 0x30(%rsp), %r12
movzwl %bx, %r15d
movzwl %r13w, %ebx
cmpl $0x400f, %ebx           # imm = 0x400F
movq %r14, %r8
jle 0x6da7
cmpl $0x4211, %ebx           # imm = 0x4211
movq %rbp, %r13
jg 0x6dd5
cmpl $0x4010, %ebx           # imm = 0x4010
je 0x6e33
cmpl $0x4015, %ebx           # imm = 0x4015
je 0x6f3c
cmpl $0x4016, %ebx           # imm = 0x4016
je 0x6e33
jmp 0x6e62
cmpl $0x62, %ebx
movq %rbp, %r13
jle 0x6e51
cmpl $0x63, %ebx
je 0x6f3c
cmpl $0x806, %ebx            # imm = 0x806
je 0x7522
cmpl $0x2abb, %ebx           # imm = 0x2ABB
je 0x6e33
jmp 0x6e62
cmpl $0x4212, %ebx           # imm = 0x4212
je 0x6f3c
cmpl $0x610a, %ebx           # imm = 0x610A
je 0x6e33
cmpl $0xcccc, %ebx           # imm = 0xCCCC
jne 0x6e62
leaq 0x1c9f(%rip), %rdi      # 0x8a97
callq 0x5070
orl $0x111, %r14d           # imm = 0x111
leaq 0x546d(%rip), %rdi      # 0xc278
leaq 0x5476(%rip), %rsi      # 0xc288
leaq 0x1a0a(%rip), %rcx      # 0x8823
leaq 0xd0(%rsp), %rdx
movl %r14d, %r8d
callq 0x56ac
leaq 0x18(%rsp), %r13
jmp 0x6f7d
leaq 0x1c38(%rip), %rdi      # 0x8a72
callq 0x5070
movl %r14d, %eax
andl $-0x80, %eax
leal (%r14,%rax,2), %r14d
incl %r14d
jmp 0x6f58
testl %ebx, %ebx
je 0x6f2b
cmpl $0x25, %ebx
je 0x6f3c
leaq 0x1c52(%rip), %rdi      # 0x8abb
callq 0x5070
movq 0x53bb(%rip), %rdi      # 0xc230
movl 0x53f5(%rip), %edx      # 0xc270
movl 0x10(%rsp), %r10d
subq $0x8, %rsp
xorl %r14d, %r14d
leaq 0x98(%rsp), %rsi
movl 0x30(%rsp), %ecx
movl 0x54(%rsp), %r8d
movq 0x88(%rsp), %r9
xorl %eax, %eax
pushq %r10
pushq 0x88(%rsp)
pushq %r9
callq 0x50c0
addq $0x20, %rsp
leaq 0x1c0f(%rip), %rdi      # 0x8acc
callq 0x5070
movq 0x5367(%rip), %rdi      # 0xc230
movl 0x53a5(%rip), %edx      # 0xc274
movzwl 0x1a(%rsp), %r8d
movzwl 0x1c(%rsp), %r9d
movl 0x20(%rsp), %r10d
subq $0x8, %rsp
leaq 0xb8(%rsp), %rsi
movl %r15d, %ecx
xorl %eax, %eax
pushq %r10
pushq 0x50(%rsp)
pushq %r9
callq 0x50c0
addq $0x20, %rsp
leaq 0x1955(%rip), %rdi      # 0x885e
movl %ebx, %esi
xorl %eax, %eax
callq 0x50c0
leaq 0x1bc7(%rip), %rdi      # 0x8ae0
callq 0x5070
movq %r12, %rdi
callq 0x5090
jmp 0x6907
movl %r8d, %eax
orl $0x20, %eax
testb $0x14, %r8b
cmovnel %r8d, %eax
movl %eax, %r8d
testb %r8b, %r8b
js 0x74e6
leaq 0x1b26(%rip), %rdi      # 0x8a72
movq %r8, %r14
callq 0x5070
orl $0x1, %r14d
leaq 0x5319(%rip), %rdi      # 0xc278
leaq 0x5322(%rip), %rsi      # 0xc288
leaq 0x18c1(%rip), %rcx      # 0x882e
leaq 0xd0(%rsp), %rdx
movl %r14d, %r8d
callq 0x56ac
leaq 0x18f1(%rip), %rdi      # 0x8875
movl %r14d, %esi
xorl %eax, %eax
movq %r14, %r15
callq 0x50c0
testb $0x1, %r15b
leaq 0x10a5(%rip), %rax      # 0x8041
leaq 0x1905(%rip), %rsi      # 0x88a8
cmoveq %rax, %rsi
testb $0x2, %r15b
leaq 0x1901(%rip), %rdx      # 0x88b3
cmoveq %rax, %rdx
testb $0x4, %r15b
leaq 0x18fd(%rip), %rcx      # 0x88be
cmoveq %rax, %rcx
testb $0x8, %r15b
leaq 0x18f9(%rip), %r8       # 0x88c9
cmoveq %rax, %r8
testb $0x10, %r15b
leaq 0x18f5(%rip), %r9       # 0x88d4
cmoveq %rax, %r9
testb $0x20, %r15b
leaq 0x18f0(%rip), %r10      # 0x88de
cmoveq %rax, %r10
testb $0x40, %r15b
leaq 0x18ed(%rip), %r11      # 0x88ea
cmoveq %rax, %r11
testb %r15b, %r15b
leaq 0x18eb(%rip), %rbx      # 0x88f6
cmovnsq %rax, %rbx
btl $0x8, %r15d
leaq 0x18e6(%rip), %r14      # 0x8901
cmovaeq %rax, %r14
leaq 0x185f(%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, 0x38(%rsp)
je 0x715d
leaq (%rax,%rax,4), %rax
leaq 0xc(,%rax,4), %rdi
callq 0x5160
movq %rax, %r14
movq %rbx, %rdi
callq 0x5160
movq %rax, %rbp
movl $0x4, %esi
movq %r12, %rdi
xorl %edx, %edx
callq 0x5190
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
testb %r15b, %r15b
jns 0x70f8
testb $0x14, %r15b
leaq 0x51c4(%rip), %rax      # 0xc274
leaq 0x51b9(%rip), %rcx      # 0xc270
cmoveq %rcx, %rax
movzwl 0x4(%r13), %edx
movl (%rax), %edi
movl 0x4068(%rip), %eax      # 0xb130
movl %edi, %ecx
xorl $0xf0f0, %ecx           # imm = 0xF0F0
leaq (%rdx,%rdx,4), %rdx
leaq 0xc(,%rdx,4), %rdx
xorl %esi, %esi
movl %eax, %r8d
imull %edi, %r8d
xorl %edi, (%r14,%rsi)
addl %ecx, %r8d
addq $0x4, %rsi
movl %r8d, %edi
cmpq %rsi, %rdx
jne 0x70de
movq %r14, 0x28(%rsp)
movzwl 0x4(%r13), %eax
movl $0x14, %r14d
leaq 0x17fe(%rip), %rbx      # 0x890d
leaq 0x1a27(%rip), %rdi      # 0x8b3d
testq %rax, %rax
je 0x726f
movq 0x28(%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 0x712d
jmp 0x726f
leaq (%rax,%rax,2), %rax
leaq 0xc(,%rax,4), %rdi
callq 0x5160
movq %rax, %r14
movq %rbx, %rdi
callq 0x5160
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 0x5190
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
testb %r15b, %r15b
jns 0x721c
testb $0x10, %r15b
leaq 0x50a0(%rip), %rax      # 0xc274
leaq 0x5095(%rip), %rcx      # 0xc270
cmoveq %rcx, %rax
movzwl 0x4(%r13), %edx
movl (%rax), %edi
movl 0x3f44(%rip), %eax      # 0xb130
movl %edi, %ecx
xorl $0xf0f0, %ecx           # imm = 0xF0F0
leaq (%rdx,%rdx,2), %rdx
leaq 0xc(,%rdx,4), %rdx
xorl %esi, %esi
movl %eax, %r8d
imull %edi, %r8d
xorl %edi, (%r14,%rsi)
addl %ecx, %r8d
addq $0x4, %rsi
movl %r8d, %edi
cmpq %rsi, %rdx
jne 0x7202
movq %r14, 0x28(%rsp)
movzwl 0x4(%r13), %eax
movl $0xc, %r14d
leaq 0x16eb(%rip), %rbx      # 0x891e
leaq 0x18f4(%rip), %rdi      # 0x8b2e
testq %rax, %rax
je 0x726a
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 0x7244
movq 0x30(%rsp), %r12
callq 0x5070
leaq 0x13cf(%rip), %rsi      # 0x864a
movq %rbx, %rdi
callq 0x51b0
movq %rax, %rbx
movzwl 0x4(%r13), %esi
imulq %r14, %rsi
addq $0xc, %rsi
movl $0x1, %edx
movq 0x28(%rsp), %rdi
movq %rax, %rcx
callq 0x5220
movq %rbx, %rdi
callq 0x5090
leaq 0x1896(%rip), %rdi      # 0x8b4a
callq 0x5070
movzwl 0x4(%r13), %eax
testw %ax, %ax
je 0x7304
leaq 0x8(%rbp), %r12
leaq 0x1663(%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), %eax
addq $0x10, %r12
cmpq %rax, %r14
jb 0x72d1
movq 0x30(%rsp), %r12
movzwl %ax, %edx
movq %r12, %rdi
movq %rbp, %rsi
movq 0x38(%rsp), %rcx
callq 0x5cf0
movq %rax, %r12
movq %r13, %r15
cmpw $0x0, 0x4(%r13)
je 0x7460
xorl %r14d, %r14d
xorl %r13d, %r13d
movq (%rbp,%r14), %rdi
movl $0x1ff, %esi            # imm = 0x1FF
callq 0x5060
movq 0x38(%rsp), %rax
testb $0x40, %al
jne 0x736c
testb $0x10, %al
jne 0x737d
testb $0x1, %al
jne 0x738c
testb $0x2, %al
jne 0x739d
testb $0x4, %al
jne 0x73ae
testb $0x8, %al
je 0x73bd
movw $0x2d, 0x54(%rsp)
movl $0x32656f7a, 0x50(%rsp) # imm = 0x32656F7A
jmp 0x73bd
movabsq $0x2d326c61697274, %rax # imm = 0x2D326C61697274
movq %rax, 0x50(%rsp)
jmp 0x73bd
movb $0x0, 0x54(%rsp)
movl $0x2d737474, 0x50(%rsp) # imm = 0x2D737474
jmp 0x73bd
movw $0x2d, 0x54(%rsp)
movl $0x3273676d, 0x50(%rsp) # imm = 0x3273676D
jmp 0x73bd
movw $0x2d, 0x54(%rsp)
movl $0x3373676d, 0x50(%rsp) # imm = 0x3373676D
jmp 0x73bd
movw $0x2d, 0x54(%rsp)
movl $0x3473676d, 0x50(%rsp) # imm = 0x3473676D
movq (%rbp,%r14), %rsi
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0x5200
leaq 0x4eaa(%rip), %rdi      # 0xc280
leaq 0x4eaf(%rip), %rsi      # 0xc28c
leaq 0xd0(%rsp), %rdx
movq %rbx, %rcx
movq 0x38(%rsp), %rbx
movl %ebx, %r8d
callq 0x56ac
movl (%r12,%r14), %esi
movq 0x8(%r12,%r14), %rdx
movq (%rbp,%r14), %rcx
movl 0x8(%rbp,%r14), %r8d
movq 0x30(%rsp), %rdi
movl %ebx, %r9d
callq 0x5e97
movq 0x4e64(%rip), %rdi      # 0xc280
testq %rdi, %rdi
je 0x7426
callq 0x5030
movq $0x0, 0x4e4f(%rip) # 0xc280
movl 0x4e55(%rip), %eax      # 0xc28c
testl %eax, %eax
jle 0x7441
subl %eax, 0x4e4f(%rip)      # 0xc290
movl $0x0, 0x4e41(%rip)      # 0xc28c
incq %r13
movzwl 0x4(%r15), %eax
addq $0x10, %r14
cmpq %rax, %r13
jb 0x732f
cmpw $0x0, 0x4(%r15)
je 0x748b
movq %r12, %rbx
addq $0x8, %rbx
xorl %r14d, %r14d
movq (%rbx), %rdi
callq 0x5030
incq %r14
movzwl 0x4(%r15), %eax
addq $0x10, %rbx
cmpq %rax, %r14
jb 0x7472
movq 0x28(%rsp), %rdi
callq 0x5030
movq %r12, %rdi
callq 0x5030
movq %rbp, %rdi
callq 0x5030
testb $0x40, 0x38(%rsp)
je 0x74b4
movq %r15, %rdi
callq 0x5030
movq 0x4dbd(%rip), %rdi      # 0xc278
testq %rdi, %rdi
movq 0x30(%rsp), %rbx
je 0x74ca
callq 0x5030
leaq 0x1684(%rip), %rdi      # 0x8b55
callq 0x5070
movq %rbx, %rdi
callq 0x5090
xorl %r14d, %r14d
jmp 0x6907
testb $0x14, %r8b
je 0x754f
cmpl $0x1, %r15d
jne 0x757f
orl $0x104, %r8d            # imm = 0x104
leaq 0x4d74(%rip), %rdi      # 0xc278
leaq 0x4d7d(%rip), %rsi      # 0xc288
leaq 0x1328(%rip), %rcx      # 0x883a
leaq 0xd0(%rsp), %rdx
movq %r8, %r14
jmp 0x6f78
leaq 0x14e5(%rip), %rdi      # 0x8a0e
callq 0x5070
orl $0x108, %r14d           # imm = 0x108
leaq 0x4d3c(%rip), %rdi      # 0xc278
leaq 0x4d45(%rip), %rsi      # 0xc288
leaq 0x1308(%rip), %rcx      # 0x8852
jmp 0x6f6d
leaq 0x14dd(%rip), %rdi      # 0x8a33
movq %r8, %r14
callq 0x5070
orl $0x102, %r14d           # imm = 0x102
leaq 0x4d0c(%rip), %rdi      # 0xc278
leaq 0x4d15(%rip), %rsi      # 0xc288
leaq 0x12cc(%rip), %rcx      # 0x8846
jmp 0x6f6d
leaq 0x14d2(%rip), %rdi      # 0x8a58
jmp 0x68fc