// File: /workspace/github_cpp_makefile_star2_O2/donqustix[P]SoftwareRenderer/src/main.cpp
// Function: main
int main()
{
    if (::SDL_Init(SDL_INIT_VIDEO) >= 0)
    {
        SDL_Window* const window = ::SDL_CreateWindow("Software Renderer",
                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
        if (window)
        {
            SDL_Surface* const surface = ::SDL_GetWindowSurface(window);
            if (surface)
            {
                try
                {
                    const Mesh mesh{::load_obj("res/bunny.obj")};

                    const auto perspective_matrix = mat4f::create_perspective(M_PI / 3,
                            static_cast<float>(WINDOW_WIDTH) / WINDOW_HEIGHT, 1e-1F, 1e3F);
                    auto matrix1 = perspective_matrix * mat4f::create_translation(0.0F, -0.12F, -0.25F);
                    auto matrix2 = perspective_matrix * mat4f::create_translation(2.0F, 1.0F, -5.0F) *
                            mat4f::create_scaling(0.4F, 0.4F, 0.4F);
                    const auto rotation_matrix = mat4f::create_rotation_y(0.05F) * mat4f::create_rotation_x(-0.01F);

                    SDL_Event event;

                    bool running = true;
                    while (running)
                    {
                        while (::SDL_PollEvent(&event))
                        {
                            if (event.type == SDL_QUIT)
                                running = false;
                        }

                        ::clear_zbuffer();

                        ::SDL_FillRect(surface, nullptr, 0);
                        ::SDL_LockSurface(surface);
                        ::render_mesh(surface, mesh, matrix1);
                        ::render_triangle(surface, {{ 0.0F, -1.0F, 0.0F}, {1.0F, 0.0F, 0.0F}},
                                                   {{-1.0F,  1.0F, 0.0F}, {0.0F, 1.0F, 0.0F}},
                                                   {{ 1.0F,  1.0F, 0.0F}, {0.0F, 0.0F, 1.0F}}, matrix2);
                        ::SDL_UnlockSurface(surface);

                        matrix1 *= rotation_matrix;
                        matrix2 *= rotation_matrix;

                        ::SDL_UpdateWindowSurface(window);
                        ::SDL_Delay(20);
                    }
                }
                catch (const std::exception& ex)
                {
                    std::cerr << ex.what() << std::endl;
                }
            }
            else
                std::cerr << "SDL_Surface getting error: " << ::SDL_GetError() << std::endl;

            ::SDL_DestroyWindow(window);
        }
        else
            std::cerr << "SDL_Window creation error: " << ::SDL_GetError() << std::endl;

        ::SDL_Quit();
    }
    else
        std::cerr << "SDL2 initialization error: " << ::SDL_GetError() << std::endl;

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x588, %rsp            # imm = 0x588
pushq $0x20
popq %rdi
callq 0x21e0
testl %eax, %eax
js 0x26b5
leaq 0x2ca5(%rip), %rdi      # 0x50fc
pushq $0x4
popq %r9
movl $0x1fff0000, %esi       # imm = 0x1FFF0000
movl $0x1fff0000, %edx       # imm = 0x1FFF0000
movl $0x280, %ecx            # imm = 0x280
movl $0x1e0, %r8d            # imm = 0x1E0
callq 0x2040
testq %rax, %rax
je 0x2c57
movq %rax, -0x50(%rbp)
movq %rax, %rdi
callq 0x2240
movq %rax, -0x38(%rbp)
testq %rax, %rax
je 0x2c87
leaq 0x2c70(%rip), %rsi      # 0x510e
leaq -0x1c0(%rbp), %rdi
leaq -0x2d(%rbp), %rdx
callq 0x20e0
leaq -0x5a8(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
pushq $0x8
popq %rdx
callq 0x2290
movq -0x5a8(%rbp), %rax
movq -0x18(%rax), %rax
testb $0x5, -0x588(%rbp,%rax)
jne 0x2cea
xorps %xmm0, %xmm0
leaq -0x180(%rbp), %rcx
andq $0x0, 0x10(%rcx)
leaq -0x140(%rbp), %rax
andq $0x0, 0x10(%rax)
movaps %xmm0, (%rcx)
movaps %xmm0, (%rax)
leaq -0xd0(%rbp), %rax
movaps %xmm0, (%rax)
andq $0x0, 0x10(%rax)
leaq -0x100(%rbp), %rcx
andq $0x0, 0x10(%rcx)
leaq -0x200(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movq %rcx, %r14
movaps %xmm0, (%rcx)
movb $0x0, (%rax)
leaq -0x3a0(%rbp), %r15
leaq -0x1d0(%rbp), %r12
leaq -0x1c8(%rbp), %r13
leaq -0x5a8(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x2080
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x26e8
movq %r15, %rdi
leaq -0x210(%rbp), %rsi
pushq $0x18
popq %rdx
callq 0x2280
leaq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
andq $0x0, -0x88(%rbp)
movb $0x0, -0x80(%rbp)
movq %r15, %rdi
leaq -0x90(%rbp), %rbx
movq %rbx, %rsi
callq 0x2230
movq %rbx, %rdi
leaq 0x2bd1(%rip), %rsi      # 0x5182
callq 0x40fc
testb %al, %al
je 0x25f7
movq %r15, %rdi
movq %r12, %rsi
callq 0x22e0
movq %rax, %rdi
movq %r13, %rsi
callq 0x22e0
movq %rax, %rdi
leaq -0x2c(%rbp), %rsi
callq 0x22e0
leaq -0x180(%rbp), %rdi
movq %r12, %rsi
movq %r13, %rdx
leaq -0x2c(%rbp), %rcx
callq 0x3d88
jmp 0x269c
movq %rbx, %rdi
leaq 0x2b83(%rip), %rsi      # 0x5184
callq 0x40fc
testb %al, %al
je 0x2644
movq %r15, %rdi
movq %r12, %rsi
callq 0x22e0
movq %rax, %rdi
movq %r13, %rsi
callq 0x22e0
movq %rax, %rdi
leaq -0x2c(%rbp), %rsi
callq 0x22e0
leaq -0x140(%rbp), %rdi
movq %r12, %rsi
movq %r13, %rdx
leaq -0x2c(%rbp), %rcx
callq 0x3d88
jmp 0x269c
movq %rbx, %rdi
leaq 0x2b39(%rip), %rsi      # 0x5187
callq 0x40fc
testb %al, %al
je 0x269c
pushq $0x3
popq %rbx
subl $0x1, %ebx
jb 0x269c
movq %r15, %rdi
movq %r12, %rsi
callq 0x2150
movq %r15, %rdi
pushq $0x2
popq %rsi
callq 0x2050
movq %r15, %rdi
movq %r13, %rsi
callq 0x2150
leaq -0xd0(%rbp), %rdi
movq %r12, %rsi
callq 0x410c
movq %r14, %rdi
movq %r13, %rsi
callq 0x410c
jmp 0x265a
leaq -0x90(%rbp), %rdi
callq 0x2100
movq %r15, %rdi
callq 0x21b0
jmp 0x2547
movq 0x492c(%rip), %rdi      # 0x6fe8
leaq 0x2a91(%rip), %rsi      # 0x5154
callq 0x21f0
movq %rax, %rbx
callq 0x21a0
movq %rbx, %rdi
movq %rax, %rsi
callq 0x21f0
movq %rax, %rdi
callq 0x2120
jmp 0x2cc3
xorps %xmm0, %xmm0
andq $0x0, -0x80(%rbp)
movaps %xmm0, -0x90(%rbp)
movq -0xd0(%rbp), %rdx
movq -0xc8(%rbp), %rsi
movq -0x180(%rbp), %rdi
leaq -0x390(%rbp), %r8
movq -0x140(%rbp), %r9
xorl %r13d, %r13d
xorl %r15d, %r15d
xorl %r14d, %r14d
movq %rsi, -0xe8(%rbp)
movq %rdi, -0xe0(%rbp)
movq %r9, -0xd8(%rbp)
cmpq %rsi, %rdx
je 0x2883
movq (%rdx), %rax
leaq -0x1(%rax), %rcx
shlq $0x4, %rcx
movups (%rdi,%rcx), %xmm0
movaps %xmm0, -0x3a0(%rbp)
movq -0x100(%rbp), %rcx
movq -0x8(%rcx,%rax,8), %rax
shlq $0x4, %rax
movups (%r9,%rax), %xmm0
movups %xmm0, (%r8)
cmpq %r13, %r15
je 0x279c
movaps -0x3a0(%rbp), %xmm0
movaps -0x390(%rbp), %xmm1
movups %xmm1, 0x10(%r15)
movups %xmm0, (%r15)
addq $0x20, %r15
movq %r15, -0x88(%rbp)
jmp 0x287a
movq %rdx, -0x48(%rbp)
movq %r13, %r15
subq %r14, %r15
movabsq $0x7fffffffffffffe0, %rax # imm = 0x7FFFFFFFFFFFFFE0
cmpq %rax, %r15
je 0x2cd7
movq %r15, %r12
sarq $0x5, %r12
cmpq %r14, %r13
movq %r12, %rax
pushq $0x1
popq %rcx
cmoveq %rcx, %rax
leaq (%rax,%r12), %rbx
movabsq $0x3ffffffffffffff, %rcx # imm = 0x3FFFFFFFFFFFFFF
cmpq %rcx, %rbx
cmovaeq %rcx, %rbx
addq %r12, %rax
cmovbq %rcx, %rbx
movq %rbx, %rdi
callq 0x3f26
movaps -0x3a0(%rbp), %xmm0
movaps -0x390(%rbp), %xmm1
movups %xmm1, 0x10(%rax,%r15)
movups %xmm0, (%rax,%r15)
movq %rax, -0x40(%rbp)
leaq 0x20(%rax), %r15
movq %r14, %rax
cmpq %r13, %rax
je 0x2836
leaq -0x20(%r15), %rcx
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%rcx)
movups %xmm0, (%rcx)
addq $0x20, %rax
addq $0x20, %r15
jmp 0x2815
movq %r14, %rdi
movq %r12, %rsi
callq 0x3f56
movq %r15, -0x88(%rbp)
shlq $0x5, %rbx
movq -0x40(%rbp), %r14
movq %r14, %r13
addq %rbx, %r13
movq %r13, -0x80(%rbp)
movq -0x48(%rbp), %rdx
movq -0xe8(%rbp), %rsi
movq -0xe0(%rbp), %rdi
leaq -0x390(%rbp), %r8
movq -0xd8(%rbp), %r9
addq $0x8, %rdx
jmp 0x2738
movq %r14, -0x90(%rbp)
movq %r15, %rbx
subq %r14, %rbx
movq %rbx, %rdi
sarq $0x5, %rdi
callq 0x3f26
movq %rax, -0xa8(%rbp)
addq %rax, %rbx
movq %rbx, -0x98(%rbp)
cmpq %r15, %r14
je 0x28cc
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
addq $0x20, %r14
addq $0x20, %rax
jmp 0x28ad
movq %rax, -0xa0(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x3ee0
leaq -0x210(%rbp), %r12
movq %r12, %rdi
callq 0x2100
leaq -0x100(%rbp), %rdi
callq 0x42ac
leaq -0xd0(%rbp), %rdi
callq 0x42ac
leaq -0x140(%rbp), %rdi
callq 0x3ef8
leaq -0x180(%rbp), %rdi
callq 0x3ef8
leaq -0x5a8(%rbp), %r14
movq %r14, %rdi
callq 0x2090
leaq -0x1c0(%rbp), %rdi
callq 0x2100
movl $0x3fa646e2, (%r14)     # imm = 0x3FA646E2
xorps %xmm0, %xmm0
movups %xmm0, 0x4(%r14)
movl $0x3fddb3d8, 0x14(%r14) # imm = 0x3FDDB3D8
movups %xmm0, 0x18(%r14)
movsd 0x26b3(%rip), %xmm0     # 0x5010
movups %xmm0, 0x28(%r14)
movl $0xbf800000, %eax       # imm = 0xBF800000
movq %rax, 0x38(%r14)
leaq -0x3a0(%rbp), %rbx
leaq -0x5a8(%rbp), %rsi
movq %rbx, %rdi
callq 0x3f6c
leaq -0x5a8(%rbp), %r15
movss 0x2750(%rip), %xmm1     # 0x50e0
movss 0x274c(%rip), %xmm2     # 0x50e4
xorps %xmm0, %xmm0
movq %r15, %rdi
callq 0x2ed6
leaq -0x210(%rbp), %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x2e60
leaq -0x180(%rbp), %r13
movss 0x2724(%rip), %xmm0     # 0x50e8
movss 0x2720(%rip), %xmm1     # 0x50ec
movss 0x271c(%rip), %xmm2     # 0x50f0
movq %r13, %rdi
callq 0x2ed6
leaq -0x1c0(%rbp), %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x2e60
movl $0x3ecccccd, %eax       # imm = 0x3ECCCCCD
movl %eax, (%r15)
xorps %xmm0, %xmm0
movups %xmm0, 0x4(%r15)
movl %eax, 0x14(%r15)
movups %xmm0, 0x18(%r15)
movl %eax, 0x28(%r15)
movups %xmm0, 0x2c(%r15)
movl $0x3f800000, %ebx       # imm = 0x3F800000
movl %ebx, 0x3c(%r15)
leaq -0x140(%rbp), %r13
movq %r13, %rdi
movq %r15, %rsi
callq 0x3f6c
leaq -0x90(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
movq %r13, %rdx
callq 0x2e60
movaps 0x25d8(%rip), %xmm0     # 0x5020
movups %xmm0, (%r15)
movsd 0x25dc(%rip), %xmm0     # 0x5030
movups %xmm0, 0x10(%r15)
movl $0xbd4cb6f5, %eax       # imm = 0xBD4CB6F5
movq %rax, 0x20(%r15)
movl $0x3f7fae19, 0x28(%r15) # imm = 0x3F7FAE19
xorps %xmm0, %xmm0
movups %xmm0, 0x2c(%r15)
movl %ebx, 0x3c(%r15)
leaq -0x180(%rbp), %r13
movq %r13, %rdi
movq %r15, %rsi
callq 0x3f6c
movl %ebx, (%r15)
xorps %xmm1, %xmm1
movups %xmm1, 0x4(%r15)
movsd 0x25a5(%rip), %xmm0     # 0x5040
movups %xmm0, 0x14(%r15)
movabsq $0x3f7ffcb9bc23d657, %rax # imm = 0x3F7FFCB9BC23D657
movq %rax, 0x24(%r15)
movups %xmm1, 0x2c(%r15)
movl %ebx, 0x3c(%r15)
leaq -0x140(%rbp), %r15
leaq -0x5a8(%rbp), %rsi
movq %r15, %rdi
callq 0x3f6c
leaq -0x1c0(%rbp), %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x2e60
movq -0xa8(%rbp), %rax
movq -0xa0(%rbp), %rbx
movq %rax, -0x40(%rbp)
subq %rax, %rbx
sarq $0x5, %rbx
movb $0x1, %r15b
leaq 0x46be(%rip), %r13      # 0x71c0
movq %r14, %rdi
callq 0x2170
testl %eax, %eax
je 0x2b20
cmpl $0x100, -0x5a8(%rbp)    # imm = 0x100
setne %al
andb %al, %r15b
jmp 0x2b02
xorl %eax, %eax
cmpq $0x12c000, %rax         # imm = 0x12C000
je 0x2b38
movl $0x7f7fffff, (%rax,%r13) # imm = 0x7F7FFFFF
addq $0x4, %rax
jmp 0x2b22
movb %r15b, -0x48(%rbp)
movq -0x38(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2060
movq -0x38(%rbp), %rdi
callq 0x2250
movq -0x40(%rbp), %r15
xorl %r14d, %r14d
cmpq %rbx, %r14
jae 0x2b7f
leaq 0x20(%r15), %rdx
leaq 0x40(%r15), %rcx
movq -0x38(%rbp), %rdi
movq %r15, %rsi
movq %r12, %r8
callq 0x2f38
addq $0x3, %r14
addq $0x60, %r15
jmp 0x2b59
movaps 0x24ca(%rip), %xmm0     # 0x5050
movups %xmm0, -0x180(%rbp)
movaps 0x24cc(%rip), %xmm0     # 0x5060
movups %xmm0, -0x170(%rbp)
movaps 0x24ce(%rip), %xmm0     # 0x5070
movups %xmm0, -0x140(%rbp)
movaps 0x24d0(%rip), %xmm0     # 0x5080
movups %xmm0, -0x130(%rbp)
movaps 0x24d2(%rip), %xmm0     # 0x5090
movups %xmm0, -0xd0(%rbp)
movaps 0x24d4(%rip), %xmm0     # 0x50a0
movups %xmm0, -0xc0(%rbp)
movq -0x38(%rbp), %r14
movq %r14, %rdi
leaq -0x180(%rbp), %rsi
leaq -0x140(%rbp), %rdx
leaq -0xd0(%rbp), %rcx
leaq -0x90(%rbp), %r8
callq 0x2f38
movq %r14, %rdi
callq 0x2260
movq %r12, %rdi
leaq -0x1c0(%rbp), %r14
movq %r14, %rsi
callq 0x3d3a
leaq -0x90(%rbp), %rdi
movq %r14, %rsi
callq 0x3d3a
movq -0x50(%rbp), %rdi
callq 0x2220
pushq $0x14
popq %rdi
callq 0x2190
testb $0x1, -0x48(%rbp)
movb $0x1, %r15b
leaq -0x5a8(%rbp), %r14
jne 0x2b02
leaq -0xa8(%rbp), %rdi
callq 0x3ee0
jmp 0x2cb5
movq 0x438a(%rip), %rdi      # 0x6fe8
leaq 0x24d3(%rip), %rsi      # 0x5138
callq 0x21f0
movq %rax, %rbx
callq 0x21a0
movq %rbx, %rdi
movq %rax, %rsi
callq 0x21f0
movq %rax, %rdi
callq 0x2120
jmp 0x2cbe
movq 0x435a(%rip), %rdi      # 0x6fe8
leaq 0x2487(%rip), %rsi      # 0x511c
callq 0x21f0
movq %rax, %rbx
callq 0x21a0
movq %rbx, %rdi
movq %rax, %rsi
callq 0x21f0
movq %rax, %rdi
callq 0x2120
movq -0x50(%rbp), %rdi
callq 0x2030
callq 0x2070
xorl %eax, %eax
addq $0x588, %rsp            # imm = 0x588
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, -0x90(%rbp)
leaq 0x24a4(%rip), %rdi      # 0x5189
callq 0x2140
pushq $0x10
popq %rdi
callq 0x2130
movq %rax, %r15
leaq 0x2474(%rip), %rsi      # 0x5170
movq %rax, %rdi
callq 0x20d0
movq 0x42e5(%rip), %rsi      # 0x6ff0
movq 0x42b6(%rip), %rdx      # 0x6fc8
movq %r15, %rdi
callq 0x22c0
movq %rdx, %r14
movq %rax, %rbx
jmp 0x2df8
movq %rdx, %r14
movq %rax, %rbx
movq %r15, %rdi
callq 0x2180
jmp 0x2df8
jmp 0x2d62
movq %rdx, %r14
movq %rax, %rbx
jmp 0x2e04
movq %rdx, %r14
movq %rax, %rbx
jmp 0x2e10
movq %r14, %rcx
movq %rdx, %r14
movq %rax, %rbx
movq %rcx, -0x90(%rbp)
jmp 0x2d68
movq %rdx, %r14
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x3ee0
jmp 0x2dbc
jmp 0x2d9e
jmp 0x2d9e
jmp 0x2d7c
movq %rdx, %r14
movq %rax, %rbx
jmp 0x2dbc
jmp 0x2d9e
jmp 0x2d88
movq %rdx, %r14
movq %rax, %rbx
leaq -0xa8(%rbp), %rdi
callq 0x3ee0
jmp 0x2e10
jmp 0x2d9e
movq %rdx, %r14
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x2100
leaq -0x3a0(%rbp), %rdi
callq 0x21b0
leaq -0x210(%rbp), %rdi
callq 0x2100
leaq -0x100(%rbp), %rdi
callq 0x42ac
leaq -0xd0(%rbp), %rdi
callq 0x42ac
leaq -0x140(%rbp), %rdi
callq 0x3ef8
leaq -0x180(%rbp), %rdi
callq 0x3ef8
leaq -0x5a8(%rbp), %rdi
callq 0x2090
leaq -0x1c0(%rbp), %rdi
callq 0x2100
cmpl $0x1, %r14d
jne 0x2e50
movq %rbx, %rdi
callq 0x20f0
movq (%rax), %rcx
movq %rax, %rdi
callq *0x10(%rcx)
movq 0x41ba(%rip), %rdi      # 0x6fe8
movq %rax, %rsi
callq 0x21f0
movq %rax, %rdi
callq 0x2120
callq 0x22b0
jmp 0x2cb5
movq %rax, %rbx
callq 0x22b0
movq %rbx, %rdi
callq 0x22d0
movq %rax, %rdi
callq 0x40ee