// File: donqustix[P]SoftwareRenderer/src/main.cpp
// Function: void (anonymous namespace)::scanline<std::greater<void>>(SDL_Surface*, (anonymous namespace)::Edge const&, (anonymous namespace)::Edge const&, std::greater<void>)
void scanline(SDL_Surface* surface, const Edge& edge1, const Edge& edge2, ComparisonFunc compare) noexcept
    {
        const vec4f& pos1 = edge1.vert1.position, pos2 = edge1.vert2.position,
                     pos3 = edge2.vert1.position, pos4 = edge2.vert2.position;

        const auto pos21 = pos2 - pos1, pos43 = pos4 - pos3;

        if (!pos21.get_y())
            return;

        auto ldx = pos21.get_x() / pos21.get_y();
        auto rdx = pos43.get_x() / pos43.get_y();

        auto ldz = pos21.get_z() / pos21.get_y();
        auto rdz = pos43.get_z() / pos43.get_y();

        auto lx = pos1.get_x();
        auto rx = pos3.get_x() + (pos1.get_y() - pos3.get_y()) * rdx;

        auto lz = pos1.get_z();
        auto rz = pos3.get_z() + (pos1.get_y() - pos3.get_y()) * rdz;

        const vec4f& color1 = edge1.vert1.color, color2 = edge1.vert2.color,
                     color3 = edge2.vert1.color, color4 = edge2.vert2.color;

        const auto color21 = color2 - color1, color43 = color4 - color3;
        
        auto ldc = color21 / pos21.get_y();
        auto rdc = color43 / pos43.get_y();

        auto lc = color1;
        auto rc = color3 + (pos1.get_y() - pos3.get_y()) * rdc;

        if (compare(ldx, rdx))
        {
            std::swap(ldx, rdx); std::swap(rx, lx);
            std::swap(ldc, rdc); std::swap(rc, lc);
        }

        const int min_y = std::ceil(pos1.get_y()), max_y = std::ceil(pos2.get_y());
        if (min_y < 0 || max_y >= surface->h)
            return;

        for (int y = min_y; y < max_y; ++y)
        {
            const int min_x = std::ceil(lx), max_x = std::ceil(rx);
            if (min_x < 0 || max_x >= surface->w)
                return;

            const auto pixel_delta_color = (rc - lc) / (rx - lx);
            auto pixel_color = lc;

            for (int x = min_x; x < max_x; ++x)
            {
                const auto zvalue = lz + (x - min_x) * (rz - lz) / (rx - lx);

                if (zvalue < *(zbuffer + WINDOW_WIDTH * y + x))
                {
                    *(zbuffer + WINDOW_WIDTH * y + x) = zvalue;
                    ::set_pixel(surface, x, y, pixel_color.get_x() * 255,
                                               pixel_color.get_y() * 255,
                                               pixel_color.get_z() * 255);
                }
                pixel_color += pixel_delta_color;
            }

            lx += ldx;
            rx += rdx;
            lz += ldz;
            rz += rdz;
            lc += ldc;
            rc += rdc;
        }
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x220, %rsp            # imm = 0x220
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rax
movups 0x20(%rax), %xmm0
movaps %xmm0, -0x40(%rbp)
movq -0x20(%rbp), %rax
movups (%rax), %xmm0
movaps %xmm0, -0x50(%rbp)
movq -0x20(%rbp), %rax
movups 0x20(%rax), %xmm0
movaps %xmm0, -0x60(%rbp)
movq -0x28(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x6e20
movlpd %xmm0, -0x70(%rbp)
movlpd %xmm1, -0x68(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x6e20
movlpd %xmm0, -0x80(%rbp)
movlpd %xmm1, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x5dd0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x5f18
jp 0x5f18
jmp 0x6662
leaq -0x70(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x5db0
movq -0x1c8(%rbp), %rdi
movss %xmm0, -0x1e8(%rbp)
callq 0x5dd0
movaps %xmm0, %xmm1
movss -0x1e8(%rbp), %xmm0
divss %xmm1, %xmm0
movss %xmm0, -0x84(%rbp)
leaq -0x80(%rbp), %rdi
movq %rdi, -0x1c0(%rbp)
callq 0x5db0
movq -0x1c0(%rbp), %rdi
movss %xmm0, -0x1e4(%rbp)
callq 0x5dd0
movq -0x1c8(%rbp), %rdi
movaps %xmm0, %xmm1
movss -0x1e4(%rbp), %xmm0
divss %xmm1, %xmm0
movss %xmm0, -0x88(%rbp)
callq 0x5df0
movq -0x1c8(%rbp), %rdi
movss %xmm0, -0x1e0(%rbp)
callq 0x5dd0
movq -0x1c0(%rbp), %rdi
movaps %xmm0, %xmm1
movss -0x1e0(%rbp), %xmm0
divss %xmm1, %xmm0
movss %xmm0, -0x8c(%rbp)
callq 0x5df0
movq -0x1c0(%rbp), %rdi
movss %xmm0, -0x1dc(%rbp)
callq 0x5dd0
movaps %xmm0, %xmm1
movss -0x1dc(%rbp), %xmm0
divss %xmm1, %xmm0
movss %xmm0, -0x90(%rbp)
movq -0x28(%rbp), %rdi
callq 0x5db0
movss %xmm0, -0x94(%rbp)
leaq -0x50(%rbp), %rdi
movq %rdi, -0x1b8(%rbp)
callq 0x5db0
movss %xmm0, -0x1d8(%rbp)
movq -0x28(%rbp), %rdi
callq 0x5dd0
movq -0x1b8(%rbp), %rdi
movss %xmm0, -0x1d4(%rbp)
callq 0x5dd0
movss -0x1d8(%rbp), %xmm1
movaps %xmm0, %xmm2
movss -0x1d4(%rbp), %xmm0
subss %xmm2, %xmm0
movss -0x88(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x98(%rbp)
movq -0x28(%rbp), %rdi
callq 0x5df0
movq -0x1b8(%rbp), %rdi
movss %xmm0, -0x9c(%rbp)
callq 0x5df0
movss %xmm0, -0x1d0(%rbp)
movq -0x28(%rbp), %rdi
callq 0x5dd0
movq -0x1b8(%rbp), %rdi
movss %xmm0, -0x1cc(%rbp)
callq 0x5dd0
movss -0x1d0(%rbp), %xmm1
movaps %xmm0, %xmm2
movss -0x1cc(%rbp), %xmm0
subss %xmm2, %xmm0
movss -0x90(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0xa0(%rbp)
movq -0x18(%rbp), %rax
addq $0x10, %rax
movq %rax, -0xa8(%rbp)
movq -0x18(%rbp), %rax
movups 0x30(%rax), %xmm0
movaps %xmm0, -0xc0(%rbp)
movq -0x20(%rbp), %rax
movups 0x10(%rax), %xmm0
movaps %xmm0, -0xd0(%rbp)
movq -0x20(%rbp), %rax
movups 0x30(%rax), %xmm0
movaps %xmm0, -0xe0(%rbp)
movq -0xa8(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0x6e20
movlpd %xmm0, -0xf0(%rbp)
movlpd %xmm1, -0xe8(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movq %rsi, -0x1a8(%rbp)
callq 0x6e20
movq -0x1c8(%rbp), %rdi
movlpd %xmm0, -0x100(%rbp)
movlpd %xmm1, -0xf8(%rbp)
callq 0x5dd0
leaq -0xf0(%rbp), %rdi
callq 0x5cc0
movq -0x1c0(%rbp), %rdi
movlpd %xmm0, -0x110(%rbp)
movlpd %xmm1, -0x108(%rbp)
callq 0x5dd0
leaq -0x100(%rbp), %rdi
callq 0x5cc0
movlpd %xmm0, -0x120(%rbp)
movlpd %xmm1, -0x118(%rbp)
movq -0xa8(%rbp), %rax
movups (%rax), %xmm0
movaps %xmm0, -0x130(%rbp)
movq -0x28(%rbp), %rdi
callq 0x5dd0
movq -0x1b8(%rbp), %rdi
movss %xmm0, -0x1ac(%rbp)
callq 0x5dd0
movaps %xmm0, %xmm1
movss -0x1ac(%rbp), %xmm0
subss %xmm1, %xmm0
leaq -0x120(%rbp), %rdi
callq 0x6f00
movq -0x1a8(%rbp), %rdi
movlpd %xmm0, -0x150(%rbp)
movlpd %xmm1, -0x148(%rbp)
leaq -0x150(%rbp), %rsi
callq 0x6e90
movlpd %xmm0, -0x140(%rbp)
movlpd %xmm1, -0x138(%rbp)
leaq -0x1(%rbp), %rdi
leaq -0x84(%rbp), %rsi
leaq -0x88(%rbp), %rdx
callq 0x7c90
testb $0x1, %al
jne 0x6254
jmp 0x62a0
leaq -0x84(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x7cd0
leaq -0x98(%rbp), %rdi
leaq -0x94(%rbp), %rsi
callq 0x7cd0
leaq -0x110(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x6f60
leaq -0x140(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x6f60
movq -0x28(%rbp), %rdi
callq 0x5dd0
callq 0x7d10
movss %xmm0, -0x1ec(%rbp)
jmp 0x62b8
movss -0x1ec(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x154(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x5dd0
callq 0x7d10
movss %xmm0, -0x1f0(%rbp)
jmp 0x62e2
movss -0x1f0(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x158(%rbp)
cmpl $0x0, -0x154(%rbp)
jl 0x630c
movl -0x158(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x14(%rcx), %eax
jl 0x6311
jmp 0x6662
movl -0x154(%rbp), %eax
movl %eax, -0x15c(%rbp)
movl -0x15c(%rbp), %eax
cmpl -0x158(%rbp), %eax
jge 0x6662
movss -0x94(%rbp), %xmm0
callq 0x7d10
movss %xmm0, -0x1f4(%rbp)
jmp 0x6346
movss -0x1f4(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x160(%rbp)
movss -0x98(%rbp), %xmm0
callq 0x7d10
movss %xmm0, -0x1f8(%rbp)
jmp 0x636f
movss -0x1f8(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x164(%rbp)
cmpl $0x0, -0x160(%rbp)
jl 0x6399
movl -0x164(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jl 0x639e
jmp 0x6662
leaq -0x140(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x6e20
movlpd %xmm0, -0x184(%rbp)
movlpd %xmm1, -0x17c(%rbp)
movss -0x98(%rbp), %xmm0
movss -0x94(%rbp), %xmm1
subss %xmm1, %xmm0
leaq -0x184(%rbp), %rdi
callq 0x5cc0
movlpd %xmm0, -0x174(%rbp)
movlpd %xmm1, -0x16c(%rbp)
movq -0x130(%rbp), %rax
movq %rax, -0x194(%rbp)
movq -0x128(%rbp), %rax
movq %rax, -0x18c(%rbp)
movl -0x160(%rbp), %eax
movl %eax, -0x198(%rbp)
movl -0x198(%rbp), %eax
cmpl -0x164(%rbp), %eax
jge 0x65c8
movss -0x9c(%rbp), %xmm0
movl -0x198(%rbp), %eax
subl -0x160(%rbp), %eax
cvtsi2ss %eax, %xmm1
movss -0xa0(%rbp), %xmm2
subss -0x9c(%rbp), %xmm2
mulss %xmm2, %xmm1
movss -0x98(%rbp), %xmm2
subss -0x94(%rbp), %xmm2
divss %xmm2, %xmm1
addss %xmm1, %xmm0
movss %xmm0, -0x19c(%rbp)
movss -0x19c(%rbp), %xmm1
imull $0x280, -0x15c(%rbp), %eax # imm = 0x280
movslq %eax, %rcx
leaq 0x5d7d(%rip), %rax      # 0xc210
shlq $0x2, %rcx
addq %rcx, %rax
movslq -0x198(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x65a1
movss -0x19c(%rbp), %xmm0
movl -0x15c(%rbp), %ecx
shll $0x7, %ecx
movl %ecx, %eax
leal (%rax,%rax,4), %eax
movslq %eax, %rcx
leaq 0x5d41(%rip), %rax      # 0xc210
leaq (%rax,%rcx,4), %rax
movslq -0x198(%rbp), %rcx
movss %xmm0, (%rax,%rcx,4)
movq -0x10(%rbp), %rax
movq %rax, -0x210(%rbp)
movl -0x198(%rbp), %eax
movl %eax, -0x204(%rbp)
movl -0x15c(%rbp), %eax
movl %eax, -0x200(%rbp)
leaq -0x194(%rbp), %rdi
movq %rdi, -0x220(%rbp)
callq 0x5db0
movq -0x220(%rbp), %rdi
movss 0x1b1c(%rip), %xmm1     # 0x8040
movss %xmm1, -0x214(%rbp)
mulss %xmm1, %xmm0
cvttss2si %xmm0, %eax
movb %al, -0x1fa(%rbp)
callq 0x5dd0
movq -0x220(%rbp), %rdi
movss -0x214(%rbp), %xmm1
mulss %xmm1, %xmm0
cvttss2si %xmm0, %eax
movb %al, -0x1f9(%rbp)
callq 0x5df0
movss -0x214(%rbp), %xmm1
movq -0x210(%rbp), %rdi
movl -0x204(%rbp), %esi
movl -0x200(%rbp), %edx
movb -0x1fa(%rbp), %cl
movb -0x1f9(%rbp), %r8b
mulss %xmm1, %xmm0
cvttss2si %xmm0, %eax
movzbl %cl, %ecx
movzbl %r8b, %r8d
movzbl %al, %r9d
callq 0x6fb0
leaq -0x194(%rbp), %rdi
leaq -0x174(%rbp), %rsi
callq 0x7050
movl -0x198(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x198(%rbp)
jmp 0x6419
movss -0x84(%rbp), %xmm0
addss -0x94(%rbp), %xmm0
movss %xmm0, -0x94(%rbp)
movss -0x88(%rbp), %xmm0
addss -0x98(%rbp), %xmm0
movss %xmm0, -0x98(%rbp)
movss -0x8c(%rbp), %xmm0
addss -0x9c(%rbp), %xmm0
movss %xmm0, -0x9c(%rbp)
movss -0x90(%rbp), %xmm0
addss -0xa0(%rbp), %xmm0
movss %xmm0, -0xa0(%rbp)
leaq -0x130(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x7050
leaq -0x140(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x7050
movl -0x15c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x15c(%rbp)
jmp 0x631d
addq $0x220, %rsp            # imm = 0x220
popq %rbp
retq
movq %rax, %rdi
callq 0x70a0
nopw %cs:(%rax,%rax)