// File: /workspace/github_c_makefile_star2_O3/baines[P]MiniGBS/minigbs.c
// Function: main
int main(int argc, char** argv){
	setlocale(LC_ALL, "");
	char* prog = argv[0];

	int opt;
	while((opt = getopt(argc, argv, "dhmqsw:t:")) != -1){
		switch(opt){
			case 'd':
				cfg.hide_ui = true;
				cfg.debug_mode++;
				break;
			case 'h':
				usage(prog, stdout);
				return 0;
			case 'm':
				cfg.monochrome = true;
				break;
			case 'q':
				cfg.hide_ui = true;
				break;
			case 's':
				cfg.subdued = true;
				break;
			case 'w':
				cfg.write_wav = true;
				cfg.output_filename = strdup(optarg);
				break;
			case 't':
				cfg.output_duration_ms = strtof(optarg, NULL) * 1000.0f;
				break;
			default:
				usage(prog, stderr);
				return 1;
		}
	}

	if(optind >= argc){
		fprintf(stderr, "Missing file argument.\n\n");
		usage(argv[0], stderr);
		return 1;
	}

	argc -= (optind-1);
	argv += (optind-1);

	FILE* f = fopen(argv[1], "r");
	if(!f){
		fprintf(stderr, "Error opening file '%s': %m\n", argv[1]);
		return 1;
	}

	if(fread(&h, sizeof(h), 1, f) != 1){
		return 1;
	}

	if(strncmp(h.id, "GBS", 3) != 0){
		fprintf(stderr, "That doesn't look like a GBS file.\n");
		return 1;
	}

	if(h.version != 1){
		fprintf(stderr, "This GBS file is version %d, I can only handle version 1 :(\n", h.version);
		return 1;
	}

	cfg.song_count = h.song_count;
	cfg.song_no = argc > 2 ? atoi(argv[2]) : MAX(0, h.start_song - 1);

	if(cfg.song_no >= h.song_count){
		fprintf(stderr, "The file says it has %d tracks, index %d is out of range.\n", h.song_count, cfg.song_no);
		return 1;
	}

	if(cfg.debug_mode){
		printf("id   : %.3s\n", h.id);
		printf("ver  : %d\n", h.version);
		printf("count: %d\n", h.song_count);
		printf("start: %d\n", h.start_song);
		printf("load : %x\n", h.load_addr);
		printf("init : %x\n", h.init_addr);
		printf("play : %x\n", h.play_addr);
		printf("sp   : %x\n", h.sp);
		printf("tma  : %d\n", h.tma);
		printf("tac  : %d\n", h.tac);
		printf("title: %.32s\n", h.title);
		printf("authr: %.32s\n", h.author);
		printf("copyr: %.32s\n", h.copyright);
	}

	mem = mmap(NULL, 0x12000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	assert(mem != MAP_FAILED);
	mem += 0x1000;

	mprotect(mem - 0x1000 , 0x1000, PROT_NONE);
	mprotect(mem + 0x10000, 0x1000, PROT_NONE);

	fseek(f, 0x70, SEEK_SET);

	if(cfg.debug_mode){
		puts("rom banks:");
	}

	int bno = h.load_addr / 0x4000;
	int off = h.load_addr % 0x4000;

	while(1){
		uint8_t* page = mmap(NULL, 0x4000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
		assert(page != MAP_FAILED);
		banks[bno] = page;

		size_t n = fread(page + off, 1, 0x4000 - off, f);
		if(cfg.debug_mode){
			printf("Bank %d: %zu\n", bno, n);
		}

		if(feof(f)){
			break;
		} else if(ferror(f)){
			printf("Error reading file: %m\n");
			break;
		}

		off = 0;
		if(++bno >= 32){
			puts("Too many banks...");
			exit(1);
		}
	}
	fclose(f);

	static const uint8_t regs_init[] = {
		0x80, 0xBF, 0xF3, 0xFF, 0x3F, 0xFF, 0x3F, 0x00,
		0xFF, 0x3F, 0x7F, 0xFF, 0x9F, 0xFF, 0x3F, 0xFF,
		0xFF, 0x00, 0x00, 0x3F, 0x77, 0xF3, 0xF1,
	};

	static const uint8_t wave_init[] = {
		0xac, 0xdd, 0xda, 0x48,
		0x36, 0x02, 0xcf, 0x16,
		0x2c, 0x04, 0xe5, 0x2c,
		0xac, 0xdd, 0xda, 0x48
	};

	mem[0xff06] = h.tma;
	mem[0xff07] = h.tac;

	cfg.volume = 1.0f;
	cfg.speed  = 1.0f;

	config_read();

	if(cfg.write_wav) {
		audio_output = output_wav;
	} else {
		audio_output = output_alsa;
	}

	if(!audio_output->interactive) {
		cfg.hide_ui = true;
		cfg.volume = 1.0;

		if(!cfg.output_filename) {
			fprintf(stderr, "No output filename supplied.\n");
			exit(1);
		}

		if(cfg.output_duration_ms <= 0) {
			cfg.output_duration_ms = 2 * 60 * 1000.0f;
		}

		printf("Writing %gs of audio to %s...\n", cfg.output_duration_ms / 1000.0f, cfg.output_filename);

		audio_output->filename = cfg.output_filename;
	}

	if(!cfg.hide_ui) {
		initscr();
	}

	sigset_t      sigmask;
	sigemptyset (&sigmask);
	sigaddset   (&sigmask, SIGWINCH);
	sigaddset   (&sigmask, SIGINT);

	int sigfd = signalfd(-1, &sigmask, SFD_NONBLOCK);

	sigprocmask(SIG_BLOCK, &sigmask, NULL);

	int draw_timer = timerfd_create(CLOCK_MONOTONIC, 0);
	struct itimerspec ts = {
		.it_value.tv_nsec = 1,
		.it_interval.tv_nsec = UINT64_C(1000000000) / UINT64_C(60),
	};
	timerfd_settime(draw_timer, 0, &ts, NULL);

	enum {
		FD_STDIN,
		FD_SIGNAL,
		FD_DRAW_TIMER,
		FD_GUI,
	};

#define NFDS 4
	struct pollfd* fds = calloc(NFDS, sizeof(struct pollfd));
	{
		struct pollfd tmp[NFDS] = {
			[FD_STDIN]      = { STDIN_FILENO , POLLIN },
			[FD_SIGNAL]     = { sigfd        , POLLIN },
			[FD_DRAW_TIMER] = { draw_timer   , POLLIN },
			[FD_GUI]        = { ui_init()    , POLLIN },
		};
		memcpy(fds, tmp, sizeof(tmp));
	}

	int nfds = audio_init(&fds, NFDS);

	// hack to avoid ALSA warnings breaking the UI
	if(!cfg.hide_ui){
		fclose(stderr);
	}

	bool paused;
	float elapsed_ms;

restart:
	elapsed_ms = 0;
	audio_reset();
	ui_reset();

	if(banks[0]) memcpy(mem, banks[0], 0x4000);
	if(banks[1]) memcpy(mem + 0x4000, banks[1], 0x4000);

	memset(&regs, 0, sizeof(regs));
	memset(mem + 0x8000, 0, 0x8000);

	memcpy(mem, mem + h.load_addr, 0x62);

	mem[(h.sp-1)&0xffff] = mem[(h.sp-2)&0xffff] = 0;
	regs.sp = h.sp - 2;

	regs.pc = h.init_addr;
	regs.a = cfg.song_no;

	mem[0xffff] = 1; // IE
	mem[0xff06] = h.tma;
	mem[0xff07] = h.tac;

	for(int i = 0; i < 23; ++i){
		mem_write(0xFF10 + i, regs_init[i]);
	}
	memcpy(mem + 0xff30, wave_init, 16);

	paused = false;
	audio_pause(false);

	while(1){
		int n = poll(fds, nfds, -1);
		if(n == -1){
			perror("poll");
			continue;
		}

		elapsed_ms += audio_update(fds + NFDS, nfds - NFDS);

		if(cfg.output_duration_ms > 0 && elapsed_ms > cfg.output_duration_ms) {
			goto end;
		}

		if(fds[FD_SIGNAL].revents & POLLIN){
			struct signalfd_siginfo info;
			bool redraw = false;
			ssize_t n;

			do {
				n = read(fds[FD_SIGNAL].fd, &info, sizeof(info));
				if(n == -1) {
					if(errno != EAGAIN) {
						perror("read");
					}
				} else {
					if(info.ssi_signo == SIGWINCH) {
						redraw = true;
					} else if(info.ssi_signo == SIGINT) {
						goto end;
					}
				}
			} while(n > 0);

			if(redraw && !cfg.hide_ui) {
				endwin();
				refresh();
				clear();
				getmaxyx(stdscr, cfg.win_h, cfg.win_w);
			}
		}

		if(fds[FD_DRAW_TIMER].revents & POLLIN){
			fd_clear(draw_timer);
			ui_refresh();
		}

		bool tui_events = fds[FD_STDIN].revents & POLLIN;
		bool gui_events = fds[FD_GUI].revents & POLLIN;

		while(tui_events || gui_events){
			int value;
			switch(ui_action(&value, &tui_events, &gui_events)){
				case ACT_QUIT:
					goto end;

				case ACT_CHAN_TOGGLE:
					ui_msg_set("Channel %c %smuted\n",
							   value + '0',
							   audio_mute(value, -1) ? "" : "un");
					break;

				case ACT_TRACK_SET:
					if(value < 0 || value >= cfg.song_count){
						ui_msg_set("Out of range.\n");
					} else {
						cfg.song_no = value;
						goto restart;
					}
					break;

				case ACT_PAUSE:
					paused = !paused;
					ui_msg_set("%s\n", paused ? "Paused" : "Resumed");
					audio_pause(paused);
					break;

				case ACT_VOL:
					cfg.volume = value / 100.0f;
					ui_msg_set("Volume: %d%%\n", value);
					break;

				case ACT_SPEED:
					cfg.speed = value ? MAX(0.1f, MIN(2.0f, cfg.speed + value / 100.0f)) : 1.0f;
					ui_msg_set("Speed: %d%%\n", (int)roundf(100.0f * cfg.speed));
					audio_update_rate();
					break;
			}
		}
	}

end:
	config_write();
	ui_quit();
	audio_quit();

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movq %rsi, %r14
movl %edi, %ebp
leaq 0x5b40(%rip), %rsi      # 0xc6d9
movl $0x6, %edi
callq 0x5550
movq (%r14), %rbx
leaq 0x564a(%rip), %r15      # 0xc1f7
leaq 0x54bc(%rip), %r12      # 0xc070
movq 0xa41d(%rip), %r13      # 0x10fd8
movl %ebp, %edi
movq %r14, %rsi
movq %r15, %rdx
callq 0x5190
cmpl $0x6c, %eax
jle 0x6beb
addl $-0x6d, %eax
cmpl $0xa, %eax
ja 0x7785
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movb $0x1, 0xa863(%rip)      # 0x1144c
jmp 0x6bbb
cmpl $0x64, %eax
jne 0x6c4a
movb $0x1, 0xa856(%rip)      # 0x1144d
incl 0xa84b(%rip)            # 0x11448
jmp 0x6bbb
movb $0x1, 0xa847(%rip)      # 0x1144d
jmp 0x6bbb
movb $0x1, 0xa840(%rip)      # 0x1144f
movq (%r13), %rdi
callq 0x5420
movq %rax, 0xa831(%rip)      # 0x11450
jmp 0x6bbb
movb $0x1, 0xa826(%rip)      # 0x1144e
jmp 0x6bbb
movq (%r13), %rdi
xorl %esi, %esi
callq 0x5340
mulss 0x5413(%rip), %xmm0     # 0xc050
movss %xmm0, 0xa813(%rip)     # 0x11458
jmp 0x6bbb
cmpl $-0x1, %eax
je 0x6c7b
cmpl $0x68, %eax
jne 0x7785
movq 0xa399(%rip), %rax      # 0x10ff8
movq (%rax), %rdi
leaq 0x58dd(%rip), %rsi      # 0xc546
xorl %r15d, %r15d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5570
jmp 0x77bb
movq 0xa336(%rip), %rax      # 0x10fb8
movslq (%rax), %r13
cmpl %ebp, %r13d
jge 0x77a2
movq (%r14,%r13,8), %rdi
leaq 0x5d3f(%rip), %rsi      # 0xc9d8
callq 0x51d0
testq %rax, %rax
je 0x77ac
movq %rax, %rbx
leaq 0xa71b(%rip), %rdi      # 0x113cc
movl $0x70, %esi
movl $0x1, %edx
movq %rax, %rcx
callq 0x5400
movl $0x1, %r15d
cmpq $0x1, %rax
jne 0x77bb
movzwl 0xa6f2(%rip), %eax      # 0x113cc
xorl $0x4247, %eax           # imm = 0x4247
movzbl 0xa6e8(%rip), %ecx      # 0x113ce
xorl $0x53, %ecx
orw %ax, %cx
jne 0x77d0
movzbl 0xa6d6(%rip), %edx      # 0x113cf
cmpl $0x1, %edx
jne 0x77d7
leaq -0x1(%r13), %rax
subl %eax, %ebp
movzbl 0xa6c0(%rip), %r12d     # 0x113d0
movl %r12d, 0xa749(%rip)     # 0x11460
cmpl $0x3, %ebp
jl 0x6d2f
leaq (%r14,%r13,8), %rax
addq $-0x8, %rax
movq 0x10(%rax), %rdi
callq 0x53a0
jmp 0x6d40
movzbl 0xa69b(%rip), %eax      # 0x113d1
cmpb $0x1, %al
adcl $0x0, %eax
movzbl %al, %eax
decl %eax
movl %eax, 0xa716(%rip)      # 0x1145c
cmpl %r12d, %eax
jge 0x77f1
cmpl $0x0, 0xa6f2(%rip)      # 0x11448
je 0x6e6d
leaq 0x5574(%rip), %rdi      # 0xc2d7
leaq 0xa662(%rip), %rsi      # 0x113cc
xorl %eax, %eax
callq 0x5050
movzbl 0xa657(%rip), %esi      # 0x113cf
leaq 0x5565(%rip), %rdi      # 0xc2e4
xorl %eax, %eax
callq 0x5050
movzbl 0xa643(%rip), %esi      # 0x113d0
leaq 0x555b(%rip), %rdi      # 0xc2ef
xorl %eax, %eax
callq 0x5050
movzbl 0xa62f(%rip), %esi      # 0x113d1
leaq 0x5551(%rip), %rdi      # 0xc2fa
xorl %eax, %eax
callq 0x5050
movzwl 0xa61b(%rip), %esi      # 0x113d2
leaq 0x5547(%rip), %rdi      # 0xc305
xorl %eax, %eax
callq 0x5050
movzwl 0xa608(%rip), %esi      # 0x113d4
leaq 0x553d(%rip), %rdi      # 0xc310
xorl %eax, %eax
callq 0x5050
movzwl 0xa5f5(%rip), %esi      # 0x113d6
leaq 0x5533(%rip), %rdi      # 0xc31b
xorl %eax, %eax
callq 0x5050
movzwl 0xa5e2(%rip), %esi      # 0x113d8
leaq 0x5529(%rip), %rdi      # 0xc326
xorl %eax, %eax
callq 0x5050
movzbl 0xa5cf(%rip), %esi      # 0x113da
leaq 0x551f(%rip), %rdi      # 0xc331
xorl %eax, %eax
callq 0x5050
movzbl 0xa5bb(%rip), %esi      # 0x113db
leaq 0x5515(%rip), %rdi      # 0xc33c
xorl %eax, %eax
callq 0x5050
leaq 0x5512(%rip), %rdi      # 0xc347
leaq 0xa5a0(%rip), %rsi      # 0x113dc
xorl %eax, %eax
callq 0x5050
leaq 0x550b(%rip), %rdi      # 0xc355
leaq 0xa5ab(%rip), %rsi      # 0x113fc
xorl %eax, %eax
callq 0x5050
leaq 0x5504(%rip), %rdi      # 0xc363
leaq 0xa5b6(%rip), %rsi      # 0x1141c
xorl %eax, %eax
callq 0x5050
movl $0x12000, %esi          # imm = 0x12000
xorl %edi, %edi
movl $0x3, %edx
movl $0x22, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
xorl %r9d, %r9d
callq 0x55b0
movq %rax, 0xa5ad(%rip)      # 0x11440
cmpq $-0x1, %rax
je 0x7826
movq %rax, %rcx
addq $0x1000, %rcx           # imm = 0x1000
movq %rcx, 0xa592(%rip)      # 0x11440
movl $0x1000, %esi           # imm = 0x1000
movq %rax, %rdi
xorl %edx, %edx
callq 0x5030
movl $0x10000, %edi          # imm = 0x10000
addq 0xa577(%rip), %rdi      # 0x11440
movl $0x1000, %esi           # imm = 0x1000
xorl %edx, %edx
callq 0x5030
movl $0x70, %esi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x5130
cmpl $0x0, 0xa55d(%rip)      # 0x11448
je 0x6ef9
leaq 0x54b0(%rip), %rdi      # 0xc3a4
callq 0x5120
movzwl 0xa4d1(%rip), %r14d     # 0x113d2
movl $0x4000, %esi           # imm = 0x4000
xorl %edi, %edi
movl $0x3, %edx
movl $0x22, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
xorl %r9d, %r9d
callq 0x55b0
cmpq $-0x1, %rax
je 0x6fd7
movl %r14d, %r13d
andl $0x3fff, %r13d          # imm = 0x3FFF
shrl $0xe, %r14d
leaq 0xa541(%rip), %rcx      # 0x11480
leaq (%rcx,%r14,8), %r12
leaq 0x5478(%rip), %r15      # 0xc3c2
movq %rax, (%r12)
movl %r13d, %edi
addq %rax, %rdi
movl $0x4000, %edx           # imm = 0x4000
subl %r13d, %edx
movl $0x1, %esi
movq %rbx, %rcx
callq 0x5400
cmpl $0x0, 0xa4d8(%rip)      # 0x11448
je 0x6f82
movq %r15, %rdi
movl %r14d, %esi
movq %rax, %rdx
xorl %eax, %eax
callq 0x5050
movq %rbx, %rdi
callq 0x54a0
testl %eax, %eax
jne 0x7004
movq %rbx, %rdi
callq 0x5280
testl %eax, %eax
jne 0x6ff6
cmpq $0x1f, %r14
je 0x7810
incq %r14
xorl %r13d, %r13d
movl $0x4000, %esi           # imm = 0x4000
xorl %edi, %edi
movl $0x3, %edx
movl $0x22, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
xorl %r9d, %r9d
callq 0x55b0
addq $0x8, %r12
cmpq $-0x1, %rax
jne 0x6f4a
leaq 0x53d1(%rip), %rdi      # 0xc3af
leaq 0x539e(%rip), %rsi      # 0xc383
leaq 0x53a1(%rip), %rcx      # 0xc38d
movl $0x31c, %edx            # imm = 0x31C
callq 0x5160
leaq 0x53d3(%rip), %rdi      # 0xc3d0
xorl %eax, %eax
callq 0x5050
movq %rbx, %rdi
callq 0x54b0
movb 0xa3c8(%rip), %al       # 0x113da
movq 0xa427(%rip), %rcx      # 0x11440
movb %al, 0xff06(%rcx)
movb 0xa3b6(%rip), %al       # 0x113db
movb %al, 0xff07(%rcx)
movsd 0x4ffd(%rip), %xmm0     # 0xc030
movsd %xmm0, 0xa429(%rip)     # 0x11464
leaq 0x5996(%rip), %rdi      # 0xc9d8
callq 0x7ac9
testq %rax, %rax
je 0x7111
movq %rax, %rbx
leaq 0x5680(%rip), %rsi      # 0xc6da
leaq 0x20(%rsp), %rdx
leaq 0xc0(%rsp), %rcx
movq %rax, %rdi
xorl %eax, %eax
callq 0x50f0
cmpl $0x2, %eax
jne 0x7109
movl $0x756c6f76, %r15d      # imm = 0x756C6F76
movl $0x656d75, %ebp         # imm = 0x656D75
leaq 0xc0(%rsp), %r14
leaq 0x5646(%rip), %r12      # 0xc6da
leaq 0x20(%rsp), %r13
movl 0x20(%rsp), %eax
xorl %r15d, %eax
movl 0x23(%rsp), %ecx
xorl %ebp, %ecx
orl %eax, %ecx
jne 0x70f1
movq %r14, %rdi
callq 0x53a0
cmpl $0x64, %eax
movl $0x64, %esi
cmovll %eax, %esi
testl %esi, %esi
movl $0x0, %ecx
cmovlel %ecx, %esi
xorps %xmm0, %xmm0
cvtsi2ss %esi, %xmm0
divss 0x4f7e(%rip), %xmm0     # 0xc054
movss %xmm0, 0xa386(%rip)     # 0x11464
cmpl $0x63, %eax
jg 0x70f1
leaq 0x5390(%rip), %rdi      # 0xc47a
xorl %eax, %eax
callq 0x9fa4
movq %rbx, %rdi
movq %r12, %rsi
movq %r13, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x50f0
cmpl $0x2, %eax
je 0x7099
movq %rbx, %rdi
callq 0x54b0
cmpb $0x0, 0xa337(%rip)      # 0x1144f
je 0x7123
leaq 0xa26f(%rip), %rax      # 0x11390
jmp 0x712a
leaq 0xa21e(%rip), %rax      # 0x11348
movq (%rax), %rax
leaq 0xa694(%rip), %rbx      # 0x117c8
movq %rax, (%rbx)
cmpb $0x0, (%rax)
jne 0x71a7
movb $0x1, 0xa30a(%rip)      # 0x1144d
movl $0x3f800000, 0xa317(%rip) # imm = 0x3F800000
movq 0xa2fc(%rip), %rsi      # 0x11450
testq %rsi, %rsi
je 0x7845
movss 0xa2f3(%rip), %xmm0     # 0x11458
xorps %xmm1, %xmm1
ucomiss %xmm0, %xmm1
jb 0x717f
movl $0x47ea6000, 0xa2e1(%rip) # imm = 0x47EA6000
movss 0x4ed9(%rip), %xmm0     # 0xc058
divss 0x4ec9(%rip), %xmm0     # 0xc050
cvtss2sd %xmm0, %xmm0
leaq 0x5286(%rip), %rdi      # 0xc418
movb $0x1, %al
callq 0x5050
movq 0xa2b0(%rip), %rax      # 0x11450
movq (%rbx), %rcx
movq %rax, 0x28(%rcx)
cmpb $0x0, 0xa29f(%rip)      # 0x1144d
jne 0x71b5
callq 0x5320
leaq 0xc0(%rsp), %r14
movq %r14, %rdi
callq 0x54e0
movq %r14, %rdi
movl $0x1c, %esi
callq 0x5440
movq %r14, %rdi
movl $0x2, %esi
callq 0x5440
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
movq %r14, %rsi
movl $0x800, %edx            # imm = 0x800
callq 0x50b0
movl %eax, %ebx
xorl %edi, %edi
movq %r14, %rsi
xorl %edx, %edx
callq 0x5350
movl $0x1, %r15d
movl $0x1, %edi
xorl %esi, %esi
callq 0x5530
movl %eax, %ebp
movups 0x55ae(%rip), %xmm0     # 0xc7c8
leaq 0xa0(%rsp), %rdx
movaps %xmm0, 0x10(%rdx)
movups 0x558b(%rip), %xmm0     # 0xc7b8
movaps %xmm0, (%rdx)
movl %eax, %edi
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x5580
movl $0x4, %edi
movl $0x8, %esi
callq 0x5490
leaq 0x8(%rsp), %r14
movq %rax, (%r14)
callq 0xa059
movq (%r14), %rcx
movabsq $0x100000000, %rdx      # imm = 0x100000000
movq %rdx, (%rcx)
movl %ebx, 0x8(%rcx)
movl %r15d, 0xc(%rcx)
movl %ebp, 0x10(%rcx)
movl %r15d, 0x14(%rcx)
movl %eax, 0x18(%rcx)
movl %r15d, 0x1c(%rcx)
movq %r14, %rdi
movl $0x4, %esi
callq 0x92e4
movl %eax, %ebx
cmpb $0x0, 0xa1bb(%rip)      # 0x1144d
jne 0x72a3
movq 0x9d4d(%rip), %rax      # 0x10fe8
movq (%rax), %rdi
callq 0x54b0
movslq %ebx, %rax
movq %rax, 0x18(%rsp)
addl $-0x4, %eax
movl %eax, 0x14(%rsp)
xorl %ebx, %ebx
leaq 0x20(%rsp), %r13
leaq 0x7(%rsp), %r12
leaq 0x4dd7(%rip), %r14      # 0xc09c
callq 0x8f7f
callq 0xb02f
movq 0xa1aa(%rip), %rsi      # 0x11480
movq 0xa163(%rip), %r15      # 0x11440
testq %rsi, %rsi
je 0x72ef
movl $0x4000, %edx           # imm = 0x4000
movq %r15, %rdi
callq 0x55a0
movq 0xa192(%rip), %rsi      # 0x11488
testq %rsi, %rsi
je 0x730c
leaq 0x4000(%r15), %rdi
movl $0x4000, %edx           # imm = 0x4000
callq 0x55a0
movq $0x0, 0xa0a9(%rip) # 0x113c0
leaq 0x8000(%r15), %rdi
movl $0x8000, %edx           # imm = 0x8000
xorl %esi, %esi
callq 0x5080
movzwl 0xa0a1(%rip), %esi      # 0x113d2
addq %r15, %rsi
movl $0x62, %edx
movq %r15, %rdi
callq 0x55a0
movzwl 0xa090(%rip), %eax      # 0x113d8
addl $-0x2, %eax
movl $0xffff, %edx           # imm = 0xFFFF
andl %edx, %eax
movb %bl, (%r15,%rax)
movq 0xa0e3(%rip), %rax      # 0x11440
movzwl 0xa074(%rip), %ecx      # 0x113d8
decl %ecx
andl %edx, %ecx
movb %bl, (%rax,%rcx)
movzwl 0xa066(%rip), %eax      # 0x113d8
addl $-0x2, %eax
movw %ax, 0xa04c(%rip)       # 0x113c8
movzwl 0xa051(%rip), %eax      # 0x113d4
movw %ax, 0xa040(%rip)       # 0x113ca
movb 0xa0cc(%rip), %al       # 0x1145c
movb %al, 0xa02b(%rip)       # 0x113c1
movq 0xa0a3(%rip), %rax      # 0x11440
movb $0x1, 0xffff(%rax)
movb 0xa030(%rip), %cl       # 0x113da
movb %cl, 0xff06(%rax)
movb 0xa025(%rip), %cl       # 0x113db
movb %cl, 0xff07(%rax)
xorl %ebx, %ebx
leaq 0x4dfb(%rip), %r15      # 0xc1c0
leal 0xff10(%rbx), %eax
movzbl (%rbx,%r15), %esi
movzwl %ax, %edi
callq 0x784a
incq %rbx
cmpq $0x17, %rbx
jne 0x73c5
movq 0xa058(%rip), %rax      # 0x11440
movaps 0x4c51(%rip), %xmm0     # 0xc040
movups %xmm0, 0xff30(%rax)
xorl %ebx, %ebx
xorl %edi, %edi
callq 0x8fe1
xorps %xmm0, %xmm0
movss %xmm0, 0x10(%rsp)
leaq 0x6(%rsp), %r15
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x5310
cmpl $-0x1, %eax
jne 0x7434
leaq 0x500a(%rip), %rdi      # 0xc437
callq 0x5560
jmp 0x740d
movq 0x8(%rsp), %rdi
addq $0x20, %rdi
movl 0x14(%rsp), %esi
callq 0x8fe9
movss 0x10(%rsp), %xmm1
addss %xmm0, %xmm1
movss 0xa000(%rip), %xmm0     # 0x11458
ucomiss 0x4c09(%rip), %xmm0     # 0xc068
jbe 0x746a
ucomiss %xmm0, %xmm1
ja 0x7730
movq 0x8(%rsp), %rax
testb $0x1, 0xe(%rax)
movss %xmm1, 0x10(%rsp)
je 0x753d
xorl %r15d, %r15d
movq 0x8(%rsp), %rax
movl 0x8(%rax), %edi
movl $0x80, %edx
movq %r13, %rsi
callq 0x51a0
cmpq $-0x1, %rax
je 0x74be
movb $0x1, %cl
movl 0x20(%rsp), %edx
cmpl $0x1c, %edx
je 0x74b4
cmpl $0x2, %edx
je 0x7730
movl %r15d, %ecx
movl %ecx, %r15d
testq %rax, %rax
jg 0x7482
jmp 0x74cf
callq 0x5410
cmpl $0xb, (%rax)
jne 0x770e
movl %r15d, %ecx
testb $0x1, %cl
leaq 0x6(%rsp), %r15
je 0x7538
cmpb $0x0, 0x9f6d(%rip)      # 0x1144d
jne 0x7538
callq 0x5430
movq 0x9ae2(%rip), %rax      # 0x10fd0
movq (%rax), %rdi
callq 0x52c0
movq 0x9ad3(%rip), %rax      # 0x10fd0
movq (%rax), %rdi
callq 0x52d0
movq 0x9ac4(%rip), %rax      # 0x10fd0
movq (%rax), %rcx
testq %rcx, %rcx
je 0x7522
movswl 0x4(%rcx), %eax
incl %eax
movswl 0x6(%rcx), %ecx
incl %ecx
jmp 0x752c
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl %eax, 0x9f42(%rip)      # 0x11474
movl %ecx, 0x9f38(%rip)      # 0x11470
movq 0x8(%rsp), %rax
testb $0x1, 0x16(%rax)
je 0x756c
movl $0x8, %edx
movl %ebp, %edi
movq %r13, %rsi
callq 0x51a0
cmpq $-0x1, %rax
jne 0x7562
callq 0x5410
cmpl $0xb, (%rax)
je 0x7543
callq 0xab92
movq 0x8(%rsp), %rax
movzwl 0x6(%rax), %ecx
movl %ecx, %edx
andb $0x1, %dl
movb %dl, 0x6(%rsp)
movzwl 0x1e(%rax), %eax
movl %eax, %edx
andb $0x1, %dl
movb %dl, 0x7(%rsp)
orl %ecx, %eax
testb $0x1, %al
je 0x740d
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0xb144
cmpl $0x5, %eax
ja 0x76f3
movl %eax, %eax
movslq (%r14,%rax,4), %rax
addq %r14, %rax
jmpq *%rax
movl 0x20(%rsp), %edi
leal 0x30(%rdi), %r15d
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x8f5d
testb %al, %al
leaq 0x4e88(%rip), %rdx      # 0xc455
leaq 0x5105(%rip), %rax      # 0xc6d9
cmovneq %rax, %rdx
leaq 0x4e62(%rip), %rdi      # 0xc441
movl %r15d, %esi
leaq 0x6(%rsp), %r15
xorl %eax, %eax
callq 0x9fa4
jmp 0x76f3
movl 0x20(%rsp), %esi
xorps %xmm0, %xmm0
cvtsi2ss %esi, %xmm0
divss 0x4a4e(%rip), %xmm0     # 0xc054
movss %xmm0, 0x9e56(%rip)     # 0x11464
leaq 0x4e65(%rip), %rdi      # 0xc47a
xorl %eax, %eax
callq 0x9fa4
jmp 0x76f3
movl 0x20(%rsp), %eax
testl %eax, %eax
js 0x7635
cmpl 0x9e31(%rip), %eax      # 0x11460
jl 0x7723
leaq 0x4e1c(%rip), %rdi      # 0xc458
xorl %eax, %eax
callq 0x9fa4
jmp 0x76f3
movl %ebx, %r15d
xorb $0x1, %r15b
testb $0x1, %bl
leaq 0x4e12(%rip), %rsi      # 0xc46b
leaq 0x4e12(%rip), %rax      # 0xc472
cmovneq %rax, %rsi
leaq 0x4dfc(%rip), %rdi      # 0xc467
xorl %eax, %eax
callq 0x9fa4
movzbl %r15b, %edi
andl $0x1, %edi
callq 0x8fe1
movl %r15d, %ebx
leaq 0x6(%rsp), %r15
jmp 0x76f3
movl 0x20(%rsp), %eax
movss 0x49c8(%rip), %xmm0     # 0xc05c
testl %eax, %eax
movss 0x49b6(%rip), %xmm2     # 0xc054
je 0x76cb
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
divss %xmm2, %xmm0
addss 0x9db5(%rip), %xmm0     # 0x11468
movss 0x49a5(%rip), %xmm1     # 0xc060
minss %xmm0, %xmm1
movss 0x499d(%rip), %xmm0     # 0xc064
maxss %xmm1, %xmm0
movss %xmm0, 0x9d95(%rip)     # 0x11468
mulss %xmm2, %xmm0
callq 0x50d0
cvttss2si %xmm0, %esi
leaq 0x4da1(%rip), %rdi      # 0xc488
xorl %eax, %eax
callq 0x9fa4
callq 0x9328
cmpb $0x0, 0x6(%rsp)
jne 0x7590
testb $0x1, 0x7(%rsp)
jne 0x7590
jmp 0x740d
leaq 0x4d27(%rip), %rdi      # 0xc43c
callq 0x5560
testb $0x1, %r15b
jmp 0x74d2
movl %eax, 0x9d33(%rip)      # 0x1145c
xorl %ebx, %ebx
jmp 0x72c5
leaq 0x6158(%rip), %rdi      # 0xd88f
callq 0x7ac9
testq %rax, %rax
je 0x7776
movq %rax, %rbx
movss 0x9d18(%rip), %xmm0     # 0x11464
mulss 0x4900(%rip), %xmm0     # 0xc054
callq 0x50d0
cvttss2si %xmm0, %edx
leaq 0x5046(%rip), %rsi      # 0xc7aa
movq %rbx, %rdi
xorl %eax, %eax
callq 0x5570
movq %rbx, %rdi
callq 0x54b0
callq 0xb01d
callq 0x943d
xorl %r15d, %r15d
jmp 0x77bb
movq 0x985c(%rip), %rax      # 0x10fe8
movq (%rax), %rdi
leaq 0x4db0(%rip), %rsi      # 0xc546
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5570
jmp 0x77b5
movq %r14, %rdi
callq 0x55f0
jmp 0x77b5
leaq (%r14,%r13,8), %rdi
callq 0x566f
movl $0x1, %r15d
movl %r15d, %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x562e
jmp 0x77bb
movq 0x980a(%rip), %rax      # 0x10fe8
movq (%rax), %rdi
leaq 0x4a77(%rip), %rsi      # 0xc25f
xorl %eax, %eax
callq 0x5570
jmp 0x77bb
movq 0x97f0(%rip), %rcx      # 0x10fe8
movq (%rcx), %rdi
leaq 0x4a9a(%rip), %rsi      # 0xc29c
movl %r12d, %edx
movl %eax, %ecx
xorl %eax, %eax
callq 0x5570
jmp 0x77bb
leaq 0x4bd1(%rip), %rdi      # 0xc3e8
callq 0x5120
movl $0x1, %edi
callq 0x5150
leaq 0x4b44(%rip), %rdi      # 0xc371
leaq 0x4b4f(%rip), %rsi      # 0xc383
leaq 0x4b52(%rip), %rcx      # 0xc38d
movl $0x30b, %edx            # imm = 0x30B
callq 0x5160
callq 0x564a