// File: /workspace/github_c_makefile_star2_O0/mesbahamin[P]star-sim/src/platform_sdl.c
// Function: main
int main(int argc, char *argv[])
{
    if (SDL_Init(SDL_INIT_VIDEO))
    {
        // TODO(amin): log SDL_Init error
    }

    SDL_Window *window = SDL_CreateWindow(
            TITLE,
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            SCREEN_WIDTH,
            SCREEN_HEIGHT,
            SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);

#ifdef FULLSCREEN
    SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
#endif

    if (window)
    {
        SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);

        if (renderer)
        {
            struct SDLWindowDimension dimension = sdl_get_window_dimension(window);
            sdl_resize_texture(&global_back_buffer, renderer, dimension.width, dimension.height);

            bool running = true;

#ifdef USE_TEST_SEED
            srand((uint32_t)0);
#else
            srand((uint32_t)time(NULL));
#endif

            uint64_t lag = 0;
            uint64_t previous_ms = (SDL_GetPerformanceCounter() * SECOND) / SDL_GetPerformanceFrequency();

            struct SimState sim_state;
            sim_init(&sim_state, dimension.width, dimension.height);

            while (running)
            {
                uint64_t current_ms = (SDL_GetPerformanceCounter() * SECOND) / SDL_GetPerformanceFrequency();
                uint64_t elapsed_ms = current_ms - previous_ms;
                previous_ms = current_ms;
                lag += elapsed_ms;
                //printf("%" PRIu64 ", %" PRIu64 ", %f\n", elapsed_ms, lag, MS_PER_UPDATE);

                SDL_Event event;

                while (SDL_PollEvent(&event))
                {
                    running = !handle_event(&event);
                }

                SDL_PumpEvents();

                dimension = sdl_get_window_dimension(window);

                const uint8_t *keystate = SDL_GetKeyboardState(0);

                // TODO: move this to a function
                if (keystate[SDL_SCANCODE_A] || keystate[SDL_SCANCODE_H])
                {
                    sim_state.view.dx += 5 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_D] || keystate[SDL_SCANCODE_L])
                {
                    sim_state.view.dx -= 5 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_W] || keystate[SDL_SCANCODE_K])
                {
                    sim_state.view.dy += 5 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_S] || keystate[SDL_SCANCODE_J])
                {
                    sim_state.view.dy -= 5 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_LEFT])
                {
                    sim_state.view.dx += 1 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_RIGHT])
                {
                    sim_state.view.dx -= 1 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_UP])
                {
                    sim_state.view.dy += 1 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_DOWN])
                {
                    sim_state.view.dy -= 1 / sim_state.view.zoom;
                }
                if (keystate[SDL_SCANCODE_EQUALS])
                {
                    sim_state.view.zoom *= 1.01;
                }
                if (keystate[SDL_SCANCODE_MINUS])
                {
                    sim_state.view.zoom *= 0.99;
                }
                if (keystate[SDL_SCANCODE_0])
                {
                    sim_state.view.zoom = 1;
                }
                if (keystate[SDL_SCANCODE_HOME])
                {
                    sim_state.view.dx = 0;
                    sim_state.view.dy = 0;
                    sim_state.view.zoom = 1;
                }

                struct OffscreenBuffer buffer;
                // WARNING: these pointers are aliased until the end of the
                // loop
                buffer.memory = global_back_buffer.memory;
                buffer.width = global_back_buffer.width;
                buffer.height = global_back_buffer.height;
                buffer.pitch = global_back_buffer.pitch;

                if (PAUSED)
                {
                    lag = 0;
                }
                else
                {
                    while (lag >= MS_PER_UPDATE)
                    {
                        sim_update(&sim_state, buffer.width, buffer.height);
                        //printf("\t%" PRIu64 ", %f\n", lag, MS_PER_UPDATE);
                        lag -= MS_PER_UPDATE;
                    }
                }

                if (!RENDER_TRAILS)
                {
                    clear_screen(&global_back_buffer, COLOR_BACKGROUND);
                }

                sim_render(&buffer, lag/SECOND, &sim_state);
                sdl_update_window(renderer, &global_back_buffer);
                if (elapsed_ms <= MS_PER_FRAME)
                {
                    SDL_Delay(MS_PER_FRAME - elapsed_ms);
                }
            }

            sim_cleanup(&sim_state);
        }
        else
        {
            // TODO(amin): log SDL_Renderer error
        }
    }
    else
    {
        // TODO(amin): log SDL_Window error
    }

    SDL_Quit();
    return(0);
}

// Assembly:
subq $0xc18, %rsp            # imm = 0xC18
movl $0x0, 0xc14(%rsp)
movl %edi, 0xc10(%rsp)
movq %rsi, 0xc08(%rsp)
movl $0x20, %edi
callq 0x1160
cmpl $0x0, %eax
je 0x16f2
jmp 0x16f2
leaq 0x2986(%rip), %rdi      # 0x407f
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
movl $0x280, %ecx            # imm = 0x280
movl $0x1e0, %r8d            # imm = 0x1E0
movl $0x2020, %r9d           # imm = 0x2020
movl %edx, %esi
callq 0x1050
movq %rax, 0xc00(%rsp)
movq 0xc00(%rsp), %rdi
movl $0x1001, %esi           # imm = 0x1001
callq 0x1190
cmpq $0x0, 0xc00(%rsp)
je 0x1f31
movq 0xc00(%rsp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
xorl %edx, %edx
callq 0x1030
movq %rax, 0xbf8(%rsp)
cmpq $0x0, 0xbf8(%rsp)
je 0x1f2d
movq 0xc00(%rsp), %rdi
callq 0x1310
movq %rax, 0xbf0(%rsp)
movq 0xbf8(%rsp), %rsi
movl 0xbf0(%rsp), %edx
movl 0xbf4(%rsp), %ecx
leaq 0x4984(%rip), %rdi      # 0x6120
callq 0x1340
movb $0x1, 0xbef(%rsp)
xorl %edi, %edi
callq 0x1170
movq $0x0, 0xbe0(%rsp)
callq 0x11c0
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x48(%rsp)
testq %rax, %rax
movss %xmm0, 0x4c(%rsp)
js 0x17fa
movss 0x48(%rsp), %xmm0
movss %xmm0, 0x4c(%rsp)
movss 0x4c(%rsp), %xmm0
movss 0x27fc(%rip), %xmm1     # 0x4004
mulss %xmm1, %xmm0
movss %xmm0, 0x3c(%rsp)
callq 0x1150
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x40(%rsp)
testq %rax, %rax
movss %xmm0, 0x44(%rsp)
js 0x1850
movss 0x40(%rsp), %xmm0
movss %xmm0, 0x44(%rsp)
movss 0x3c(%rsp), %xmm0
movss 0x44(%rsp), %xmm1
divss %xmm1, %xmm0
movaps %xmm0, %xmm1
cvttss2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
movss 0x2791(%rip), %xmm1     # 0x4008
subss %xmm1, %xmm0
cvttss2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, 0xbd8(%rsp)
movl 0xbf0(%rsp), %esi
movl 0xbf4(%rsp), %edx
leaq 0xc0(%rsp), %rdi
callq 0x1f50
testb $0x1, 0xbef(%rsp)
je 0x1f1e
callq 0x11c0
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x34(%rsp)
testq %rax, %rax
movss %xmm0, 0x38(%rsp)
js 0x18f5
movss 0x34(%rsp), %xmm0
movss %xmm0, 0x38(%rsp)
movss 0x38(%rsp), %xmm0
movss 0x2701(%rip), %xmm1     # 0x4004
mulss %xmm1, %xmm0
movss %xmm0, 0x28(%rsp)
callq 0x1150
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x2c(%rsp)
testq %rax, %rax
movss %xmm0, 0x30(%rsp)
js 0x194b
movss 0x2c(%rsp), %xmm0
movss %xmm0, 0x30(%rsp)
movss 0x28(%rsp), %xmm0
movss 0x30(%rsp), %xmm1
divss %xmm1, %xmm0
movaps %xmm0, %xmm1
cvttss2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
movss 0x2696(%rip), %xmm1     # 0x4008
subss %xmm1, %xmm0
cvttss2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rax
subq 0xbd8(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0xbd8(%rsp)
movq 0xb0(%rsp), %rax
addq 0xbe0(%rsp), %rax
movq %rax, 0xbe0(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x10c0
cmpl $0x0, %eax
je 0x19ef
leaq 0x78(%rsp), %rdi
callq 0x14a0
xorb $-0x1, %al
andb $0x1, %al
movb %al, 0xbef(%rsp)
jmp 0x19c9
callq 0x1140
movq 0xc00(%rsp), %rdi
callq 0x1310
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0xbf0(%rsp)
xorl %eax, %eax
movl %eax, %edi
callq 0x1200
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movzbl 0x4(%rax), %eax
cmpl $0x0, %eax
jne 0x1a3d
movq 0x68(%rsp), %rax
movzbl 0xb(%rax), %eax
cmpl $0x0, %eax
je 0x1a60
movss 0x25c7(%rip), %xmm0     # 0x400c
divss 0xdc(%rsp), %xmm0
addss 0xd4(%rsp), %xmm0
movss %xmm0, 0xd4(%rsp)
movq 0x68(%rsp), %rax
movzbl 0x7(%rax), %eax
cmpl $0x0, %eax
jne 0x1a7c
movq 0x68(%rsp), %rax
movzbl 0xf(%rax), %eax
cmpl $0x0, %eax
je 0x1aa3
movss 0x2588(%rip), %xmm1     # 0x400c
divss 0xdc(%rsp), %xmm1
movss 0xd4(%rsp), %xmm0
subss %xmm1, %xmm0
movss %xmm0, 0xd4(%rsp)
movq 0x68(%rsp), %rax
movzbl 0x1a(%rax), %eax
cmpl $0x0, %eax
jne 0x1abf
movq 0x68(%rsp), %rax
movzbl 0xe(%rax), %eax
cmpl $0x0, %eax
je 0x1ae2
movss 0x2545(%rip), %xmm0     # 0x400c
divss 0xdc(%rsp), %xmm0
addss 0xd8(%rsp), %xmm0
movss %xmm0, 0xd8(%rsp)
movq 0x68(%rsp), %rax
movzbl 0x16(%rax), %eax
cmpl $0x0, %eax
jne 0x1afe
movq 0x68(%rsp), %rax
movzbl 0xd(%rax), %eax
cmpl $0x0, %eax
je 0x1b25
movss 0x2506(%rip), %xmm1     # 0x400c
divss 0xdc(%rsp), %xmm1
movss 0xd8(%rsp), %xmm0
subss %xmm1, %xmm0
movss %xmm0, 0xd8(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x50(%rax)
je 0x1b53
movss 0x24d8(%rip), %xmm0     # 0x4010
divss 0xdc(%rsp), %xmm0
addss 0xd4(%rsp), %xmm0
movss %xmm0, 0xd4(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x4f(%rax)
je 0x1b85
movss 0x24aa(%rip), %xmm1     # 0x4010
divss 0xdc(%rsp), %xmm1
movss 0xd4(%rsp), %xmm0
subss %xmm1, %xmm0
movss %xmm0, 0xd4(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x52(%rax)
je 0x1bb3
movss 0x2478(%rip), %xmm0     # 0x4010
divss 0xdc(%rsp), %xmm0
addss 0xd8(%rsp), %xmm0
movss %xmm0, 0xd8(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x51(%rax)
je 0x1be5
movss 0x244a(%rip), %xmm1     # 0x4010
divss 0xdc(%rsp), %xmm1
movss 0xd8(%rsp), %xmm0
subss %xmm1, %xmm0
movss %xmm0, 0xd8(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x2e(%rax)
je 0x1c16
movss 0xdc(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x241b(%rip), %xmm1     # 0x4020
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xdc(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x2d(%rax)
je 0x1c47
movss 0xdc(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x23f2(%rip), %xmm1     # 0x4028
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xdc(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x27(%rax)
je 0x1c63
movss 0x23b6(%rip), %xmm0     # 0x4010
movss %xmm0, 0xdc(%rsp)
movq 0x68(%rsp), %rax
cmpb $0x0, 0x4a(%rax)
je 0x1c97
xorps %xmm0, %xmm0
movss %xmm0, 0xd4(%rsp)
xorps %xmm0, %xmm0
movss %xmm0, 0xd8(%rsp)
movss 0x2382(%rip), %xmm0     # 0x4010
movss %xmm0, 0xdc(%rsp)
movq 0x448a(%rip), %rax      # 0x6128
movq %rax, 0x50(%rsp)
movl 0x4487(%rip), %eax      # 0x6130
movl %eax, 0x58(%rsp)
movl 0x4481(%rip), %eax      # 0x6134
movl %eax, 0x5c(%rsp)
movl 0x447b(%rip), %eax      # 0x6138
movl %eax, 0x60(%rsp)
leaq 0x4478(%rip), %rax      # 0x6140
testb $0x1, (%rax)
je 0x1cde
movq $0x0, 0xbe0(%rsp)
jmp 0x1dd5
jmp 0x1ce0
movq 0xbe0(%rsp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x20(%rsp)
testq %rax, %rax
movss %xmm0, 0x24(%rsp)
js 0x1d21
movss 0x20(%rsp), %xmm0
movss %xmm0, 0x24(%rsp)
movss 0x24(%rsp), %xmm0
movss 0x22e5(%rip), %xmm1     # 0x4014
ucomiss %xmm1, %xmm0
jb 0x1dd3
movl 0x58(%rsp), %esi
movl 0x5c(%rsp), %edx
leaq 0xc0(%rsp), %rdi
callq 0x22d0
movq 0xbe0(%rsp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x18(%rsp)
testq %rax, %rax
movss %xmm0, 0x1c(%rsp)
js 0x1d8e
movss 0x18(%rsp), %xmm0
movss %xmm0, 0x1c(%rsp)
movss 0x1c(%rsp), %xmm0
movss 0x227c(%rip), %xmm1     # 0x4018
addss %xmm1, %xmm0
movaps %xmm0, %xmm1
cvttss2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
movss 0x2251(%rip), %xmm1     # 0x4008
subss %xmm1, %xmm0
cvttss2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, 0xbe0(%rsp)
jmp 0x1ce0
jmp 0x1dd5
leaq 0x4368(%rip), %rax      # 0x6144
testb $0x1, (%rax)
jne 0x1def
leaq 0x4338(%rip), %rdi      # 0x6120
xorl %esi, %esi
callq 0x1460
movq 0xbe0(%rsp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x10(%rsp)
testq %rax, %rax
movss %xmm0, 0x14(%rsp)
js 0x1e30
movss 0x10(%rsp), %xmm0
movss %xmm0, 0x14(%rsp)
movss 0x14(%rsp), %xmm0
movss 0x21c6(%rip), %xmm1     # 0x4004
divss %xmm1, %xmm0
leaq 0x50(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x26d0
movq 0xbf8(%rsp), %rdi
leaq 0x42bd(%rip), %rsi      # 0x6120
callq 0x1400
movq 0xb0(%rsp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, 0x8(%rsp)
testq %rax, %rax
movss %xmm0, 0xc(%rsp)
js 0x1ea9
movss 0x8(%rsp), %xmm0
movss %xmm0, 0xc(%rsp)
movss 0xc(%rsp), %xmm1
movss 0x2165(%rip), %xmm0     # 0x401c
ucomiss %xmm1, %xmm0
jb 0x1f19
movq 0xb0(%rsp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, (%rsp)
testq %rax, %rax
movss %xmm0, 0x4(%rsp)
js 0x1efb
movss (%rsp), %xmm0
movss %xmm0, 0x4(%rsp)
movss 0x4(%rsp), %xmm1
movss 0x2113(%rip), %xmm0     # 0x401c
subss %xmm1, %xmm0
cvttss2si %xmm0, %rax
movl %eax, %edi
callq 0x10e0
jmp 0x18a9
leaq 0xc0(%rsp), %rdi
callq 0x31e0
jmp 0x1f2f
jmp 0x1f2f
jmp 0x1f33
jmp 0x1f33
callq 0x1060
xorl %eax, %eax
addq $0xc18, %rsp            # imm = 0xC18
retq
nopw %cs:(%rax,%rax)
nopl (%rax)