// File: tomfunkhouser[P]gaps/pkgs/fglut/freeglut_geometry.c
// Function: glutSolidCone
void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks )
{
    int i,j;

    /* Step in z and radius as stacks are drawn. */

    double z0,z1;
    double r0,r1;

    const double zStep = height / ( ( stacks > 0 ) ? stacks : 1 );
    const double rStep = base / ( ( stacks > 0 ) ? stacks : 1 );

    /* Scaling factors for vertex normals */

    const double cosn = ( height / sqrt ( height * height + base * base ));
    const double sinn = ( base   / sqrt ( height * height + base * base ));

    /* Pre-computed circle */

    double *sint,*cost;

    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidCone" );

    fghCircleTable(&sint,&cost,-slices);

    /* Cover the circular base with a triangle fan... */

    z0 = 0.0;
    z1 = zStep;

    r0 = base;
    r1 = r0 - rStep;

    glBegin(GL_TRIANGLE_FAN);

        glNormal3d(0.0,0.0,-1.0);
        glVertex3d(0.0,0.0, z0 );

        for (j=0; j<=slices; j++)
            glVertex3d(cost[j]*r0, sint[j]*r0, z0);

    glEnd();

    /* Cover each stack with a quad strip, except the top stack */

    for( i=0; i<stacks-1; i++ )
    {
        glBegin(GL_QUAD_STRIP);

            for(j=0; j<=slices; j++)
            {
                glNormal3d(cost[j]*sinn, sint[j]*sinn, cosn);
                glVertex3d(cost[j]*r0,   sint[j]*r0,   z0  );
                glVertex3d(cost[j]*r1,   sint[j]*r1,   z1  );
            }

            z0 = z1; z1 += zStep;
            r0 = r1; r1 -= rStep;

        glEnd();
    }

    /* The top stack is covered with individual triangles */

    glBegin(GL_TRIANGLES);

        glNormal3d(cost[0]*sinn, sint[0]*sinn, cosn);

        for (j=0; j<slices; j++)
        {
            glVertex3d(cost[j+0]*r0,   sint[j+0]*r0,   z0    );
            glVertex3d(0,              0,              height);
            glNormal3d(cost[j+1]*sinn, sint[j+1]*sinn, cosn  );
            glVertex3d(cost[j+1]*r0,   sint[j+1]*r0,   z0    );
        }

    glEnd();

    /* Release sin and cos tables */

    free(sint);
    free(cost);
}

// Assembly:
subq $0xa8, %rsp
movsd %xmm0, 0xa0(%rsp)
movsd %xmm1, 0x98(%rsp)
movl %edi, 0x94(%rsp)
movl %esi, 0x90(%rsp)
movsd 0x98(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
cmpl $0x0, 0x90(%rsp)
jle 0x18868d
movl 0x90(%rsp), %eax
movl %eax, 0x2c(%rsp)
jmp 0x188698
movl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x188698
movsd 0x30(%rsp), %xmm0
movl 0x2c(%rsp), %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
cmpl $0x0, 0x90(%rsp)
jle 0x1886d6
movl 0x90(%rsp), %eax
movl %eax, 0x1c(%rsp)
jmp 0x1886e1
movl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x1886e1
movsd 0x20(%rsp), %xmm0
movl 0x1c(%rsp), %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x98(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x98(%rsp), %xmm0
movsd 0x98(%rsp), %xmm2
movsd 0xa0(%rsp), %xmm1
mulsd 0xa0(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x22780
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x98(%rsp), %xmm0
movsd 0x98(%rsp), %xmm2
movsd 0xa0(%rsp), %xmm1
mulsd 0xa0(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
callq 0x22780
movaps %xmm0, %xmm1
movsd 0x10(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rsp)
leaq 0x71bea(%rip), %rax     # 0x1fa390
cmpb $0x0, 0x1c(%rax)
jne 0x1887c1
leaq 0x1511f(%rip), %rdi     # 0x19d8d2
leaq 0x26a0c(%rip), %rsi     # 0x1af1c6
movb $0x0, %al
callq 0x17de70
xorl %edx, %edx
subl 0x94(%rsp), %edx
leaq 0x40(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x188210
xorps %xmm0, %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movsd 0x70(%rsp), %xmm0
subsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
movl $0x6, %edi
callq 0x221b0
xorps %xmm1, %xmm1
movsd 0x5d89(%rip), %xmm2     # 0x18e5b0
movaps %xmm1, %xmm0
callq 0x22330
movsd 0x80(%rsp), %xmm2
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x23020
movl $0x0, 0x88(%rsp)
movl 0x88(%rsp), %eax
cmpl 0x94(%rsp), %eax
jg 0x1888af
movq 0x38(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x70(%rsp), %xmm0
movq 0x40(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x70(%rsp), %xmm1
movsd 0x80(%rsp), %xmm2
callq 0x23020
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x18884e
callq 0x22de0
movl $0x0, 0x8c(%rsp)
movl 0x8c(%rsp), %eax
movl 0x90(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x188a29
movl $0x8, %edi
callq 0x221b0
movl $0x0, 0x88(%rsp)
movl 0x88(%rsp), %eax
cmpl 0x94(%rsp), %eax
jg 0x1889cb
movq 0x38(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x48(%rsp), %xmm0
movq 0x40(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x48(%rsp), %xmm1
movsd 0x50(%rsp), %xmm2
callq 0x22330
movq 0x38(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x70(%rsp), %xmm0
movq 0x40(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x70(%rsp), %xmm1
movsd 0x80(%rsp), %xmm2
callq 0x23020
movq 0x38(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x68(%rsp), %xmm0
movq 0x40(%rsp), %rax
movslq 0x88(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x68(%rsp), %xmm1
movsd 0x78(%rsp), %xmm2
callq 0x23020
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x1888ed
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x60(%rsp), %xmm0
addsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movsd 0x58(%rsp), %xmm1
movsd 0x68(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x68(%rsp)
callq 0x22de0
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0x1888bf
movl $0x4, %edi
callq 0x221b0
movq 0x38(%rsp), %rax
movsd (%rax), %xmm0
mulsd 0x48(%rsp), %xmm0
movq 0x40(%rsp), %rax
movsd (%rax), %xmm1
mulsd 0x48(%rsp), %xmm1
movsd 0x50(%rsp), %xmm2
callq 0x22330
movl $0x0, 0x88(%rsp)
movl 0x88(%rsp), %eax
cmpl 0x94(%rsp), %eax
jge 0x188b7a
movq 0x38(%rsp), %rax
movl 0x88(%rsp), %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x70(%rsp), %xmm0
movq 0x40(%rsp), %rax
movl 0x88(%rsp), %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x70(%rsp), %xmm1
movsd 0x80(%rsp), %xmm2
callq 0x23020
movsd 0x98(%rsp), %xmm2
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0x23020
movq 0x38(%rsp), %rax
movl 0x88(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x48(%rsp), %xmm0
movq 0x40(%rsp), %rax
movl 0x88(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x48(%rsp), %xmm1
movsd 0x50(%rsp), %xmm2
callq 0x22330
movq 0x38(%rsp), %rax
movl 0x88(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
mulsd 0x70(%rsp), %xmm0
movq 0x40(%rsp), %rax
movl 0x88(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
mulsd 0x70(%rsp), %xmm1
movsd 0x80(%rsp), %xmm2
callq 0x23020
movl 0x88(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x88(%rsp)
jmp 0x188a67
callq 0x22de0
movq 0x40(%rsp), %rdi
callq 0x22c30
movq 0x38(%rsp), %rdi
callq 0x22c30
addq $0xa8, %rsp
retq
nopl (%rax,%rax)