shithub: riscv

Download patch

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();
 }