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)
This commit is contained in:
cinap_lenrek 2014-04-14 20:44:04 +02:00
parent 96a94c3891
commit 81545f346f
2 changed files with 31 additions and 21 deletions

View file

@ -8,7 +8,7 @@ int ppux, ppuy, rx;
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 @@ pixeldraw(int x, int y, u16int v)
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;
}
}

View file

@ -179,7 +179,7 @@ screeninit(void)
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 @@ usage:
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 @@ flush(void)
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();
}