// File: /workspace/github_c_makefile_star2_O0/theandrew168[P]skylark/src/main.c
// Function: main
int
main(int argc, char* argv[])
{
    if (argc != 2) {
        fprintf(stderr, "usage: %s <rom_file>\n", argv[0]);
        return EXIT_FAILURE;
    }

    FILE* fp = fopen(argv[1], "rb");
    if (fp == NULL) {
        fprintf(stderr, "failed to open rom: %s\n", argv[1]);
        return EXIT_FAILURE;
    }

    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    uint8_t* buf = malloc(size);
    if (buf == NULL) {
        fclose(fp);
        fprintf(stderr, "failed to allocate buffer to hold ROM contents\n");
        return EXIT_FAILURE;
    }

    long count = fread(buf, 1, size, fp);
    if (count != size) {
        free(buf);
        fclose(fp);
        fprintf(stderr, "failed to read ROM into buffer\n");
        return EXIT_FAILURE;
    }
    fclose(fp);

    struct chip8 chip8 = { 0 };
    chip8_init(&chip8);

    int rc = chip8_load(&chip8, buf, size);
    if (rc != CHIP8_OK) {
        free(buf);
        fprintf(stderr, "failed to init chip8 emulator\n");
        return EXIT_FAILURE;
    }
    free(buf);

    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        fprintf(stderr, "failed to init SDL2: %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }

    SDL_Window* window = SDL_CreateWindow(
        "Skylark CHIP-8 Emulator",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        CHIP8_DISPLAY_WIDTH * SKYLARK_DISPLAY_PIXEL_SIZE,
        CHIP8_DISPLAY_HEIGHT * SKYLARK_DISPLAY_PIXEL_SIZE,
        SDL_WINDOW_RESIZABLE);
    if (window == NULL) {
        fprintf(stderr, "failed to create SDL2 window: %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }

    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    if (renderer == NULL) {
        fprintf(stderr, "failed to create SDL2 renderer: %s\n", SDL_GetError());
        SDL_DestroyWindow(window);
        return EXIT_FAILURE;
    }

    bool running = true;
    while (running) {
        // input
        SDL_Event event = { 0 };
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) running = false;
            if (event.type == SDL_KEYUP) {
                SDL_Keycode key = event.key.keysym.sym;
                if (key == SDLK_ESCAPE) running = false;
            }
        }

        // execute the next instruction
        rc = chip8_step(&chip8);
        if (rc != CHIP8_OK) {
            running = false;
            break;
        }

        // graphics
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);

        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
        for (long y = 0; y < CHIP8_DISPLAY_HEIGHT; y++) {
            for (long x = 0; x < CHIP8_DISPLAY_WIDTH; x++) {
                if (!chip8_pixel_on(&chip8, x, y)) continue;

                SDL_Rect pixel = {
                    .w = SKYLARK_DISPLAY_PIXEL_SIZE,
                    .h = SKYLARK_DISPLAY_PIXEL_SIZE,
                    .x = x * SKYLARK_DISPLAY_PIXEL_SIZE,
                    .y = y * SKYLARK_DISPLAY_PIXEL_SIZE,
                };
                SDL_RenderFillRect(renderer, &pixel);
            }
        }
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1910, %rsp           # imm = 0x1910
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x231a
movq 0x3cea(%rip), %rax      # 0x5fe0
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rdx
leaq 0x1cfd(%rip), %rsi      # 0x4004
movb $0x0, %al
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x27b1
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x1cf1(%rip), %rsi      # 0x401a
callq 0x2160
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x2365
movq 0x3ca0(%rip), %rax      # 0x5fe0
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdx
leaq 0x1ccb(%rip), %rsi      # 0x401d
movb $0x0, %al
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x27b1
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x2150
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x2150
movq -0x20(%rbp), %rdi
callq 0x2180
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x23d4
movq -0x18(%rbp), %rdi
callq 0x2140
movq 0x3c29(%rip), %rax      # 0x5fe0
movq (%rax), %rdi
leaq 0x1c74(%rip), %rsi      # 0x4035
movb $0x0, %al
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x27b1
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rdx
movq -0x18(%rbp), %rcx
movl $0x1, %esi
callq 0x21b0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x242e
movq -0x28(%rbp), %rdi
callq 0x2170
movq -0x18(%rbp), %rdi
callq 0x2140
movq 0x3bcf(%rip), %rax      # 0x5fe0
movq (%rax), %rdi
leaq 0x1c4a(%rip), %rsi      # 0x4065
movb $0x0, %al
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x27b1
movq -0x18(%rbp), %rdi
callq 0x2140
leaq -0x1878(%rbp), %rdi
xorl %esi, %esi
movl $0x1848, %edx           # imm = 0x1848
callq 0x20c0
leaq -0x1878(%rbp), %rdi
callq 0x27c0
movq -0x28(%rbp), %rsi
movq -0x20(%rbp), %rdx
leaq -0x1878(%rbp), %rdi
callq 0x2860
movl %eax, -0x187c(%rbp)
cmpl $0x0, -0x187c(%rbp)
je 0x24a6
movq -0x28(%rbp), %rdi
callq 0x2170
movq 0x3b57(%rip), %rax      # 0x5fe0
movq (%rax), %rdi
leaq 0x1bf2(%rip), %rsi      # 0x4085
movb $0x0, %al
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x27b1
movq -0x28(%rbp), %rdi
callq 0x2170
movl $0x20, %edi
callq 0x2100
cmpl $0x0, %eax
je 0x24f8
movq 0x3b1b(%rip), %rax      # 0x5fe0
movq (%rax), %rax
movq %rax, -0x1900(%rbp)
callq 0x20f0
movq -0x1900(%rbp), %rdi
movq %rax, %rdx
leaq 0x1bbf(%rip), %rsi      # 0x40a4
movb $0x0, %al
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x27b1
leaq 0x1bbe(%rip), %rdi      # 0x40bd
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
movl $0x400, %ecx            # imm = 0x400
movl $0x200, %r8d            # imm = 0x200
movl $0x20, %r9d
movl %edx, %esi
callq 0x2060
movq %rax, -0x1888(%rbp)
cmpq $0x0, -0x1888(%rbp)
jne 0x2567
movq 0x3aac(%rip), %rax      # 0x5fe0
movq (%rax), %rax
movq %rax, -0x1908(%rbp)
callq 0x20f0
movq -0x1908(%rbp), %rdi
movq %rax, %rdx
leaq 0x1b81(%rip), %rsi      # 0x40d5
movb $0x0, %al
callq 0x21a0
movl $0x1, -0x4(%rbp)
jmp 0x27b1
movq -0x1888(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0x2, %edx
callq 0x2050
movq %rax, -0x1890(%rbp)
cmpq $0x0, -0x1890(%rbp)
jne 0x25d4
movq 0x3a4b(%rip), %rax      # 0x5fe0
movq (%rax), %rax
movq %rax, -0x1910(%rbp)
callq 0x20f0
movq -0x1910(%rbp), %rdi
movq %rax, %rdx
leaq 0x1b42(%rip), %rsi      # 0x40f7
movb $0x0, %al
callq 0x21a0
movq -0x1888(%rbp), %rdi
callq 0x2040
movl $0x1, -0x4(%rbp)
jmp 0x27b1
movb $0x1, -0x1891(%rbp)
testb $0x1, -0x1891(%rbp)
je 0x278d
leaq -0x18d0(%rbp), %rdi
xorl %esi, %esi
movl $0x38, %edx
callq 0x20c0
leaq -0x18d0(%rbp), %rdi
callq 0x20d0
cmpl $0x0, %eax
je 0x264b
cmpl $0x100, -0x18d0(%rbp)   # imm = 0x100
jne 0x261f
movb $0x0, -0x1891(%rbp)
cmpl $0x301, -0x18d0(%rbp)   # imm = 0x301
jne 0x2649
movl -0x18bc(%rbp), %eax
movl %eax, -0x18d4(%rbp)
cmpl $0x1b, -0x18d4(%rbp)
jne 0x2647
movb $0x0, -0x1891(%rbp)
jmp 0x2649
jmp 0x25fb
leaq -0x1878(%rbp), %rdi
callq 0x28f0
movl %eax, -0x187c(%rbp)
cmpl $0x0, -0x187c(%rbp)
je 0x2672
movb $0x0, -0x1891(%rbp)
jmp 0x278d
movq -0x1890(%rbp), %rdi
xorl %ecx, %ecx
movl $0xff, %r8d
movl %ecx, %esi
movl %ecx, %edx
callq 0x2190
movq -0x1890(%rbp), %rdi
callq 0x2120
movq -0x1890(%rbp), %rdi
movl $0xff, %r8d
movl %r8d, %esi
movl %r8d, %edx
movl %r8d, %ecx
callq 0x2190
movq $0x0, -0x18e0(%rbp)
cmpq $0x20, -0x18e0(%rbp)
jge 0x277c
movq $0x0, -0x18e8(%rbp)
cmpq $0x40, -0x18e8(%rbp)
jge 0x2763
movq -0x18e8(%rbp), %rsi
movq -0x18e0(%rbp), %rdx
leaq -0x1878(%rbp), %rdi
callq 0x2a20
testb $0x1, %al
jne 0x2703
jmp 0x274c
movq -0x18e8(%rbp), %rax
shlq $0x4, %rax
movl %eax, -0x18f8(%rbp)
movq -0x18e0(%rbp), %rax
shlq $0x4, %rax
movl %eax, -0x18f4(%rbp)
movl $0x10, -0x18f0(%rbp)
movl $0x10, -0x18ec(%rbp)
movq -0x1890(%rbp), %rdi
leaq -0x18f8(%rbp), %rsi
callq 0x20b0
movq -0x18e8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18e8(%rbp)
jmp 0x26d5
jmp 0x2765
movq -0x18e0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18e0(%rbp)
jmp 0x26bc
movq -0x1890(%rbp), %rdi
callq 0x2080
jmp 0x25db
movq -0x1890(%rbp), %rdi
callq 0x20a0
movq -0x1888(%rbp), %rdi
callq 0x2040
callq 0x2070
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x1910, %rsp           # imm = 0x1910
popq %rbp
retq
nopl (%rax)