ref: 81545f346f985241083062f73d45e9426d519ba8
parent: 96a94c38917bf52c17cc1a280cbb672f4d1d13d3
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Apr 14 16:44:04 EDT 2014
games/snes: faster scaling load x-stretched scanline and use image replication bit to let devdraw do the y-stretching. this reduces slow RGB15 -> display conversions as devdraw caches small numbers of converted source scanlines (one in hour case). setting pixels should also be a bit faster. (only 3 writes instead of 9 for x3 scaling)
--- a/sys/src/games/snes/ppu.c
+++ b/sys/src/games/snes/ppu.c
@@ -8,7 +8,7 @@
static u8int mode, bright, pixelpri[2];
static u32int pixelcol[2];
u16int vtime = 0x1ff, htime = 0x1ff, subcolor;
-uchar pic[256*239*2*9];
+uchar pic[256*239*2*3];
u16int hofs[5], vofs[5];
s16int m7[6];
@@ -43,33 +43,26 @@
uchar *p;
u16int *q;
union { u16int w; u8int b[2]; } u;
- int i;
if(bright != 0xf)
v = darken(v);
if(scale == 1){
p = pic + (x + y * 256) * 2;
- *p++ = v;
- *p = v >> 8;
+ p[0] = v;
+ p[1] = v >> 8;
return;
}
u.b[0] = v;
u.b[1] = v >> 8;
if(scale == 2){
- q = (u16int*)pic + (x + y * 256 * 2) * 2;
- *q++ = u.w;
- *q = u.w;
- q += 256 * 2 - 1;
- *q++ = u.w;
- *q = u.w;
+ q = (u16int*)pic + (x + y * 256) * 2;
+ q[0] = u.w;
+ q[1] = u.w;
}else{
- q = (u16int*)pic + (x + y * 256 * 3) * 3;
- for(i = 0; i < 3; i++){
- *q++ = u.w;
- *q++ = u.w;
- *q = u.w;
- q += 256 * 3 - 2;
- }
+ q = (u16int*)pic + (x + y * 256) * 3;
+ q[0] = u.w;
+ q[1] = u.w;
+ q[2] = u.w;
}
}
--- a/sys/src/games/snes/snes.c
+++ b/sys/src/games/snes/snes.c
@@ -179,7 +179,7 @@
originwindow(screen, Pt(0, 0), screen->r.min);
p = divpt(addpt(screen->r.min, screen->r.max), 2);
picr = (Rectangle){subpt(p, Pt(scale * 128, scale * 112)), addpt(p, Pt(scale * 128, scale * 112))};
- tmp = allocimage(display, Rect(0, 0, scale * 256, scale * 239), RGB15, 0, 0);
+ tmp = allocimage(display, Rect(0, 0, scale * 256, scale > 1 ? 1 : scale * 239), RGB15, scale > 1, 0);
bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
draw(screen, screen->r, bg, nil, ZP);
}
@@ -314,7 +314,7 @@
void
flush(void)
{
- extern uchar pic[256*240*2*9];
+ extern uchar pic[256*240*2*3];
Mouse m;
Point p;
@@ -336,8 +336,25 @@
if((m.buttons & 2) != 0)
lastkeys = keys;
}
- loadimage(tmp, tmp->r, pic, 256*239*2*scale*scale);
- draw(screen, picr, tmp, nil, ZP);
+ if(scale == 1){
+ loadimage(tmp, tmp->r, pic, 256*239*2);
+ draw(screen, picr, tmp, nil, ZP);
+ } else {
+ Rectangle r;
+ uchar *s;
+ int w;
+
+ s = pic;
+ r = picr;
+ w = 256*2*scale;
+ while(r.min.y < picr.max.y){
+ loadimage(tmp, tmp->r, s, w);
+ s += w;
+ r.max.y = r.min.y+scale;
+ draw(screen, r, tmp, nil, ZP);
+ r.min.y = r.max.y;
+ }
+ }
flushimage(display, 1);
audioout();
}