craigix
Mega GP Mania
I think the best way, after reading this interesting thread, would be to work on the core in a thread just like this, I think it would provide the best optimised code as the work went on with everyone chipping in ideas.
void gp2x_blitter_rect15(gp2x_rect *r)
{
int x, y; unsigned short *data=(unsigned short *)r->data, *offset=&gp2x_video_RGB[0].screen16[r->x+r->y*320];
x=r->w, y=r->h; if(r->solid)
while(y--) { while(x--) *offset++=*data++; offset+=320-(x=r->w); }
else
while(y--) { while(x--) { if(*data) *offset=*data; offset++, data++; }
offset+=320-(x=r->w); }
}
void gp2x_blitter_rect15(gp2x_rect *r) {
// TODO - Maybe some clip checking??
// Does making two variables, woffset, and xblock work better than calculating them in the loop?
unsigned short *data=(unsigned short *)r->data, *offset=&gp2x_video_RGB[0].screen16[r->x+r->y*320];
unsigned int x = r->w, y=r->h, woffset = 320 - x, xblock = sizeof(unsigned short) * x;
// if its solid, Do the loop...
if (r->solid) while(y--) { // this could be...... while ((r->solid) && (y--)) { ?
//old method.. while(x--) *offset++=*data++;
//Scanline method... TODO - use ASM memcpy.
memcpy(offset,data, xblock);
offset += woffset;
}
// not solid, do this. If it WAS solid, Y would == 0 and not run =) This is to remove a branch.
while(y--) {
while(x--) {
if(*data) *offset=*data;
++offset, ++data;
}
offset += woffset;
}
}
Squidge posted on Aug 10 2006 at 11:07 PM said:Another great optimisation, but unfortunately for a function that isn't actually called in SquidgeSNES...
line 1369: minimal.c
#ifdef NEW_DUALPAUSE
inline void gp2x_dualcore_pause() { gp2x_memregs[0x0904>>1] &= 0xFFFE; }
inline void gp2x_dualcore_unpause() { gp2x_memregs[0x0904>>1] |= 1; }
#else
void gp2x_dualcore_pause(int yes) { if(yes) gp2x_memregs[0x0904>>1] &= 0xFFFE; else gp2x_memregs[0x0904>>1] |= 1; }
#endif
line 1430: minimal.c
#ifdef NEW_DUALPAUSE
gp2x_940t_unpause();
#else
gp2x_940t_pause(0);
#endif
line 1871: minimal.c
//If statements can be faster if case's are not linear.
if (buffer[c] == '\b') {
g->x = x; g->y = y;
} else if (buffer[c] == '\n') {
g->y += g->h;
//previous code ran "default" here too.. is it needed?
} else if (buffer[c] == '\r') {
g->x = x;
} else {
gp2x_printfchar(g, (unsigned char)buffer[c]);
g->x += g->w;
}
line 175: minimal.c
#ifdef USE_UNSATURATE
#define UNSATURATE asm volatile ("nop"); \
asm volatile ("nop"); \
asm volatile ("nop"); \
asm volatile ("nop");
#else
#define UNSATURATE
#endif
inline void gp2x_video_waitvsync(void)
{
while(gp2x_memregs[0x1182>>1]&(1<<4)) { UNSATURATE };
}
/* Function: gp2x_video_waithsync
This function halts the program until an horizontal sync is done.
See also:
<gp2x_video_waitvsync> */
inline void gp2x_video_waithsync(void)
{
while(gp2x_memregs[0x1182>>1]&(1<<5)) { UNSATURATE };
}