// File: /workspace/github_c_makefile_star2_O2/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 $0x258, %rsp            # imm = 0x258
movq %rsi, %r14
cmpl $0x1, %edi
jg 0x14f3
movq (%r14), %rsi
leaq 0xbad(%rip), %rdi       # 0x207c
xorl %eax, %eax
callq 0x1070
leaq 0xd78(%rip), %rdi       # 0x2255
callq 0x1040
leaq 0xd96(%rip), %rdi       # 0x227f
callq 0x1040
jmp 0x18f4
leaq 0x50(%rsp), %rdi
movl $0x200, %edx            # imm = 0x200
xorl %esi, %esi
callq 0x1080
movq 0x8(%r14), %rdi
leaq 0xb90(%rip), %rsi       # 0x209f
callq 0x10c0
testq %rax, %rax
je 0x15ef
movq %rax, %rbx
xorl %ebp, %ebp
pushq $0x2
popq %rdx
movq %rax, %rdi
xorl %esi, %esi
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 0x15ff
leaq 0xc2c(%rip), %rdi       # 0x2186
callq 0x1040
leaq 0xc68(%rip), %rdi       # 0x21ce
callq 0x1040
movups 0xb30(%rip), %xmm0      # 0x20a2
leaq 0x50(%rsp), %rdi
movaps %xmm0, (%rdi)
movl $0x6e6962, 0xf(%rdi)    # imm = 0x6E6962
leaq 0xab9(%rip), %rsi       # 0x2041
callq 0x10c0
testq %rax, %rax
je 0x18e1
movq %rax, %r15
movl $0x800, %edi            # imm = 0x800
callq 0x10a0
movq %rax, %r12
pushq $0x1
popq %r13
movl $0x800, %esi            # imm = 0x800
movq %rax, %rdi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x1050
movl $0x800, %esi            # imm = 0x800
movq %r12, %rdi
movq %r13, %rdx
movq %r15, %rcx
callq 0x10e0
movq %r15, %rdi
callq 0x1060
movq %r12, %rdi
callq 0x1030
movl $0x100, 0xc(%rsp)       # imm = 0x100
movl $0x800, %ebp            # imm = 0x800
jmp 0x1613
movq 0x8(%r14), %rsi
leaq 0xa4a(%rip), %rdi       # 0x2044
jmp 0x18ed
leaq 0xba9(%rip), %rdi       # 0x21af
callq 0x1040
movl $0x80, 0xc(%rsp)
leaq 0xbe7(%rip), %rdi       # 0x2201
callq 0x1040
movups 0xa8f(%rip), %xmm0      # 0x20b5
leaq 0x50(%rsp), %rdi
movaps %xmm0, (%rdi)
movl $0x6e6962, 0xf(%rdi)    # imm = 0x6E6962
leaq 0xa05(%rip), %rsi       # 0x2041
callq 0x10c0
testq %rax, %rax
je 0x18e1
movq %rax, %r15
movl $0x800, %edi            # imm = 0x800
callq 0x10a0
movq %rax, %r12
pushq $0x1
popq %r13
movl $0x800, %esi            # imm = 0x800
movq %rax, %rdi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x1050
movl $0x800, %esi            # imm = 0x800
movq %r12, %rdi
movq %r13, %rdx
movq %r15, %rcx
callq 0x10e0
movq %r15, %rdi
callq 0x1060
movq %r12, %rdi
callq 0x1030
leaq 0xb8c(%rip), %rdi       # 0x2227
callq 0x1040
movabsq $0x6e69622e736563, %rax # imm = 0x6E69622E736563
leaq 0x50(%rsp), %rdi
movq %rax, 0xd(%rdi)
movups 0xa0e(%rip), %xmm0      # 0x20c8
movaps %xmm0, (%rdi)
leaq 0x97d(%rip), %rsi       # 0x2041
callq 0x10c0
testq %rax, %rax
je 0x18e1
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, %r13
pushq $0x1
popq %r14
movq %rax, %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1050
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %r15, %rcx
callq 0x10e0
movq %r15, %rdi
callq 0x1060
movq %r13, %rdi
callq 0x1030
movl 0xc(%rsp), %eax
movl %eax, %ecx
shll $0x4, %eax
addl %ebp, %eax
movl %eax, 0xc(%rsp)
movl %ebp, %eax
movq %rax, 0x40(%rsp)
pushq $0x4
popq %r12
leaq 0x14(%rsp), %r13
xorl %r15d, %r15d
movq %rcx, 0x38(%rsp)
cmpq %rcx, %r15
je 0x1920
movq %r15, %rsi
shlq $0x4, %rsi
addq 0x40(%rsp), %rsi
movq %rbx, %rdi
movq %rsi, 0x28(%rsp)
xorl %edx, %edx
callq 0x10b0
leaq 0x10(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1050
movzbl 0x10(%rsp), %esi
movzbl 0x11(%rsp), %ebp
movzbl 0x12(%rsp), %ecx
movzbl 0x13(%rsp), %r8d
leaq 0x934(%rip), %rdi       # 0x20dd
movl %ebp, %edx
xorl %eax, %eax
callq 0x1070
leaq 0x943(%rip), %rdi       # 0x20fc
movq %r15, 0x18(%rsp)
movl %r15d, %esi
movl %ebp, %edx
xorl %eax, %eax
callq 0x1070
movq %rbp, 0x48(%rsp)
testl %ebp, %ebp
je 0x18cf
orq $0x4, 0x28(%rsp)
xorl %ebp, %ebp
cmpq 0x48(%rsp), %rbp
je 0x18cf
andl $0x0, 0x14(%rsp)
movq 0x28(%rsp), %rax
leaq (%rax,%rbp,4), %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x10b0
leaq 0x24(%rsp), %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1050
movl 0x24(%rsp), %r15d
cmpl $-0x1, %r15d
je 0x1909
leaq 0x921(%rip), %rdi       # 0x214c
movq %rbp, 0x30(%rsp)
movq 0x18(%rsp), %rbp
movl %ebp, %esi
movq 0x30(%rsp), %rdx
movl %r15d, %ecx
xorl %eax, %eax
callq 0x1070
addl 0xc(%rsp), %r15d
movq %rbx, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x10b0
leaq 0x50(%rsp), %r15
movq %r15, %rdi
leaq 0x90d(%rip), %rsi       # 0x2174
movl %ebp, %edx
movq 0x30(%rsp), %rbp
movl %ebp, %ecx
xorl %eax, %eax
callq 0x10d0
movq %r15, %rdi
leaq 0x7c0(%rip), %rsi       # 0x2041
callq 0x10c0
testq %rax, %rax
je 0x18e1
movq %rax, %r15
xorl %eax, %eax
cmpl $0xfffe0000, %eax       # imm = 0xFFFE0000
je 0x18bf
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x1050
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rdx
movq %r15, %rcx
callq 0x10e0
movl 0x14(%rsp), %eax
jmp 0x1890
movq %r15, %rdi
callq 0x1060
incq %rbp
jmp 0x17df
movq 0x18(%rsp), %r15
incq %r15
movq 0x38(%rsp), %rcx
jmp 0x1756
leaq 0x75c(%rip), %rdi       # 0x2044
leaq 0x50(%rsp), %rsi
xorl %eax, %eax
callq 0x1070
pushq $0x1
popq %rax
addq $0x258, %rsp            # imm = 0x258
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x809(%rip), %rdi       # 0x2119
movq 0x18(%rsp), %rsi
movl %ebp, %edx
xorl %eax, %eax
callq 0x1070
jmp 0x18f4
leaq 0x928(%rip), %rdi       # 0x224f
callq 0x1040
movq %rbx, %rdi
callq 0x1060
xorl %eax, %eax
jmp 0x18f7