https://bitbucket.org/coutts/5dplus
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.
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;
}