// File: /workspace/github_c_makefile_star2_O3/Joy-Division[P]tools-zoe/efx-splitter.c
// Function: main
int main( int argc, char **argv ) {
	
	if ( argc < 2 ) {
		printf("Not enough args!\nUse: %s EFX-file\n", argv[0]);
		printf("supported games are:\nMGS1\nZoE1 and MGS2HD\n");
		printf("The game will be automatically detected based on filesize!\n");
		return 1;
	}
	
	FILE *f, *o;
	char outputname[512] = {0};
	unsigned char *dumpblock = NULL;
	unsigned int numentries, sizelimit = 0x2000, size, game, blocksize, sequenceblockoffset;
	unsigned int i, j;
	efxFlags minihead;
	
	uint32_t sequenceoffset;
	uint32_t curtoken;
	
	if( !(f = fopen( argv[1], "rb" ))) {
		printf("Couldnt open file %s\n", argv[1]);
		return 1;
	}
	
	fseek(f, 0, SEEK_END);
	size = ftell(f);
	fseek(f, 0, SEEK_SET);
	if(size < sizelimit) {
		game = mgs1;
		numentries = 0x80;
		sequenceblockoffset = 0;
		printf("Game based on filesize is MGS1\n");
	}
	else {
		game = zoe1;
		numentries = 0x100;
		sequenceblockoffset = 0x800;
		printf("Game based on filesize is ZoE1 or MGS2HD\n");
	}
	
	if(game == zoe1) {
		printf("Dumping block 0 of efx (found in games after MGS1)\n");
		sprintf(outputname, "block0-unknown.bin");
		if( !(o = fopen( outputname, "wb" ))) {
			printf("Couldnt open file %s\n", outputname);
			return 1;
		}
		dumpblock = malloc(0x800);
		fread(dumpblock, 0x800, 1, f);
		fwrite(dumpblock, 0x800, 1, o);
		fclose(o);
		free(dumpblock);
	}
	
	printf("Dumping block 1 of efx (offset block)\n");
	sprintf(outputname, "block1-offsets.bin");
	if( !(o = fopen( outputname, "wb" ))) {
		printf("Couldnt open file %s\n", outputname);
		return 1;
	}
	dumpblock = malloc(0x800);
	fread(dumpblock, 0x800, 1, f);
	fwrite(dumpblock, 0x800, 1, o);
	fclose(o);
	free(dumpblock);
	
	printf("Dumping block 2 of efx (sequence block)\n");
	sprintf(outputname, "block2-sequences.bin");
	if( !(o = fopen( outputname, "wb" ))) {
		printf("Couldnt open file %s\n", outputname);
		return 1;
	}
	if(game == mgs1) blocksize = size-0x800;
	else if(game == zoe1) blocksize = size-0x1000;
	dumpblock = malloc(blocksize);
	fread(dumpblock, blocksize, 1, f);
	fwrite(dumpblock, blocksize, 1, o);
	fclose(o);
	free(dumpblock);
	
	
	for(i = 0; i < numentries; i++) {
		fseek(f, sequenceblockoffset + (0x10*i), SEEK_SET);
		fread(&minihead, 4, 1, f);
		printf("Minihead: %02x %02x %02x %02x\n", minihead.unknown1, minihead.numSequences, minihead.unknown2, minihead.unknown3);
		printf("Sequences in entry %02x: %d\n", i, minihead.numSequences);
		if(minihead.numSequences) {
			for(j = 0; j < minihead.numSequences; j++) {
				curtoken = 0;
				fseek(f, sequenceblockoffset + (0x10*i) + 4 + (4*j), SEEK_SET);
				fread(&sequenceoffset, 4, 1, f);
				if(sequenceoffset == 0xFFFFFFFF) {
					printf("Invalid sequence offset!\nEntry %02x - Sequence %d\n", i, j);
					return 1;
				}
				printf("Entry %02x - Sequence %d - Offset %08x\n", i, j, sequenceoffset);
				fseek(f, sequenceblockoffset+(numentries*0x10)+sequenceoffset, SEEK_SET);
				sprintf(outputname, "ent%03d-seq%d.bin", i, j);
				if( !(o = fopen( outputname, "wb" ))) {
					printf("Couldnt open file %s\n", outputname);
					return 1;
				}
				while(curtoken != 0xFFFE0000) {
					fread(&curtoken, 4, 1, f);
					fwrite(&curtoken, 4, 1, o);
				}
				fclose(o);
			}
		}
	}
	
	printf("Done.\n");
	
	fclose(f);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq %rsi, %r14
cmpl $0x1, %edi
jg 0x1513
movq (%r14), %rsi
leaq 0xb8d(%rip), %rdi       # 0x207c
xorl %eax, %eax
callq 0x1070
leaq 0xd58(%rip), %rdi       # 0x2255
callq 0x1040
leaq 0xd76(%rip), %rdi       # 0x227f
callq 0x1040
jmp 0x191e
leaq 0x30(%rsp), %rdi
movl $0x200, %edx            # imm = 0x200
xorl %esi, %esi
callq 0x1080
movq 0x8(%r14), %rdi
leaq 0xb70(%rip), %rsi       # 0x209f
callq 0x10c0
testq %rax, %rax
je 0x1610
movq %rax, %rbx
xorl %r13d, %r13d
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x10b0
movq %rbx, %rdi
callq 0x1090
movq %rax, %r14
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x10b0
testl $0xffffe000, %r14d      # imm = 0xFFFFE000
je 0x1620
leaq 0xc09(%rip), %rdi       # 0x2186
callq 0x1040
leaq 0xc45(%rip), %rdi       # 0x21ce
callq 0x1040
movups 0xb0d(%rip), %xmm0      # 0x20a2
leaq 0x30(%rsp), %rdi
movaps %xmm0, (%rdi)
movl $0x6e6962, 0xf(%rdi)    # imm = 0x6E6962
leaq 0xa96(%rip), %rsi       # 0x2041
callq 0x10c0
testq %rax, %rax
je 0x190b
movq %rax, %r15
movl $0x800, %edi            # imm = 0x800
callq 0x10a0
movq %rax, %r12
movl $0x800, %esi            # imm = 0x800
movl $0x1, %edx
movq %rax, %rdi
movq %rbx, %rcx
callq 0x1050
movl $0x800, %esi            # imm = 0x800
movl $0x1, %edx
movq %r12, %rdi
movq %r15, %rcx
callq 0x10e0
movq %r15, %rdi
callq 0x1060
movq %r12, %rdi
callq 0x1030
movl $0x100, %ebp            # imm = 0x100
movl $0x800, %r13d           # imm = 0x800
jmp 0x1631
movq 0x8(%r14), %rsi
leaq 0xa29(%rip), %rdi       # 0x2044
jmp 0x1917
leaq 0xb88(%rip), %rdi       # 0x21af
callq 0x1040
movl $0x80, %ebp
leaq 0xbc9(%rip), %rdi       # 0x2201
callq 0x1040
movups 0xa71(%rip), %xmm0      # 0x20b5
leaq 0x30(%rsp), %rdi
movaps %xmm0, (%rdi)
movl $0x6e6962, 0xf(%rdi)    # imm = 0x6E6962
leaq 0x9e7(%rip), %rsi       # 0x2041
callq 0x10c0
testq %rax, %rax
je 0x190b
movq %rax, %r15
movl $0x800, %edi            # imm = 0x800
callq 0x10a0
movq %rax, %r12
movl $0x800, %esi            # imm = 0x800
movl $0x1, %edx
movq %rax, %rdi
movq %rbx, %rcx
callq 0x1050
movl $0x800, %esi            # imm = 0x800
movl $0x1, %edx
movq %r12, %rdi
movq %r15, %rcx
callq 0x10e0
movq %r15, %rdi
callq 0x1060
movq %r12, %rdi
callq 0x1030
leaq 0xb6e(%rip), %rdi       # 0x2227
callq 0x1040
movabsq $0x6e69622e736563, %rax # imm = 0x6E69622E736563
leaq 0x30(%rsp), %rdi
movq %rax, 0xd(%rdi)
movups 0x9f0(%rip), %xmm0      # 0x20c8
movaps %xmm0, (%rdi)
leaq 0x95f(%rip), %rsi       # 0x2041
callq 0x10c0
testq %rax, %rax
je 0x190b
movq %rax, %r15
testl $0xffffe000, %r14d      # imm = 0xFFFFE000
movl $0xfffff000, %eax       # imm = 0xFFFFF000
movl $0xfffff800, %r12d      # imm = 0xFFFFF800
cmovnel %eax, %r12d
addl %r14d, %r12d
movq %r12, %rdi
callq 0x10a0
movq %rax, %r14
movl $0x1, %edx
movq %rax, %rdi
movq %r12, %rsi
movq %rbx, %rcx
callq 0x1050
movl $0x1, %edx
movq %r14, %rdi
movq %r12, %rsi
movq %r15, %rcx
callq 0x10e0
movq %r15, %rdi
callq 0x1060
movq %r14, %rdi
callq 0x1030
movl %ebp, %eax
movq %rax, 0x20(%rsp)
shll $0x4, %ebp
addl %r13d, %ebp
movl %ebp, 0x10(%rsp)
movl %r13d, %eax
leaq 0x8(%rsp), %r12
leaq 0x970(%rip), %rbp       # 0x20dd
leaq 0xc(%rsp), %r15
xorl %r13d, %r13d
movq %rax, 0x18(%rsp)
movq %r13, %r14
shlq $0x4, %r14
addq %rax, %r14
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x10b0
movl $0x4, %esi
movl $0x1, %edx
movq %r12, %rdi
movq %rbx, %rcx
callq 0x1050
movzbl 0x8(%rsp), %esi
movzbl 0x9(%rsp), %r12d
movzbl 0xa(%rsp), %ecx
movzbl 0xb(%rsp), %r8d
movq %rbp, %rdi
movl %r12d, %edx
xorl %eax, %eax
callq 0x1070
leaq 0x92c(%rip), %rdi       # 0x20fc
movl %r13d, %esi
movl %r12d, %edx
xorl %eax, %eax
callq 0x1070
movq %r12, 0x28(%rsp)
testl %r12d, %r12d
je 0x18d4
orq $0x4, %r14
xorl %r12d, %r12d
movl $0x0, 0xc(%rsp)
leaq (%r14,%r12,4), %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x10b0
movl $0x4, %esi
movl $0x1, %edx
leaq 0x14(%rsp), %rdi
movq %rbx, %rcx
callq 0x1050
movl 0x14(%rsp), %ebp
cmpl $-0x1, %ebp
je 0x1935
leaq 0x919(%rip), %rdi       # 0x214c
movl %r13d, %esi
movl %r12d, %edx
movl %ebp, %ecx
xorl %eax, %eax
callq 0x1070
addl 0x10(%rsp), %ebp
movq %rbx, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x10b0
leaq 0x30(%rsp), %rbp
movq %rbp, %rdi
leaq 0x912(%rip), %rsi       # 0x2174
movl %r13d, %edx
movl %r12d, %ecx
xorl %eax, %eax
callq 0x10d0
movq %rbp, %rdi
leaq 0x7c8(%rip), %rsi       # 0x2041
callq 0x10c0
movq %rax, %rbp
testq %rax, %rax
je 0x190b
movl $0x4, %esi
movl $0x1, %edx
movq %r15, %rdi
movq %rbx, %rcx
callq 0x1050
movl $0x4, %esi
movl $0x1, %edx
movq %r15, %rdi
movq %rbp, %rcx
callq 0x10e0
cmpl $0xfffe0000, 0xc(%rsp)  # imm = 0xFFFE0000
jne 0x188a
movq %rbp, %rdi
callq 0x1060
incq %r12
cmpq 0x28(%rsp), %r12
jne 0x17f2
incq %r13
cmpq 0x20(%rsp), %r13
movq 0x18(%rsp), %rax
leaq 0x8(%rsp), %r12
leaq 0x7f0(%rip), %rbp       # 0x20dd
jne 0x177a
leaq 0x955(%rip), %rdi       # 0x224f
callq 0x1040
movq %rbx, %rdi
callq 0x1060
xorl %eax, %eax
jmp 0x1923
leaq 0x732(%rip), %rdi       # 0x2044
leaq 0x30(%rsp), %rsi
xorl %eax, %eax
callq 0x1070
movl $0x1, %eax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x7dd(%rip), %rdi       # 0x2119
movl %r13d, %esi
movl %r12d, %edx
xorl %eax, %eax
callq 0x1070
jmp 0x191e