GP2X Squidgesnes_0.37 Code Comments


cxzuk

Still Fresh
Joined
Aug 4, 2006
Messages
34
Hi all,

Was reading squidgesnes_0.37mmu source code. Just thought id post a thread here so people can read my comments and maybe see if they help improve?

Math improvements:

Code:
void drawRect (unsigned short *vram, int x, int y, int w, int h)
{
   for (int y1 = y; y1 < y+h; y1 ++)
	  for (int x1 = x; x1 < x+w; x1 ++)
		 vram[(y1*320)+x1] ^= 0xFFFF;
}

I know this change would provide a marginal (possible) improvement. But would it not be more efficient working out y1*320 in the y1 loop?

Code:
void drawRect (unsigned short *vram, int x, int y, int w, int h) 
{
   for (int y1 = y, y2 = y1 * 320; y1 < y+h; y1 ++)
	  for (int x1 = x; x1 < x+w; x1 ++)
		 vram[y2+x1] ^= 0xFFFF;
}

---

Code:
void blankscreen (void)
{
	int x,y;	
	for (y = 0; y < 240; y ++)
		for (x = 0; x < 320; x ++)
			gp2x_video_RGB[0].screen16[(y*320)+x] = 0;
	gp2x_video_RGB_flip(0);
	for (y = 0; y < 240; y ++)
		for (x = 0; x < 320; x ++)
			gp2x_video_RGB[0].screen16[(y*320)+x] = 0;
	gp2x_video_RGB_flip(0);
}

This bit seems to be a repeat? I think its due to the double buffering? Could we not do...

Code:
void blankscreen (void)
{
  unsigned int xy = 240*320;
  //memset(gp2x_video_RGB[0].screen16, 0, xy); Use ZeroMemory as snes9x complient?
  ZeroMemory(gp2x_video_RGB[0].screen16, xy);
  gp2x_video_RGB_flip(0);

  // Is it needed?
  ZeroMemory(gp2x_video_RGB[0].screen16, xy);
  gp2x_video_RGB_flip(0);
}

---

Code:
void drawbackground (void)
{
  int i=0;
  // draw the background image onto both buffers if possible
  if (!gamebg) return;
  if (local_mr.wantscale) return;
	
  unsigned short *dstpix;
  unsigned char *pix;
	
  for (i=0;i<4;i++)
  {
	dstpix = gp2x_video_RGB[0].screen16;
	pix = gamebg->getPixels();
	
	for (int yy = 0; yy < 240; yy ++) 
	for (int xx = 0; xx < 320; xx ++)
	{
	  unsigned char r, g, b;
	  unsigned short p;

	  r = pix[(yy*(320*3))+(xx*3)+0];
	  g = pix[(yy*(320*3))+(xx*3)+1];
	  b = pix[(yy*(320*3))+(xx*3)+2];

	  r /= 8;
	  g /= 4;
	  b /= 8;

	  r &= 31;
	  g &= 63;
	  b &= 31;

	  p = (b << 11 ) | (g << 5) | (r);
	  *dstpix++ = p;
	}
	gp2x_video_RGB_flip(0);
  }	
}

Just a few things on this one... again some of the math and declairation could be moved out of the loop?

Code:
for (int xx = 0, pos = (yy*(320*3))+(xx*3)); xx < 320; xx ++)

then

Code:
	  r = pix[pos+0];
	  g = pix[pos+1];
	  b = pix[pos+2];

Also, with your color conversion could you not do..

Code:
  // bit shifting tends to be faster, but remove's rounding (which ur &= bits did anyway)
  r >>= 4;
  g >>= 3;
  b >>= 4;

#ifdef SAFE
  // this bit isn't needed as a char can only hold a number upto 255. 
  r &= 31;
  g &= 63;
  b &= 31;
#endif

a more improtant comment.. Your loop runs 4 times? (i=0, i=1, i=2, i=3)

Code:
for (i=0;i<4;i++)

should this not be set to 2?

Code:
void drawbackground (void)
{
  int i=0;
  // draw the background image onto both buffers if possible
  if (!gamebg) return;
  if (local_mr.wantscale) return;
	
  unsigned short *dstpix;
  unsigned char *pix;

  unsigned char r, g, b;
  unsigned short p;

  pix = gamebg->getPixels();
	
  for (i=0;i<[b]2[/b];i++)
  {
	dstpix = gp2x_video_RGB[0].screen16;
	
	for (int yy = 0, [b]ty = (yy*(320*3))[/b]; yy < 240; yy ++) for (int xx = 0, [b]pos = (ty+(xx*3))[/b]; xx < 320; xx ++)
	{

[b]	  r = pix[pos+0] >> 4;
	  g = pix[pos+1] >> 3;
	  b = pix[pos+2] >> 4;

#ifdef SAFE
	  r &= 31;
	  g &= 63;
	  b &= 31;
#endif
[/b]
	  p = (b << 11 ) | (g << 5) | (r);
	  *dstpix++ = p;
	}
	gp2x_video_RGB_flip(0);
  }	
}

---

On another note, What exactly does C4.cpp and C4emu.cpp do? - I think its something to do with special effects processing..

I would reckon that if you replace the sin and cos in c4.cpp with a lookup table, that would improve speed on that too... c4emu.cpp already has a sin and cos lookup table so would be simple (and silly not to) do this.

At a guess, i would say that this would improve mode7 functions.

---

Ok ill keep reading on, and will post anything interesting. great code so far tho!

If someone could tell me the most important parts, and possibly slowest.. Ill have a crack at 'em =)

Mike
 
Those changes seem to make sence to me, although trying them will be the best way forward, sometimes other things are happening which you don't notice until testing.

Also putting in notaz's ARM ASM sound core would give another good boost, although he might be doing that himself.
 
craigix posted on Aug 6 2006 at 06:36 PM said:
Also putting in notaz's ARM ASM sound core would give another good boost, although he might be doing that himself.

I doubt that, Notaz doesn't have a GP2X he is a PPC/Symbian dev. He just came here to share the Cyclone fixes and sound core.
 
Last edited by a moderator:
These are good observations; the emulator definitely still has a lot of optimization that can be done (it wasn't built from the ground up, so that makes sense if it's not perfectly optimized for the GP2X hardware. Have you recompiled this yet to see if you found any significant performance benefit? Maybe you'll save a frame or two. Or something more dramatic, who knows. DrawBackground() and Blankscreen() probably run every frame.

I also noticed the loops are run in the wrong direction for maximum optimization compiled for an ARM9.

e.g. in this simple loop ..
Code:
for (i=0;i<4;i++)

It should really read:
Code:
for (i=3;i>=0;i--)

Note the loop starts at its goal value and decrements down rather than incrementing up. This compiles down to less machine instructions. There's a whole PDF floating around with optimizations like that, very useful little doc.
 
How about setting up a cvs and letting evryone who wants contribute?
I gues thet would be the fastest way to get as many optimisations as possible.
 
DaveC posted on Aug 6 2006 at 07:49 PM said:
craigix posted on Aug 6 2006 at 06:36 PM said:
Also putting in notaz's ARM ASM sound core would give another good boost, although he might be doing that himself.

I doubt that, Notaz doesn't have a GP2X he is a PPC/Symbian dev. He just came here to share the Cyclone fixes and sound core.

Check your inbox.
 
Last edited by a moderator:
craigix posted on Aug 6 2006 at 01:36 PM said:
Those changes seem to make sence to me, although trying them will be the best way forward, sometimes other things are happening which you don't notice until testing.

Also putting in notaz's ARM ASM sound core would give another good boost, although he might be doing that himself.

Probably the biggest benefit right now would come from rewriting most, of not all, of the graphics handling code in ASM. The SNES' CPU is very anemic and not difficult to emulate. It's VDPs however, are quite complex and are the real burden for any emulator. Although ASM sound emulation can't hurt either-- though I don't know if it would really benefit most games too much if they don't heavily use generated FM waves, and not just play back a lot of prerecorded samples.
 
Last edited by a moderator:
I have noticed that the code is still very generic, i dont know if this is because its going to be re-entered into the snes9x code.. or just for ease but could be much better for an overall improvement.

Changing the sin and cos in c4.cpp to a look up table i believe would improve the mode7 stuff (mario kart) but im unable to test as i dont have a gp2x yet =(

will post a patch here with the changes if someone is willing to try it out?

Mike
 
why wasnt it released to the public(was it?)? any bigger issues with it?
cxzuk im sure would like to, if i can get it to compile.
 
cxzuk: Some nice optimizations there. However, those functions are only ever called when the menu is on the screen, which is why I didn't really care how long they took to execute (ie. Who cares if the menu runs at 10fps or 60fps when it only changes when you move the selection bar with your joystick?)

As for C4.cpp and c4emu.cpp, those handle the SNES's C4 co-processor present in some game cartridges. The C4 chip is the base of Mega Man X2 and 3 among some other popular SNES games. It was designed by Capcom. I don't think it's used in Mario Cart, that used a DSP chip.

If you want to look at code that would make a big improvement if optimized, look at gfx.cpp, tile.cpp & ppu.cpp
 
I found the source code. It is here. And apparently 0.37 is not Reesy's, its Pepone's.
 
Last edited by a moderator:
Vimacs posted on Aug 6 2006 at 01:01 PM said:
How about setting up a cvs and letting evryone who wants contribute?
I gues thet would be the fastest way to get as many optimisations as possible.

I liked that idea, so here:

http://svn.mudiweb.com/ssnes

It requires username/password for write access... anyone who has previously worked on SquidgeSNES can PM me for a username/password, others I don't know, I guess we can figure that out

As of writing here, it's exactly the same as the source zip file.
 
Last edited by a moderator:
Hi all again,

Looked at DSP1emu.c

Code:
[b]__inline[/b] double Atan(double x)
{
	if ((x>=1) || (x<=1)) 
		return (x/(1+0.28*x*x));
	else
		return (PI/2 - Atan(1/x));
}

atan() is only ever called once, and would prolly benefit being inline or even a lookup table like sin and cos.

on the subject of the sin/cos lookup tables..

Code:
#define Cos(x) ((double) CosTable2[x])
#define Sin(x) ((double) SinTable2[x])

they are defined as "Cos" and "Sin"..

I notice that some of the code uses "cos" and "sin", which uses the math sin and cos???

Code:
   ViewerZ1=-cos(Op02AZS*6.2832/65536.0);
   ViewerX1=sin(Op02AZS*6.2832/65536.0)*sin(Op02AAS*6.2832/65536.0);
   ViewerY1=sin(Op02AZS*6.2832/65536.0)*cos(-Op02AAS*6.2832/65536.0);

could we convert them to use the lookup tables?

---

Love CVS, but a thread is the best way to throw ideas around =)

Mike
 
Squidge posted on Aug 6 2006 at 10:46 PM said:
cxzuk: Some nice optimizations there. However, those functions are only ever called when the menu is on the screen, which is why I didn't really care how long they took to execute (ie. Who cares if the menu runs at 10fps or 60fps when it only changes when you move the selection bar with your joystick?)

Has anyone got a profiler running on the GP2X?

This is an example of another of those 80:20 rules - 80% of the processing is done in 20% of the code so most of the time random optimisations are to the 80% and will make no significant difference. You really need a profiler to identify the true bottlenecks.
 
Last edited by a moderator:
Well, I've got no profiler, but stopping the graphics routines from running increased the frame rate by about 40 - 60 fps :)
 
How expensive is the '%' operator on the GP2X?
Also, can we use gprof for GP2X executables?
 
Hi Squidge (or anyone),

If you could compile the code with the -pg flag, it will create a file called "gmon.out" in the working directory at exit.

E.g So you might want to add chdir("") where the program exits.

Run the program as normal, play a game or two, then exit. (it will be slow running)

If you dont have gprof then post it back here, ill decode the file and post back the report in readable.

P.s I know many people have problems with gprof, but its better than nothing.

Mike
 
Back
Top