// File: /workspace/github_c_makefile_star2_O2/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 $0x158, %rsp            # imm = 0x158
movq %rsi, %r14
movl %edi, %r15d
leaq 0x5c30(%rip), %rsi      # 0xc6d9
pushq $0x6
popq %rdi
callq 0x5560
movq (%r14), %rax
movq %rax, 0x18(%rsp)
leaq 0x5737(%rip), %r12      # 0xc1f7
leaq 0x55a9(%rip), %r13      # 0xc070
movq 0xb50a(%rip), %rbx      # 0x11fd8
pushq $0x1
popq %rbp
movl %r15d, %edi
movq %r14, %rsi
movq %r12, %rdx
callq 0x5190
leal -0x6d(%rax), %ecx
cmpl $0xa, %ecx
ja 0x6afa
movslq (%r13,%rcx,4), %rax
addq %r13, %rax
jmpq *%rax
movb $0x1, 0xb954(%rip)      # 0x1244c
jmp 0x6ad1
cmpl $0x64, %eax
jne 0x6b57
movb $0x1, 0xb947(%rip)      # 0x1244d
incl 0xb93c(%rip)            # 0x12448
jmp 0x6ad1
movq (%rbx), %rdi
xorl %esi, %esi
callq 0x5340
mulss 0x5530(%rip), %xmm0     # 0xc050
movss %xmm0, 0xb930(%rip)     # 0x12458
jmp 0x6ad1
movb $0x1, 0xb91c(%rip)      # 0x1244d
jmp 0x6ad1
movb $0x1, 0xb914(%rip)      # 0x1244e
jmp 0x6ad1
movb $0x1, 0xb90c(%rip)      # 0x1244f
movq (%rbx), %rdi
callq 0x5430
movq %rax, 0xb8fe(%rip)      # 0x12450
jmp 0x6ad1
cmpl $-0x1, %eax
je 0x6b93
cmpl $0x68, %eax
jne 0x6b7a
movq 0xb490(%rip), %rax      # 0x11ff8
movq (%rax), %rsi
movq 0x18(%rsp), %rdi
callq 0x76f2
jmp 0x75db
movq 0xb467(%rip), %rax      # 0x11fe8
movq (%rax), %rsi
movq 0x18(%rsp), %rdi
callq 0x76f2
jmp 0x75dd
movq 0xb41e(%rip), %rax      # 0x11fb8
movslq (%rax), %r13
cmpl %r15d, %r13d
jge 0x75f1
movq (%r14,%r13,8), %rdi
leaq 0x5e27(%rip), %rsi      # 0xc9d8
callq 0x51d0
testq %rax, %rax
je 0x7618
movq %rax, %rbx
leaq 0xb803(%rip), %rdi      # 0x123cc
pushq $0x70
popq %rsi
pushq $0x1
popq %rdx
movq %rax, %rcx
callq 0x5410
cmpq $0x1, %rax
jne 0x75dd
leaq 0xb7e4(%rip), %rdi      # 0x123cc
leaq 0x5648(%rip), %rsi      # 0xc237
pushq $0x3
popq %rdx
callq 0x5360
testl %eax, %eax
jne 0x7636
movzbl 0xb7c9(%rip), %edx      # 0x123cf
cmpl $0x1, %edx
jne 0x7654
leaq -0x1(%r13), %rax
subl %eax, %r15d
movzbl 0xb7b2(%rip), %r12d     # 0x123d0
movl %r12d, 0xb83b(%rip)     # 0x12460
cmpl $0x3, %r15d
jl 0x6c37
movq 0x8(%r14,%r13,8), %rdi
callq 0x53b0
jmp 0x6c48
movzbl 0xb793(%rip), %eax      # 0x123d1
cmpb $0x1, %al
adcl $0x0, %eax
movzbl %al, %eax
decl %eax
movl %eax, 0xb80e(%rip)      # 0x1245c
cmpl %r12d, %eax
jge 0x7671
cmpl $0x0, 0xb7ea(%rip)      # 0x12448
je 0x6d75
leaq 0x566c(%rip), %rdi      # 0xc2d7
leaq 0xb75a(%rip), %rsi      # 0x123cc
xorl %eax, %eax
callq 0x5050
movzbl 0xb74f(%rip), %esi      # 0x123cf
leaq 0x565d(%rip), %rdi      # 0xc2e4
xorl %eax, %eax
callq 0x5050
movzbl 0xb73b(%rip), %esi      # 0x123d0
leaq 0x5653(%rip), %rdi      # 0xc2ef
xorl %eax, %eax
callq 0x5050
movzbl 0xb727(%rip), %esi      # 0x123d1
leaq 0x5649(%rip), %rdi      # 0xc2fa
xorl %eax, %eax
callq 0x5050
movzwl 0xb713(%rip), %esi      # 0x123d2
leaq 0x563f(%rip), %rdi      # 0xc305
xorl %eax, %eax
callq 0x5050
movzwl 0xb700(%rip), %esi      # 0x123d4
leaq 0x5635(%rip), %rdi      # 0xc310
xorl %eax, %eax
callq 0x5050
movzwl 0xb6ed(%rip), %esi      # 0x123d6
leaq 0x562b(%rip), %rdi      # 0xc31b
xorl %eax, %eax
callq 0x5050
movzwl 0xb6da(%rip), %esi      # 0x123d8
leaq 0x5621(%rip), %rdi      # 0xc326
xorl %eax, %eax
callq 0x5050
movzbl 0xb6c7(%rip), %esi      # 0x123da
leaq 0x5617(%rip), %rdi      # 0xc331
xorl %eax, %eax
callq 0x5050
movzbl 0xb6b3(%rip), %esi      # 0x123db
leaq 0x560d(%rip), %rdi      # 0xc33c
xorl %eax, %eax
callq 0x5050
leaq 0x560a(%rip), %rdi      # 0xc347
leaq 0xb698(%rip), %rsi      # 0x123dc
xorl %eax, %eax
callq 0x5050
leaq 0x5603(%rip), %rdi      # 0xc355
leaq 0xb6a3(%rip), %rsi      # 0x123fc
xorl %eax, %eax
callq 0x5050
leaq 0x55fc(%rip), %rdi      # 0xc363
leaq 0xb6ae(%rip), %rsi      # 0x1241c
xorl %eax, %eax
callq 0x5050
pushq $0x3
popq %rdx
pushq $0x22
popq %rcx
pushq $-0x1
popq %r8
movl $0x12000, %esi          # imm = 0x12000
xorl %edi, %edi
xorl %r9d, %r9d
callq 0x55c0
movq %rax, 0xb6ab(%rip)      # 0x12440
cmpq $-0x1, %rax
je 0x76b2
movq %rax, %rcx
addq $0x1000, %rcx           # imm = 0x1000
movq %rcx, 0xb690(%rip)      # 0x12440
movl $0x1000, %esi           # imm = 0x1000
movq %rax, %rdi
xorl %edx, %edx
callq 0x5030
movl $0x10000, %edi          # imm = 0x10000
addq 0xb675(%rip), %rdi      # 0x12440
movl $0x1000, %esi           # imm = 0x1000
xorl %edx, %edx
callq 0x5030
pushq $0x70
popq %rsi
movq %rbx, %rdi
xorl %edx, %edx
callq 0x5130
cmpl $0x0, 0xb65d(%rip)      # 0x12448
je 0x6df9
leaq 0x55b0(%rip), %rdi      # 0xc3a4
callq 0x5120
movzwl 0xb5d1(%rip), %r14d     # 0x123d2
movl %r14d, %r15d
andl $0x3fff, %r15d          # imm = 0x3FFF
shrl $0xe, %r14d
leaq 0xb66a(%rip), %rax      # 0x12480
leaq (%rax,%r14,8), %rbp
pushq $-0x1
popq %r12
pushq $0x1
popq %r13
movl $0x4000, %esi           # imm = 0x4000
xorl %edi, %edi
pushq $0x3
popq %rdx
pushq $0x22
popq %rcx
movl %r12d, %r8d
xorl %r9d, %r9d
callq 0x55c0
cmpq $-0x1, %rax
je 0x7693
movq %rax, (%rbp)
movl %r15d, %edi
addq %rax, %rdi
movl $0x4000, %edx           # imm = 0x4000
subl %r15d, %edx
movq %r13, %rsi
movq %rbx, %rcx
callq 0x5410
cmpl $0x0, 0xb5e0(%rip)      # 0x12448
je 0x6e7e
leaq 0x5551(%rip), %rdi      # 0xc3c2
movl %r14d, %esi
movq %rax, %rdx
xorl %eax, %eax
callq 0x5050
movq %rbx, %rdi
callq 0x54b0
testl %eax, %eax
jne 0x6ecc
movq %rbx, %rdi
callq 0x5280
testl %eax, %eax
jne 0x6ebe
incq %r14
addq $0x8, %rbp
xorl %r15d, %r15d
cmpq $0x20, %r14
jne 0x6e22
leaq 0x5537(%rip), %rdi      # 0xc3e8
callq 0x5120
pushq $0x1
popq %rdi
callq 0x5150
leaq 0x550b(%rip), %rdi      # 0xc3d0
xorl %eax, %eax
callq 0x5050
movq %rbx, %rdi
callq 0x54c0
movb 0xb500(%rip), %al       # 0x123da
movq 0xb55f(%rip), %rcx      # 0x12440
movb %al, 0xff06(%rcx)
movb 0xb4ee(%rip), %al       # 0x123db
movb %al, 0xff07(%rcx)
movsd 0x5135(%rip), %xmm0     # 0xc030
movsd %xmm0, 0xb561(%rip)     # 0x12464
leaq 0x5ace(%rip), %rdi      # 0xc9d8
callq 0x796f
testq %rax, %rax
je 0x6faf
movq %rax, %rbx
leaq 0x57b8(%rip), %r14      # 0xc6da
leaq 0x30(%rsp), %r15
leaq 0xd0(%rsp), %r12
leaq 0x57b1(%rip), %r13      # 0xc6e7
pushq $0x7
popq %rbp
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0x50f0
cmpl $0x2, %eax
jne 0x6fa7
movq %r15, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x5360
testl %eax, %eax
jne 0x6f39
movq %r12, %rdi
callq 0x53b0
cmpl $0x64, %eax
pushq $0x64
popq %rsi
cmovll %eax, %esi
testl %esi, %esi
movl $0x0, %ecx
cmovlel %ecx, %esi
cvtsi2ss %esi, %xmm0
divss 0x50ca(%rip), %xmm0     # 0xc054
movss %xmm0, 0xb4d2(%rip)     # 0x12464
cmpl $0x63, %eax
jg 0x6f39
leaq 0x54dc(%rip), %rdi      # 0xc47a
xorl %eax, %eax
callq 0x99c6
jmp 0x6f39
movq %rbx, %rdi
callq 0x54c0
cmpb $0x0, 0xb499(%rip)      # 0x1244f
je 0x6fc1
leaq 0xb3d9(%rip), %rax      # 0x12398
jmp 0x6fc8
leaq 0xb388(%rip), %rax      # 0x12350
movq (%rax), %rax
leaq 0xb7f6(%rip), %rbx      # 0x127c8
movq %rax, (%rbx)
cmpb $0x0, (%rax)
jne 0x7045
movb $0x1, 0xb46c(%rip)      # 0x1244d
movl $0x3f800000, 0xb479(%rip) # imm = 0x3F800000
movq 0xb45e(%rip), %rsi      # 0x12450
testq %rsi, %rsi
je 0x76d1
movss 0xb455(%rip), %xmm0     # 0x12458
xorps %xmm1, %xmm1
ucomiss %xmm0, %xmm1
jb 0x701d
movl $0x47ea6000, 0xb443(%rip) # imm = 0x47EA6000
movss 0x503b(%rip), %xmm0     # 0xc058
divss 0x502b(%rip), %xmm0     # 0xc050
cvtss2sd %xmm0, %xmm0
leaq 0x53e8(%rip), %rdi      # 0xc418
movb $0x1, %al
callq 0x5050
movq 0xb412(%rip), %rax      # 0x12450
movq (%rbx), %rcx
movq %rax, 0x28(%rcx)
cmpb $0x0, 0xb401(%rip)      # 0x1244d
jne 0x7053
callq 0x5320
leaq 0xd0(%rsp), %r14
movq %r14, %rdi
callq 0x54f0
pushq $0x1c
popq %rsi
movq %r14, %rdi
callq 0x5450
pushq $0x2
popq %rsi
movq %r14, %rdi
callq 0x5450
pushq $-0x1
popq %rdi
movq %r14, %rsi
movl $0x800, %edx            # imm = 0x800
callq 0x50b0
movl %eax, %ebx
xorl %edi, %edi
movq %r14, %rsi
xorl %edx, %edx
callq 0x5350
pushq $0x1
popq %rbp
movl %ebp, %edi
xorl %esi, %esi
callq 0x5540
movl %eax, %r14d
movups 0x571b(%rip), %xmm0     # 0xc7c8
leaq 0xb0(%rsp), %rdx
movaps %xmm0, 0x10(%rdx)
movups 0x56f8(%rip), %xmm0     # 0xc7b8
movaps %xmm0, (%rdx)
movl %eax, %edi
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x5590
pushq $0x4
popq %rdi
pushq $0x8
popq %rsi
callq 0x54a0
leaq 0x8(%rsp), %r15
movq %rax, (%r15)
callq 0x9a7b
movq (%r15), %rcx
movabsq $0x100000000, %rdx      # imm = 0x100000000
movq %rdx, (%rcx)
movl %ebx, 0x8(%rcx)
movl %ebp, 0xc(%rcx)
movl %r14d, 0x18(%rsp)
movl %r14d, 0x10(%rcx)
movl %ebp, 0x14(%rcx)
movl %eax, 0x18(%rcx)
movl %ebp, 0x1c(%rcx)
pushq $0x4
popq %rsi
movq %r15, %rdi
callq 0x8eff
movl %eax, %ebx
cmpb $0x0, 0xb32b(%rip)      # 0x1244d
jne 0x7133
movq 0xaebd(%rip), %rax      # 0x11fe8
movq (%rax), %rdi
callq 0x54c0
movslq %ebx, %rax
movq %rax, 0x28(%rsp)
addl $-0x4, %eax
movl %eax, 0x24(%rsp)
xorl %r14d, %r14d
leaq 0x30(%rsp), %r13
leaq 0x7(%rsp), %r12
leaq 0x6(%rsp), %rbx
leaq 0x4f41(%rip), %rbp      # 0xc09c
callq 0x8bad
callq 0xa7f3
movq 0xb314(%rip), %rsi      # 0x12480
movq 0xb2cd(%rip), %r15      # 0x12440
testq %rsi, %rsi
je 0x7185
movl $0x4000, %edx           # imm = 0x4000
movq %r15, %rdi
callq 0x55b0
movq 0xb2fc(%rip), %rsi      # 0x12488
testq %rsi, %rsi
je 0x71a2
leaq 0x4000(%r15), %rdi
movl $0x4000, %edx           # imm = 0x4000
callq 0x55b0
andq $0x0, 0xb216(%rip)      # 0x123c0
leaq 0x8000(%r15), %rdi
movl $0x8000, %edx           # imm = 0x8000
xorl %esi, %esi
callq 0x5080
movzwl 0xb20e(%rip), %esi      # 0x123d2
addq %r15, %rsi
movq %r15, %rdi
pushq $0x62
popq %rdx
callq 0x55b0
movzwl 0xb1ff(%rip), %eax      # 0x123d8
addl $-0x2, %eax
movl $0xffff, %edx           # imm = 0xFFFF
andl %edx, %eax
movb %r14b, (%r15,%rax)
movq 0xb252(%rip), %rax      # 0x12440
movzwl 0xb1e3(%rip), %ecx      # 0x123d8
decl %ecx
andl %edx, %ecx
movb %r14b, (%rax,%rcx)
movzwl 0xb1d4(%rip), %eax      # 0x123d8
addl $-0x2, %eax
movw %ax, 0xb1ba(%rip)       # 0x123c8
movzwl 0xb1bf(%rip), %eax      # 0x123d4
movw %ax, 0xb1ae(%rip)       # 0x123ca
movb 0xb23a(%rip), %al       # 0x1245c
movb %al, 0xb199(%rip)       # 0x123c1
movq 0xb211(%rip), %rax      # 0x12440
movb $0x1, 0xffff(%rax)
movb 0xb19e(%rip), %cl       # 0x123da
movb %cl, 0xff06(%rax)
movb 0xb193(%rip), %cl       # 0x123db
movb %cl, 0xff07(%rax)
xorl %r14d, %r14d
cmpq $0x17, %r14
je 0x7277
leal 0xff10(%r14), %eax
leaq 0x4f5b(%rip), %rcx      # 0xc1c0
movzbl (%r14,%rcx), %esi
movzwl %ax, %edi
callq 0x7709
incq %r14
jmp 0x7251
movq 0xb1c2(%rip), %rax      # 0x12440
movaps 0x4dbb(%rip), %xmm0     # 0xc040
movups %xmm0, 0xff30(%rax)
xorl %r14d, %r14d
xorl %edi, %edi
callq 0x8c0c
xorps %xmm0, %xmm0
movss %xmm0, 0x14(%rsp)
movq 0x8(%rsp), %rdi
movq 0x28(%rsp), %rsi
pushq $-0x1
popq %rdx
callq 0x5310
cmpl $-0x1, %eax
jne 0x72c4
leaq 0x517a(%rip), %rdi      # 0xc437
callq 0x5570
jmp 0x729f
movq 0x8(%rsp), %rdi
addq $0x20, %rdi
movl 0x24(%rsp), %esi
callq 0x8c14
movss 0x14(%rsp), %xmm1
addss %xmm0, %xmm1
movss 0xb170(%rip), %xmm0     # 0x12458
ucomiss 0x4d79(%rip), %xmm0     # 0xc068
jbe 0x72fa
ucomiss %xmm0, %xmm1
ja 0x758b
movq 0x8(%rsp), %rax
testb $0x1, 0xe(%rax)
movss %xmm1, 0x14(%rsp)
je 0x73b3
xorl %r15d, %r15d
movq 0x8(%rsp), %rax
movl 0x8(%rax), %edi
movl $0x80, %edx
movq %r13, %rsi
callq 0x51a0
cmpq $-0x1, %rax
je 0x734e
movb $0x1, %cl
movl 0x30(%rsp), %edx
cmpl $0x1c, %edx
je 0x7344
cmpl $0x2, %edx
je 0x758b
movl %r15d, %ecx
movl %ecx, %r15d
testq %rax, %rax
jg 0x7312
jmp 0x735f
callq 0x5420
cmpl $0xb, (%rax)
jne 0x7562
movl %r15d, %ecx
testb $0x1, %cl
je 0x73ae
cmpb $0x0, 0xb0e2(%rip)      # 0x1244d
jne 0x73ae
callq 0x5440
movq 0xac57(%rip), %r15      # 0x11fd0
movq (%r15), %rdi
callq 0x52c0
movq (%r15), %rdi
callq 0x52d0
movq (%r15), %rdx
pushq $-0x1
popq %rcx
movl %ecx, %eax
testq %rdx, %rdx
je 0x73a2
movswl 0x4(%rdx), %eax
incl %eax
movswl 0x6(%rdx), %ecx
incl %ecx
movl %eax, 0xb0cc(%rip)      # 0x12474
movl %ecx, 0xb0c2(%rip)      # 0x12470
movq 0x8(%rsp), %rax
testb $0x1, 0x16(%rax)
je 0x73e2
movl 0x18(%rsp), %edi
movq %r13, %rsi
pushq $0x8
popq %rdx
callq 0x51a0
cmpq $-0x1, %rax
jne 0x73d8
callq 0x5420
cmpl $0xb, (%rax)
je 0x73b9
callq 0xa555
movq 0x8(%rsp), %rax
movb 0x6(%rax), %cl
andb $0x1, %cl
movb %cl, 0x7(%rsp)
movb 0x1e(%rax), %al
andb $0x1, %al
movb %al, 0x6(%rsp)
testb $0x1, %cl
jne 0x7402
testb $0x1, %al
je 0x729f
movq %r13, %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0xa906
cmpl $0x5, %eax
ja 0x7555
movl %eax, %eax
movslq (%rbp,%rax,4), %rax
addq %rbp, %rax
jmpq *%rax
movl 0x30(%rsp), %edi
leal 0x30(%rdi), %r15d
pushq $-0x1
popq %rsi
callq 0x8b8b
testb %al, %al
leaq 0x5017(%rip), %rdx      # 0xc455
leaq 0x5294(%rip), %rax      # 0xc6d9
cmovneq %rax, %rdx
leaq 0x4ff1(%rip), %rdi      # 0xc441
movl %r15d, %esi
xorl %eax, %eax
callq 0x99c6
jmp 0x7555
movl 0x30(%rsp), %esi
cvtsi2ss %esi, %xmm0
divss 0x4be5(%rip), %xmm0     # 0xc054
movss %xmm0, 0xafed(%rip)     # 0x12464
leaq 0x4ffc(%rip), %rdi      # 0xc47a
xorl %eax, %eax
callq 0x99c6
jmp 0x7555
movl 0x30(%rsp), %eax
testl %eax, %eax
js 0x749e
cmpl 0xafc8(%rip), %eax      # 0x12460
jl 0x757d
leaq 0x4fb3(%rip), %rdi      # 0xc458
xorl %eax, %eax
callq 0x99c6
jmp 0x7555
movl %r14d, %r15d
xorb $0x1, %r15b
testb $0x1, %r14b
leaq 0x4fa8(%rip), %rsi      # 0xc46b
leaq 0x4fa8(%rip), %rax      # 0xc472
cmovneq %rax, %rsi
leaq 0x4f92(%rip), %rdi      # 0xc467
xorl %eax, %eax
callq 0x99c6
movzbl %r15b, %edi
andl $0x1, %edi
callq 0x8c0c
movl %r15d, %r14d
jmp 0x7555
movl 0x30(%rsp), %eax
movss 0x4b63(%rip), %xmm0     # 0xc05c
testl %eax, %eax
movss 0x4b51(%rip), %xmm2     # 0xc054
je 0x752d
cvtsi2ss %eax, %xmm0
divss %xmm2, %xmm0
addss 0xaf53(%rip), %xmm0     # 0x12468
movss 0x4b43(%rip), %xmm1     # 0xc060
minss %xmm0, %xmm1
movss 0x4b3b(%rip), %xmm0     # 0xc064
maxss %xmm1, %xmm0
movss %xmm0, 0xaf33(%rip)     # 0x12468
mulss %xmm2, %xmm0
callq 0x50d0
cvttss2si %xmm0, %esi
leaq 0x4f3f(%rip), %rdi      # 0xc488
xorl %eax, %eax
callq 0x99c6
callq 0x8f43
movb 0x7(%rsp), %cl
movb 0x6(%rsp), %al
jmp 0x73f5
leaq 0x4ed3(%rip), %rdi      # 0xc43c
callq 0x5570
testb $0x1, %r15b
jne 0x7364
jmp 0x73ae
movl %eax, 0xaed9(%rip)      # 0x1245c
xorl %r14d, %r14d
jmp 0x715b
leaq 0x625d(%rip), %rdi      # 0xd7ef
callq 0x796f
testq %rax, %rax
je 0x75d1
movq %rax, %rbx
movss 0xaebd(%rip), %xmm0     # 0x12464
mulss 0x4aa5(%rip), %xmm0     # 0xc054
callq 0x50d0
cvttss2si %xmm0, %edx
leaq 0x51eb(%rip), %rsi      # 0xc7aa
movq %rbx, %rdi
xorl %eax, %eax
callq 0x5580
movq %rbx, %rdi
callq 0x54c0
callq 0xa7e1
callq 0x9054
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xa9f0(%rip), %rbx      # 0x11fe8
movq (%rbx), %rcx
leaq 0x4bff(%rip), %rdi      # 0xc201
pushq $0x18
popq %rsi
pushq $0x1
popq %rdx
callq 0x5510
movq (%r14), %rdi
movq (%rbx), %rsi
jmp 0x6b89
movq 0xa9c9(%rip), %rax      # 0x11fe8
movq (%rax), %rdi
movq (%r14,%r13,8), %rdx
leaq 0x4bed(%rip), %rsi      # 0xc21a
xorl %eax, %eax
callq 0x5580
jmp 0x75dd
movq 0xa9ab(%rip), %rax      # 0x11fe8
movq (%rax), %rcx
leaq 0x4bf4(%rip), %rdi      # 0xc23b
pushq $0x23
popq %rsi
pushq $0x1
popq %rdx
callq 0x5510
jmp 0x75dd
movq 0xa98d(%rip), %rax      # 0x11fe8
movq (%rax), %rdi
leaq 0x4bfa(%rip), %rsi      # 0xc25f
xorl %eax, %eax
callq 0x5580
jmp 0x75dd
movq 0xa970(%rip), %rcx      # 0x11fe8
movq (%rcx), %rdi
leaq 0x4c1a(%rip), %rsi      # 0xc29c
movl %r12d, %edx
movl %eax, %ecx
xorl %eax, %eax
callq 0x5580
jmp 0x75dd
leaq 0x4d15(%rip), %rdi      # 0xc3af
leaq 0x4ce2(%rip), %rsi      # 0xc383
leaq 0x4ce5(%rip), %rcx      # 0xc38d
movl $0x31c, %edx            # imm = 0x31C
callq 0x5160
leaq 0x4cb8(%rip), %rdi      # 0xc371
leaq 0x4cc3(%rip), %rsi      # 0xc383
leaq 0x4cc6(%rip), %rcx      # 0xc38d
movl $0x30b, %edx            # imm = 0x30B
callq 0x5160
movq 0xa910(%rip), %rax      # 0x11fe8
movq (%rax), %rcx
leaq 0x4d18(%rip), %rdi      # 0xc3fa
pushq $0x1d
popq %rsi
pushq $0x1
popq %rdx
callq 0x5510
jmp 0x6eb6