GP32 Timing Problem Or Is My Code To Slow?


nutribrain

Still Fresh
Joined
Mar 26, 2003
Messages
39
Age
51
Location
Germany
Website
home.wtal.de
I'm having a problem on my second little programm I write. I want to do a Space Invaders type game and are stuck now at the point I want to draw all the invaders sprites to the buffer. I seems that from the upper left corner to the middle of the bottom a diagonal line/area is spanned which is black opague and hide my sprites and everything under it.

I'm using Mr.Mirkos SDK (BTW great one!).
I suspect the 'gp_clearFramebuffer16' function to be too slow to fill the whole buffer and keeps on filling it right after I write my sprites. And that results in the black "curtain". Also I've read about a cache problem concerning the Samsung chip inside the GP32.

I bet that this is a timing problem so I tried to unroll the code but didn't succeed. And I also tried to adjust the clockspeed from 66 to 133 but this only had the result that the "curtain" has a different position.

My code looks like this:

Code:
while(1) {
  swap_screen();
  gp_clearFramebuffer16(framebuffer[nflip],0x0000); // very very fast asm, faster than memset
      	
  for (i=0; i<INVADERLINES; i++) {
  	j = 0;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  }
  
  gp_drawSpriteT ( &cruiserSprite, cruiser.x, cruiser.y, framebuffer[nflip], 0x0000, cruiser.width, cruiser.height );
  if (shotFired) draw_shot();

It would be very nice if someone could help me on this.

BTW: The first steps in C programming for then GP32 I did about one and a half year ago. And when I saw that there is a replacement lib for the original Gamepark SDK, I thought about give it a try. And I have to say till now this lib my Mr.Mirko is absolutely GREAT!!! I appreciate very much the work and effort he puts into this project.
 
I'm having a problem on my second little programm I write. I want to do a Space Invaders type game and are stuck now at the point I want to draw all the invaders sprites to the buffer. I seems that from the upper left corner to the middle of the bottom a diagonal line/area is spanned which is black opague and hide my sprites and everything under it.

I'm using Mr.Mirkos SDK (BTW great one!).
I suspect the 'gp_clearFramebuffer16' function to be too slow to fill the whole buffer and keeps on filling it right after I write my sprites. And that results in the black "curtain". Also I've read about a cache problem concerning the Samsung chip inside the GP32.

I bet that this is a timing problem so I tried to unroll the code but didn't succeed. And I also tried to adjust the clockspeed from 66 to 133 but this only had the result that the "curtain" has a different position.

My code looks like this:

Code:
while(1) {
  swap_screen();
  gp_clearFramebuffer16(framebuffer[nflip],0x0000); // very very fast asm, faster than memset
      	
  for (i=0; i<INVADERLINES; i++) {
  	j = 0;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  	gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT ); j++;
  }
  
  gp_drawSpriteT ( &cruiserSprite, cruiser.x, cruiser.y, framebuffer[nflip], 0x0000, cruiser.width, cruiser.height );
  if (shotFired) draw_shot();

It would be very nice if someone could help me on this.

BTW: The first steps in C programming for then GP32 I did about one and a half year ago. And when I saw that there is a replacement lib for the original Gamepark SDK, I thought about give it a try. And I have to say till now this lib my Mr.Mirko is absolutely GREAT!!! I appreciate very much the work and effort he puts into this project.
Of couse your screen is bad,

you are switching to a framebuffer, clearing it, and then draw the sprites.
This is not good.

Try this:

clear frambuffer 1
draw to framebuffer 1
switch to framebuffer1

clear fraqmebuffer 2
draw to framebuffer 2
switch to framebuffer 2

check you swap_screen(); function...
 
Last edited by a moderator:
Hmm, the same thing sometimes happens to me and I am quite sure the swapping order is okay. The reason seem to be connected with the CPU speed. If the problem persists, try chagning the CPU speed or use the whole screen, eg. draw a fullscreen background that you flip in each program loop.
It has never happened to me when I leave the speed as it is default, only when I lower it and then the fullscreen image solves it.
 
Hmm, the same thing sometimes happens to me and I am quite sure the swapping order is okay. The reason seem to be connected with the CPU speed. If the problem persists, try chagning the CPU speed or use the whole screen, eg. draw a fullscreen background that you flip in each program loop.
It has never happened to me when I leave the speed as it is default, only when I lower it and then the fullscreen image solves it.
The cpu speed has bothing to do with errors on a correct working double buffering:

I use this code:

Code:
char swapper=0;
void swap_screen () {
   gp_setFramebuffer(framebuffer[swapper],1);  // wait for vsync
   swapper++; if (swapper == 2) swapper=0;
}

 while (1) {

  swap_screen();  // swapper is now pointing to the not visible screen

    gp_clearFramebuffer16(framebuffer[swapper],0xffff); // clearing not visible screen

    gp_drawSpriteHT (     test,100, 10, framebuffer[swapper], 0xFFFE ); // draw sprite on not visible screen
  if (gp_getButton()&BUTTON_A) gp_Reset();
 }

}

It runs on all CPU clock rates...
 
Last edited by a moderator:
Your problem is not a clockspeed issue. GP32 is fast enough to output all these sprites on screen without problems. I'm pretty sure it has something to do with your backscreen as stated by Mr. Mirko.

And just a little note: why don't you use 2 nested for loops instead of your difficult to read single for loop?

Here is a nicer solution for your loop (it doesn't correct the problem anyway :rolleyes: )

Code:
for (i=0; i<INVADERLINES; i++)
  for (j=0; j<8; j++)
    gp_drawSprite ( &invader20Sprite, invaders[i][j].x, invaders[i][j].y, framebuffer[nflip], INVADERWIDTH, INVADERHEIGHT );
 
@mr.mirko: Thanks mate! I'll try this as soon as I have time to continue to work on my little project (that will be tomorrow). Could have been that I'm mixing things up when to paint what. I'll let you know about my success.

@Oankali: I've read some articles concerning code optimization and they said that a kind of strategy could be the code "loop-unrolling". That means that the loops should be simpler and avoid nested loops. As I thought that my code had a timing problem I've tried everything which could speed it up.

I don't know if gcc does this kind of optimization on its own. But just in case it doesn't I wrote it this way. BTW: before I changed my code into that not so nice to read one I had it exactly the way you suggest :)
 
@Oankali: I've read some articles concerning code optimization and they said that a kind of strategy could be the code "loop-unrolling". That means that the loops should be simpler and avoid nested loops. As I thought that my code had a timing problem I've tried everything which could speed it up.
Isn't that what the gcc options "-funroll-loops" and "-floop-optimize" are for?

Greetings,
SvOlli
 
Last edited by a moderator:
@mr.mirko: Thanks again! Your suggestion that my swap_screen() function didn't do the right things was correct. In fact I painted to a visible screenbuffer. I corrected this and are now working on the collision detectio (hard job, for me) ;) Thank you for your time and effort!

@SvOlli: As I'm a noviced C programmer I don't know that much of compiler optimization options. I've tried -floop-optimize yesterday and couldn't compile the project. But probably I'll get into this kind of stuff in some days when I've the time...
 
Back
Top