GP32 Speed Of 16bit Colour Mode


pea

developer
Joined
Oct 3, 2004
Messages
1,089
Age
45
Location
New Zealand
Website
www.projectitis.com
Hi all,

Is 16bit colour mode very slow?
Apart from double the memory requirements, what do the other overheads involve?

How fast is MrMirkos SDK in 16bit mode rather than 8bit?

Cheers,
Pea
 
mirko's sdk is great, and very functional. However, it's also quite slow. If you write your own routines, you can make your stuff run quite quickly. Don't use mirko's sprite code though, it's slow as hell.
 
Hehe ok. One reason I think is because he checks for every single pixel whether it is ouside the screen area. I think I can at least speed that up a bit...

The draw sprite routine loops through every pixel in the whole sprite regardless of whether it is viewable or not:
Code:
void gp_drawSpriteHT( u16 *sprite, short put_x, short put_y, u16 *framebuffer, u16 trans) {
     int xx,yy,i=0;
     SHEADER *sheader;
     u16   color;
     sheader = (SHEADER*) sprite;
     // loop through every single pixel in the sprite
     for (yy=0; yy<(sheader->size_y); yy++)
        for (xx=0; xx<(sheader->size_x); xx++) {
           color = sprite[6+i++];
           if ( color != trans ) 
             setpixel(put_x+xx,put_y+yy,color,framebuffer);
        }
}

And the setPixel routine then does four less than or greater than comparisons for every single pixel:
Code:
void setpixel(short x, short y, u16 color, u16 *framebuffer ) {
     if ( !((x<0) || (x>319) || (y<0) || (y>239)) )
       gp_drawPixel16(x,y,color,framebuffer);
}

I'll speed it up and post the code to Mr Mirko for his next release when I'm done...
 
if you want fast routine, you can try to use blit system of Gdl2

assuming draw 20000 32² transparent sprite in 666 ticks without any clipping
~800 tick with all clipping

it work on gp sdk but not really use it, must work fine with mirko, just link the framebufer with the function.

but there are limitation :
you must use c++,
you must use 8 bit mode,
you need to precompute all the graphic before draw them,
sprite are limited to ~100 pixels in size y (no limit in x),
the function is slower than gpsdk one without any transparency in the sprite,
slow when there is y clipping at draw,

but in eatch way must be pretty faster than a for for function with putpixel.

i you use it, get the yAnl version who are the last, with memory save and load of the object for faster load without precomputing ^^
(in /lib/Gdl/gfx/Gfm.cpp and .h)
 
If you want some fast sprite routines, have a look at the ones I wrote for BOR. Although not the fastest, they are about the best memory/performance that I could think of at the time. Open the "sprite.c" file to find the routines for creating compressed sprites from bitmaps (to save memory) and the routines for displaying them. There's also routines in there for flipping them, etc.
 
You can find some other blitting code in my partial IGM release here: http://www.gp32x.de/board/index.php?showtopic=14027

With the help of Kuwanger, I was able to get about GP32SDK speeds for blitting, with a nice porting layer. The non-transparent blitting is faster then the SDK, blitting two pixels at a time instead of one.
 
Last edited by a moderator:
The best advice I can give you, is pre-rotate the sprite data to matcht the orientation of the framebuffer to prevent cache horror :)
 
If you want something really fast check my compiled sprite example I made a while ago <_< The code is for 8bits but should be easily ported over to 16bits..
 
To sum up some basic ideas..

1) Just making a fast while() loop is pretty fast, but you can of course do better; but comparing 8bpp to 16bpp straight while loop copies (no bounds checks etc) they're not that far apart.. going to 16bpp doesn't hit too much. A few %ent.

2) You can compress the sprite (using RLE since its easy and fast to decode); if coded super tight (even in C) you can decompress faster than a straight uncompressed copy, since you can just repeat over the samey areas

3) For 8bpp its not too hard to make a sprite-compiler that writes the asm code for the sprite; for 16bpp its more work of course...

4) On gp32 since the screen is sideways pre-rotating the sprites can help; this is something I only tried recently.. way cool :)

jeff
 
Thanks for all the answers guys. Just a couple of quickies:

1) If the difference between 8 and 16 bit is not that great, why do many people still use 8 bit for their games and launchers etc?

2) Sorry for the newbie Q, but in which direction does the LCD data go? Bottom left as 0,0 in vertical rows?

Cheers,
Pea
 
1) If the difference between 8 and 16 bit is not that great, why do many people still use 8 bit for their games and launchers etc?

2) Sorry for the newbie Q, but in which direction does the LCD data go? Bottom left as 0,0 in vertical rows?
1) I use 8 bit for YAFL because fxe icons are 8 bit and it makes things easier to just use a standard 8 bit display (I may change to 16 bit in the next version though - it's something I'm thinking about at the moment), and my games are 8 bit because I can't draw so it makes sense to only use about 5 colours ;).

2) Hold your gp32 with the joystick at the top. That is the correct orientation for the screen.
 
Last edited by a moderator:
Hi Pea! how are you doing with your sprite functions? Do you mind posting them? I had a go with Mirko's and changed them to pre-rotated data and some other things maybe we can mix our stuff for the better ...
I also did a scaling function, but that one need some speed ups I am not capable of...
I also try to upload the fucntions some where .... tomorrow I guess...
Example:
Code:
/*
 * Same as the Mirko SDK function but uses real screen coords
 * and rotatet sprite data like the official SDK.
 * You can create this format with dalto's Imageconverter
 */
void syn_drawSpriteHT(unsigned short *sprite, int put_x, int put_y, u16 *framebuffer,
                      unsigned short trans)
{
  int             xx, yy, tempx, tempy, offset, i = 0;
  unsigned short  color;
  SHEADER         *sprite_header = (SHEADER*) sprite;

  for (xx=0; xx<(sprite_header->size_x); xx++)
  {
    tempx  = put_x + xx;

    // cut sprite on the left and right
    if((tempx>319) || (tempx<0))
    {
      i += sprite_header->size_y;
      continue;
    }

    offset = tempx * 240;

    for (yy=0; yy<(sprite_header->size_y); yy++)
    {
            color = sprite[6+i++];
            // check for transparency
            if(!(color - trans))
              continue;
            tempy = put_y + yy;

            // cut sprite on the top and bottom
            if( !( ((tempy<0) || (tempy>239)) ))
              *(framebuffer + tempy + offset) = color;
    }
  }

}

Code:
/*
 * Anamorphic Sprite Scaling (synlib)
 *
 * Scales and draws a sprite with header, transparency
 * STILL BUGGY! DOES NOT WORK WITH ALL SPRITES!
 *
 * u16*   sprite      sprite data with header
 * short  put_x       [0-319] x-pos on screen
 * short  put_y       [0-239] y-pos on screen
 * short  size_x      [0-...] desired width in pixel
 * short  size_y      [0-...] desired height in pixel
 * u16*   buffer      sprite destination
 * u16    trans       transparent color, 16bit
 */
void syn_scaleSpriteH(unsigned short *sprite, short put_x, short put_y, short size_x,
                      short size_y, unsigned short *framebuffer)
{
  SHEADER*       sheader = (SHEADER*) sprite;
  short          src_x_size = sheader->size_x;
  short          src_y_size = sheader->size_y;
  unsigned short color;
  int            sx, sy, dy, dx;
  int            temp_x, temp_y, offset;

  for(dx=0; dx<size_x; dx++)
  {
    sx = ((dx*src_x_size) / size_x);
    temp_x = dx + put_x;
    // cut sprite on the left and right
    if((temp_x>319) || (temp_x<0))
      continue;

    for(dy=0; dy<size_y; dy++)
    {
      sy     = ((dy*src_y_size) / size_y);
      color  = sprite[6+(sx*src_x_size)+sy];

      temp_y = dy + put_y;
      offset = temp_x * 240;

      if( !((temp_y<0) || (temp_y>239)) )
        *(framebuffer + temp_y + offset) = color;
    }
  }
}
 
Hi Synchro,

All I have is a sprite drawing routine (that uses pre-rotated prite data) that is faster than Mr.Mirkos (by 10 times or so) but so far only on geepee32 - no idea if it is faster on an actual GP32 (mine is under the christmas tree).

I will upload my stuff, and provide a link soon.

EDIT: Uploaded to my site: http://www.pea.co.nz/gp32/gpd_downloads.php

You will need to put your sprite data in a tGPD_canvas struct, which is very simple:
Code:
typedef struct tGPD_canvas{
	int width; // width of sprite (actual width before rotation)
	int height; // height of sprite data (actual height before rotation)
	unsigned short *data; // pointer to rotated sprite data (should be width*height in length)
}tGPD_canvas;
 
ah, thank you so far. You are quiet abitious for someone with no gp32.... don't take the speed of geepee too serious, on the real gp32_console everything runs better ....
 
Hi synkro - I DO have GP32, just haven't been able to use it yet :)
Am working on a new version of memcpy to speed up my blitting routine. Will let you know how it unfolds.
 
Back
Top