From 81545f346f985241083062f73d45e9426d519ba8 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 14 Apr 2014 20:44:04 +0200 Subject: [PATCH] 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) --- sys/src/games/snes/ppu.c | 27 ++++++++++----------------- sys/src/games/snes/snes.c | 25 +++++++++++++++++++++---- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/sys/src/games/snes/ppu.c b/sys/src/games/snes/ppu.c index 1f2175a49..eb0d222f6 100644 --- a/sys/src/games/snes/ppu.c +++ b/sys/src/games/snes/ppu.c @@ -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; } } diff --git a/sys/src/games/snes/snes.c b/sys/src/games/snes/snes.c index 230622876..303139f92 100644 --- a/sys/src/games/snes/snes.c +++ b/sys/src/games/snes/snes.c @@ -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(); }