// File: /workspace/github_c_makefile_star2_O2/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 $0x10c8, %rsp           # imm = 0x10C8
andl $0x0, 0x10(%rsp)
andq $0x0, 0x8(%rsp)
movq %rsi, %rbx
andl $0x0, 0x30(%rsp)
movl %edi, %ebp
andq $0x0, 0x28(%rsp)
leaq 0xc0(%rsp), %rdi
movl $0x1000, %edx           # imm = 0x1000
xorl %esi, %esi
callq 0x5100
cmpl $0x1, %ebp
jg 0x6700
movq (%rbx), %rsi
leaq 0x2045(%rip), %rdi      # 0x873c
xorl %eax, %eax
callq 0x50c0
jmp 0x673a
cmpl $0x3, %ebp
jne 0x6718
movq 0x10(%rbx), %rdi
pushq $0x10
popq %rdx
xorl %esi, %esi
callq 0x5200
movq %rax, %r13
jmp 0x671b
xorl %r13d, %r13d
movq (%rbx), %r14
movq %r14, %rdi
callq 0x50b0
cmpq $0x1001, %rax           # imm = 0x1001
jb 0x6751
leaq 0x2426(%rip), %rdi      # 0x8b5b
callq 0x5070
pushq $0x1
popq %rbp
movl %ebp, %eax
addq $0x10c8, %rsp           # imm = 0x10C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xc0(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x5050
pushq $0x2f
popq %rsi
movq %r15, %rdi
callq 0x50f0
movq %rax, %r14
testq %rax, %rax
jne 0x6790
leaq 0xc0(%rsp), %rdi
pushq $0x5c
popq %rsi
callq 0x50f0
testq %rax, %rax
je 0x6aee
movb $0x0, (%r14)
movq 0x8(%rbx), %rdi
leaq 0x1fd1(%rip), %rsi      # 0x8770
callq 0x51c0
testq %rax, %rax
je 0x68a1
movq %rax, %r14
leaq 0x5ab9(%rip), %rdi      # 0xc270
pushq $0x4
popq %rsi
pushq $0x1
popq %rbx
movq %rbx, %rdx
movq %rax, %rcx
callq 0x5080
movl 0x5aa2(%rip), %eax      # 0xc270
bswapl %eax
movl %eax, 0x5a9e(%rip)      # 0xc274
leaq 0x8(%rsp), %r12
pushq $0xc
popq %rsi
movq %r12, %rdi
movq %rbx, %rdx
movq %r14, 0x40(%rsp)
movq %r14, %rcx
callq 0x5080
movl 0x5a78(%rip), %r14d     # 0xc270
cmpq $0x1, %r14
jne 0x68b1
leaq 0x5a6f(%rip), %rdi      # 0xc278
leaq 0x5a78(%rip), %rsi      # 0xc288
leaq 0x1f5c(%rip), %rcx      # 0x8773
leaq 0xc0(%rsp), %rdx
pushq $0x41
popq %r15
movl %r15d, %r8d
callq 0x5684
pushq $0xc
popq %rdi
callq 0x5170
movq %rax, %r12
movl 0x8(%rsp), %ebx
leaq 0x78(%rsp), %rdi
movq %rbx, (%rdi)
callq 0x51f0
movq 0x59da(%rip), %rdx      # 0xc228
leaq 0x80(%rsp), %r14
pushq $0x20
popq %rsi
movq %r14, %rdi
movq %rax, %rcx
callq 0x51b0
leaq 0x2291(%rip), %rdi      # 0x8afc
callq 0x5070
movl 0xc(%rsp), %ebp
movl 0x10(%rsp), %r9d
leaq 0x1f01(%rip), %rdi      # 0x8781
movq %r14, %rsi
movl %ebx, %edx
movl %ebp, %ecx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x50c0
movw %bp, 0x4(%r12)
movq 0x40(%rsp), %rbp
jmp 0x6c65
movq 0x8(%rbx), %rsi
leaq 0x1dcd(%rip), %rdi      # 0x8679
jmp 0x66f7
pushq $0x3
popq %rbx
pushq $0x4
popq %rbp
movq %r12, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x5a84
movzwl 0x8(%rsp), %r15d
movl %r15d, %eax
rolw $0x8, %ax
movzwl 0xa(%rsp), %ecx
movl %eax, 0x18(%rsp)
movw %ax, 0x28(%rsp)
rolw $0x8, %cx
movl %ecx, 0x38(%rsp)
movw %cx, 0x2a(%rsp)
movzwl 0xc(%rsp), %eax
rolw $0x8, %ax
movl %eax, 0x4c(%rsp)
movw %ax, 0x2c(%rsp)
movzwl 0xe(%rsp), %eax
rolw $0x8, %ax
movl %eax, 0x20(%rsp)
movw %ax, 0x2e(%rsp)
movl 0x10(%rsp), %eax
bswapl %eax
movq %rax, 0x70(%rsp)
movl %eax, 0x30(%rsp)
movq %r12, %rdi
movl %ebx, %esi
movl %ebp, %edx
callq 0x5a84
xorl %ebp, %ebp
movq %r12, %rdi
movl %ebx, %esi
xorl %edx, %edx
callq 0x5a84
leaq 0x78(%rsp), %rbx
movq %r14, (%rbx)
movq %rbx, %rdi
callq 0x51f0
movq 0x58d9(%rip), %rdx      # 0xc228
leaq 0x80(%rsp), %rdi
pushq $0x20
popq %r14
movq %r14, %rsi
movq %rax, %rcx
callq 0x51b0
movl 0x5908(%rip), %eax      # 0xc274
movq %rax, (%rbx)
movq %rbx, %rdi
callq 0x51f0
movq 0x58aa(%rip), %rdx      # 0xc228
leaq 0xa0(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
movq %rax, %rcx
callq 0x51b0
movw $0x100, %ax             # imm = 0x100
cmpw %ax, 0x8(%rsp)
setb %cl
cmpw %ax, 0xa(%rsp)
setb %dl
andb %cl, %dl
cmpw %ax, %r15w
sete %al
orb %dl, %al
je 0x69c4
movl $0x80, %ebp
leaq 0x8(%rsp), %r15
jmp 0x6a49
leaq 0x2014(%rip), %rdi      # 0x89df
callq 0x5070
leaq 0x8(%rsp), %r15
pushq $0x3
popq %rsi
movq %r15, %rdi
xorl %edx, %edx
callq 0x5a84
movl 0x8(%r15), %ebx
testb %bl, %bl
jne 0x6a49
leaq 0x1fff(%rip), %rdi      # 0x89f0
callq 0x5070
movq 0x8(%rsp), %xmm0
movdqa %xmm0, %xmm1
psrlw $0x8, %xmm1
psllw $0x8, %xmm0
por %xmm1, %xmm0
leaq 0x28(%rsp), %r15
movq %xmm0, (%r15)
bswapl %ebx
movl %ebx, 0x8(%r15)
movd %xmm0, 0x18(%rsp)
pextrw $0x1, %xmm0, %eax
movl %eax, 0x38(%rsp)
pextrw $0x2, %xmm0, %eax
movl %eax, 0x4c(%rsp)
pextrw $0x3, %xmm0, %eax
movl %eax, 0x20(%rsp)
pushq $0x10
popq %rbp
movl %ebx, %eax
movq %rax, 0x70(%rsp)
movl 0x18(%rsp), %eax
xorl $0x1, %eax
movl %ebp, %ecx
orl $0x4, %ecx
orw 0x20(%rsp), %ax
cmovnel %ebp, %ecx
leaq 0x28(%rsp), %rax
cmoveq %rax, %r15
movq %rcx, %r14
testb $0x14, %cl
leaq 0x1d72(%rip), %rax      # 0x87e5
leaq 0x1d68(%rip), %rsi      # 0x87e2
cmoveq %rax, %rsi
leaq 0x80(%rsp), %rax
cmoveq %rax, %r12
leaq 0x1d2f(%rip), %rdi      # 0x87c0
xorl %eax, %eax
callq 0x50c0
movq 0x5791(%rip), %rdi      # 0xc230
movl 0x57cb(%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 %r12, %rsi
xorl %eax, %eax
pushq %r11
pushq %r10
pushq %r9
callq 0x50c0
addq $0x20, %rsp
testw %r13w, %r13w
je 0x6b05
movzwl %r13w, %esi
leaq 0x1d03(%rip), %rdi      # 0x87e8
xorl %eax, %eax
callq 0x50c0
jmp 0x6b0a
movb $0x0, 0xc2(%rsp)
movw $0x2f2e, 0xc0(%rsp)     # imm = 0x2F2E
jmp 0x6794
movzwl 0x6(%r15), %r13d
movq 0x40(%rsp), %rbp
movq %r15, %r12
testw %r13w, %r13w
movq %r14, %r15
je 0x6c16
movzwl %r13w, %ebx
cmpl $0x25, %ebx
je 0x6c27
cmpl $0x63, %ebx
je 0x6c27
cmpl $0x806, %ebx            # imm = 0x806
je 0x6be9
cmpl $0x2abb, %ebx           # imm = 0x2ABB
je 0x6bc6
cmpl $0x4010, %ebx           # imm = 0x4010
je 0x6bc6
cmpl $0x4015, %ebx           # imm = 0x4015
je 0x6be4
cmpl $0x4016, %ebx           # imm = 0x4016
je 0x6bc6
cmpl $0x4212, %ebx           # imm = 0x4212
je 0x6be4
cmpl $0x610a, %ebx           # imm = 0x610A
je 0x6bc6
cmpl $0xcccc, %ebx           # imm = 0xCCCC
jne 0x714e
leaq 0x1f0f(%rip), %rdi      # 0x8a97
callq 0x5070
movq %r14, %r15
orl $0x111, %r15d           # imm = 0x111
leaq 0x56da(%rip), %rdi      # 0xc278
leaq 0x56e3(%rip), %rsi      # 0xc288
leaq 0x1c77(%rip), %rcx      # 0x8823
leaq 0xc0(%rsp), %rdx
movl %r15d, %r8d
callq 0x5684
leaq 0x28(%rsp), %r12
jmp 0x6c65
leaq 0x1ea5(%rip), %rdi      # 0x8a72
callq 0x5070
movq %r14, %r15
movl %r15d, %eax
andl $-0x80, %eax
leal (%r14,%rax,2), %r15d
incl %r15d
jmp 0x6c40
movq %r14, %r15
jmp 0x6c27
leaq 0x1e1e(%rip), %rdi      # 0x8a0e
callq 0x5070
movq %r14, %r15
orl $0x108, %r15d           # imm = 0x108
leaq 0x5672(%rip), %rdi      # 0xc278
leaq 0x567b(%rip), %rsi      # 0xc288
leaq 0x1c3e(%rip), %rcx      # 0x8852
jmp 0x6c55
movl %r15d, %eax
orl $0x20, %eax
testb $0x14, %r15b
cmovnel %r15d, %eax
movl %eax, %r15d
testb %r15b, %r15b
js 0x7117
leaq 0x1e3b(%rip), %rdi      # 0x8a72
callq 0x5070
orl $0x1, %r15d
leaq 0x5631(%rip), %rdi      # 0xc278
leaq 0x563a(%rip), %rsi      # 0xc288
leaq 0x1bd9(%rip), %rcx      # 0x882e
leaq 0xc0(%rsp), %rdx
movl %r15d, %r8d
callq 0x5684
leaq 0x1c09(%rip), %rdi      # 0x8875
movl %r15d, %esi
xorl %eax, %eax
callq 0x50c0
testb $0x1, %r15b
leaq 0x13c0(%rip), %rax      # 0x8041
leaq 0x1c20(%rip), %rsi      # 0x88a8
cmoveq %rax, %rsi
testb $0x2, %r15b
leaq 0x1c1c(%rip), %rdx      # 0x88b3
cmoveq %rax, %rdx
testb $0x4, %r15b
leaq 0x1c18(%rip), %rcx      # 0x88be
cmoveq %rax, %rcx
testb $0x8, %r15b
leaq 0x1c14(%rip), %r8       # 0x88c9
cmoveq %rax, %r8
testb $0x10, %r15b
leaq 0x1c10(%rip), %r9       # 0x88d4
cmoveq %rax, %r9
testb $0x20, %r15b
leaq 0x1c0b(%rip), %r10      # 0x88de
cmoveq %rax, %r10
testb $0x40, %r15b
leaq 0x1c08(%rip), %r11      # 0x88ea
cmoveq %rax, %r11
testb %r15b, %r15b
leaq 0x1c06(%rip), %rbx      # 0x88f6
cmovnsq %rax, %rbx
btl $0x8, %r15d
leaq 0x1c01(%rip), %r14      # 0x8901
cmovaeq %rax, %r14
leaq 0x1b7a(%rip), %rdi      # 0x8885
xorl %eax, %eax
pushq %r14
pushq %rbx
pushq %r11
pushq %r10
callq 0x50c0
addq $0x20, %rsp
movzwl 0x4(%r12), %eax
movl %eax, %ebx
shll $0x4, %ebx
testb $0x2c, %r15b
movq %r15, 0x18(%rsp)
je 0x6df6
imulq $0x14, %rax, %rdi
addq $0xc, %rdi
callq 0x5170
movq %rax, %r14
movq %rbx, %rdi
callq 0x5170
movq %rax, %r13
pushq $0x4
popq %rsi
movq %rbp, %rdi
xorl %edx, %edx
callq 0x51a0
movzwl 0x4(%r12), %eax
imulq $0x14, %rax, %rsi
addq $0xc, %rsi
pushq $0x1
popq %rdx
movq %r14, %rdi
movq %rbp, %rcx
callq 0x5080
testb %r15b, %r15b
jns 0x6d9c
movzwl 0x4(%r12), %eax
leal (%rax,%rax,4), %esi
addl $0x3, %esi
movq %r14, %rdi
movl %r15d, %edx
callq 0x5a84
movq 0x18(%rsp), %r15
movzwl 0x4(%r12), %eax
shll $0x4, %eax
movq %r14, 0x20(%rsp)
movq %r14, %rcx
addq $0x1c, %rcx
xorl %edx, %edx
pushq $0x14
popq %r14
leaq 0x1b4f(%rip), %rbx      # 0x890d
leaq 0x1d78(%rip), %rdi      # 0x8b3d
cmpq %rdx, %rax
je 0x6ecd
testb $0x14, %r15b
movl (%rcx), %esi
movl %esi, %r8d
bswapl %r8d
cmovel %esi, %r8d
leaq -0x10(%rcx), %rsi
movq %rsi, (%r13,%rdx)
movl %r8d, 0x8(%r13,%rdx)
addq $0x10, %rdx
addq $0x14, %rcx
jmp 0x6dc5
imulq $0xc, %rax, %rdi
addq $0xc, %rdi
callq 0x5170
movq %r12, 0x38(%rsp)
movq %rbp, %r12
movq %rax, %rbp
movq %rbx, %rdi
callq 0x5170
leaq 0xc(%rbp), %r14
testb $0x40, %r15b
cmovneq %rbp, %r14
movq %rax, %r13
pushq $0x10
popq %rsi
pushq $0x4
popq %rax
cmoveq %rax, %rsi
movq %r12, %rdi
xorl %edx, %edx
callq 0x51a0
movq 0x38(%rsp), %rax
movzwl 0x4(%rax), %eax
imulq $0xc, %rax, %rsi
addq $0xc, %rsi
pushq $0x1
popq %rdx
movq %rbp, 0x20(%rsp)
movq %rbp, %rdi
movq %r12, %rbp
movq 0x38(%rsp), %r12
movq %rbp, %rcx
callq 0x5080
testb %r15b, %r15b
jns 0x6e88
movzwl 0x4(%r12), %eax
leal (%rax,%rax,2), %esi
addl $0x3, %esi
movq 0x20(%rsp), %rdi
movl %r15d, %edx
callq 0x5a84
movq 0x18(%rsp), %r15
movzwl 0x4(%r12), %eax
shll $0x4, %eax
xorl %ecx, %ecx
leaq 0x1a84(%rip), %rbx      # 0x891e
leaq 0x1c8d(%rip), %rdi      # 0x8b2e
cmpq %rcx, %rax
je 0x6ec9
testb $0x10, %r15b
movl 0x8(%r14), %edx
movl %edx, %esi
bswapl %esi
cmovel %edx, %esi
movq %r14, (%r13,%rcx)
movl %esi, 0x8(%r13,%rcx)
addq $0x10, %rcx
addq $0xc, %r14
jmp 0x6ea1
pushq $0xc
popq %r14
callq 0x5070
leaq 0x1771(%rip), %rsi      # 0x864a
movq %rbx, %rdi
callq 0x51c0
movq %rax, %rbx
movq %r12, %r15
movzwl 0x4(%r12), %esi
imulq %r14, %rsi
addq $0xc, %rsi
pushq $0x1
popq %rdx
movq 0x20(%rsp), %rdi
movq %rax, %rcx
callq 0x5230
movq %rbx, %rdi
callq 0x5090
leaq 0x1c36(%rip), %rdi      # 0x8b4a
callq 0x5070
leaq 0x8(%r13), %r12
leaq 0x1a0d(%rip), %rbx      # 0x8931
xorl %r14d, %r14d
movzwl 0x4(%r15), %edx
cmpq %rdx, %r14
jae 0x6f57
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
addq $0x10, %r12
jmp 0x6f27
movq %rbp, %rdi
movq %r13, %rsi
movq 0x18(%rsp), %rcx
callq 0x5c37
movq %rax, %r12
xorl %r14d, %r14d
xorl %ebx, %ebx
movzwl 0x4(%r15), %eax
cmpq %rax, %rbx
jae 0x709a
movq (%r13,%r14), %rdi
movl $0x1ff, %esi            # imm = 0x1FF
callq 0x5060
movq 0x18(%rsp), %rax
testb $0x40, %al
jne 0x6fba
testb $0x10, %al
jne 0x6fcb
testb $0x1, %al
jne 0x6fda
testb $0x2, %al
jne 0x6feb
testb $0x4, %al
jne 0x6ffc
testb $0x8, %al
je 0x700b
movw $0x2d, 0x54(%rsp)
movl $0x32656f7a, 0x50(%rsp) # imm = 0x32656F7A
jmp 0x700b
movabsq $0x2d326c61697274, %rax # imm = 0x2D326C61697274
movq %rax, 0x50(%rsp)
jmp 0x700b
movb $0x0, 0x54(%rsp)
movl $0x2d737474, 0x50(%rsp) # imm = 0x2D737474
jmp 0x700b
movw $0x2d, 0x54(%rsp)
movl $0x3273676d, 0x50(%rsp) # imm = 0x3273676D
jmp 0x700b
movw $0x2d, 0x54(%rsp)
movl $0x3373676d, 0x50(%rsp) # imm = 0x3373676D
jmp 0x700b
movw $0x2d, 0x54(%rsp)
movl $0x3473676d, 0x50(%rsp) # imm = 0x3473676D
movq (%r13,%r14), %rsi
leaq 0x50(%rsp), %rbp
movq %rbp, %rdi
callq 0x5210
leaq 0x525c(%rip), %rdi      # 0xc280
leaq 0x5261(%rip), %rsi      # 0xc28c
leaq 0xc0(%rsp), %rdx
movq %rbp, %rcx
movq 0x18(%rsp), %rbp
movl %ebp, %r8d
callq 0x5684
movl (%r12,%r14), %esi
movq 0x8(%r12,%r14), %rdx
movq (%r13,%r14), %rcx
movl 0x8(%r13,%r14), %r8d
movq 0x40(%rsp), %rdi
movl %ebp, %r9d
callq 0x5dce
movq 0x5216(%rip), %rdi      # 0xc280
callq 0x5030
andq $0x0, 0x5209(%rip)      # 0xc280
movl 0x520f(%rip), %eax      # 0xc28c
testl %eax, %eax
jle 0x7087
subl %eax, 0x5209(%rip)      # 0xc290
andl $0x0, 0x51fe(%rip)      # 0xc28c
incq %rbx
addq $0x10, %r14
jmp 0x6f6f
movq %r12, %rbx
addq $0x8, %rbx
xorl %r14d, %r14d
movq 0x40(%rsp), %rbp
movzwl %ax, %eax
cmpq %rax, %r14
jae 0x70c7
movq (%rbx), %rdi
callq 0x5030
incq %r14
movzwl 0x4(%r15), %eax
addq $0x10, %rbx
jmp 0x70a9
movq 0x20(%rsp), %rdi
callq 0x5030
movq %r12, %rdi
callq 0x5030
movq %r13, %rdi
callq 0x5030
testb $0x40, 0x18(%rsp)
je 0x70f0
movq %r15, %rdi
callq 0x5030
movq 0x5181(%rip), %rdi      # 0xc278
callq 0x5030
leaq 0x1a52(%rip), %rdi      # 0x8b55
callq 0x5070
movq %rbp, %rdi
callq 0x5090
xorl %ebp, %ebp
jmp 0x673d
testb $0x14, %r15b
je 0x721d
cmpw $0x1, 0x18(%rsp)
jne 0x724a
orl $0x104, %r15d           # imm = 0x104
leaq 0x513d(%rip), %rdi      # 0xc278
leaq 0x5146(%rip), %rsi      # 0xc288
leaq 0x16f1(%rip), %rcx      # 0x883a
jmp 0x6c55
leaq 0x1966(%rip), %rdi      # 0x8abb
callq 0x5070
movq 0x50cf(%rip), %rdi      # 0xc230
movl 0x5109(%rip), %edx      # 0xc270
movzwl 0x8(%rsp), %ecx
movzwl 0xa(%rsp), %r8d
movzwl 0xc(%rsp), %r9d
movzwl 0xe(%rsp), %r10d
movl 0x10(%rsp), %r11d
subq $0x8, %rsp
movq %rbp, %r14
xorl %ebp, %ebp
leaq 0x88(%rsp), %rsi
xorl %eax, %eax
pushq %r11
pushq %r10
pushq %r9
callq 0x50c0
addq $0x20, %rsp
leaq 0x1920(%rip), %rdi      # 0x8acc
callq 0x5070
movq 0x5078(%rip), %rdi      # 0xc230
movl 0x50b6(%rip), %edx      # 0xc274
movzwl 0x18(%rsp), %ecx
movzwl 0x38(%rsp), %r8d
movzwl 0x4c(%rsp), %r9d
movzwl 0x20(%rsp), %r10d
subq $0x8, %rsp
leaq 0xa8(%rsp), %rsi
xorl %eax, %eax
pushq 0x78(%rsp)
pushq %r10
pushq %r9
callq 0x50c0
addq $0x20, %rsp
leaq 0x1663(%rip), %rdi      # 0x885e
movl %ebx, %esi
xorl %eax, %eax
callq 0x50c0
leaq 0x18d5(%rip), %rdi      # 0x8ae0
callq 0x5070
movq %r14, %rdi
callq 0x5090
jmp 0x673d
leaq 0x180f(%rip), %rdi      # 0x8a33
callq 0x5070
orl $0x102, %r15d           # imm = 0x102
leaq 0x5041(%rip), %rdi      # 0xc278
leaq 0x504a(%rip), %rsi      # 0xc288
leaq 0x1601(%rip), %rcx      # 0x8846
jmp 0x6c55
leaq 0x1807(%rip), %rdi      # 0x8a58
jmp 0x6735