// File: /workspace/github_cpp_makefile_star2_O2/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 0x2140
testl %eax, %eax
jns 0x3324
movq 0x2cd1(%rip), %rdi      # 0x5fd8
leaq 0x100b(%rip), %rsi      # 0x4319
callq 0x2190
movq %rax, %rdi
callq 0x20b0
xorl %edi, %edi
xorl %esi, %esi
callq 0x2630
leaq 0x37cd(%rip), %rsi      # 0x6af8
xorl %edi, %edi
callq 0x20c0
movq 0x37cf(%rip), %rax      # 0x6b08
movq %rax, 0x10(%rsp)
movups 0x37b3(%rip), %xmm0     # 0x6af8
movups %xmm0, (%rsp)
callq 0x3118
movl %eax, 0x3808(%rip)      # 0x6b5c
movq 0x37ad(%rip), %rax      # 0x6b08
movq %rax, 0x10(%rsp)
movups 0x3791(%rip), %xmm0     # 0x6af8
movups %xmm0, (%rsp)
callq 0x3136
movl %eax, %ecx
movl %eax, 0x37e0(%rip)      # 0x6b58
pushq $0x14
popq %rsi
cltd
idivl %esi
movl %eax, 0x37dc(%rip)      # 0x6b60
movl 0x37d1(%rip), %r8d      # 0x6b5c
movl %r8d, %eax
cltd
idivl %esi
movl %eax, 0x37cd(%rip)      # 0x6b64
leaq 0xfa0(%rip), %rdi       # 0x433e
movl $0x1fff0000, %esi       # imm = 0x1FFF0000
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
xorl %r9d, %r9d
callq 0x2050
movq %rax, 0x3791(%rip)      # 0x6b48
testq %rax, %rax
jne 0x33e7
movq 0x2c15(%rip), %rdi      # 0x5fd8
leaq 0xf7b(%rip), %rsi       # 0x4345
callq 0x2190
movq %rax, %rdi
callq 0x20b0
xorl %edi, %edi
xorl %esi, %esi
callq 0x2630
movq 0x3761(%rip), %rax      # 0x6b48
pushq $-0x1
popq %rsi
pushq $0x2
popq %rdx
movq %rax, %rdi
callq 0x2040
movq %rax, 0x3754(%rip)      # 0x6b50
testq %rax, %rax
jne 0x342a
movq 0x2bd0(%rip), %rdi      # 0x5fd8
leaq 0xf5c(%rip), %rsi       # 0x436b
callq 0x2190
movq %rax, %rdi
callq 0x20b0
movq 0x3725(%rip), %rdi      # 0x6b48
xorl %esi, %esi
callq 0x2630
xorl %edi, %edi
callq 0x2150
movl %eax, %edi
callq 0x2180
callq 0x26aa
movq 0x2b94(%rip), %rbx      # 0x5fd8
leaq 0xf48(%rip), %rsi       # 0x4393
movq %rbx, %rdi
callq 0x2190
movl 0x36a3(%rip), %esi      # 0x6afc
movq %rax, %rdi
callq 0x21f0
leaq 0xf3a(%rip), %rsi       # 0x43a2
movq %rax, %rdi
callq 0x2190
movl 0x368a(%rip), %esi      # 0x6b00
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20b0
leaq 0xf27(%rip), %rsi       # 0x43b4
movq %rbx, %rdi
callq 0x2190
movl 0x36bd(%rip), %esi      # 0x6b58
movq %rax, %rdi
callq 0x21f0
leaq 0xf19(%rip), %rsi       # 0x43c3
movq %rax, %rdi
callq 0x2190
movl 0x36a4(%rip), %esi      # 0x6b5c
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20b0
leaq 0xf06(%rip), %rsi       # 0x43d5
movq %rbx, %rdi
callq 0x2190
movl 0x3683(%rip), %esi      # 0x6b60
movq %rax, %rdi
callq 0x21f0
leaq 0xef7(%rip), %rsi       # 0x43e3
movq %rax, %rdi
callq 0x2190
movl 0x366a(%rip), %esi      # 0x6b64
movq %rax, %rdi
callq 0x21f0
movq %rax, %rdi
callq 0x20b0
leaq 0x35ff(%rip), %r14      # 0x6b10
leaq 0xeed(%rip), %r13       # 0x4405
pushq $0xa
popq %rbp
callq 0x2060
movq %rax, %r15
movq 0x3626(%rip), %rdi      # 0x6b50
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x21d0
movq 0x3611(%rip), %rdi      # 0x6b50
callq 0x2160
callq 0x2fd6
testb %al, %al
je 0x3552
callq 0x2e69
callq 0x2de1
callq 0x2dcf
movq 0x35ed(%rip), %rdi      # 0x6b50
callq 0x2080
movb $0x1, %r12b
movq %r14, %rdi
callq 0x20e0
testl %eax, %eax
je 0x3592
cmpl $0x100, 0x358f(%rip)    # imm = 0x100
je 0x358d
movq %r14, %rdi
callq 0x3154
jmp 0x356b
xorl %r12d, %r12d
jmp 0x356b
movb 0x35d8(%rip), %al       # 0x6b70
testb %al, %al
je 0x3604
movq 0x35c5(%rip), %rdi      # 0x6b68
callq 0x31da
callq 0x2060
movq %rax, %rbx
movq 0x2a21(%rip), %rdi      # 0x5fd8
leaq 0xe36(%rip), %rsi       # 0x43f4
callq 0x2190
movq %rax, %rdi
subq %r15, %rbx
movq %rbx, %rax
cqto
movl $0x3e8, %ecx            # imm = 0x3E8
idivq %rcx
movq %rax, %rsi
callq 0x2170
movq %rax, %rdi
movq %r13, %rsi
callq 0x2190
movq %rax, %rdi
callq 0x20b0
movl %ebp, %edi
callq 0x2110
testb $0x1, %r12b
jne 0x351b
jmp 0x3633
leaq 0x3565(%rip), %rdi      # 0x6b70
callq 0x2210
testl %eax, %eax
je 0x359c
xorl %edi, %edi
callq 0x2220
movq %rax, 0x3546(%rip)      # 0x6b68
leaq 0x3547(%rip), %rdi      # 0x6b70
callq 0x2100
jmp 0x359c
movq 0x350e(%rip), %rdi      # 0x6b48
movq 0x350f(%rip), %rsi      # 0x6b50
callq 0x2630
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x350f(%rip), %rdi      # 0x6b70
callq 0x20f0
movq %rbx, %rdi
callq 0x2200