GP32 Mr.mirkos Sdk Replacement


JyCet posted on Apr 6 2004 at 05:21 PM said:
Hi Mirko,

Today I just make a little test of your SDK,
lot of example in your sdk very good, but for me more complicate than gamepark SDK.


I change the double buffer switch to a gamepark style, I prefere it :).
But I've a pb to use the gp_SpritePut function. I've nothing on the screen and I dont undersabd why ?
The header titre.h is same type here:
const unsigned short titre[9416] = {
0x1, 0x3253...};
It's a 24Bits bmp convert by GP32converter

So and finaly, are you add some news GFX function ?

Thks
Read Chapter 9 of the DOCUMENTATION !

short *sprite: Pointer to the sprite raw data, generated with
./bmp2bin -x 1.bmp 1.raw


> It's a 24Bits bmp convert by GP32converter
This is your Problem.

I modified the raw data, and added a header to each sprite.
In the header is the size of the sprite.

I add some new blitting functions tomorrow.

Mirko
 
Last edited by a moderator:
I use these functions, maybe they'll help you out... with these you can use images from the GPconverter w/o using that weird head...

Code:
/*********************************************************************
 *	Inline functions to check a point is inside the screen boundary.
 *  coded by Joel Lairo(21/10/03)
 */
inline int withinWidth(int x)
{
	return ((unsigned int)x < WIDTH);
}

inline int withinHeight(int y)
{
	return ((unsigned int)y < HEIGHT);
}

inline int withinScreen(int x, int y)
{
	return (withinWidth(x) && withinHeight(y));
}

/*********************************
 * Substitute for gp_putSprite()
 * uses real screen coords
 */
void drawSprite(unsigned short *sprite, unsigned short sprite_x,
                unsigned short sprite_y, int put_x, int put_y,
                unsigned short *framebuffer)
{
     int xx,yy,i,tempx;
     u16   color;

     i=0;
      for (xx=0; xx<sprite_x; xx++)
      {
         tempx = put_x+xx;
         for (yy=0; yy<sprite_y; yy++)
         {
            color = sprite[i++];
            if(withinScreen(tempx, put_y+yy))
            *(framebuffer +(put_y+yy)+(240*(tempx)) ) = color;
         }
      }
}

/*********************************
 * Draws sprite with transperancy
 * uses real screen coords
 */
void drawSpriteT(unsigned short *sprite, unsigned short sprite_x,
                unsigned short sprite_y, int put_x, int put_y,
                unsigned short *framebuffer, unsigned short trans)
{
     int xx,yy,i,tempx;
     u16   color;

     i=0;
     for (xx=0; xx<sprite_x; xx++)
     {
       tempx = put_x+xx;
       for (yy=0; yy<sprite_y; yy++)
       {
        color = sprite[i++];
        if(withinScreen(tempx, put_y+yy) && (color != trans))
          *(framebuffer +(put_y+yy)+(240*(tempx)) ) = color;
       }
}    }

/********************************
 * Substitute for gp_SetPixel()
 * uses real screen coords
 */
void putPixel(int x, int y, unsigned short color, unsigned short *framebuffer)
{
  if(withinScreen(x, y))
    *(framebuffer + y + (240 * x)) = color;
}
 
Synkro: You really need to get rid of the multiply that gets calculated for every pixel in your sprite routines. The easy way to do this, is multiply once at the start, to get the correct starting position in the framebuffer, and then just add 240 each time you cycle through your outer loop.
 
Code:
static
void setpixel (short x, short y, u16 color, u16 *framebuffer ) {
     if ( !((x<0) || (x>319) || (y<0) || (y>239)) )
       gp_SetPixel16(x,y,color,framebuffer);
}

void gp_SpriteBlit( u16 *sprite, u16 trans, u16 laenge, u16 hoehe, short put_x, short put_y, u16 *framebuffer ) {

     short xx,yy;
     int   i=0;
     u16   color;

     for (yy=0;yy<hoehe;yy++)
     for (xx=0;xx<laenge;xx++) {
         color = sprite[i++];
         if ( color != trans )
           setpixel(put_x+xx,put_y+yy,color,framebuffer);
     }
}

Iam now using this to blit some stuff to the screen, and using not one mul :)
 
Not true, there is a multiply in gp_SetPixel16 and gp_SetPixel8 so there is a multiply for every pixel.

there should be an alternative gp_SetPixel16 and gp_SetPixel8 that takes a single index value rather than both x and y. This way you can increment the value rather than multiply every time.
 
I found this page on sprite optimisation: http://www.beesknees.freeserve.co.uk/artic...imisation1.html

Here is his code slightly modified.
I don't know how much faster it is but...

Code:
void gp_drawSprite( unsigned short * sprite, short sprite_x, short sprite_y, short put_x, short put_y, unsigned short *framebuffer )
{
  const unsigned short * s = sprite;
  unsigned short * b = framebuffer + (put_x * 240) + (239-put_y-sprite_y);
  const  short offset = 240 - sprite_y;
  short row = sprite_x;
  
  do
  {
    short col = sprite_y;
    do
      *b++ = *s++;
    while( --col > 0 );
    b += offset;
  } while( --row > 0 );

// With Transparency
void gp_drawSpriteT( unsigned short * sprite, u16 trans ,short sprite_x, short sprite_y, short put_x, short put_y, unsigned short *framebuffer )
{
  const unsigned short * s = sprite;
  unsigned short * b = framebuffer + (put_x * 240) + (239-put_y-sprite_y);
  const  short offset = 240 - sprite_y;
  short row = sprite_x;
  
  do
  {
    short col = sprite_y;
	do{
        if(*s!=trans)
             *b = *s;
             b++;
             s++;
	} while( --col > 0 );
    b += offset;
  } while( --row > 0 );
}
}
 
Calculating the offset, once, and then only add it, is a great thing.
But there is one thing missing, you can not move the sprite, out of the window... :)
Today i start with some asm code writing...
 
Daz_Genetic posted on Apr 6 2004 at 11:56 PM said:
Synkro: You really need to get rid of the multiply that gets calculated for every pixel in your sprite routines. The easy way to do this, is multiply once at the start, to get the correct starting position in the framebuffer, and then just add 240 each time you cycle through your outer loop.
yes, that's right... But I am the typ of guy to make things work the logical way I am optimizing just after everything works... juts a bit odd :) I wanted to give him an idea... shouldn't anyone close this thread an start a new one?!
 
Last edited by a moderator:
Added SDK066 to my site, enjoy...

New:

- 2 new Sprite Blitting functions, now works with raw data, and
the sprite can be out of window range. ( moving something in the screen )
- The fastest ScreenClear ever seen, 100% asm code :)


The asm tutorial was not finished yet, so i include it (hope) to the next release.

Mirko
 
mr.mirko, you are doing great with this SDK. How easy is it to get it to work with ARM ADS? I got a license through work and I really like working in a neat graphical environment. I know I'm being lazy, but every alternative seems like way too much work, and I much prefer coding than messing around with makefiles ;)

Also, do you have a stretch blit function. For scaling sprites. I use that a lot and I would love a fast version.

When drawing sprites that go out of the window, it's usually faster to calculate the clipping using something similar to Cohen-Sutherland and only draw the pixels on the screen. Is this the way you are doing it, or are you just checking if each pixel is within bounds?
 
Daz_Genetic posted on Apr 7 2004 at 11:39 PM said:
mr.mirko, you are doing great with this SDK. How easy is it to get it to work with ARM ADS? I got a license through work and I really like working in a neat graphical environment. I know I'm being lazy, but every alternative seems like way too much work, and I much prefer coding than messing around with makefiles ;)

Also, do you have a stretch blit function. For scaling sprites. I use that a lot and I would love a fast version.

When drawing sprites that go out of the window, it's usually faster to calculate the clipping using something similar to Cohen-Sutherland and only draw the pixels on the screen. Is this the way you are doing it, or are you just checking if each pixel is within bounds?
bobintrees posted a real fast blitting function, its fast, but excluded the off screen feature. I am now on the assembler trip, and try to write something real fast... :)

I can not say something to the ads problem, i included a ads file in the help folder. Ask loki666, he ported most parts of the sdk to ads.I think he is using it to port his new os to gp.


greets,
 
Last edited by a moderator:
mr.mirko,

In gp_irq.S, you have the following functions:


ARMEnableInterrupt:
STMDB r13!,{r0,lr}
MRS r0,CPSR
BIC r0,r0,#0x80
MSR CPSR,r0
LDMIA r13!,{r0,pc}
@MOV pc,lr

ARMDisableInterrupt:
STMDB r13!,{r0,lr}
MRS r0,CPSR
ORR r0,r0,#0xc0
MSR CPSR,r0
LDMIA r13!,{r0,pc}
@MOV pc,lr

Are you sure these functions work? I know they are also in libgpstdlib.a from GamePark SDK, but I remember reading in the the Samsung documentation that the CPSR control bits (which the IRQ flag is part of) is read-only in user mode, and so can only be changed in priviledged mode (Eg. during an exception handler)

Actually, I'll just check that :)

"IRQ's may be disabled at any time by setting the I bit in the CPSR, though this can only be done from a privileged (non-User) mode."
 
This i tried to get 1fps.

Code:
while(gp_GetRTC()<128);

Its simply. Geepee takes arount a sec. But on hardware its ca. 3 seconds.
Can it bee that the code is "too slow" für 66Mhz o_O

Code:
#include "gp32.h"

// Pointer für die Framebuffer
u16 *framebuffer1;
u16 *framebuffer2;

int main() {

	int x;
	framebuffer1 = (u16*)  FRAMEBUFFER;        // 0x0C7B4000
	framebuffer2 = (u16*) (FRAMEBUFFER + (320*240*2));  // 0x0C7D9800      
  
	// Initialisierung
	gp_SetScreen(framebuffer1,16);
	gp_ButtonInit();
	gp_InstallRTC();

	// Basiswerte
	gp_ScreenClear16(framebuffer1, 0xFFFF);
	gp_ScreenClear16(framebuffer2, 0xFFFF);
	gp_ResetRTC();
	gp_SetCpuSpeed(66);
 
	while (1) {
  gp_SetView(framebuffer1);
  gp_ScreenClear16(framebuffer2, 0xFFFF);
  gp_SetFont8(30,110,13,"Iam Screen 2 ",0xF800,framebuffer2);	
  // loop
  while(gp_GetRTC()<128);
  gp_ResetRTC();

  gp_SetView(framebuffer2);
  gp_ScreenClear16(framebuffer1, 0xFFFF);
  gp_SetFont8(30,100,13,"Iam Screen 1 ",0xF800,framebuffer1);
  // loop
//  for (x=0;x<9000000;x++) x=x;
  while(gp_GetRTC()<128);
  gp_ResetRTC();
        
  // A gedrückt? Reset.
  if (gp_ButtonResult()&BA) gp_Reset();
	}
 
 }
 
I beleive that the internal tick counter does in fact run faster when you overclock. It only runs at 1000ticks per second when at 40Mhz. So you need to adjust that based on how fast you are running the processor.
 
Hmm the SDK Doc means it always run at 128 tics. I dont have a problem in case that it runs faster but fact is that it runs slower.

Edit:
At 133 MHz it seems to need the same time. The Timer seems to work but its faaar away from 128 per sec.
 
Daz_Genetic posted on Apr 18 2004 at 09:22 PM said:
I beleive that the internal tick counter does in fact run faster when you overclock. It only runs at 1000ticks per second when at 40Mhz. So you need to adjust that based on how fast you are running the processor.
The rtc is cpu clock independent...

Let me check the 128 ticks / sec

66Mhz:
60 seconds result in 3800 tick counts = 63.333 ticks /second

133Mhz:
60 seconds result in 3800 tick counts too.

So the RTc is not running in 128 ticks/sec


!!!!!Its running in 63 ticks / sec..!!!!!!

argh :(

thanx for the info...
 
Last edited by a moderator:
Please use in the samples something like that to be sure that it dont flicker later

Code:
u16 *framebuffer[2];  // buffers
char swapper=0;    // swap variable

// wait for screen blank
static void WaitVBlank (void) {
	while ((rLCDCON1 >> 18) != 2);
	while ((rLCDCON1 >> 18) != 1);
}

// Double buffer handling
// "back" is the central back picture
// returns pointer to the now used screen
 u16 * double_buffer (u16 *back) {
	WaitVBlank();
	gp_SetView(framebuffer[swapper]);
	if(++swapper==2) swapper=0;
	if(back) memcpy(framebuffer[swapper], back, 320*240*2);
	return framebuffer[swapper];
}
 
Can someone test something for me with Mirko's sdk? Unfortunately I can't as I don't use GCC.

Time the following:

1) Create any file
2) Write out 16 bytes worth of any data
3) Write out a further 24 bytes worth of any data
4) Close file

On my build of the smc library under ADS, that takes over 3 seconds, which is I think you'll agree is bloody ridiculous for such a small amount of data. :)

Reading seems perfectly fast, so this is only a writing issue. And I never had any speed issues with writing when using the official SDK (which I can't really go back to now).

TIA!
 
are you sure it's not to do with caching? the gp32 sdk may cache the writes and do them later on (like on the close file). Where as the ones in this sdk may all be direct.
 
Back
Top