// File: /workspace/github_c_makefile_star2_O0/adelciotto[P]plasma/src/palette_plasma.c
// Function: main
int main(int argc, char *argv[]) {
    char opt;
    while ((opt = getopt(argc, argv, ":w:h:f")) != -1) {
        switch (opt) {
        case 'w':
            // Obviously not proper use of strtol, but, thats fine
            // for this simple program.
            width = strtol(optarg, (char **)NULL, 10);
            if (width == 0) {
                fprintf(stderr, "invalid value for w: %s\n", optarg);
                return EXIT_FAILURE;
            }
            break;
        case 'h':
            height = strtol(optarg, (char **)NULL, 10);
            if (height == 0) {
                fprintf(stderr, "invalid value for h: %s\n", optarg);
                return EXIT_FAILURE;
            }
            break;
        case 'f':
            fullscreen = 1;
            break;
        }
    }

    if (InitSDL() != 0) {
        fprintf(stderr, "error initializing SDL, %s\n", SDL_GetError());
        return EXIT_FAILURE;
    }

    int refreshRate = GetDisplayRefreshRate(displayMode);
    const double targetSecsPerFrame = 1.0 / (double)refreshRate;
    LogInfo("display refresh rate %d, target secs per frame %f", refreshRate,
            targetSecsPerFrame);

    pixelBuffer = calloc(width * height, sizeof(*pixelBuffer));
    if (pixelBuffer == NULL) {
        LogError("failed to calloc pixel buffer %dx%d", width, height);
        return EXIT_FAILURE;
    }
    plasmaBuffer = calloc(width * height, sizeof(*plasmaBuffer));
    if (plasmaBuffer == NULL) {
        LogError("failed to calloc plasma buffer %dx%d", width, height);
        return EXIT_FAILURE;
    }

    InitPalette();
    InitPlasma();

    double elapsedTimeMs = 0.0;
    Uint64 lastCounter = SDL_GetPerformanceCounter();
    Uint64 metricsPrintCounter = SDL_GetPerformanceCounter();
    SDL_Event event;
    int isRunning = 1;

    while (isRunning) {
        SDL_PollEvent(&event);
        switch (event.type) {
        case SDL_QUIT:
            isRunning = 0;
            break;
        case SDL_KEYDOWN:
            if (event.key.keysym.sym == SDLK_ESCAPE) {
                isRunning = 0;
            }
            break;
        }

        elapsedTimeMs += targetSecsPerFrame * 1000.0;

        DrawFrame(elapsedTimeMs);

        // Manually cap the frame rate
        while (GetElapsedTimeSecs(lastCounter, SDL_GetPerformanceCounter()) <
               targetSecsPerFrame) {
        }
        assert(GetElapsedTimeSecs(lastCounter, SDL_GetPerformanceCounter()) >=
               targetSecsPerFrame);

        Uint64 endCounter = SDL_GetPerformanceCounter();

        SDL_UpdateTexture(texture, NULL, pixelBuffer,
                          width * sizeof(*pixelBuffer));
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);

        double msPerFrame = GetElapsedTimeMs(lastCounter, endCounter);
        double fps = (double)SDL_GetPerformanceFrequency() /
                     (double)(endCounter - lastCounter);

        if (GetElapsedTimeMs(metricsPrintCounter, SDL_GetPerformanceCounter()) >
            1000.0) {
            printf("ms/f: %f, fps: %f\r", msPerFrame, fps);
            fflush(stdout);
            metricsPrintCounter = SDL_GetPerformanceCounter();
        }

        lastCounter = endCounter;
    }

    free(plasmaBuffer);
    free(pixelBuffer);
    DestroySDL();

    return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x668(%rip), %rdx       # 0x20df
callq 0x10a0
movb %al, -0x11(%rbp)
movsbl %al, %eax
cmpl $-0x1, %eax
je 0x1b7b
movsbl -0x11(%rbp), %eax
movl %eax, -0x94(%rbp)
subl $0x66, %eax
je 0x1b6c
jmp 0x1aa0
movl -0x94(%rbp), %eax
subl $0x68, %eax
je 0x1b15
jmp 0x1aad
movl -0x94(%rbp), %eax
subl $0x77, %eax
jne 0x1b76
jmp 0x1abe
movq 0x250b(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x11d0
movl %eax, 0x264c(%rip)      # 0x4128
cmpl $0x0, 0x2645(%rip)      # 0x4128
jne 0x1b13
movq 0x24f4(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
movq 0x24da(%rip), %rax      # 0x3fd0
movq (%rax), %rdx
leaq 0x5e6(%rip), %rsi       # 0x20e6
movb $0x0, %al
callq 0x11e0
movl $0x1, -0x4(%rbp)
jmp 0x1f3a
jmp 0x1b76
movq 0x24b4(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x11d0
movl %eax, 0x25f9(%rip)      # 0x412c
cmpl $0x0, 0x25f2(%rip)      # 0x412c
jne 0x1b6a
movq 0x249d(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
movq 0x2483(%rip), %rax      # 0x3fd0
movq (%rax), %rdx
leaq 0x5a8(%rip), %rsi       # 0x20ff
movb $0x0, %al
callq 0x11e0
movl $0x1, -0x4(%rbp)
jmp 0x1f3a
jmp 0x1b76
movl $0x1, 0x25f2(%rip)      # 0x4168
jmp 0x1a69
callq 0x1510
cmpl $0x0, %eax
je 0x1bbf
movq 0x2454(%rip), %rax      # 0x3fe0
movq (%rax), %rax
movq %rax, -0xa0(%rbp)
callq 0x1110
movq -0xa0(%rbp), %rdi
movq %rax, %rdx
leaq 0x56c(%rip), %rsi       # 0x2118
movb $0x0, %al
callq 0x11e0
movl $0x1, -0x4(%rbp)
jmp 0x1f3a
leaq 0x25aa(%rip), %rax      # 0x4170
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x14e0
movl %eax, -0x18(%rbp)
cvtsi2sdl -0x18(%rbp), %xmm1
movsd 0x48c(%rip), %xmm0      # 0x2080
divsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rbp)
movl -0x18(%rbp), %edx
movsd -0x20(%rbp), %xmm0
xorl %edi, %edi
leaq 0x526(%rip), %rsi       # 0x2134
movb $0x1, %al
callq 0x1200
movl 0x250d(%rip), %eax      # 0x4128
imull 0x250a(%rip), %eax      # 0x412c
movslq %eax, %rdi
movl $0x4, %esi
callq 0x10f0
movq %rax, 0x2522(%rip)      # 0x4158
cmpq $0x0, 0x251a(%rip)      # 0x4158
jne 0x1c68
movl 0x24e2(%rip), %edx      # 0x4128
movl 0x24e0(%rip), %ecx      # 0x412c
xorl %edi, %edi
leaq 0x511(%rip), %rsi       # 0x2166
movb $0x0, %al
callq 0x11b0
movl $0x1, -0x4(%rbp)
jmp 0x1f3a
movl 0x24ba(%rip), %eax      # 0x4128
imull 0x24b7(%rip), %eax      # 0x412c
movslq %eax, %rdi
movl $0x4, %esi
callq 0x10f0
movq %rax, 0x24d7(%rip)      # 0x4160
cmpq $0x0, 0x24cf(%rip)      # 0x4160
jne 0x1cbb
movl 0x248f(%rip), %edx      # 0x4128
movl 0x248d(%rip), %ecx      # 0x412c
xorl %edi, %edi
leaq 0x4e2(%rip), %rsi       # 0x218a
movb $0x0, %al
callq 0x11b0
movl $0x1, -0x4(%rbp)
jmp 0x1f3a
callq 0x1680
callq 0x1770
xorps %xmm0, %xmm0
movsd %xmm0, -0x28(%rbp)
callq 0x11c0
movq %rax, -0x30(%rbp)
callq 0x11c0
movq %rax, -0x38(%rbp)
movl $0x1, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
je 0x1f16
leaq -0x70(%rbp), %rdi
callq 0x10d0
movl -0x70(%rbp), %eax
movl %eax, -0xa4(%rbp)
subl $0x100, %eax            # imm = 0x100
je 0x1d1a
jmp 0x1d0b
movl -0xa4(%rbp), %eax
subl $0x300, %eax            # imm = 0x300
je 0x1d23
jmp 0x1d32
movl $0x0, -0x74(%rbp)
jmp 0x1d32
cmpl $0x1b, -0x5c(%rbp)
jne 0x1d30
movl $0x0, -0x74(%rbp)
jmp 0x1d32
movsd -0x20(%rbp), %xmm0
movsd -0x28(%rbp), %xmm1
movsd 0x2ec(%rip), %xmm2      # 0x2030
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x28(%rbp)
movsd -0x28(%rbp), %xmm0
callq 0x1970
movq -0x30(%rbp), %rax
movq %rax, -0xb0(%rbp)
callq 0x11c0
movq -0xb0(%rbp), %rdi
movq %rax, %rsi
callq 0x13c0
movaps %xmm0, %xmm1
movsd -0x20(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x1d8a
jmp 0x1d5b
movq -0x30(%rbp), %rax
movq %rax, -0xb8(%rbp)
callq 0x11c0
movq -0xb8(%rbp), %rdi
movq %rax, %rsi
callq 0x13c0
ucomisd -0x20(%rbp), %xmm0
jb 0x1db2
jmp 0x1dd1
leaq 0x3f6(%rip), %rdi       # 0x21af
leaq 0x442(%rip), %rsi       # 0x2202
movl $0xe5, %edx
leaq 0x44b(%rip), %rcx       # 0x2217
callq 0x10e0
callq 0x11c0
movq %rax, -0x80(%rbp)
movq 0x236f(%rip), %rdi      # 0x4150
movq 0x2370(%rip), %rdx      # 0x4158
movl 0x233a(%rip), %ecx      # 0x4128
shll $0x2, %ecx
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0xc8(%rbp)
callq 0x1120
movq 0x2340(%rip), %rdi      # 0x4148
callq 0x1160
movq -0xc8(%rbp), %rcx
movq 0x232d(%rip), %rdi      # 0x4148
movq 0x232e(%rip), %rsi      # 0x4150
movq %rcx, %rdx
callq 0x1170
movq 0x2317(%rip), %rdi      # 0x4148
callq 0x1080
movq -0x30(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x1450
movsd %xmm0, -0x88(%rbp)
callq 0x1140
movq %rax, %xmm0
movaps 0x1b4(%rip), %xmm3      # 0x2010
punpckldq %xmm3, %xmm0    # xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
movapd 0x1b8(%rip), %xmm2      # 0x2020
subpd %xmm2, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq -0x80(%rbp), %rax
movq -0x30(%rbp), %rcx
subq %rcx, %rax
movq %rax, %xmm1
punpckldq %xmm3, %xmm1    # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x90(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0xc0(%rbp)
callq 0x11c0
movq -0xc0(%rbp), %rdi
movq %rax, %rsi
callq 0x1450
movsd 0x163(%rip), %xmm1      # 0x2030
ucomisd %xmm1, %xmm0
jbe 0x1f09
movsd -0x88(%rbp), %xmm0
movsd -0x90(%rbp), %xmm1
leaq 0x344(%rip), %rdi       # 0x222e
movb $0x2, %al
callq 0x1050
movq 0x20c8(%rip), %rax      # 0x3fc0
movq (%rax), %rdi
callq 0x1190
callq 0x11c0
movq %rax, -0x38(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x1ce6
movq 0x2243(%rip), %rdi      # 0x4160
callq 0x11a0
movq 0x222f(%rip), %rdi      # 0x4158
callq 0x11a0
callq 0x1a20
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xe0, %rsp
popq %rbp
retq