// File: misohena[P]drawstars/drawstars.cpp
// Function: void drawStarsPerspective<Range<GaiaStar>>(Image<ColorRGB<double>>&, Range<GaiaStar>, Mat4<float>, float, float, StarAppearanceOptions const&)
void drawStarsPerspective(ImageType &canvas, Range stars, Mat4F mat, float minMag, float maxMag, const StarAppearanceOptions &starAppearanceOptions)
{
    for(const auto &star : stars){
        const auto mag = star.mag();
        if(!(mag >= minMag && mag <= maxMag)){
            continue;
        }

        Vec4F pos = mat * dirRADec(star.ra_rad(), star.dec_rad());
        if(pos.w != 0){
            const float invW = 1 / pos.w;
            const float x = pos.x * invW;
            const float y = pos.y * invW;
            const float z = pos.z * invW;
            if(x >= -1 && x <= 1 && y >= -1 && y <= 1 && z >= -1 && z <= 1){
                const float screenX = canvas.width()/2*(1+x);
                const float screenY = canvas.height()/2*(1-y);
                if(canvas.includes(screenX, screenY)){
                    const StarAppearance appearance = calculateStarAppearance(star, starAppearanceOptions);
                    const ColorType color = appearance.color;
                    const float radius = appearance.radius;
                    //*canvas.at(screenX, screenY) += color;
                    fillCircle(
                        canvas, screenX, screenY, radius,
                        PixelPlotter(appearance));
                }
            }
        }
    }
}

// Assembly:
subq $0x128, %rsp            # imm = 0x128
leaq 0x130(%rsp), %rax
movq %rax, 0x38(%rsp)
movq %rsi, 0x118(%rsp)
movq %rdx, 0x120(%rsp)
movq %rdi, 0x110(%rsp)
movss %xmm0, 0x10c(%rsp)
movss %xmm1, 0x108(%rsp)
movq %rcx, 0x100(%rsp)
leaq 0x118(%rsp), %rax
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rdi
callq 0x1b5c0
movq %rax, 0xf0(%rsp)
movq 0xf8(%rsp), %rdi
callq 0x1b5d0
movq %rax, 0xe8(%rsp)
movq 0xf0(%rsp), %rax
cmpq 0xe8(%rsp), %rax
je 0x1d30e
movq 0xf0(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x1b5e0
movss %xmm0, 0xdc(%rsp)
movss 0xdc(%rsp), %xmm0
ucomiss 0x10c(%rsp), %xmm0
jb 0x1d006
movss 0xdc(%rsp), %xmm1
movss 0x108(%rsp), %xmm0
ucomiss %xmm1, %xmm0
jae 0x1d00b
jmp 0x1d2f5
movq 0xe0(%rsp), %rdi
callq 0x1d320
movss %xmm0, 0x34(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x1d350
movaps %xmm0, %xmm1
movss 0x34(%rsp), %xmm0
callq 0x80c0
movq 0x38(%rsp), %rdi
movlpd %xmm0, 0xbc(%rsp)
movlpd %xmm1, 0xc4(%rsp)
leaq 0xbc(%rsp), %rsi
callq 0xeaa0
movlpd %xmm0, 0xcc(%rsp)
movlpd %xmm1, 0xd4(%rsp)
movss 0xd8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x1d087
jp 0x1d087
jmp 0x1d2f3
movss 0xf7d(%rip), %xmm0      # 0x1e00c
divss 0xd8(%rsp), %xmm0
movss %xmm0, 0xb8(%rsp)
movss 0xcc(%rsp), %xmm0
mulss 0xb8(%rsp), %xmm0
movss %xmm0, 0xb4(%rsp)
movss 0xd0(%rsp), %xmm0
mulss 0xb8(%rsp), %xmm0
movss %xmm0, 0xb0(%rsp)
movss 0xd4(%rsp), %xmm0
mulss 0xb8(%rsp), %xmm0
movss %xmm0, 0xac(%rsp)
movss 0xb4(%rsp), %xmm0
movss 0xf15(%rip), %xmm1      # 0x1e018
ucomiss %xmm1, %xmm0
jb 0x1d2f1
movss 0xef8(%rip), %xmm0      # 0x1e00c
ucomiss 0xb4(%rsp), %xmm0
jb 0x1d2f1
movss 0xb0(%rsp), %xmm0
movss 0xee5(%rip), %xmm1      # 0x1e018
ucomiss %xmm1, %xmm0
jb 0x1d2f1
movss 0xec8(%rip), %xmm0      # 0x1e00c
ucomiss 0xb0(%rsp), %xmm0
jb 0x1d2f1
movss 0xac(%rsp), %xmm0
movss 0xeb5(%rip), %xmm1      # 0x1e018
ucomiss %xmm1, %xmm0
jb 0x1d2f1
movss 0xe98(%rip), %xmm0      # 0x1e00c
ucomiss 0xac(%rsp), %xmm0
jb 0x1d2f1
movq 0x110(%rsp), %rdi
callq 0x11c00
shrl %eax
cvtsi2ss %eax, %xmm0
movss 0xb4(%rsp), %xmm1
movss 0xe66(%rip), %xmm2      # 0x1e00c
addss %xmm2, %xmm1
mulss %xmm1, %xmm0
movss %xmm0, 0xa8(%rsp)
movq 0x110(%rsp), %rdi
callq 0x11c10
shrl %eax
cvtsi2ss %eax, %xmm0
movss 0xe3a(%rip), %xmm1      # 0x1e00c
subss 0xb0(%rsp), %xmm1
mulss %xmm1, %xmm0
movss %xmm0, 0xa4(%rsp)
movq 0x110(%rsp), %rdi
cvttss2si 0xa8(%rsp), %esi
cvttss2si 0xa4(%rsp), %edx
callq 0x1c320
testb $0x1, %al
jne 0x1d210
jmp 0x1d2ef
movq 0xe0(%rsp), %rsi
movq 0x100(%rsp), %rdx
leaq 0x80(%rsp), %rdi
callq 0x1b6d0
movq 0x80(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x78(%rsp)
movss 0x98(%rsp), %xmm0
movss %xmm0, 0x64(%rsp)
movq 0x110(%rsp), %rax
movq %rax, 0x20(%rsp)
movss 0xa8(%rsp), %xmm0
movss %xmm0, 0x28(%rsp)
movss 0xa4(%rsp), %xmm0
movss %xmm0, 0x2c(%rsp)
movss 0x64(%rsp), %xmm0
movss %xmm0, 0x30(%rsp)
leaq 0x40(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x1bec0
movq 0x20(%rsp), %rdi
movss 0x28(%rsp), %xmm0
movss 0x2c(%rsp), %xmm1
movss 0x30(%rsp), %xmm2
leaq 0x40(%rsp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x1d380
jmp 0x1d2f1
jmp 0x1d2f3
jmp 0x1d2f5
movq 0xf0(%rsp), %rax
addq $0x18, %rax
movq %rax, 0xf0(%rsp)
jmp 0x1cfa0
addq $0x128, %rsp            # imm = 0x128
retq
nopw %cs:(%rax,%rax)