pea
developer
Hi all,
I decided to start a new thread with this. I have a large image (640x480) and I am moving it about the screen in geepee32.
Please note that I know I am using an emulator, and it only goes at 40MHz, and I also know that the image is larger than the framebuffer.
Using Mr Mirko SDK function I can get 1fps because it tries to process every pixel regardless if its on the srceen or not, and at 640x480, thats a lot of processing Also, the 1fps is constant, even if the sprite image is completely or mostly offscreen.
Using my own code, I first check whether the sprite is even on the screen at all, then I calculate an offset to start drawing the data if the sprite starts off the screen, and then I calculate a 'step' value to jump through the sprite data at the end of every line. In this way the sprite data is effectively 'cropped' before I try to draw it, and the function only processes those pixels that are actually drawn.
As well as this, since the pixels are all garanteed on the screen, I don't have to check (4 comparisons) that the pixel is on the screen before I draw it.
Using this method I get 7fps, and once the image moves closer to the edge of the screen, the framerate increases to about 20 or 30.
The reason for this is because Mr Mirko's sprite routines will work almost as fast with small sprites that are completely (or mostly) within the screen area, whereas my routine will work well with any, but especially larger images.
The question is:
Can anyone see how I can improve this routine, or can anyone with the knowledge convert this to assembler
Cheers,
Pea
I decided to start a new thread with this. I have a large image (640x480) and I am moving it about the screen in geepee32.
Please note that I know I am using an emulator, and it only goes at 40MHz, and I also know that the image is larger than the framebuffer.
Using Mr Mirko SDK function I can get 1fps because it tries to process every pixel regardless if its on the srceen or not, and at 640x480, thats a lot of processing Also, the 1fps is constant, even if the sprite image is completely or mostly offscreen.
Code:
void gpd_drawCanvas( tGPD_canvas *canvas, short x, short y, u16 *framebuffer ){
short xx,yy;
int i=0;
for (yy=0; yy<canvas->height; yy++)
for (xx=0; xx<canvas->width; xx++) gpd_setPixel(x+xx,y+yy,(u16)canvas->data[i++],framebuffer);
}
Using my own code, I first check whether the sprite is even on the screen at all, then I calculate an offset to start drawing the data if the sprite starts off the screen, and then I calculate a 'step' value to jump through the sprite data at the end of every line. In this way the sprite data is effectively 'cropped' before I try to draw it, and the function only processes those pixels that are actually drawn.
As well as this, since the pixels are all garanteed on the screen, I don't have to check (4 comparisons) that the pixel is on the screen before I draw it.
Using this method I get 7fps, and once the image moves closer to the edge of the screen, the framerate increases to about 20 or 30.
Code:
void gpd_drawCanvasFast( tGPD_canvas *canvas, short x, short y, u16 *framebuffer ) {
unsigned short xx,yy;
unsigned short vw,vh;
unsigned short loff;
unsigned long doff;
unsigned short px,py;
short tx,ty;
// If canvas is off the screen, exit
if ((x>=LCD_WIDTH) || (y>=LCD_HEIGHT)){ return; }
tx = x+canvas->width; ty = y+canvas->height;
if ((tx<0) || (ty<0)){ return; }
// Positional offsets
px = max( 0, x );
py = max( 0, y );
// Visible height
if (y<0){
vh = min( ty, LCD_HEIGHT );
}else{
if (ty>LCD_HEIGHT){
vh = canvas->height - (ty-LCD_HEIGHT);
}else{
vh = canvas->height;
}
}
// Visible width
if (x<0){
vw = min( tx, LCD_WIDTH );
}else{
if (tx>LCD_WIDTH){
vw = canvas->width - (tx-LCD_WIDTH);
}else{
vw = canvas->width;
}
}
// Data offset
doff = ( canvas->width * max( 0, -y ) ) + max( 0, -x );
// Line offset
loff = max( 0, -x ) + max( 0, (tx-LCD_WIDTH) );
// Draw visible pixels only
for ( yy=0; yy<vh; yy++ ){
for ( xx=0; xx<vw; xx++ ){
gp_drawPixel16(px+xx,py+yy, (u16)canvas->data[doff++], framebuffer ); //No bound checking
}
doff += loff;
}
}
The reason for this is because Mr Mirko's sprite routines will work almost as fast with small sprites that are completely (or mostly) within the screen area, whereas my routine will work well with any, but especially larger images.
The question is:
Can anyone see how I can improve this routine, or can anyone with the knowledge convert this to assembler
Cheers,
Pea