https://bitbucket.org/coutts/5dplus
Raw File
Tip revision: 0d7cbec6dea8a278a468d89a5bf23bf5670a3172 authored by Coutts on 21 June 2012, 12:32:49 UTC
Fix font sizes (thanks Alex!) and fixed problem of bmp_buffer moving around, using a pointer to the bmp_vram now instead of the raw address. Also testing ML menu with skeleton shoot menu, not working yet though.
Tip revision: 0d7cbec
bmp.c
/**
 * Drawing routines.
 *
 * These are Magic Lantern routines to draw into the BMP LVRAM.
 * They are not derived from DryOS routines.
 */
/*
 * Copyright (C) 2009 Trammell Hudson <hudson+ml@osresearch.net>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#include "arm-mcr.h"
#include "vxworks.h"
#include "bmp.h"
#include <stdarg.h>


/** Returns a pointer to currently selected BMP vram (real or mirror) */
uint8_t * bmp_vram(void)
{
    //- uint8_t * bmp_buf = bmp_idle_flag ? bmp_vram_idle() : bmp_vram_real();
    //- return bmp_buf;
    return MEM(0x29328);
}


static void
_draw_char(
           unsigned        fontspec,
           uint8_t *       bmp_vram_row,
           char            c
           )
{
    //~ if (!bmp_enabled) return;
    unsigned i,j;
    const struct font * const font = fontspec_font( fontspec );
    
    uint32_t        fg_color        = fontspec_fg( fontspec ) << 24;
    uint32_t        bg_color        = fontspec_bg( fontspec ) << 24;
    
    // Special case -- fg=bg=0 => white on black
    if( fg_color == 0 && bg_color == 0 )
    {
        fg_color = COLOR_WHITE << 24;
        bg_color = COLOR_BLACK << 24;
    }
    
    const uint32_t  pitch           = BMPPITCH / 4;
    uint32_t *      front_row       = (uint32_t *) bmp_vram_row;

    
#define FPIX(i,j) (font->bitmap[ c + ((i) << 7) ] & (1 << (31-(j))))
    //- #define BMPIX(i,j) bmp_vram_row[(i) * BMPPITCH + (j)]
#define BMPIX(i,j,color) char* p = &bmp_vram_row[((i)/2) * BMPPITCH + (j)/2]; *p = j%2 ? ((*p & 0x0F) | (color << 4)) : ((*p & 0xF0) | (color & 0x0F))    
    for( i = 0 ; i<font->height ; i++ )
    {
        for( j=0 ; j<font->width ; j++ )
        {
            if FPIX(i,j)
            {
                BMPIX(i,j,fg_color>>24);
            }
            else
            {
                BMPIX(i,j,bg_color>>24);
            }
        }
    }
    
    //sei( flags );
}






void
bmp_puts(
         unsigned                fontspec,
         unsigned *              x,
         unsigned *              y,
         const char *            s
         )
{
    const uint32_t          pitch = BMPPITCH;
    uint8_t * vram = bmp_vram();
    if( !vram || ((uintptr_t)vram & 1) == 1 )
        return;
    const unsigned initial_x = *x;
    uint8_t * first_row = vram + (*y) * pitch + (*x);
    uint8_t * row = first_row;
    
    char c;
    
    const struct font * const font = fontspec_font( fontspec );
    
    while( (c = *s++) )
    {
        if( c == '\n' )
        {
            row = first_row += pitch * font->height;
            (*y) += font->height;
            (*x) = initial_x;
            continue;
        }
        
        _draw_char( fontspec, row, c );
        row += font->width/2;
        (*x) += font->width;
    }
    
}


void bmp_draw_rect(uint8_t color, int x0, int y0, int w, int h)
{
    //~ if (!bmp_enabled) return;
    uint8_t * const bvram = bmp_vram();
    //- ASSERT(bvram)
    if (!bvram) return;
    
    int x, y;
#define P(X,Y) bvram[COERCE(X, BMP_W_MINUS, BMP_W_PLUS-1) + COERCE(Y, BMP_H_MINUS, BMP_H_PLUS-1) * BMPPITCH]
    for (x = x0; x <= x0 + w; x++)
        P(x, y0) = P(x, y0+h) = color;
    for (y = y0; y <= y0 + h; y++)
        P(x0, y) = P(x0+w, y) = color;
#undef P
}



void
bmp_printf(
           unsigned                fontspec,
           unsigned                x,
           unsigned                y,
           const char *            fmt,
           ...
           )
{
    va_list                 ap;
    char                    buf[ 256 ];
    
    va_start( ap, fmt );
    vsnprintf( buf, sizeof(buf), fmt, ap );
    va_end( ap );
    
    bmp_puts( fontspec, &x, &y, buf );
}

//~ Scaled in half from ML version. always have len as a multiple of 16. General
//~ use is 16 * num of lines desired printed.
void
bmp_hexdump(
            unsigned        fontspec,
            unsigned        x,
            unsigned        y,
            const void *        buf,
            int            len
            )
{
    if( len == 0 )
        return;
    
    // Round up
    len = (len + 15) & ~15;
    
    const uint32_t *    d = (uint32_t*) buf;
    
    do {
        bmp_printf(
                   fontspec,
                   x,
                   y,
                   "%08x: %08x %08x %08x %08x",
                   (unsigned) d,
                   len >  0 ? MEMX(d+0) : 0,
                   len >  4 ? MEMX(d+1) : 0,
                   len >  8 ? MEMX(d+2) : 0,
                   len > 12 ? MEMX(d+3) : 0
                   );
        
        y += fontspec_height( fontspec );
        d += 4;
        len -= 16;
    } while(len > 0);
}

/** Fill a section of bitmap memory with solid color
 * Only has a four-pixel resolution in X.
 */
void
bmp_fill(
         uint8_t            color,
         int        x,
         int        y,
         int        w,
         int        h
         )
{
    //~ if (!bmp_enabled) return;
    x = COERCE(x, BMP_W_MINUS, BMP_W_PLUS-1);
    y = COERCE(y, BMP_H_MINUS, BMP_H_PLUS-1);
    w = COERCE(w, 0, BMP_W_PLUS-x-1);
    h = COERCE(h, 0, BMP_H_PLUS-y-1);
    
    const int start = x;
    //~ const uint32_t width = BMP_WIDTH;
    const uint32_t pitch = BMPPITCH;
    //~ const uint32_t height = BMP_HEIGHT;
    
    const uint32_t word = 0
    | (color << 24)
    | (color << 16)
    | (color <<  8)
    | (color <<  0);
    
    int y_end = y + h;
    
    if( w == 0 || h == 0 )
        return;
    
    uint8_t * const vram = bmp_vram();
    uint32_t * row = (void*)( vram + y * pitch + start );
    //- ASSERT(row)
    
    if( !vram || ( 1 & (uintptr_t) vram ) )
    {
        //sei( flags );
        return;
    }
    
    
    for( ; y<y_end ; y++, row += pitch/4 )
    {
        int x;
        
#if defined(CONFIG_500D) || defined(CONFIG_50D) || defined(CONFIG_5D2) // what's going on here?!?!
        for( x=w/4-1 ; x >= 0 ; x-- )
#else
            for( x=0 ; x < (int)w/4 ; x++ )
#endif
            {
                row[ x ] = word;
#if defined(CONFIG_500D) || defined(CONFIG_50D) || defined(CONFIG_5D2) // what's going on here?!?!
                asm( "nop" );
                asm( "nop" );
                asm( "nop" );
                asm( "nop" );
#endif
                asm( "nop" );
                asm( "nop" );
                asm( "nop" );
                asm( "nop" );
            }
    }
}


/** Draw a picture of the BMP color palette. */
void
bmp_draw_palette( void )
{
    uint32_t x, y, msb, lsb;
    const uint32_t height = 15;
    const uint32_t width = 22;
    
    for( msb=0 ; msb<16; msb++ )
    {
        for( y=0 ; y<height; y++ )
        {
            uint8_t * const row = bmp_vram() + (y + height*msb) * BMPPITCH;
            
            for( lsb=0 ; lsb<16 ; lsb++ )
            {
                for( x=0 ; x<width ; x++ )
                    row[x+width*lsb] = 17 * lsb;
            }
        }
    }
    
    static int written;
    if( !written )
        //dispcheck();
        written = 1;
    msleep(2000);
}


// this is slow, but is good for a small number of pixels :)
uint8_t bmp_getpixel(int x, int y)
{
    //- ASSERT(x >= BMP_W_MINUS && x < BMP_W_PLUS)
    //- ASSERT(y >= BMP_H_MINUS && y < BMP_H_PLUS)
    
    uint8_t * const bvram = bmp_vram();
    return bvram[x + y * BMPPITCH];
}

uint8_t bmp_getpixel_real(int x, int y)
{
    //- ASSERT(x >= BMP_W_MINUS && x < BMP_W_PLUS)
    //- ASSERT(y >= BMP_H_MINUS && y < BMP_H_PLUS)
    
    uint8_t * const bvram = bmp_vram();
    return bvram[x + y * BMPPITCH];
}

void bmp_putpixel(int x, int y, uint8_t color)
{
    uint8_t * const bvram = bmp_vram();
    if (!bvram) return;
    x = COERCE(x, BMP_W_MINUS, BMP_W_PLUS-1);
    y = COERCE(y, BMP_H_MINUS, BMP_H_PLUS-1);
    bvram[x + y * BMPPITCH] = color;
}
back to top