// File: sgielen[P]clife/multicolor.cpp
// Function: main
int main(int argc, char *argv[]) {
	int microsleeptime = 100'000;
	if(argc == 2) {
		std::stringstream ss;
		ss << argv[1];
		ss >> microsleeptime;
		if(!ss) {
			std::cerr << "Usage: " << argv[0] << " [microsleeptime]" << std::endl;
		}
	} else if(argc > 2) {
		std::cerr << "Usage: " << argv[0] << " [microsleeptime]" << std::endl;
	}

	init_random();

	winsize current_winsize;
#if defined(FIXED_SIZE)
	current_winsize.ws_col = FIXED_WIDTH;
	current_winsize.ws_row = FIXED_HEIGHT;
#else
	ioctl(STDOUT_FILENO, TIOCGWINSZ, &current_winsize);
#endif
	std::vector<uint64_t> earlier_hashes;
	GameOfLifeField<MulticolorValue> field(current_winsize.ws_col, current_winsize.ws_row);
	get_width = [&field]() {
		return field.get_width();
	};

	field.generateRandom(35);

	bool field_done = false;
	int repeats_to_do = 0;

	pthread_mutex_t mtx;
	pthread_mutex_init(&mtx, nullptr);
	pthread_cond_t cond;
	pthread_cond_init(&cond, nullptr);
	struct timespec ts = {};
	ts.tv_sec = std::time(nullptr);
	pthread_mutex_lock(&mtx);

	while(!field_done || repeats_to_do > 0) {
#if !defined(FIXED_SIZE)
		winsize new_winsize;
		ioctl(STDOUT_FILENO, TIOCGWINSZ, &new_winsize);
		if(current_winsize.ws_col != new_winsize.ws_col
		|| current_winsize.ws_row != new_winsize.ws_row) {
			field.resize(new_winsize.ws_col, new_winsize.ws_row);
		}
		current_winsize = new_winsize;
#endif

		if(repeats_to_do > 0) {
			--repeats_to_do;
		}
		field.nextState();
		field.print_simple(std::cout);
		if(!field_done) {
			check_stop_condition(field, earlier_hashes, field_done, repeats_to_do);
		}
		ts.tv_nsec += microsleeptime * 1'000;
		ts.tv_sec += ts.tv_nsec / 1'000'000'000;
		ts.tv_nsec %= 1'000'000'000;
		pthread_cond_timedwait(&cond, &mtx, &ts);
	}

	pthread_mutex_unlock(&mtx);
	pthread_cond_destroy(&cond);
	pthread_mutex_destroy(&mtx);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x186a0, -0x14(%rbp)   # imm = 0x186A0
cmpl $0x2, -0x8(%rbp)
jne 0x57e9
leaq -0x1a0(%rbp), %rdi
callq 0x20f0
leaq -0x190(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x2180
jmp 0x570c
leaq -0x1a0(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x20d0
jmp 0x571e
movq -0x1a0(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x1a0(%rbp,%rax), %rdi
callq 0x2080
movb %al, -0x289(%rbp)
jmp 0x573e
movb -0x289(%rbp), %al
testb $0x1, %al
jne 0x574d
jmp 0x57db
movq 0xe894(%rip), %rdi      # 0x13fe8
leaq 0x8ac1(%rip), %rsi      # 0xe21c
callq 0x2180
movq %rax, -0x298(%rbp)
jmp 0x5769
movq -0x298(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x2180
movq %rax, -0x2a0(%rbp)
jmp 0x5785
movq -0x2a0(%rbp), %rdi
leaq 0x8a91(%rip), %rsi      # 0xe224
callq 0x2180
movq %rax, -0x2a8(%rbp)
jmp 0x57a1
movq -0x2a8(%rbp), %rdi
movq 0xe7f9(%rip), %rsi      # 0x13fa8
callq 0x21b0
jmp 0x57b6
jmp 0x57db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x2110
jmp 0x5b31
leaq -0x1a0(%rbp), %rdi
callq 0x2110
jmp 0x5831
cmpl $0x2, -0x8(%rbp)
jle 0x582f
movq 0xe7f2(%rip), %rdi      # 0x13fe8
leaq 0x8a1f(%rip), %rsi      # 0xe21c
callq 0x2180
movq %rax, %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x2180
movq %rax, %rdi
leaq 0x8a09(%rip), %rsi      # 0xe224
callq 0x2180
movq %rax, %rdi
movq 0xe77e(%rip), %rsi      # 0x13fa8
callq 0x21b0
jmp 0x5831
callq 0x5690
movw $0x50, -0x1b2(%rbp)
movw $0x8, -0x1b4(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x7980
movzwl -0x1b2(%rbp), %esi
movzwl -0x1b4(%rbp), %edx
leaq -0x1f0(%rbp), %rdi
callq 0x79a0
jmp 0x5870
leaq -0x1f0(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movq %rax, -0x1f8(%rbp)
leaq 0xe914(%rip), %rdi      # 0x141a0
leaq -0x1f8(%rbp), %rsi
callq 0x5b40
movq -0x2b0(%rbp), %rdi
movl $0x23, %esi
callq 0x7a40
jmp 0x58ab
movb $0x0, -0x1f9(%rbp)
movl $0x0, -0x200(%rbp)
leaq -0x228(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2230
leaq -0x258(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x21f0
leaq -0x268(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x20b0
xorl %eax, %eax
movl %eax, %edi
callq 0x2160
movq %rax, -0x268(%rbp)
leaq -0x228(%rbp), %rdi
callq 0x2220
movb $0x1, %al
testb $0x1, -0x1f9(%rbp)
movb %al, -0x2b1(%rbp)
je 0x592c
cmpl $0x0, -0x200(%rbp)
setg %al
movb %al, -0x2b1(%rbp)
movb -0x2b1(%rbp), %al
testb $0x1, %al
jne 0x593b
jmp 0x5ad1
cmpl $0x0, -0x200(%rbp)
jle 0x5983
movl -0x200(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x200(%rbp)
jmp 0x5983
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
jmp 0x5b25
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
jmp 0x5b19
leaq -0x1f0(%rbp), %rdi
callq 0x7b70
jmp 0x5991
movq 0xe628(%rip), %rsi      # 0x13fc0
leaq -0x1f0(%rbp), %rdi
callq 0x7e30
jmp 0x59a6
testb $0x1, -0x1f9(%rbp)
jne 0x5a18
leaq -0x288(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x8010
jmp 0x59c4
leaq -0x288(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
leaq -0x1f9(%rbp), %rdx
leaq -0x200(%rbp), %rcx
callq 0x7f70
jmp 0x59e7
leaq -0x288(%rbp), %rdi
callq 0x8050
jmp 0x5a18
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1a8(%rbp)
movl %eax, -0x1ac(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x8050
jmp 0x5b19
movl -0x14(%rbp), %eax
imull $0x3e8, %eax, %eax      # imm = 0x3E8
movslq %eax, %rcx
movq -0x260(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x260(%rbp)
movq -0x268(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movq -0x260(%rbp), %rax
movabsq $0x112e0be826d694b3, %rcx # imm = 0x112E0BE826D694B3
imulq %rcx
movq -0x2c8(%rbp), %rax
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x1a, %rdx
addq %rsi, %rdx
addq %rdx, %rax
movq %rax, -0x268(%rbp)
movq -0x260(%rbp), %rax
movq %rax, -0x2c0(%rbp)
imulq %rcx
movq -0x2c0(%rbp), %rax
movq %rdx, %rcx
movq %rcx, %rdx
shrq $0x3f, %rdx
sarq $0x1a, %rcx
addq %rdx, %rcx
imulq $0x3b9aca00, %rcx, %rcx # imm = 0x3B9ACA00
subq %rcx, %rax
movq %rax, -0x260(%rbp)
leaq -0x258(%rbp), %rdi
leaq -0x228(%rbp), %rsi
leaq -0x268(%rbp), %rdx
callq 0x2240
jmp 0x5acc
jmp 0x590b
leaq -0x228(%rbp), %rdi
callq 0x2120
leaq -0x258(%rbp), %rdi
callq 0x22e0
leaq -0x228(%rbp), %rdi
callq 0x21d0
leaq -0x1f0(%rbp), %rdi
callq 0x8050
leaq -0x1d0(%rbp), %rdi
callq 0x8070
movl -0x4(%rbp), %eax
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
leaq -0x1f0(%rbp), %rdi
callq 0x8050
leaq -0x1d0(%rbp), %rdi
callq 0x8070
movq -0x1a8(%rbp), %rdi
callq 0x22d0
nopl (%rax)