// File: /workspace/github_c_makefile_star2_O2/adelciotto[P]scg/examples/voxel_space.c
// Function: draw
static void draw(scg_image_t *draw_target, terrain_t terrain, camera_t camera) {
    scg_image_clear(draw_target, SCG_COLOR_WHITE);

    int w = draw_target->width;
    int h = draw_target->height;
    int map_w_period = terrain.map_w - 1;
    int map_h_period = terrain.map_h - 1;

    float32_t s = sinf(camera.angle);
    float32_t c = cosf(camera.angle);

    float32_t ybuffer[w];
    for (int x = 0; x < w; x++) {
        ybuffer[x] = h;
    }

    float32_t dt = 1.0f;
    float32_t inv_max_distance = 1.0f / camera.max_distance;

    for (float32_t z = 1; z < camera.max_distance; z += dt) {
        float32_t pleft_x = -c * z - s * z;
        float32_t pleft_y = s * z - c * z;
        float32_t pright_x = c * z - s * z;
        float32_t pright_y = -s * z - c * z;

        float32_t dx = (pright_x - pleft_x) / (float32_t)w;
        float32_t dy = (pright_y - pleft_y) / (float32_t)w;
        pleft_x += camera.x;
        pleft_y += camera.y;
        float32_t invz = 1.0f / z * 240.0f;

        float32_t fog = fog_factor(z * inv_max_distance, 2.2f);

        for (int x = 0; x < w; x++) {
            int i = (((int)pleft_y & map_w_period) << 10) +
                    ((int)pleft_x & map_h_period);

            scg_pixel_t color_map_pixel =
                scg_pixel_new_uint32(terrain.color_map->pixels[i]);
            scg_pixel_t height_map_pixel =
                scg_pixel_new_uint32(terrain.height_map->pixels[i]);

            color_map_pixel = shade_pixel(color_map_pixel, fog);

            float32_t height_on_screen =
                (camera.height - height_map_pixel.packed) * invz +
                camera.horizon;
            draw_vertical_line(draw_target, x, height_on_screen, ybuffer[x],
                               color_map_pixel);

            if (height_on_screen < ybuffer[x]) {
                ybuffer[x] = height_on_screen;
            }

            pleft_x += dx;
            pleft_y += dy;
        }

        dt += 0.01f;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rdi, %rbx
leaq 0x28(%rbp), %r12
leaq 0x10(%rbp), %r14
pushq $-0x1
popq %rsi
callq 0x2c56
movl (%rbx), %r13d
movsd (%r14), %xmm0
movaps %xmm0, -0x70(%rbp)
movss 0x8(%r12), %xmm1
movss %xmm1, -0x2c(%rbp)
cvtsi2ssl 0x4(%rbx), %xmm0
movss %xmm0, -0x60(%rbp)
movaps %xmm1, %xmm0
callq 0x21d0
movaps %xmm0, -0x50(%rbp)
movss -0x2c(%rbp), %xmm0
callq 0x2180
movss -0x60(%rbp), %xmm1
movq %rsp, %r14
leaq 0xf(,%r13,4), %rax
andq $-0x10, %rax
subq %rax, %r14
movq %r14, %rsp
xorl %eax, %eax
testl %r13d, %r13d
movl $0x0, %r15d
cmovgl %r13d, %r15d
cmpq %rax, %r15
je 0x554b
movss %xmm1, (%r14,%rax,4)
incq %rax
jmp 0x553b
pshufd $0xe1, -0x70(%rbp), %xmm7 # xmm7 = mem[1,0,2,3]
paddd 0xb67(%rip), %xmm7      # 0x60c0
movss 0x14(%r12), %xmm1
movss 0xaa0(%rip), %xmm3      # 0x6008
movaps %xmm3, %xmm2
movss %xmm1, -0x3c(%rbp)
divss %xmm1, %xmm2
movss %xmm2, -0x38(%rbp)
movaps -0x50(%rbp), %xmm2
movaps %xmm2, %xmm1
unpcklps %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
movaps 0xb06(%rip), %xmm4      # 0x6090
xorps %xmm1, %xmm4
cvtsi2ss %r13d, %xmm5
movsd (%r12), %xmm6
movaps %xmm6, -0xa0(%rbp)
leaq 0x10(%rbp), %rax
movq 0x8(%rax), %r9
movq 0x10(%rax), %r13
movss 0xc(%r12), %xmm8
movss 0x10(%r12), %xmm9
shufps $0x10, %xmm4, %xmm2     # xmm2 = xmm2[0,0],xmm4[1,0]
shufps $0xe2, %xmm4, %xmm2     # xmm2 = xmm2[2,0],xmm4[2,3]
movaps %xmm2, -0x50(%rbp)
shufps $0x0, %xmm5, %xmm5      # xmm5 = xmm5[0,0,0,0]
movaps %xmm5, -0xb0(%rbp)
movaps %xmm4, -0xc0(%rbp)
movlhps %xmm0, %xmm4            # xmm4 = xmm4[0],xmm0[0]
shufps $0xe2, %xmm1, %xmm4     # xmm4 = xmm4[2,0],xmm1[2,3]
movaps %xmm4, -0x90(%rbp)
movl $0xff, %r12d
movaps %xmm3, %xmm1
movdqa %xmm7, -0xd0(%rbp)
movq %r9, -0x78(%rbp)
movss %xmm8, -0x34(%rbp)
movss %xmm9, -0x30(%rbp)
movss -0x3c(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x581e
movss %xmm3, -0x2c(%rbp)
movaps %xmm1, %xmm2
shufps $0x0, %xmm1, %xmm2      # xmm2 = xmm2[0,0],xmm1[0,0]
movaps %xmm2, %xmm0
mulps -0xc0(%rbp), %xmm0
movaps -0x50(%rbp), %xmm3
mulps %xmm2, %xmm3
addps %xmm0, %xmm3
mulps -0x90(%rbp), %xmm2
addps %xmm0, %xmm2
subps %xmm3, %xmm2
divps -0xb0(%rbp), %xmm2
movaps %xmm2, -0xf0(%rbp)
addps -0xa0(%rbp), %xmm3
movaps %xmm3, -0xe0(%rbp)
movss 0x9a3(%rip), %xmm0      # 0x6008
divss %xmm1, %xmm0
mulss 0x9d3(%rip), %xmm0      # 0x6044
movss %xmm0, -0x70(%rbp)
movss -0x38(%rbp), %xmm0
movaps %xmm1, -0x60(%rbp)
mulss %xmm1, %xmm0
mulss 0x9bd(%rip), %xmm0      # 0x6048
mulss %xmm0, %xmm0
mulss 0x9b5(%rip), %xmm0      # 0x604c
callq 0x23e0
movaps -0xe0(%rbp), %xmm12
movaps -0xf0(%rbp), %xmm11
movss 0x957(%rip), %xmm10     # 0x600c
xorl %r10d, %r10d
movss -0x30(%rbp), %xmm9
movss -0x34(%rbp), %xmm8
movq -0x78(%rbp), %r9
movdqa -0xd0(%rbp), %xmm7
xorps %xmm1, %xmm1
maxss %xmm0, %xmm1
movss 0x929(%rip), %xmm0      # 0x6008
movaps %xmm0, %xmm2
minss %xmm1, %xmm2
subss %xmm2, %xmm0
xorl %eax, %eax
cmpq %r15, %rax
je 0x5804
cvttps2dq %xmm12, %xmm1
pand %xmm7, %xmm1
pshufd $0x55, %xmm1, %xmm2     # xmm2 = xmm1[1,1,1,1]
movd %xmm2, %ecx
shll $0xa, %ecx
movd %xmm1, %edx
addl %ecx, %edx
movslq %edx, %rsi
movq 0x10(%r13), %rcx
movl (%rcx,%rsi,4), %ecx
cvtsi2ss %rcx, %xmm2
movaps %xmm8, %xmm1
subss %xmm2, %xmm1
mulss -0x70(%rbp), %xmm1
addss %xmm9, %xmm1
cvttss2si %xmm1, %edx
movss (%r14,%rax,4), %xmm2
cvttss2si %xmm2, %ecx
testl %edx, %edx
cmovlel %r10d, %edx
subl %edx, %ecx
jge 0x575d
ucomiss %xmm1, %xmm2
jbe 0x5754
movss %xmm1, (%r14,%rax,4)
addps %xmm11, %xmm12
incq %rax
jmp 0x56ec
movq 0x10(%r9), %rdi
movl (%rdi,%rsi,4), %esi
movl %esi, %edi
shrl $0x8, %edi
movl %esi, %r8d
shrl $0x10, %r8d
andl %r12d, %r8d
cvtsi2ss %r8d, %xmm3
andl %r12d, %edi
cvtsi2ss %edi, %xmm4
andl %r12d, %esi
cvtsi2ss %esi, %xmm5
movaps %xmm10, %xmm6
subss %xmm4, %xmm6
mulss %xmm0, %xmm6
addss %xmm4, %xmm6
movaps %xmm10, %xmm4
subss %xmm5, %xmm4
mulss %xmm0, %xmm4
addss %xmm5, %xmm4
movaps %xmm10, %xmm5
subss %xmm3, %xmm5
mulss %xmm0, %xmm5
cvttss2si %xmm4, %esi
cvttss2si %xmm6, %edi
addss %xmm3, %xmm5
cvttss2si %xmm5, %r8d
shll $0x10, %r8d
andl %r12d, %edi
shll $0x8, %edi
orl %r8d, %edi
andl %r12d, %esi
orl %edi, %esi
orl $0xff000000, %esi       # imm = 0xFF000000
movslq (%rbx), %rdi
imull %edi, %edx
addl %eax, %edx
movslq %edx, %rdx
shlq $0x2, %rdx
shlq $0x2, %rdi
subl $0x1, %ecx
jb 0x5749
movq 0x10(%rbx), %r8
movl %esi, (%r8,%rdx)
addq %rdi, %rdx
jmp 0x57ee
movss -0x2c(%rbp), %xmm3
addss 0x83f(%rip), %xmm3      # 0x6050
movaps -0x60(%rbp), %xmm1
addss %xmm3, %xmm1
jmp 0x5606
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq