// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x6, %edi
leaq 0x7f15(%rip), %rsi      # 0x1099a
callq 0x5560
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x7a15(%rip), %rdx      # 0x104b8
callq 0x5180
movl %eax, -0x1c(%rbp)
cmpl $-0x1, %eax
je 0x8ba4
movl -0x1c(%rbp), %eax
addl $-0x64, %eax
movl %eax, %ecx
movq %rcx, -0x1f0(%rbp)
subl $0x13, %eax
ja 0x8b80
movq -0x1f0(%rbp), %rax
leaq 0x755e(%rip), %rcx      # 0x10038
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x1, 0xde33(%rip)      # 0x1691d
movl 0xde28(%rip), %eax      # 0x16918
addl $0x1, %eax
movl %eax, 0xde1f(%rip)      # 0x16918
jmp 0x8b9f
movq -0x18(%rbp), %rdi
movq 0xc4ef(%rip), %rax      # 0x14ff8
movq (%rax), %rsi
callq 0x9ae0
movl $0x0, -0x4(%rbp)
jmp 0x9ac7
movb $0x1, 0xddf8(%rip)      # 0x1691c
jmp 0x8b9f
movb $0x1, 0xddf0(%rip)      # 0x1691d
jmp 0x8b9f
movb $0x1, 0xdde8(%rip)      # 0x1691e
jmp 0x8b9f
movb $0x1, 0xdde0(%rip)      # 0x1691f
movq 0xc492(%rip), %rax      # 0x14fd8
movq (%rax), %rdi
callq 0x5420
movq %rax, 0xddcb(%rip)      # 0x16920
jmp 0x8b9f
movq 0xc47a(%rip), %rax      # 0x14fd8
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x5340
movss 0x749a(%rip), %xmm1     # 0x1000c
mulss %xmm1, %xmm0
movss %xmm0, 0xddaa(%rip)     # 0x16928
jmp 0x8b9f
movq -0x18(%rbp), %rdi
movq 0xc45d(%rip), %rax      # 0x14fe8
movq (%rax), %rsi
callq 0x9ae0
movl $0x1, -0x4(%rbp)
jmp 0x9ac7
jmp 0x8a95
movq 0xc40d(%rip), %rax      # 0x14fb8
movl (%rax), %eax
cmpl -0x8(%rbp), %eax
jl 0x8bec
movq 0xc42f(%rip), %rax      # 0x14fe8
movq (%rax), %rdi
leaq 0x78ff(%rip), %rsi      # 0x104c2
movb $0x0, %al
callq 0x5580
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq 0xc410(%rip), %rax      # 0x14fe8
movq (%rax), %rsi
callq 0x9ae0
movl $0x1, -0x4(%rbp)
jmp 0x9ac7
movq 0xc3c5(%rip), %rax      # 0x14fb8
movl (%rax), %ecx
subl $0x1, %ecx
movl -0x8(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x8(%rbp)
movq 0xc3b1(%rip), %rax      # 0x14fb8
movl (%rax), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
movslq %ecx, %rcx
shlq $0x3, %rcx
addq %rcx, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x8332(%rip), %rsi      # 0x10f5f
callq 0x51c0
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x8c69
movq 0xc3a4(%rip), %rax      # 0x14fe8
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdx
leaq 0x7885(%rip), %rsi      # 0x104db
movb $0x0, %al
callq 0x5580
movl $0x1, -0x4(%rbp)
jmp 0x9ac7
movq -0x28(%rbp), %rcx
leaq 0xdc28(%rip), %rdi      # 0x1689c
movl $0x70, %esi
movl $0x1, %edx
callq 0x5400
cmpq $0x1, %rax
je 0x8c95
movl $0x1, -0x4(%rbp)
jmp 0x9ac7
leaq 0xdc00(%rip), %rdi      # 0x1689c
leaq 0x7855(%rip), %rsi      # 0x104f8
movl $0x3, %edx
callq 0x51a0
cmpl $0x0, %eax
je 0x8cd6
movq 0xc32f(%rip), %rax      # 0x14fe8
movq (%rax), %rdi
leaq 0x7839(%rip), %rsi      # 0x104fc
movb $0x0, %al
callq 0x5580
movl $0x1, -0x4(%rbp)
jmp 0x9ac7
movzbl 0xdbc2(%rip), %eax      # 0x1689f
cmpl $0x1, %eax
je 0x8d0d
movq 0xc2ff(%rip), %rax      # 0x14fe8
movq (%rax), %rdi
movzbl 0xdbac(%rip), %edx      # 0x1689f
leaq 0x7826(%rip), %rsi      # 0x10520
movb $0x0, %al
callq 0x5580
movl $0x1, -0x4(%rbp)
jmp 0x9ac7
movzbl 0xdb8c(%rip), %eax      # 0x168a0
movl %eax, 0xdc16(%rip)      # 0x16930
cmpl $0x2, -0x8(%rbp)
jle 0x8d35
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x53a0
movl %eax, -0x1f4(%rbp)
jmp 0x8d77
movl $0x0, -0x2c(%rbp)
movzbl 0xdb5e(%rip), %eax      # 0x168a1
subl $0x1, %eax
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jle 0x8d5c
movl -0x2c(%rbp), %eax
movl %eax, -0x1f8(%rbp)
jmp 0x8d65
movl -0x30(%rbp), %eax
movl %eax, -0x1f8(%rbp)
movl -0x1f8(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x1f4(%rbp)
movl -0x1f4(%rbp), %eax
movl %eax, 0xdba9(%rip)      # 0x1692c
movl 0xdba3(%rip), %eax      # 0x1692c
movzbl 0xdb10(%rip), %ecx      # 0x168a0
cmpl %ecx, %eax
jl 0x8dc5
movq 0xc24d(%rip), %rax      # 0x14fe8
movq (%rax), %rdi
movzbl 0xdafb(%rip), %edx      # 0x168a0
movl 0xdb81(%rip), %ecx      # 0x1692c
leaq 0x77ab(%rip), %rsi      # 0x1055d
movb $0x0, %al
callq 0x5580
movl $0x1, -0x4(%rbp)
jmp 0x9ac7
cmpl $0x0, 0xdb4c(%rip)      # 0x16918
je 0x8eef
leaq 0x77bf(%rip), %rdi      # 0x10598
leaq 0xdabc(%rip), %rsi      # 0x1689c
movb $0x0, %al
callq 0x5050
movzbl 0xdab1(%rip), %esi      # 0x1689f
leaq 0x77b0(%rip), %rdi      # 0x105a5
movb $0x0, %al
callq 0x5050
movzbl 0xda9d(%rip), %esi      # 0x168a0
leaq 0x77a6(%rip), %rdi      # 0x105b0
movb $0x0, %al
callq 0x5050
movzbl 0xda89(%rip), %esi      # 0x168a1
leaq 0x779c(%rip), %rdi      # 0x105bb
movb $0x0, %al
callq 0x5050
movzwl 0xda75(%rip), %esi      # 0x168a2
leaq 0x7792(%rip), %rdi      # 0x105c6
movb $0x0, %al
callq 0x5050
movzwl 0xda62(%rip), %esi      # 0x168a4
leaq 0x7788(%rip), %rdi      # 0x105d1
movb $0x0, %al
callq 0x5050
movzwl 0xda4f(%rip), %esi      # 0x168a6
leaq 0x777e(%rip), %rdi      # 0x105dc
movb $0x0, %al
callq 0x5050
movzwl 0xda3c(%rip), %esi      # 0x168a8
leaq 0x7774(%rip), %rdi      # 0x105e7
movb $0x0, %al
callq 0x5050
movzbl 0xda29(%rip), %esi      # 0x168aa
leaq 0x776a(%rip), %rdi      # 0x105f2
movb $0x0, %al
callq 0x5050
movzbl 0xda15(%rip), %esi      # 0x168ab
leaq 0x7760(%rip), %rdi      # 0x105fd
movb $0x0, %al
callq 0x5050
leaq 0x775d(%rip), %rdi      # 0x10608
leaq 0xd9ea(%rip), %rsi      # 0x1689c
addq $0x10, %rsi
movb $0x0, %al
callq 0x5050
leaq 0x7752(%rip), %rdi      # 0x10616
leaq 0xd9d1(%rip), %rsi      # 0x1689c
addq $0x30, %rsi
movb $0x0, %al
callq 0x5050
leaq 0x7747(%rip), %rdi      # 0x10624
leaq 0xd9b8(%rip), %rsi      # 0x1689c
addq $0x50, %rsi
movb $0x0, %al
callq 0x5050
xorl %eax, %eax
movl %eax, %r9d
movl $0x12000, %esi          # imm = 0x12000
movl $0x3, %edx
movl $0x22, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movq %r9, %rdi
callq 0x55d0
movq %rax, 0xd9f8(%rip)      # 0x16910
movq $-0x1, %rax
cmpq %rax, 0xd9ea(%rip)      # 0x16910
je 0x8f2a
jmp 0x8f49
leaq 0x7701(%rip), %rdi      # 0x10632
leaq 0x770c(%rip), %rsi      # 0x10644
movl $0x30b, %edx            # imm = 0x30B
leaq 0x770a(%rip), %rcx      # 0x1064e
callq 0x5150
movq 0xd9c0(%rip), %rax      # 0x16910
addq $0x1000, %rax           # imm = 0x1000
movq %rax, 0xd9b3(%rip)      # 0x16910
movq 0xd9ac(%rip), %rdi      # 0x16910
addq $-0x1000, %rdi          # imm = 0xF000
movl $0x1000, %esi           # imm = 0x1000
xorl %edx, %edx
callq 0x5030
movq 0xd992(%rip), %rdi      # 0x16910
addq $0x10000, %rdi          # imm = 0x10000
movl $0x1000, %esi           # imm = 0x1000
xorl %edx, %edx
callq 0x5030
movq -0x28(%rbp), %rdi
movl $0x70, %esi
xorl %edx, %edx
callq 0x5120
cmpl $0x0, 0xd970(%rip)      # 0x16918
je 0x8fb6
leaq 0x76b4(%rip), %rdi      # 0x10665
callq 0x5110
movzwl 0xd8e5(%rip), %eax      # 0x168a2
movl $0x4000, %ecx           # imm = 0x4000
cltd
idivl %ecx
movl %eax, -0x38(%rbp)
movzwl 0xd8d3(%rip), %eax      # 0x168a2
movl $0x4000, %ecx           # imm = 0x4000
cltd
idivl %ecx
movl %edx, -0x3c(%rbp)
xorl %eax, %eax
movl %eax, %r9d
movl $0x4000, %esi           # imm = 0x4000
movl $0x3, %edx
movl $0x22, %ecx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movq %r9, %rdi
callq 0x55d0
movq %rax, -0x48(%rbp)
movq $-0x1, %rax
cmpq %rax, -0x48(%rbp)
je 0x900f
jmp 0x902e
leaq 0x765a(%rip), %rdi      # 0x10670
leaq 0x7627(%rip), %rsi      # 0x10644
movl $0x31c, %edx            # imm = 0x31C
leaq 0x7625(%rip), %rcx      # 0x1064e
callq 0x5150
movq -0x48(%rbp), %rdx
movslq -0x38(%rbp), %rcx
leaq 0xd913(%rip), %rax      # 0x16950
movq %rdx, (%rax,%rcx,8)
movq -0x48(%rbp), %rdi
movslq -0x3c(%rbp), %rax
addq %rax, %rdi
movl $0x4000, %eax           # imm = 0x4000
subl -0x3c(%rbp), %eax
movslq %eax, %rdx
movq -0x28(%rbp), %rcx
movl $0x1, %esi
callq 0x5400
movq %rax, -0x50(%rbp)
cmpl $0x0, 0xd8a8(%rip)      # 0x16918
je 0x9087
movl -0x38(%rbp), %esi
movq -0x50(%rbp), %rdx
leaq 0x7603(%rip), %rdi      # 0x10683
movb $0x0, %al
callq 0x5050
movq -0x28(%rbp), %rdi
callq 0x54b0
cmpl $0x0, %eax
je 0x9097
jmp 0x90e7
movq -0x28(%rbp), %rdi
callq 0x5280
cmpl $0x0, %eax
je 0x90b5
leaq 0x75e5(%rip), %rdi      # 0x10691
movb $0x0, %al
callq 0x5050
jmp 0x90e7
jmp 0x90b7
movl $0x0, -0x3c(%rbp)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
cmpl $0x20, %eax
jl 0x90e2
leaq 0x75d6(%rip), %rdi      # 0x106a9
callq 0x5110
movl $0x1, %edi
callq 0x5140
jmp 0x8fda
movq -0x28(%rbp), %rdi
callq 0x54c0
movb 0xd7b4(%rip), %cl       # 0x168aa
movq 0xd813(%rip), %rax      # 0x16910
movb %cl, 0xff06(%rax)
movb 0xd7a2(%rip), %cl       # 0x168ab
movq 0xd800(%rip), %rax      # 0x16910
movb %cl, 0xff07(%rax)
movss 0x6ee6(%rip), %xmm0     # 0x10004
movss %xmm0, 0xd80e(%rip)     # 0x16934
movss 0x6ed6(%rip), %xmm0     # 0x10004
movss %xmm0, 0xd802(%rip)     # 0x16938
callq 0x9b10
testb $0x1, 0xd7dd(%rip)      # 0x1691f
je 0x915a
leaq 0xd5c5(%rip), %rax      # 0x16710
movq (%rax), %rcx
leaq 0xdb43(%rip), %rax      # 0x16c98
movq %rcx, (%rax)
jmp 0x916e
leaq 0xd567(%rip), %rax      # 0x166c8
movq (%rax), %rcx
leaq 0xdb2d(%rip), %rax      # 0x16c98
movq %rcx, (%rax)
leaq 0xdb23(%rip), %rax      # 0x16c98
movq (%rax), %rax
testb $0x1, (%rax)
jne 0x9222
movb $0x1, 0xd795(%rip)      # 0x1691d
movss 0x6e74(%rip), %xmm0     # 0x10004
movss %xmm0, 0xd79c(%rip)     # 0x16934
cmpq $0x0, 0xd780(%rip)      # 0x16920
jne 0x91c4
movq 0xbe3f(%rip), %rax      # 0x14fe8
movq (%rax), %rdi
leaq 0x7508(%rip), %rsi      # 0x106bb
movb $0x0, %al
callq 0x5580
movl $0x1, %edi
callq 0x5140
xorps %xmm0, %xmm0
ucomiss 0xd75a(%rip), %xmm0     # 0x16928
jb 0x91e0
movss 0x6e30(%rip), %xmm0     # 0x10008
movss %xmm0, 0xd748(%rip)     # 0x16928
movss 0xd740(%rip), %xmm0     # 0x16928
movss 0x6e1c(%rip), %xmm1     # 0x1000c
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
movq 0xd721(%rip), %rsi      # 0x16920
leaq 0x74d3(%rip), %rdi      # 0x106d9
movb $0x1, %al
callq 0x5050
movq 0xd70c(%rip), %rcx      # 0x16920
leaq 0xda7d(%rip), %rax      # 0x16c98
movq (%rax), %rax
movq %rcx, 0x28(%rax)
testb $0x1, 0xd6f4(%rip)      # 0x1691d
jne 0x9230
callq 0x5320
leaq -0xd0(%rbp), %rdi
callq 0x54f0
leaq -0xd0(%rbp), %rdi
movl $0x1c, %esi
callq 0x5440
leaq -0xd0(%rbp), %rdi
movl $0x2, %esi
callq 0x5440
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
leaq -0xd0(%rbp), %rsi
movl $0x800, %edx            # imm = 0x800
callq 0x50b0
movl %eax, -0xd4(%rbp)
xorl %edi, %edi
leaq -0xd0(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x5350
movl $0x1, %edi
xorl %esi, %esi
callq 0x5540
movl %eax, -0xd8(%rbp)
movq 0x77d3(%rip), %rax      # 0x10a78
movq %rax, -0xf8(%rbp)
movq 0x77cd(%rip), %rax      # 0x10a80
movq %rax, -0xf0(%rbp)
movq 0x77c7(%rip), %rax      # 0x10a88
movq %rax, -0xe8(%rbp)
movq 0x77c1(%rip), %rax      # 0x10a90
movq %rax, -0xe0(%rbp)
movl -0xd8(%rbp), %edi
xorl %esi, %esi
leaq -0xf8(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x5590
movl $0x4, %edi
movl $0x8, %esi
callq 0x54a0
movq %rax, -0x100(%rbp)
movl $0x0, -0x120(%rbp)
movw $0x1, -0x11c(%rbp)
movw $0x0, -0x11a(%rbp)
movl -0xd4(%rbp), %eax
movl %eax, -0x118(%rbp)
movw $0x1, -0x114(%rbp)
movw $0x0, -0x112(%rbp)
movl -0xd8(%rbp), %eax
movl %eax, -0x110(%rbp)
movw $0x1, -0x10c(%rbp)
movw $0x0, -0x10a(%rbp)
callq 0xd7c0
movl %eax, -0x108(%rbp)
movw $0x1, -0x104(%rbp)
movw $0x0, -0x102(%rbp)
movq -0x100(%rbp), %rax
movq -0x120(%rbp), %rcx
movq %rcx, (%rax)
movq -0x118(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0x110(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x108(%rbp), %rcx
movq %rcx, 0x18(%rax)
leaq -0x100(%rbp), %rdi
movl $0x4, %esi
callq 0xc210
movl %eax, -0x124(%rbp)
testb $0x1, 0xd554(%rip)      # 0x1691d
jne 0x93da
movq 0xbc16(%rip), %rax      # 0x14fe8
movq (%rax), %rdi
callq 0x54c0
jmp 0x93dc
xorps %xmm0, %xmm0
movss %xmm0, -0x12c(%rbp)
callq 0xbd40
callq 0xed70
cmpq $0x0, 0xd557(%rip)      # 0x16950
je 0x9413
movq 0xd50e(%rip), %rdi      # 0x16910
movq 0xd547(%rip), %rsi      # 0x16950
movl $0x4000, %edx           # imm = 0x4000
callq 0x55c0
cmpq $0x0, 0xd53d(%rip)      # 0x16958
je 0x943c
movq 0xd4ec(%rip), %rdi      # 0x16910
addq $0x4000, %rdi           # imm = 0x4000
movq 0xd526(%rip), %rsi      # 0x16958
movl $0x4000, %edx           # imm = 0x4000
callq 0x55c0
leaq 0xd44d(%rip), %rdi      # 0x16890
xorl %esi, %esi
movl $0xc, %edx
callq 0x5080
movq 0xd4ba(%rip), %rdi      # 0x16910
addq $0x8000, %rdi           # imm = 0x8000
xorl %esi, %esi
movl $0x8000, %edx           # imm = 0x8000
callq 0x5080
movq 0xd4a0(%rip), %rdi      # 0x16910
movq 0xd499(%rip), %rsi      # 0x16910
movzwl 0xd424(%rip), %eax      # 0x168a2
cltq
addq %rax, %rsi
movl $0x62, %edx
callq 0x55c0
movq 0xd47c(%rip), %rax      # 0x16910
movzwl 0xd40d(%rip), %ecx      # 0x168a8
subl $0x2, %ecx
andl $0xffff, %ecx           # imm = 0xFFFF
movslq %ecx, %rcx
movb $0x0, (%rax,%rcx)
movq 0xd45e(%rip), %rax      # 0x16910
movzwl 0xd3ef(%rip), %ecx      # 0x168a8
subl $0x1, %ecx
andl $0xffff, %ecx           # imm = 0xFFFF
movslq %ecx, %rcx
movb $0x0, (%rax,%rcx)
movzwl 0xd3d8(%rip), %eax      # 0x168a8
subl $0x2, %eax
movw %ax, 0xd3be(%rip)       # 0x16898
movw 0xd3c3(%rip), %ax       # 0x168a4
movw %ax, 0xd3b2(%rip)       # 0x1689a
movl 0xd43e(%rip), %eax      # 0x1692c
movb %al, 0xd39d(%rip)       # 0x16891
movq 0xd415(%rip), %rax      # 0x16910
movb $0x1, 0xffff(%rax)
movb 0xd3a2(%rip), %cl       # 0x168aa
movq 0xd401(%rip), %rax      # 0x16910
movb %cl, 0xff06(%rax)
movb 0xd390(%rip), %cl       # 0x168ab
movq 0xd3ee(%rip), %rax      # 0x16910
movb %cl, 0xff07(%rax)
movl $0x0, -0x130(%rbp)
cmpl $0x17, -0x130(%rbp)
jge 0x9574
movl -0x130(%rbp), %eax
addl $0xff10, %eax           # imm = 0xFF10
movw %ax, %dx
movslq -0x130(%rbp), %rcx
leaq 0x6f29(%rip), %rax      # 0x10480
movzwl %dx, %edi
movzbl (%rax,%rcx), %esi
callq 0x9c20
movl -0x130(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x130(%rbp)
jmp 0x9532
movq 0xd395(%rip), %rax      # 0x16910
movq 0x6f1e(%rip), %rcx      # 0x104a0
movq %rcx, 0xff30(%rax)
movq 0x6f18(%rip), %rcx      # 0x104a8
movq %rcx, 0xff38(%rax)
movb $0x0, -0x125(%rbp)
xorl %edi, %edi
callq 0xbdb0
movq -0x100(%rbp), %rdi
movslq -0x124(%rbp), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x5310
movl %eax, -0x134(%rbp)
cmpl $-0x1, -0x134(%rbp)
jne 0x95da
leaq 0x7125(%rip), %rdi      # 0x106f8
callq 0x5570
jmp 0x95a5
movq -0x100(%rbp), %rdi
addq $0x20, %rdi
movl -0x124(%rbp), %esi
subl $0x4, %esi
callq 0xbdd0
addss -0x12c(%rbp), %xmm0
movss %xmm0, -0x12c(%rbp)
movss 0xd31d(%rip), %xmm0     # 0x16928
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jbe 0x9629
movss -0x12c(%rbp), %xmm0
ucomiss 0xd306(%rip), %xmm0     # 0x16928
jbe 0x9629
jmp 0x9ab1
movq -0x100(%rbp), %rax
movswl 0xe(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x977a
movb $0x0, -0x1b9(%rbp)
movq -0x100(%rbp), %rax
movl 0x8(%rax), %edi
leaq -0x1b8(%rbp), %rsi
movl $0x80, %edx
callq 0x5190
movq %rax, -0x1c8(%rbp)
cmpq $-0x1, -0x1c8(%rbp)
jne 0x968b
callq 0x5410
cmpl $0xb, (%rax)
je 0x9689
leaq 0x7079(%rip), %rdi      # 0x106fd
callq 0x5570
jmp 0x96af
cmpl $0x1c, -0x1b8(%rbp)
jne 0x969d
movb $0x1, -0x1b9(%rbp)
jmp 0x96ad
cmpl $0x2, -0x1b8(%rbp)
jne 0x96ab
jmp 0x9ab1
jmp 0x96ad
jmp 0x96af
jmp 0x96b1
cmpq $0x0, -0x1c8(%rbp)
jg 0x9647
testb $0x1, -0x1b9(%rbp)
je 0x9778
testb $0x1, 0xd24e(%rip)      # 0x1691d
jne 0x9778
callq 0x5430
movq 0xb8ef(%rip), %rax      # 0x14fd0
movq (%rax), %rdi
callq 0x52c0
movq 0xb8e0(%rip), %rax      # 0x14fd0
movq (%rax), %rdi
callq 0x52d0
xorl %eax, %eax
movq 0xb8cf(%rip), %rcx      # 0x14fd0
cmpq (%rcx), %rax
je 0x971f
movq 0xb8c3(%rip), %rax      # 0x14fd0
movq (%rax), %rax
movswl 0x4(%rax), %eax
addl $0x1, %eax
movl %eax, -0x1fc(%rbp)
jmp 0x972c
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x1fc(%rbp)
jmp 0x972c
movl -0x1fc(%rbp), %eax
movl %eax, 0xd20c(%rip)      # 0x16944
xorl %eax, %eax
movq 0xb88f(%rip), %rcx      # 0x14fd0
cmpq (%rcx), %rax
je 0x975f
movq 0xb883(%rip), %rax      # 0x14fd0
movq (%rax), %rax
movswl 0x6(%rax), %eax
addl $0x1, %eax
movl %eax, -0x200(%rbp)
jmp 0x976c
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x200(%rbp)
jmp 0x976c
movl -0x200(%rbp), %eax
movl %eax, 0xd1c8(%rip)      # 0x16940
jmp 0x977a
movq -0x100(%rbp), %rax
movswl 0x16(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x979d
movl -0xd8(%rbp), %edi
callq 0x9de0
callq 0xe860
movq -0x100(%rbp), %rax
movswl 0x6(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x1c9(%rbp)
movq -0x100(%rbp), %rax
movswl 0x1e(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, -0x1ca(%rbp)
movb $0x1, %al
testb $0x1, -0x1c9(%rbp)
movb %al, -0x201(%rbp)
jne 0x97f2
movb -0x1ca(%rbp), %al
movb %al, -0x201(%rbp)
movb -0x201(%rbp), %al
testb $0x1, %al
jne 0x9801
jmp 0x9aac
leaq -0x1d0(%rbp), %rdi
leaq -0x1c9(%rbp), %rsi
leaq -0x1ca(%rbp), %rdx
callq 0xeee0
movl %eax, %ecx
movq %rcx, -0x210(%rbp)
subl $0x5, %eax
ja 0x9aa7
movq -0x210(%rbp), %rax
leaq 0x67e5(%rip), %rcx      # 0x10020
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x9ab1
movl -0x1d0(%rbp), %eax
addl $0x30, %eax
movl %eax, -0x214(%rbp)
movl -0x1d0(%rbp), %edi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0xbcd0
movl -0x214(%rbp), %esi
movb %al, %cl
leaq 0x6e9f(%rip), %rdx      # 0x10716
leaq 0x711c(%rip), %rax      # 0x1099a
testb $0x1, %cl
cmovneq %rax, %rdx
leaq 0x6e76(%rip), %rdi      # 0x10702
movb $0x0, %al
callq 0xd6e0
jmp 0x9aa7
cmpl $0x0, -0x1d0(%rbp)
jl 0x98af
movl -0x1d0(%rbp), %eax
cmpl 0xd083(%rip), %eax      # 0x16930
jl 0x98bf
leaq 0x6e63(%rip), %rdi      # 0x10719
movb $0x0, %al
callq 0xd6e0
jmp 0x98d0
movl -0x1d0(%rbp), %eax
movl %eax, 0xd061(%rip)      # 0x1692c
jmp 0x93dc
jmp 0x9aa7
movb -0x125(%rbp), %al
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0x125(%rbp)
movb -0x125(%rbp), %cl
leaq 0x6e41(%rip), %rsi      # 0x10733
leaq 0x6e33(%rip), %rax      # 0x1072c
testb $0x1, %cl
cmovneq %rax, %rsi
leaq 0x6e21(%rip), %rdi      # 0x10728
movb $0x0, %al
callq 0xd6e0
movb -0x125(%rbp), %al
andb $0x1, %al
movzbl %al, %edi
callq 0xbdb0
jmp 0x9aa7
cvtsi2ssl -0x1d0(%rbp), %xmm0
movss 0x66dd(%rip), %xmm1     # 0x10010
divss %xmm1, %xmm0
movss %xmm0, 0xcff5(%rip)     # 0x16934
movl -0x1d0(%rbp), %esi
leaq 0x6def(%rip), %rdi      # 0x1073b
movb $0x0, %al
callq 0xd6e0
jmp 0x9aa7
cmpl $0x0, -0x1d0(%rbp)
je 0x9a59
movss 0x66ab(%rip), %xmm0     # 0x10018
movss %xmm0, -0x1d4(%rbp)
movss 0x6697(%rip), %xmm0     # 0x10014
movss %xmm0, -0x1dc(%rbp)
movss 0xcfab(%rip), %xmm0     # 0x16938
cvtsi2ssl -0x1d0(%rbp), %xmm1
movss 0x6673(%rip), %xmm2     # 0x10010
divss %xmm2, %xmm1
addss %xmm1, %xmm0
movss %xmm0, -0x1e0(%rbp)
movss -0x1dc(%rbp), %xmm1
movss -0x1e0(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jb 0x99d4
movss -0x1dc(%rbp), %xmm0
movss %xmm0, -0x218(%rbp)
jmp 0x99e4
movss -0x1e0(%rbp), %xmm0
movss %xmm0, -0x218(%rbp)
movss -0x218(%rbp), %xmm0
movss %xmm0, -0x1e4(%rbp)
movss -0x1e4(%rbp), %xmm0
movss %xmm0, -0x1d8(%rbp)
movss -0x1d4(%rbp), %xmm0
ucomiss -0x1d8(%rbp), %xmm0
jbe 0x9a27
movss -0x1d4(%rbp), %xmm0
movss %xmm0, -0x21c(%rbp)
jmp 0x9a37
movss -0x1d8(%rbp), %xmm0
movss %xmm0, -0x21c(%rbp)
movss -0x21c(%rbp), %xmm0
movss %xmm0, -0x1e8(%rbp)
movss -0x1e8(%rbp), %xmm0
movss %xmm0, -0x220(%rbp)
jmp 0x9a6b
movss 0x65a3(%rip), %xmm0     # 0x10004
movss %xmm0, -0x220(%rbp)
jmp 0x9a6b
movss -0x220(%rbp), %xmm0
movss %xmm0, 0xcebd(%rip)     # 0x16938
movss 0x658d(%rip), %xmm0     # 0x10010
mulss 0xcead(%rip), %xmm0     # 0x16938
callq 0x50d0
cvttss2si %xmm0, %esi
leaq 0x6cae(%rip), %rdi      # 0x10749
movb $0x0, %al
callq 0xd6e0
callq 0xc290
jmp 0x97d5
jmp 0x95a5
callq 0x9e30
callq 0xed50
callq 0xc490
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
nopw %cs:(%rax,%rax)