// File: /workspace/github_c_makefile_star2_O1/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 0x5b18(%rip), %rsi      # 0xc689
movl $0x6, %edi
callq 0x5550
movq (%r14), %rbx
leaq 0x5622(%rip), %r15      # 0xc1a7
leaq 0x5494(%rip), %r12      # 0xc020
movq 0xa445(%rip), %r13      # 0x10fd8
movl %ebp, %edi
movq %r14, %rsi
movq %r15, %rdx
callq 0x5190
cmpl $0x6c, %eax
jle 0x6bc3
addl $-0x6d, %eax
cmpl $0xa, %eax
ja 0x77fb
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movb $0x1, 0xa88b(%rip)      # 0x1144c
jmp 0x6b93
cmpl $0x64, %eax
jne 0x6c22
movb $0x1, 0xa87e(%rip)      # 0x1144d
incl 0xa873(%rip)            # 0x11448
jmp 0x6b93
movb $0x1, 0xa86f(%rip)      # 0x1144d
jmp 0x6b93
movb $0x1, 0xa868(%rip)      # 0x1144f
movq (%r13), %rdi
callq 0x5420
movq %rax, 0xa859(%rip)      # 0x11450
jmp 0x6b93
movb $0x1, 0xa84e(%rip)      # 0x1144e
jmp 0x6b93
movq (%r13), %rdi
xorl %esi, %esi
callq 0x5340
mulss 0x53ef(%rip), %xmm0     # 0xc004
movss %xmm0, 0xa83b(%rip)     # 0x11458
jmp 0x6b93
cmpl $-0x1, %eax
je 0x6c53
cmpl $0x68, %eax
jne 0x77fb
movq 0xa3c1(%rip), %rax      # 0x10ff8
movq (%rax), %rdi
leaq 0x58b5(%rip), %rsi      # 0xc4f6
xorl %r15d, %r15d
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5570
jmp 0x7831
movq 0xa35e(%rip), %rax      # 0x10fb8
movslq (%rax), %r13
cmpl %ebp, %r13d
jge 0x7818
movq (%r14,%r13,8), %rdi
leaq 0x5cce(%rip), %rsi      # 0xc93f
callq 0x51d0
testq %rax, %rax
je 0x7822
movq %rax, %rbx
leaq 0xa743(%rip), %rdi      # 0x113cc
movl $0x70, %esi
movl $0x1, %edx
movq %rax, %rcx
callq 0x5400
movl $0x1, %r15d
cmpq $0x1, %rax
jne 0x7831
movzwl 0xa71a(%rip), %eax      # 0x113cc
xorl $0x4247, %eax           # imm = 0x4247
movzbl 0xa710(%rip), %ecx      # 0x113ce
xorl $0x53, %ecx
orw %ax, %cx
jne 0x7846
movzbl 0xa6fe(%rip), %edx      # 0x113cf
cmpl $0x1, %edx
jne 0x784d
leaq -0x1(%r13), %rax
subl %eax, %ebp
movzbl 0xa6e8(%rip), %r12d     # 0x113d0
movl %r12d, 0xa771(%rip)     # 0x11460
cmpl $0x3, %ebp
jl 0x6d07
leaq (%r14,%r13,8), %rax
addq $-0x8, %rax
movq 0x10(%rax), %rdi
callq 0x53a0
jmp 0x6d1b
movzbl 0xa6c3(%rip), %ecx      # 0x113d1
cmpl $0x2, %ecx
movl $0x1, %eax
cmovgel %ecx, %eax
decl %eax
movl %eax, 0xa73b(%rip)      # 0x1145c
cmpl %r12d, %eax
jge 0x7867
cmpl $0x0, 0xa717(%rip)      # 0x11448
je 0x6e48
leaq 0x5549(%rip), %rdi      # 0xc287
leaq 0xa687(%rip), %rsi      # 0x113cc
xorl %eax, %eax
callq 0x5050
movzbl 0xa67c(%rip), %esi      # 0x113cf
leaq 0x553a(%rip), %rdi      # 0xc294
xorl %eax, %eax
callq 0x5050
movzbl 0xa668(%rip), %esi      # 0x113d0
leaq 0x5530(%rip), %rdi      # 0xc29f
xorl %eax, %eax
callq 0x5050
movzbl 0xa654(%rip), %esi      # 0x113d1
leaq 0x5526(%rip), %rdi      # 0xc2aa
xorl %eax, %eax
callq 0x5050
movzwl 0xa640(%rip), %esi      # 0x113d2
leaq 0x551c(%rip), %rdi      # 0xc2b5
xorl %eax, %eax
callq 0x5050
movzwl 0xa62d(%rip), %esi      # 0x113d4
leaq 0x5512(%rip), %rdi      # 0xc2c0
xorl %eax, %eax
callq 0x5050
movzwl 0xa61a(%rip), %esi      # 0x113d6
leaq 0x5508(%rip), %rdi      # 0xc2cb
xorl %eax, %eax
callq 0x5050
movzwl 0xa607(%rip), %esi      # 0x113d8
leaq 0x54fe(%rip), %rdi      # 0xc2d6
xorl %eax, %eax
callq 0x5050
movzbl 0xa5f4(%rip), %esi      # 0x113da
leaq 0x54f4(%rip), %rdi      # 0xc2e1
xorl %eax, %eax
callq 0x5050
movzbl 0xa5e0(%rip), %esi      # 0x113db
leaq 0x54ea(%rip), %rdi      # 0xc2ec
xorl %eax, %eax
callq 0x5050
leaq 0x54e7(%rip), %rdi      # 0xc2f7
leaq 0xa5c5(%rip), %rsi      # 0x113dc
xorl %eax, %eax
callq 0x5050
leaq 0x54e0(%rip), %rdi      # 0xc305
leaq 0xa5d0(%rip), %rsi      # 0x113fc
xorl %eax, %eax
callq 0x5050
leaq 0x54d9(%rip), %rdi      # 0xc313
leaq 0xa5db(%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, 0xa5d2(%rip)      # 0x11440
cmpq $-0x1, %rax
je 0x78bb
movq %rax, %rcx
addq $0x1000, %rcx           # imm = 0x1000
movq %rcx, 0xa5b7(%rip)      # 0x11440
movl $0x1000, %esi           # imm = 0x1000
movq %rax, %rdi
xorl %edx, %edx
callq 0x5030
movl $0x10000, %edi          # imm = 0x10000
addq 0xa59c(%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, 0xa582(%rip)      # 0x11448
je 0x6ed4
leaq 0x5485(%rip), %rdi      # 0xc354
callq 0x5120
movzwl 0xa4f6(%rip), %r12d     # 0x113d2
movl %r12d, %ebp
shrl $0xe, %ebp
andl $0x3fff, %r12d          # imm = 0x3FFF
leaq 0xa590(%rip), %r13      # 0x11480
leaq 0x547b(%rip), %r15      # 0xc372
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 0x7886
movslq %ebp, %rcx
movq %rax, (%r13,%rcx,8)
movl %r12d, %edi
addq %rax, %rdi
movl $0x4000, %edx           # imm = 0x4000
subl %r12d, %edx
movl $0x1, %esi
movq %rbx, %rcx
callq 0x5400
cmpl $0x0, 0xa4fe(%rip)      # 0x11448
je 0x6f5b
movq %r15, %rdi
movl %ebp, %esi
movq %rax, %rdx
xorl %eax, %eax
callq 0x5050
movq %rbx, %rdi
callq 0x54a0
testl %eax, %eax
je 0x6f6c
xorl %r14d, %r14d
jmp 0x6f9c
movq %rbx, %rdi
callq 0x5280
testl %eax, %eax
je 0x6f8b
xorl %r14d, %r14d
leaq 0x53fe(%rip), %rdi      # 0xc380
xorl %eax, %eax
callq 0x5050
jmp 0x6f9c
cmpl $0x1f, %ebp
jge 0x78a5
incl %ebp
movb $0x1, %r14b
xorl %r12d, %r12d
testb %r14b, %r14b
jne 0x6ef7
movq %rbx, %rdi
callq 0x54b0
movb 0xa427(%rip), %al       # 0x113da
movq 0xa486(%rip), %rcx      # 0x11440
movb %al, 0xff06(%rcx)
movb 0xa415(%rip), %al       # 0x113db
movb %al, 0xff07(%rcx)
movabsq $0x3f8000003f800000, %rax # imm = 0x3F8000003F800000
movq %rax, 0xa487(%rip)      # 0x11464
leaq 0x595b(%rip), %rdi      # 0xc93f
callq 0x7b71
testq %rax, %rax
je 0x70b3
movq %rax, %rbx
leaq 0x568e(%rip), %rsi      # 0xc68a
leaq 0x20(%rsp), %rdx
leaq 0xc0(%rsp), %rcx
movq %rax, %rdi
xorl %eax, %eax
callq 0x50f0
cmpl $0x2, %eax
jne 0x70ab
movl $0x756c6f76, %r15d      # imm = 0x756C6F76
movl $0x656d75, %ebp         # imm = 0x656D75
leaq 0xc0(%rsp), %r14
leaq 0x5654(%rip), %r12      # 0xc68a
leaq 0x20(%rsp), %r13
movl 0x20(%rsp), %eax
xorl %r15d, %eax
movl 0x23(%rsp), %ecx
xorl %ebp, %ecx
orl %eax, %ecx
jne 0x7093
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 0x4f90(%rip), %xmm0     # 0xc008
movss %xmm0, 0xa3e4(%rip)     # 0x11464
cmpl $0x63, %eax
jg 0x7093
leaq 0x539e(%rip), %rdi      # 0xc42a
xorl %eax, %eax
callq 0xa06c
movq %rbx, %rdi
movq %r12, %rsi
movq %r13, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x50f0
cmpl $0x2, %eax
je 0x703b
movq %rbx, %rdi
callq 0x54b0
cmpb $0x0, 0xa395(%rip)      # 0x1144f
je 0x70c5
leaq 0xa2cd(%rip), %rax      # 0x11390
jmp 0x70cc
leaq 0xa27c(%rip), %rax      # 0x11348
movq (%rax), %rax
leaq 0xa6f2(%rip), %rbx      # 0x117c8
movq %rax, (%rbx)
cmpb $0x0, (%rax)
jne 0x7145
movb $0x1, 0xa368(%rip)      # 0x1144d
movl $0x3f800000, 0xa375(%rip) # imm = 0x3F800000
movq 0xa35a(%rip), %rsi      # 0x11450
testq %rsi, %rsi
je 0x78da
xorps %xmm0, %xmm0
ucomiss 0xa34f(%rip), %xmm0     # 0x11458
jb 0x7115
movl $0x47ea6000, 0xa343(%rip) # imm = 0x47EA6000
movss 0xa33b(%rip), %xmm0     # 0x11458
divss 0x4edf(%rip), %xmm0     # 0xc004
cvtss2sd %xmm0, %xmm0
leaq 0x5298(%rip), %rdi      # 0xc3c8
movb $0x1, %al
callq 0x5050
movq 0xa312(%rip), %rax      # 0x11450
movq (%rbx), %rcx
movq %rax, 0x28(%rcx)
cmpb $0x0, 0xa301(%rip)      # 0x1144d
jne 0x7153
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, %ebp
movl $0x1, %edi
xorl %esi, %esi
callq 0x5530
movl %eax, %r15d
movups 0x55d8(%rip), %xmm0     # 0xc790
leaq 0xa0(%rsp), %rdx
movaps %xmm0, 0x10(%rdx)
movups 0x55b5(%rip), %xmm0     # 0xc780
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 0xa121
movq (%r14), %rcx
movabsq $0x100000000, %rdx      # imm = 0x100000000
movq %rdx, (%rcx)
movl %ebx, 0x8(%rcx)
movl %ebp, 0xc(%rcx)
movl %r15d, 0x10(%rcx)
movl %ebp, 0x14(%rcx)
movl %eax, 0x18(%rcx)
movl %ebp, 0x1c(%rcx)
movq %r14, %rdi
movl $0x4, %esi
callq 0x9471
movl %eax, %ebx
cmpb $0x0, 0xa21f(%rip)      # 0x1144d
jne 0x723f
movq 0x9db1(%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
movl $0xffff, %ebp           # imm = 0xFFFF
leaq 0x4f14(%rip), %r12      # 0xc170
leaq 0x20(%rsp), %r13
leaq 0x4de4(%rip), %r14      # 0xc04c
movl %r15d, 0x10(%rsp)
callq 0x90ee
callq 0xaf21
movq 0xa202(%rip), %rsi      # 0x11480
testq %rsi, %rsi
je 0x7294
movq 0xa1b6(%rip), %rdi      # 0x11440
movl $0x4000, %edx           # imm = 0x4000
callq 0x55a0
movq 0xa1ed(%rip), %rsi      # 0x11488
testq %rsi, %rsi
je 0x72b9
movq 0xa199(%rip), %rdi      # 0x11440
movl $0x4000, %eax           # imm = 0x4000
addq %rax, %rdi
movl $0x4000, %edx           # imm = 0x4000
callq 0x55a0
movl $0x0, 0xa105(%rip)      # 0x113c8
movq $0x0, 0xa0f2(%rip) # 0x113c0
movq 0xa16b(%rip), %r15      # 0x11440
leaq 0x8000(%r15), %rdi
movl $0x8000, %edx           # imm = 0x8000
xorl %esi, %esi
callq 0x5080
movzwl 0xa0e3(%rip), %esi      # 0x113d2
addq %r15, %rsi
movl $0x62, %edx
movq %r15, %rdi
callq 0x55a0
movzwl 0xa0d2(%rip), %eax      # 0x113d8
addl $-0x2, %eax
andl %ebp, %eax
movb %bl, (%r15,%rax)
movq 0xa12a(%rip), %rax      # 0x11440
movzwl 0xa0bb(%rip), %ecx      # 0x113d8
decl %ecx
andl %ebp, %ecx
movb %bl, (%rax,%rcx)
movzwl 0xa0ad(%rip), %eax      # 0x113d8
addl $-0x2, %eax
movw %ax, 0xa093(%rip)       # 0x113c8
movzwl 0xa098(%rip), %eax      # 0x113d4
movw %ax, 0xa087(%rip)       # 0x113ca
movb 0xa113(%rip), %al       # 0x1145c
movb %al, 0xa072(%rip)       # 0x113c1
movq 0xa0ea(%rip), %rax      # 0x11440
movb $0x1, 0xffff(%rax)
movb 0xa077(%rip), %cl       # 0x113da
movb %cl, 0xff06(%rax)
movb 0xa06c(%rip), %cl       # 0x113db
movb %cl, 0xff07(%rax)
xorl %r15d, %r15d
leal 0xff10(%r15), %eax
movzbl (%r15,%r12), %esi
movzwl %ax, %edi
callq 0x78df
incq %r15
cmpq $0x17, %r15
jne 0x7378
movq 0xa0a4(%rip), %rax      # 0x11440
movaps 0x53cd(%rip), %xmm0     # 0xc770
movups %xmm0, 0xff30(%rax)
xorl %ebp, %ebp
xorl %edi, %edi
callq 0x9150
xorps %xmm1, %xmm1
leaq 0x3(%rsp), %rbx
leaq 0x2(%rsp), %r15
movss %xmm1, 0x4(%rsp)
movq 0x8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x5310
cmpl $-0x1, %eax
je 0x74ee
movq 0x8(%rsp), %rdi
addq $0x20, %rdi
movl 0x14(%rsp), %esi
callq 0x9158
movss 0x4(%rsp), %xmm1
addss %xmm0, %xmm1
movss 0xa051(%rip), %xmm0     # 0x11458
ucomiss 0x4c0a(%rip), %xmm0     # 0xc018
jbe 0x741f
movl $0xd, %r12d
ucomiss %xmm0, %xmm1
ja 0x7746
movq 0x8(%rsp), %rax
testb $0x1, 0xe(%rax)
movss %xmm1, 0x4(%rsp)
je 0x7528
xorl %eax, %eax
movl %eax, %r12d
movq 0x8(%rsp), %rax
movl 0x8(%rax), %edi
movl $0x80, %edx
movq %r13, %rsi
callq 0x51a0
movq %rax, %r15
cmpq $-0x1, %rax
je 0x746c
movb $0x1, %al
movl 0x20(%rsp), %ecx
cmpl $0x1c, %ecx
je 0x7479
cmpl $0x2, %ecx
jne 0x7476
jmp 0x750b
callq 0x5410
cmpl $0xb, (%rax)
jne 0x7480
movl %r12d, %eax
testq %r15, %r15
jg 0x7436
jmp 0x748e
leaq 0x4f65(%rip), %rdi      # 0xc3ec
callq 0x5560
jmp 0x7476
xorl %r12d, %r12d
movb $0x1, %r15b
testb $0x1, %al
je 0x7514
cmpb $0x0, 0x9fae(%rip)      # 0x1144d
jne 0x7514
callq 0x5430
movq 0x9b23(%rip), %rax      # 0x10fd0
movq (%rax), %rdi
callq 0x52c0
movq 0x9b14(%rip), %rax      # 0x10fd0
movq (%rax), %rdi
callq 0x52d0
movq 0x9b05(%rip), %rax      # 0x10fd0
movq (%rax), %rax
testq %rax, %rax
je 0x7763
movswl 0x4(%rax), %ecx
incl %ecx
movl %ecx, 0x9f91(%rip)      # 0x11474
movswl 0x6(%rax), %eax
incl %eax
jmp 0x7772
leaq 0x4ef2(%rip), %rdi      # 0xc3e7
callq 0x5560
movl $0xb, %r12d
movss 0x4(%rsp), %xmm1
jmp 0x7746
movl $0xd, %r12d
xorl %r15d, %r15d
movss 0x4(%rsp), %xmm1
testb %r15b, %r15b
leaq 0x2(%rsp), %r15
je 0x7746
movq 0x8(%rsp), %rax
testb $0x1, 0x16(%rax)
je 0x7566
movl 0x10(%rsp), %ebx
movl $0x8, %edx
movl %ebx, %edi
movq %r13, %rsi
callq 0x51a0
cmpq $-0x1, %rax
jne 0x7556
callq 0x5410
cmpl $0xb, (%rax)
je 0x7537
callq 0xac54
leaq 0x3(%rsp), %rbx
movss 0x4(%rsp), %xmm1
movq 0x8(%rsp), %rax
movb 0x6(%rax), %cl
andb $0x1, %cl
movb %cl, 0x3(%rsp)
movb 0x1e(%rax), %al
andb $0x1, %al
movb %al, 0x2(%rsp)
cmpb $0x0, 0x3(%rsp)
jne 0x7590
testb $0x1, 0x2(%rsp)
je 0x7743
movq %r13, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0xb036
xorl %r12d, %r12d
cmpl $0x5, %eax
ja 0x7731
movl %eax, %eax
movslq (%r14,%rax,4), %rax
addq %r14, %rax
jmpq *%rax
movl $0xd, %r12d
jmp 0x7612
movl 0x20(%rsp), %esi
xorps %xmm0, %xmm0
cvtsi2ss %esi, %xmm0
divss 0x4a38(%rip), %xmm0     # 0xc008
movss %xmm0, 0x9e8c(%rip)     # 0x11464
xorl %r12d, %r12d
leaq 0x4e48(%rip), %rdi      # 0xc42a
xorl %eax, %eax
callq 0xa06c
jmp 0x7731
movl 0x20(%rsp), %eax
testl %eax, %eax
js 0x7720
cmpl 0x9e60(%rip), %eax      # 0x11460
jge 0x7720
movl %eax, 0x9e50(%rip)      # 0x1145c
movl $0x7, %r12d
xorl %eax, %eax
jmp 0x7733
movl %ebp, %r15d
xorb $0x1, %r15b
movl %r15d, %ebx
andb $0x1, %bl
testb $0x1, %bpl
leaq 0x4dea(%rip), %rsi      # 0xc41b
leaq 0x4dea(%rip), %rax      # 0xc422
cmovneq %rax, %rsi
xorl %r12d, %r12d
leaq 0x4dd1(%rip), %rdi      # 0xc417
xorl %eax, %eax
callq 0xa06c
movzbl %r15b, %edi
leaq 0x2(%rsp), %r15
andl $0x1, %edi
callq 0x9150
movb $0x1, %al
movl %ebx, %ebp
leaq 0x3(%rsp), %rbx
jmp 0x7733
movl 0x20(%rsp), %edi
leal 0x30(%rdi), %r15d
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x90cc
testb %al, %al
leaq 0x4d7e(%rip), %rdx      # 0xc405
leaq 0x4ffb(%rip), %rax      # 0xc689
cmovneq %rax, %rdx
xorl %r12d, %r12d
leaq 0x4d55(%rip), %rdi      # 0xc3f1
movl %r15d, %esi
leaq 0x2(%rsp), %r15
xorl %eax, %eax
callq 0xa06c
jmp 0x7731
movl 0x20(%rsp), %eax
movss 0x4950(%rip), %xmm0     # 0xc00c
testl %eax, %eax
movss 0x4942(%rip), %xmm2     # 0xc008
je 0x76f3
xorps %xmm0, %xmm0
cvtsi2ss %eax, %xmm0
divss %xmm2, %xmm0
addss 0x9d8d(%rip), %xmm0     # 0x11468
movss 0x492d(%rip), %xmm1     # 0xc010
minss %xmm0, %xmm1
movss 0x4925(%rip), %xmm0     # 0xc014
maxss %xmm1, %xmm0
movss %xmm0, 0x9d6d(%rip)     # 0x11468
mulss %xmm2, %xmm0
callq 0x50d0
cvttss2si %xmm0, %esi
xorl %r12d, %r12d
leaq 0x4d26(%rip), %rdi      # 0xc438
xorl %eax, %eax
callq 0xa06c
callq 0x94b5
jmp 0x7731
xorl %r12d, %r12d
leaq 0x4cde(%rip), %rdi      # 0xc408
xorl %eax, %eax
callq 0xa06c
movb $0x1, %al
movss 0x4(%rsp), %xmm1
testb %al, %al
jne 0x757e
jmp 0x7746
xorl %r12d, %r12d
cmpl $0xa, %r12d
jg 0x7757
testl %r12d, %r12d
je 0x73c0
jmp 0x7783
cmpl $0xb, %r12d
je 0x73c0
jmp 0x77a0
movl $0xffffffff, 0x9d07(%rip) # imm = 0xFFFFFFFF
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movss 0x4(%rsp), %xmm1
movl %eax, 0x9cf2(%rip)      # 0x11470
jmp 0x751a
cmpl $0x7, %r12d
movl $0x0, %ebx
movl $0xffff, %ebp           # imm = 0xFFFF
leaq 0x49d8(%rip), %r12      # 0xc170
je 0x726d
jmp 0x77f6
cmpl $0xd, %r12d
jne 0x77f6
leaq 0x6022(%rip), %rdi      # 0xd7cf
callq 0x7b71
testq %rax, %rax
je 0x77ec
movq %rax, %rbx
movss 0x9ca2(%rip), %xmm0     # 0x11464
mulss 0x483e(%rip), %xmm0     # 0xc008
callq 0x50d0
cvttss2si %xmm0, %edx
leaq 0x4f80(%rip), %rsi      # 0xc75a
movq %rbx, %rdi
xorl %eax, %eax
callq 0x5570
movq %rbx, %rdi
callq 0x54b0
callq 0xaf0f
callq 0x95da
xorl %r15d, %r15d
jmp 0x7831
movq 0x97e6(%rip), %rax      # 0x10fe8
movq (%rax), %rdi
leaq 0x4cea(%rip), %rsi      # 0xc4f6
movq %rbx, %rdx
xorl %eax, %eax
callq 0x5570
jmp 0x782b
movq %r14, %rdi
callq 0x55f0
jmp 0x782b
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 0x7831
movq 0x9794(%rip), %rax      # 0x10fe8
movq (%rax), %rdi
leaq 0x49b1(%rip), %rsi      # 0xc20f
xorl %eax, %eax
callq 0x5570
jmp 0x7831
movq 0x977a(%rip), %rcx      # 0x10fe8
movq (%rcx), %rdi
leaq 0x49d4(%rip), %rsi      # 0xc24c
movl %r12d, %edx
movl %eax, %ecx
xorl %eax, %eax
callq 0x5570
jmp 0x7831
leaq 0x4ad2(%rip), %rdi      # 0xc35f
leaq 0x4a9f(%rip), %rsi      # 0xc333
leaq 0x4aa2(%rip), %rcx      # 0xc33d
movl $0x31c, %edx            # imm = 0x31C
callq 0x5160
leaq 0x4aec(%rip), %rdi      # 0xc398
callq 0x5120
movl $0x1, %edi
callq 0x5150
leaq 0x4a5f(%rip), %rdi      # 0xc321
leaq 0x4a6a(%rip), %rsi      # 0xc333
leaq 0x4a6d(%rip), %rcx      # 0xc33d
movl $0x30b, %edx            # imm = 0x30B
callq 0x5160
callq 0x564a