// File: /workspace/github_cpp_makefile_star2_O3/miklhh[P]tetris/src/main.cpp
// Function: main
int main(int argc, char* argv[])
{
    /* Intialize SDL. */
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        std::cout << "Failed to initialize SDL... Exiting." << std::endl;
        exit_game(NULL, NULL);
    }

	/* Aquire the monitor size and set the window size variables. */
	#define MONITOR_0 0
	SDL_GetCurrentDisplayMode(MONITOR_0, &display_mode);
	window_height   = get_window_height(display_mode);
	window_width    = get_window_width(display_mode);
	block_width     = window_width / 20;
	block_height    = window_height / 20;

	/* Initialize the window. */
	window = SDL_CreateWindow(
		"Tetris", 
		SDL_WINDOWPOS_UNDEFINED, 
		SDL_WINDOWPOS_UNDEFINED, 
		window_width, 
		window_height,
		NULL
	);
	if (window == NULL)
	{
		std::cout << "Failed to create a window... Exiting." << std::endl;
		exit_game(NULL, NULL);
	}

	/* Intialize the renderer. */
	#define FIRST_RENDERING_DEVICE -1
	renderer = SDL_CreateRenderer(
		window,
		FIRST_RENDERING_DEVICE,
		SDL_RENDERER_ACCELERATED
	);
	if (renderer == NULL)
	{
		std::cout << "Failed to create a renderer... Exiting." << std::endl;
		exit_game(window, NULL);
	}



	/* Initialize random seed, and setup the game. */
	srand((unsigned int)time(NULL));
	setup_game();

	/* Print screen and window information. */
	std::cout << "Screen-width: "   << display_mode.w   << ", Screen-height: "  << display_mode.h   << std::endl;
	std::cout << "Window-width: "   << window_width     << ", Window-height: "  << window_height    << std::endl;
	std::cout << "Block-width: "    << block_width      << ", Block-height: "   << block_height     << std::endl;

	/* DEBUGING TIMINGS, REMOVE LATER ON. */
	using namespace std::chrono;
	time_point<high_resolution_clock> t1;
	time_point<high_resolution_clock> t2;
	/* DEBUGING TIMINGS, REMOVE LATER ON. */

	bool is_running = true;
	while (is_running)
	{
		/* DEBUGING TIMINGS, REMOVE LATER ON. */
		t1 = high_resolution_clock::now();
		/* DEBUGING TIMINGS, REMOVE LATER ON. */

		/* Clear the screen. */
		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
		SDL_RenderClear(renderer);

		/* Replace with real timer instead. */
		if (iteration_timer())
		{ 
            iterate_game();
		}


        game_draw_field();
        game_draw_current_block();
		SDL_RenderPresent(renderer);

		while (SDL_PollEvent(&events))
		{
            if (events.type == SDL_QUIT)
                is_running = false;
            else
                handle_event(&events);
		}

        static keyboard_state_t* keyboard_state = SDL_GetKeyboardState(NULL);
        handle_keyboard_input(keyboard_state);

		/* DEBUGING TIMINGS, REMOVE LATER ON. */
		t2 = high_resolution_clock::now();
		std::cout << "Iteration time: " << duration_cast<microseconds>(t2 - t1).count() << " microseconds." << std::endl;
		/* DEBUGING TIMINGS, REMOVE LATER ON. */

		/* Later we want a total time of 10 milliseconds per iteration. Game updates 100 times a seconds.*/
		SDL_Delay(10);
	}
	

	exit_game(window, renderer);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl $0xf231, %edi           # imm = 0xF231
callq 0x2160
testl %eax, %eax
jns 0x34fb
movq 0x2b21(%rip), %rbx      # 0x5fd8
leaq 0xe5b(%rip), %rsi       # 0x4319
movl $0x24, %edx
movq %rbx, %rdi
callq 0x21f0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
xorl %edi, %edi
xorl %esi, %esi
callq 0x26b0
leaq 0x3616(%rip), %rsi      # 0x6b18
xorl %edi, %edi
callq 0x20d0
movq 0x3618(%rip), %rax      # 0x6b28
movq %rax, 0x10(%rsp)
movups 0x35fc(%rip), %xmm0     # 0x6b18
movups %xmm0, (%rsp)
callq 0x32c0
movl %eax, 0x3651(%rip)      # 0x6b7c
movq 0x35f6(%rip), %rax      # 0x6b28
movq %rax, 0x10(%rsp)
movups 0x35da(%rip), %xmm0     # 0x6b18
movups %xmm0, (%rsp)
callq 0x32ef
movl %eax, 0x362b(%rip)      # 0x6b78
movslq %eax, %rcx
imulq $0x66666667, %rcx, %rax # imm = 0x66666667
movq %rax, %rdx
shrq $0x3f, %rdx
sarq $0x23, %rax
addl %edx, %eax
movl %eax, 0x3616(%rip)      # 0x6b80
movslq 0x360b(%rip), %r8       # 0x6b7c
imulq $0x66666667, %r8, %rax  # imm = 0x66666667
movq %rax, %rdx
shrq $0x3f, %rdx
sarq $0x23, %rax
addl %edx, %eax
movl %eax, 0x35f9(%rip)      # 0x6b84
leaq 0xdac(%rip), %rdi       # 0x433e
movl $0x1fff0000, %esi       # imm = 0x1FFF0000
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
xorl %r9d, %r9d
callq 0x2060
movq %rax, 0x35bd(%rip)      # 0x6b68
testq %rax, %rax
jne 0x3602
movq 0x2a21(%rip), %rbx      # 0x5fd8
leaq 0xd87(%rip), %rsi       # 0x4345
movl $0x25, %edx
movq %rbx, %rdi
callq 0x21f0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
xorl %edi, %edi
xorl %esi, %esi
callq 0x26b0
movq 0x3566(%rip), %rax      # 0x6b68
movq %rax, %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0x2, %edx
callq 0x2050
movq %rax, 0x3555(%rip)      # 0x6b70
testq %rax, %rax
jne 0x3670
movq 0x29b1(%rip), %rbx      # 0x5fd8
leaq 0xd3d(%rip), %rsi       # 0x436b
movl $0x27, %edx
movq %rbx, %rdi
callq 0x21f0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x34ff(%rip), %rdi      # 0x6b68
xorl %esi, %esi
callq 0x26b0
xorl %edi, %edi
callq 0x2170
movl %eax, %edi
callq 0x21a0
callq 0x275d
movq 0x294e(%rip), %rbx      # 0x5fd8
leaq 0xd02(%rip), %rsi       # 0x4393
movl $0xe, %edx
movq %rbx, %rdi
callq 0x21f0
movl 0x3478(%rip), %esi      # 0x6b1c
movq %rbx, %rdi
callq 0x2230
movq %rax, %r14
leaq 0xcec(%rip), %rsi       # 0x43a2
movl $0x11, %edx
movq %rax, %rdi
callq 0x21f0
movl 0x3457(%rip), %esi      # 0x6b20
movq %r14, %rdi
callq 0x2230
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0xcb2(%rip), %rsi       # 0x43b4
movl $0xe, %edx
movq %rbx, %rdi
callq 0x21f0
movl 0x3463(%rip), %esi      # 0x6b78
movq %rbx, %rdi
callq 0x2230
movq %rax, %r14
leaq 0xc9c(%rip), %rsi       # 0x43c3
movl $0x11, %edx
movq %rax, %rdi
callq 0x21f0
movl 0x3442(%rip), %esi      # 0x6b7c
movq %r14, %rdi
callq 0x2230
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0xc62(%rip), %rsi       # 0x43d5
movl $0xd, %edx
movq %rbx, %rdi
callq 0x21f0
movl 0x33fa(%rip), %esi      # 0x6b80
movq %rbx, %rdi
callq 0x2230
movq %rax, %r14
leaq 0xc4b(%rip), %rsi       # 0x43e3
movl $0x10, %edx
movq %rax, %rdi
callq 0x21f0
movl 0x33d9(%rip), %esi      # 0x6b84
movq %r14, %rdi
callq 0x2230
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x334c(%rip), %r14      # 0x6b30
leaq 0xc1a(%rip), %r13       # 0x4405
callq 0x2070
movq %rax, %rbp
movq 0x3376(%rip), %rdi      # 0x6b70
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x2210
movq 0x3361(%rip), %rdi      # 0x6b70
callq 0x2180
callq 0x3159
testb %al, %al
je 0x3822
callq 0x2f34
callq 0x2eae
callq 0x2e9c
movq 0x333d(%rip), %rdi      # 0x6b70
callq 0x2090
movq %r14, %rdi
callq 0x20f0
movb $0x1, %r12b
testl %eax, %eax
je 0x386a
cmpl $0x100, 0x32df(%rip)    # imm = 0x100
jne 0x3858
xorl %r12d, %r12d
jmp 0x3860
movq %r14, %rdi
callq 0x3320
movq %r14, %rdi
callq 0x20f0
jmp 0x3843
movb 0x3320(%rip), %al       # 0x6b90
testb %al, %al
je 0x3919
movq 0x3309(%rip), %rdi      # 0x6b88
callq 0x33aa
callq 0x2070
movq %rax, %r15
movl $0x10, %edx
movq %rbx, %rdi
leaq 0xb59(%rip), %rsi       # 0x43f4
callq 0x21f0
subq %rbp, %r15
movq %r15, %rax
movabsq $0x20c49ba5e353f7cf, %rcx # imm = 0x20C49BA5E353F7CF
imulq %rcx
movq %rdx, %rsi
shrq $0x3f, %rsi
sarq $0x7, %rdx
addq %rdx, %rsi
movq %rbx, %rdi
callq 0x2190
movq %rax, %r15
movl $0xe, %edx
movq %rax, %rdi
movq %r13, %rsi
callq 0x21f0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x21b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0xa, %edi
callq 0x2130
testb $0x1, %r12b
jne 0x37eb
jmp 0x394c
leaq 0x3270(%rip), %rdi      # 0x6b90
callq 0x2250
testl %eax, %eax
je 0x3878
xorl %edi, %edi
callq 0x2260
movq %rax, 0x324d(%rip)      # 0x6b88
leaq 0x324e(%rip), %rdi      # 0x6b90
callq 0x2110
jmp 0x3878
movq 0x3215(%rip), %rdi      # 0x6b68
movq 0x3216(%rip), %rsi      # 0x6b70
callq 0x26b0
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x3216(%rip), %rdi      # 0x6b90
callq 0x2100
movq %rbx, %rdi
callq 0x2240