// File: /workspace/github_c_makefile_star2_O0/skeeto[P]goblin-com/src/main.c
// Function: main
int
main(void)
{
    int w, h;
    display_init();
    device_terminal_size(&w, &h);
    if (w < DISPLAY_WIDTH || h < DISPLAY_HEIGHT) {
        display_free();
        printf("Goblin-COM requires a terminal of at least %dx%d characters!\n"
               "I see %dx%d\n"
               "Press enter to exit ...\n",
               DISPLAY_WIDTH, DISPLAY_HEIGHT, w, h);
        fflush(stdout);
        getchar();
        exit(EXIT_FAILURE);
    }
    device_entropy(&rand_state, sizeof(rand_state));
    device_title("Goblin-COM");

    panel_t loading;
    uint8_t loading_message[] = "Initializing world ...";
    panel_center_init(&loading, sizeof(loading_message), 1);
    display_push(&loading);
    panel_puts(&loading, 0, 0, FONT_DEFAULT, (char *)loading_message);
    display_refresh();
    game_t *game;
    FILE *save = fopen(PERSIST_FILE, "rb");
    if (save) {
        game = game_load(save);
        fclose(save);
        game->speed = SPEED_FACTOR;
        unlink(PERSIST_FILE);
    } else {
        game = game_create(xorshift(&rand_state));
        game->speed = SPEED_FACTOR;
    }
    atexit_save_game = game;
    atexit(atexit_save);
    display_pop_free();

    panel_t sidemenu;
    panel_init(&sidemenu, DISPLAY_WIDTH - SIDEMENU_WIDTH, 0,
               SIDEMENU_WIDTH, DISPLAY_HEIGHT);
    display_push(&sidemenu);

    panel_t terrain;
    panel_init(&terrain, 0, 0, MAP_WIDTH, MAP_HEIGHT);
    display_push(&terrain);

    panel_t buildings;
    panel_init(&buildings, 0, 0, MAP_WIDTH, MAP_HEIGHT);
    display_push(&buildings);

    panel_t units;
    panel_init(&units, 0, 0, MAP_WIDTH, MAP_HEIGHT);
    display_push(&units);

    /* Main Loop */
    bool running = true;
    while (running) {
        yield_t diff;
        for (int i = 0; running && i < game->speed; i++) {
            diff = game_step(game);
            enum game_event event;
            while ((event = game_event_pop(game)) != EVENT_NONE) {
                sidemenu_draw(&sidemenu, game, diff);
                display_refresh();
                switch (event) {
                case EVENT_LOSE:
                    atexit_save_game = NULL;
                    running = false;
                    ui_gameover(game, &terrain);
                break;
                case EVENT_PROGRESS_1:
                    ui_halfway(game, &terrain);
                    break;
                case EVENT_WIN:
                    atexit_save_game = NULL;
                    running = false;
                    ui_win(game, &terrain);
                    break;
                case EVENT_BATTLE:
                    ui_apology(game, &terrain);
                    break;
                case EVENT_NONE:
                    break;
                }
            }
        }

        sidemenu_draw(&sidemenu, game, diff);
        map_draw_terrain(game->map, &terrain);
        panel_clear(&buildings);
        map_draw_buildings(game->map, &buildings);
        panel_clear(&units);
        game_draw_units(game, &units, false);
        display_refresh();
        uint64_t wait = device_uepoch() % PERIOD;
        if (device_kbhit(wait)) {
            int key = device_getch();
            switch (key) {
            case 'b':
                ui_build(game, &terrain);
                break;
            case 's':
                ui_squads(game, &terrain, &units);
                break;
            case 'h':
                ui_heroes(game, &terrain);
                break;
            case 't':
                ui_story(game, &terrain);
                break;
            case 'p':
                ui_help(game, &terrain);
                break;
            case '>':
            case '.':
                if (game->speed < SPEED_MAX)
                    game->speed *= SPEED_FACTOR;
                break;
            case '<':
            case ',':
                game->speed /= SPEED_FACTOR;
                if (game->speed == 0)
                    game->speed = 1;
                break;
            case 'R':
                display_invalidate();
                break;
            case 'q':
                running = !popup_quit(true);
                break;
            case 'Q':
                running = !popup_quit(false);
                if (!running)
                    atexit_save_game = NULL;
                break;
            default:
                break;
            }
        }
    };

    atexit_save();
    atexit_save_game = NULL;
    game_free(game);

    display_pop(); // units
    display_pop(); // buildings
    display_pop(); // terrain
    display_pop(); // sidemenu
    panel_free(&units);
    panel_free(&buildings);
    panel_free(&terrain);
    panel_free(&sidemenu);
    display_free();
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x12d40, %rsp          # imm = 0x12D40
movl $0x0, -0x4(%rbp)
callq 0x4280
leaq -0x8(%rbp), %rdi
leaq -0xc(%rbp), %rsi
callq 0x8d10
cmpl $0x50, -0x8(%rbp)
jl 0x13c0
cmpl $0x18, -0xc(%rbp)
jge 0x1402
callq 0x46f0
movl -0x8(%rbp), %ecx
movl -0xc(%rbp), %r8d
leaq 0x7dbd(%rip), %rdi      # 0x9190
movl $0x50, %esi
movl $0x18, %edx
movb $0x0, %al
callq 0x10e0
movq 0xbbf5(%rip), %rax      # 0xcfe0
movq (%rax), %rdi
callq 0x11d0
callq 0x1180
movl $0x1, %edi
callq 0x1250
leaq 0x14def(%rip), %rdi     # 0x161f8
movl $0x8, %esi
callq 0x8d50
leaq 0x7dd8(%rip), %rdi      # 0x91f2
callq 0x8ce0
movq 0x82ca(%rip), %rax      # 0x96f0
movq %rax, -0x3c40(%rbp)
movq 0x82c4(%rip), %rax      # 0x96f8
movq %rax, -0x3c38(%rbp)
movl 0x82bf(%rip), %eax      # 0x9700
movl %eax, -0x3c30(%rbp)
movw 0x82b6(%rip), %ax       # 0x9704
movw %ax, -0x3c2c(%rbp)
movb 0x82ab(%rip), %al       # 0x9706
movb %al, -0x3c2a(%rbp)
leaq -0x3c28(%rbp), %rdi
movl $0x17, %esi
movl $0x1, %edx
callq 0x48e0
leaq -0x3c28(%rbp), %rdi
callq 0x47b0
movb $0x7, -0x3c44(%rbp)
movb $0x0, -0x3c43(%rbp)
movb $0x1, -0x3c42(%rbp)
movb $0x0, -0x3c41(%rbp)
leaq -0x3c40(%rbp), %r8
movl -0x3c44(%rbp), %ecx
leaq -0x3c28(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x49e0
callq 0x4510
leaq 0x7d35(%rip), %rdi      # 0x91fd
leaq 0x7d3b(%rip), %rsi      # 0x920a
callq 0x1220
movq %rax, -0x3c58(%rbp)
cmpq $0x0, -0x3c58(%rbp)
je 0x1520
movq -0x3c58(%rbp), %rdi
callq 0x6660
movq %rax, -0x3c50(%rbp)
movq -0x3c58(%rbp), %rdi
callq 0x10b0
movq -0x3c50(%rbp), %rax
movl $0x6, 0x10(%rax)
leaq 0x7ce4(%rip), %rdi      # 0x91fd
callq 0x1040
jmp 0x1549
leaq 0x14cd1(%rip), %rdi     # 0x161f8
callq 0x83a0
movq %rax, %rdi
callq 0x6430
movq %rax, -0x3c50(%rbp)
movq -0x3c50(%rbp), %rax
movl $0x6, 0x10(%rax)
movq -0x3c50(%rbp), %rax
movq %rax, 0xe339(%rip)      # 0xf890
leaq 0x512(%rip), %rdi       # 0x1a70
callq 0x8df0
callq 0x4820
leaq -0x7870(%rbp), %rdi
movl $0x3c, %esi
xorl %edx, %edx
movl $0x14, %ecx
movl $0x18, %r8d
callq 0x4340
leaq -0x7870(%rbp), %rdi
callq 0x47b0
leaq -0xb488(%rbp), %rdi
xorl %edx, %edx
movl $0x3c, %ecx
movl $0x18, %r8d
movl %edx, %esi
callq 0x4340
leaq -0xb488(%rbp), %rdi
callq 0x47b0
leaq -0xf0a0(%rbp), %rdi
xorl %edx, %edx
movl $0x3c, %ecx
movl $0x18, %r8d
movl %edx, %esi
callq 0x4340
leaq -0xf0a0(%rbp), %rdi
callq 0x47b0
leaq -0x12cb8(%rbp), %rdi
xorl %edx, %edx
movl $0x3c, %ecx
movl $0x18, %r8d
movl %edx, %esi
callq 0x4340
leaq -0x12cb8(%rbp), %rdi
callq 0x47b0
movb $0x1, -0x12cb9(%rbp)
testb $0x1, -0x12cb9(%rbp)
je 0x19fb
movl $0x0, -0x12ccc(%rbp)
xorl %eax, %eax
testb $0x1, -0x12cb9(%rbp)
movb %al, -0x12d1d(%rbp)
je 0x164f
movl -0x12ccc(%rbp), %eax
movq -0x3c50(%rbp), %rcx
cmpl 0x10(%rcx), %eax
setl %al
movb %al, -0x12d1d(%rbp)
movb -0x12d1d(%rbp), %al
testb $0x1, %al
jne 0x165e
jmp 0x17c8
movq -0x3c50(%rbp), %rdi
callq 0x7540
movl %edx, -0x12ce0(%rbp)
movq %rax, -0x12ce8(%rbp)
movq -0x12ce8(%rbp), %rax
movq %rax, -0x12cd8(%rbp)
movl -0x12ce0(%rbp), %eax
movl %eax, -0x12cd0(%rbp)
movq -0x12cd8(%rbp), %rax
movq %rax, -0x12cc8(%rbp)
movl -0x12cd0(%rbp), %eax
movl %eax, -0x12cc0(%rbp)
movq -0x3c50(%rbp), %rdi
callq 0x7170
movl %eax, -0x12cec(%rbp)
cmpl $0x0, %eax
je 0x17b2
movq -0x3c50(%rbp), %rsi
movl -0x12cc0(%rbp), %eax
movl %eax, -0x12cf8(%rbp)
movq -0x12cc8(%rbp), %rax
movq %rax, -0x12d00(%rbp)
movq -0x12d00(%rbp), %rdx
movl -0x12cf8(%rbp), %ecx
leaq -0x7870(%rbp), %rdi
callq 0x1a90
callq 0x4510
movl -0x12cec(%rbp), %eax
movq %rax, -0x12d28(%rbp)
subq $0x4, %rax
ja 0x17ad
movq -0x12d28(%rbp), %rax
leaq 0x79fe(%rip), %rcx      # 0x9128
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq $0x0, 0xe152(%rip) # 0xf890
movb $0x0, -0x12cb9(%rbp)
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x1d40
jmp 0x17ad
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x1d80
jmp 0x17ad
movq $0x0, 0xe116(%rip) # 0xf890
movb $0x0, -0x12cb9(%rbp)
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x1dc0
jmp 0x17ad
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x1e00
jmp 0x17ad
jmp 0x17ad
jmp 0x16ab
jmp 0x17b4
movl -0x12ccc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x12ccc(%rbp)
jmp 0x1625
movq -0x3c50(%rbp), %rsi
movq -0x12cc8(%rbp), %rax
movq %rax, -0x12d10(%rbp)
movl -0x12cc0(%rbp), %eax
movl %eax, -0x12d08(%rbp)
movq -0x12d10(%rbp), %rdx
movl -0x12d08(%rbp), %ecx
leaq -0x7870(%rbp), %rdi
callq 0x1a90
movq -0x3c50(%rbp), %rax
movq 0x38(%rax), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x5e70
leaq -0xf0a0(%rbp), %rdi
callq 0x50a0
movq -0x3c50(%rbp), %rax
movq 0x38(%rax), %rdi
leaq -0xf0a0(%rbp), %rsi
callq 0x6180
leaq -0x12cb8(%rbp), %rdi
callq 0x50a0
movq -0x3c50(%rbp), %rdi
leaq -0x12cb8(%rbp), %rsi
xorl %edx, %edx
callq 0x7f90
callq 0x4510
callq 0x8cb0
movl $0x1046a, %ecx          # imm = 0x1046A
xorl %edx, %edx
divq %rcx
movq %rdx, -0x12d18(%rbp)
movq -0x12d18(%rbp), %rdi
callq 0x8bf0
testb $0x1, %al
jne 0x188d
jmp 0x19f6
callq 0x8b60
movl %eax, -0x12d1c(%rbp)
movl -0x12d1c(%rbp), %eax
addl $-0x2c, %eax
movl %eax, %ecx
movq %rcx, -0x12d30(%rbp)
subl $0x48, %eax
ja 0x19f2
movq -0x12d30(%rbp), %rax
leaq 0x7743(%rip), %rcx      # 0x9004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x1e50
jmp 0x19f4
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
leaq -0x12cb8(%rbp), %rdx
callq 0x1f40
jmp 0x19f4
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x2170
jmp 0x19f4
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x2760
jmp 0x19f4
movq -0x3c50(%rbp), %rdi
leaq -0xb488(%rbp), %rsi
callq 0x27a0
jmp 0x19f4
movq -0x3c50(%rbp), %rax
cmpl $0x1e60, 0x10(%rax)     # imm = 0x1E60
jge 0x1967
movq -0x3c50(%rbp), %rax
imull $0x6, 0x10(%rax), %ecx
movl %ecx, 0x10(%rax)
jmp 0x19f4
movq -0x3c50(%rbp), %rax
movq %rax, -0x12d38(%rbp)
movl 0x10(%rax), %eax
movl $0x6, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x12d38(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x3c50(%rbp), %rax
cmpl $0x0, 0x10(%rax)
jne 0x19ac
movq -0x3c50(%rbp), %rax
movl $0x1, 0x10(%rax)
jmp 0x19f4
callq 0x48b0
jmp 0x19f4
movl $0x1, %edi
callq 0x27e0
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0x12cb9(%rbp)
jmp 0x19f4
xorl %edi, %edi
callq 0x27e0
xorb $-0x1, %al
andb $0x1, %al
movb %al, -0x12cb9(%rbp)
testb $0x1, -0x12cb9(%rbp)
jne 0x19f0
movq $0x0, 0xdea0(%rip) # 0xf890
jmp 0x19f4
jmp 0x19f4
jmp 0x19f6
jmp 0x160e
callq 0x1a70
movq $0x0, 0xde85(%rip) # 0xf890
movq -0x3c50(%rbp), %rdi
callq 0x66f0
callq 0x47e0
callq 0x47e0
callq 0x47e0
callq 0x47e0
leaq -0x12cb8(%rbp), %rdi
callq 0x4760
leaq -0xf0a0(%rbp), %rdi
callq 0x4760
leaq -0xb488(%rbp), %rdi
callq 0x4760
leaq -0x7870(%rbp), %rdi
callq 0x4760
callq 0x46f0
xorl %eax, %eax
addq $0x12d40, %rsp          # imm = 0x12D40
popq %rbp
retq
nopl (%rax,%rax)