// File: tomfunkhouser[P]gaps/pkgs/fglut/freeglut_font.c
// Function: glutBitmapString
void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
{
    unsigned char c;
    float x = 0.0f ;
    SFG_Font* font;
    FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapString" );
    font = fghFontByID( fontID );
    freeglut_return_if_fail( font );
    if ( !string || ! *string )
        return;

    glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
    glPixelStorei( GL_UNPACK_SWAP_BYTES,  GL_FALSE );
    glPixelStorei( GL_UNPACK_LSB_FIRST,   GL_FALSE );
    glPixelStorei( GL_UNPACK_ROW_LENGTH,  0        );
    glPixelStorei( GL_UNPACK_SKIP_ROWS,   0        );
    glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0        );
    glPixelStorei( GL_UNPACK_ALIGNMENT,   1        );

    /*
     * Step through the string, drawing each character.
     * A newline will simply translate the next character's insertion
     * point back to the start of the line and down one line.
     */
    while( ( c = *string++) )
        if( c == '\n' )
        {
            glBitmap ( 0, 0, 0, 0, -x, (float) -font->Height, NULL );
            x = 0.0f;
        }
        else  /* Not an EOL, draw the bitmap character */
        {
            const GLubyte* face = font->Characters[ c ];

            glBitmap(
                face[ 0 ], font->Height,     /* Bitmap's width and height    */
                font->xorig, font->yorig,    /* The origin in the font glyph */
                ( float )( face[ 0 ] ), 0.0, /* The raster advance; inc. x,y */
                ( face + 1 )                 /* The packed bitmap data...    */
            );

            x += ( float )( face[ 0 ] );
        }

    glPopClientAttrib( );
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movq %rsi, 0x18(%rsp)
xorps %xmm0, %xmm0
movss %xmm0, 0x10(%rsp)
leaq 0x7ffa2(%rip), %rax     # 0x1fa390
cmpb $0x0, 0x1c(%rax)
jne 0x17a409
leaq 0x234d7(%rip), %rdi     # 0x19d8d2
leaq 0x238d2(%rip), %rsi     # 0x19dcd4
movb $0x0, %al
callq 0x17de70
movq 0x20(%rsp), %rdi
callq 0x17a2d0
movq %rax, 0x8(%rsp)
cmpq $0x0, 0x8(%rsp)
jne 0x17a425
jmp 0x17a558
cmpq $0x0, 0x18(%rsp)
je 0x17a437
movq 0x18(%rsp), %rax
cmpb $0x0, (%rax)
jne 0x17a43c
jmp 0x17a558
movl $0x1, %edi
callq 0x226c0
movl $0xcf0, %edi            # imm = 0xCF0
xorl %esi, %esi
callq 0x22490
movl $0xcf1, %edi            # imm = 0xCF1
xorl %esi, %esi
callq 0x22490
movl $0xcf2, %edi            # imm = 0xCF2
xorl %esi, %esi
callq 0x22490
movl $0xcf3, %edi            # imm = 0xCF3
xorl %esi, %esi
callq 0x22490
movl $0xcf4, %edi            # imm = 0xCF4
xorl %esi, %esi
callq 0x22490
movl $0xcf5, %edi            # imm = 0xCF5
movl $0x1, %esi
callq 0x22490
movq 0x18(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x18(%rsp)
movb (%rax), %al
movb %al, 0x17(%rsp)
cmpb $0x0, %al
je 0x17a553
movzbl 0x17(%rsp), %eax
cmpl $0xa, %eax
jne 0x17a4f9
movss 0x10(%rsp), %xmm0
movd %xmm0, %eax
xorl $0x80000000, %eax       # imm = 0x80000000
movd %eax, %xmm2
movq 0x8(%rsp), %rcx
xorl %eax, %eax
subl 0xc(%rcx), %eax
cvtsi2ss %eax, %xmm3
xorl %esi, %esi
xorps %xmm1, %xmm1
xorl %eax, %eax
movl %eax, %edx
movl %esi, %edi
movaps %xmm1, %xmm0
callq 0x22970
xorps %xmm0, %xmm0
movss %xmm0, 0x10(%rsp)
jmp 0x17a54e
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rax
movzbl 0x17(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, (%rsp)
movq (%rsp), %rdx
movzbl (%rdx), %edi
movq 0x8(%rsp), %rax
movl 0xc(%rax), %esi
movss 0x18(%rax), %xmm0
movss 0x1c(%rax), %xmm1
cvtsi2ss %edi, %xmm2
incq %rdx
xorps %xmm3, %xmm3
callq 0x22970
movq (%rsp), %rax
movzbl (%rax), %eax
cvtsi2ss %eax, %xmm0
addss 0x10(%rsp), %xmm0
movss %xmm0, 0x10(%rsp)
jmp 0x17a491
callq 0x22c20
addq $0x28, %rsp
retq
nopl (%rax)