ref: 6d53af9408f199aea5c2440cb23f2467359d0c25
parent: b7e11e6c459c75585be93fbb4823a13591c08e65
author: qwx <qwx@sciops.net>
date: Tue Aug 5 05:38:16 EDT 2025
eui: handle screen scaling ourselves
--- a/sys/src/games/2600/tia.c
+++ b/sys/src/games/2600/tia.c
@@ -51,25 +51,8 @@
u.c[1] = c >> 8;
u.c[2] = c >> 16;
u.c[3] = 0xff;
- p = (u32int *)pic + ppuy * PICW * scale + ppux * 2 * scale;
- switch(scale){
- case 16: *p++ = u.l; *p++ = u.l;
- case 15: *p++ = u.l; *p++ = u.l;
- case 14: *p++ = u.l; *p++ = u.l;
- case 13: *p++ = u.l; *p++ = u.l;
- case 12: *p++ = u.l; *p++ = u.l;
- case 11: *p++ = u.l; *p++ = u.l;
- case 10: *p++ = u.l; *p++ = u.l;
- case 9: *p++ = u.l; *p++ = u.l;
- case 8: *p++ = u.l; *p++ = u.l;
- case 7: *p++ = u.l; *p++ = u.l;
- case 6: *p++ = u.l; *p++ = u.l;
- case 5: *p++ = u.l; *p++ = u.l;
- case 4: *p++ = u.l; *p++ = u.l;
- case 3: *p++ = u.l; *p++ = u.l;
- case 2: *p++ = u.l; *p++ = u.l;
- default: *p++ = u.l; *p = u.l;
- }
+ p = (u32int *)pic + ppuy * PICW + ppux * 2;
+ p[0] = p[1] = u.l;
}
static void
--- a/sys/src/games/c64/vic.c
+++ b/sys/src/games/c64/vic.c
@@ -100,7 +100,7 @@
u8int c;
u32int *q;
- q = (u32int *)pic + picidx * scale;
+ q = (u32int *)pic + picidx;
for(i = 0; i < n; i++){
c = p >> 56;
p <<= 8;
@@ -108,24 +108,7 @@
u.c[1] = cg[c];
u.c[2] = cr[c];
u.c[3] = 0;
- switch(scale){
- case 16: *q++ = u.l;
- case 15: *q++ = u.l;
- case 14: *q++ = u.l;
- case 13: *q++ = u.l;
- case 12: *q++ = u.l;
- case 11: *q++ = u.l;
- case 10: *q++ = u.l;
- case 9: *q++ = u.l;
- case 8: *q++ = u.l;
- case 7: *q++ = u.l;
- case 6: *q++ = u.l;
- case 5: *q++ = u.l;
- case 4: *q++ = u.l;
- case 3: *q++ = u.l;
- case 2: *q++ = u.l;
- default: *q++ = u.l;
- }
+ *q++ = u.l;
}
picidx += n;
}
--- a/sys/src/games/eui.c
+++ b/sys/src/games/eui.c
@@ -23,7 +23,7 @@
static ulong vwchan;
static Image *fb;
static Channel *conv, *sync[2];
-static uchar *screenconv[2];
+static uchar *screenconv[2], *backfb;
static int screenconvi;
struct Kfn{
@@ -48,6 +48,16 @@
return v;
}
+Image *
+eallocimage(Rectangle r, ulong chan, int repl, ulong col)
+{
+ Image *i;
+
+ if((i = allocimage(display, r, chan, repl, col)) == nil)
+ sysfatal("allocimage: %r");
+ return i;
+}
+
static void
joyproc(void *)
{
@@ -206,14 +216,13 @@
picr = Rpt(subpt(p, Pt(scale * vwdx/2, scale * vwdy/2)),
addpt(p, Pt(scale * vwdx/2, scale * vwdy/2)));
freeimage(fb);
- fb = allocimage(display, Rect(0, 0, scale * vwdx, scale > 1 ? 1 : scale * vwdy),
+ fb = eallocimage(Rect(0, 0, scale * vwdx, scale > 1 ? 1 : vwdy),
vwchan, scale > 1, 0);
- free(pic);
- pic = emalloc(vwdx * vwdy * vwbpp * scale);
- free(screenconv[0]);
- free(screenconv[1]);
- screenconv[0] = emalloc(vwdx * vwdy * vwbpp * scale);
- screenconv[1] = emalloc(vwdx * vwdy * vwbpp * scale);
+ free(backfb);
+ if(scale > 1)
+ backfb = emalloc(vwdx * vwbpp * scale);
+ else
+ backfb = nil;
draw(screen, screen->r, bg, nil, ZP);
recv(sync[1], nil);
}
@@ -254,15 +263,44 @@
draw(screen, picr, fb, nil, ZP);
} else {
Rectangle r;
- uchar *s;
- int w;
-
- s = p;
+ int w, x;
+
r = picr;
w = vwdx * vwbpp * scale;
while(r.min.y < picr.max.y){
- loadimage(fb, fb->r, s, w);
- s += w;
+ switch(vwbpp){
+ case 4: {
+ u32int *d = (u32int *)backfb, *e, s;
+ for(x=0; x<vwdx; x++){
+ s = *(u32int *)p;
+ p += vwbpp;
+ e = d + scale;
+ while(d < e)
+ *d++ = s;
+ }
+ break;
+ } case 2: {
+ u16int *d = (u16int *)backfb, *e, s;
+ for(x=0; x<vwdx; x++){
+ s = *(u16int *)p;
+ p += vwbpp;
+ e = d + scale;
+ while(d < e)
+ *d++ = s;
+ }
+ break;
+ } case 1: {
+ u8int *d = (u8int *)backfb, *e, s;
+ for(x=0; x<vwdx; x++){
+ s = *(u8int *)p;
+ p += vwbpp;
+ e = d + scale;
+ while(d < e)
+ *d++ = s;
+ }
+ break;
+ }}
+ loadimage(fb, fb->r, backfb, w);
r.max.y = r.min.y+scale;
draw(screen, r, fb, nil, ZP);
r.min.y = r.max.y;
@@ -286,7 +324,7 @@
void
flushscreen(void)
{
- memmove(screenconv[screenconvi], pic, vwdx * vwdy * vwbpp * scale);
+ memmove(screenconv[screenconvi], pic, vwdx * vwdy * vwbpp);
if(sendp(conv, screenconv[screenconvi]) > 0)
screenconvi = (screenconvi + 1) % 2;
if(profile)
@@ -365,11 +403,14 @@
proccreate(kproc != nil ? kproc : keyproc, nil, mainstacksize);
if(kproc == nil)
proccreate(joyproc, nil, mainstacksize);
- bg = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
+ bg = eallocimage(Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
scale = fixscale;
conv = chancreate(sizeof(uchar*), 0);
sync[0] = chancreate(1, 0);
sync[1] = chancreate(1, 0);
proccreate(screenproc, nil, mainstacksize);
+ pic = emalloc(vwdx * vwdy * vwbpp);
+ screenconv[0] = emalloc(vwdx * vwdy * vwbpp);
+ screenconv[1] = emalloc(vwdx * vwdy * vwbpp);
screeninit();
}
--- a/sys/src/games/gb/ppu.c
+++ b/sys/src/games/gb/ppu.c
@@ -63,7 +63,7 @@
}
ppux = 0;
ppux0 = 0;
- picp = (u32int*)pic + ppuy * PICW * scale;
+ picp = (u32int*)pic + ppuy * PICW;
y = ppuy + reg[SCY] << 1 & 14;
ta = 0x1800 | reg[LCDC] << 7 & 0x400 | ppuy + reg[SCY] << 2 & 0x3e0 | reg[SCX] >> 3;
x = -(reg[SCX] & 7);
@@ -197,7 +197,7 @@
int x, x1;
u16int chr;
- picp = (u32int*)pic + ppuy * PICW * scale;
+ picp = (u32int*)pic + ppuy * PICW;
for(q = spr; q < sprm; q++){
if(q->x <= ppux0 || q->x >= ppux + 8)
continue;
@@ -251,38 +251,6 @@
return t*2;
}
-static void
-lineexpand(void)
-{
- u32int *picp, *p, *q, l;
- int i;
-
- picp = (u32int*)pic + ppuy * PICW * scale;
- p = picp + PICW;
- q = picp + PICW * scale;
- for(i = PICW; --i >= 0; ){
- l = *--p;
- switch(scale){
- case 16: *--q = l;
- case 15: *--q = l;
- case 14: *--q = l;
- case 13: *--q = l;
- case 12: *--q = l;
- case 11: *--q = l;
- case 10: *--q = l;
- case 9: *--q = l;
- case 8: *--q = l;
- case 7: *--q = l;
- case 6: *--q = l;
- case 5: *--q = l;
- case 4: *--q = l;
- case 3: *--q = l;
- case 2: *--q = l;
- case 1: *--q = l;
- }
- }
-}
-
void
hblanktick(void *)
{
@@ -336,8 +304,6 @@
ppusync();
if(!done) print("not done?!\n");
done = 0;
- if(scale > 1)
- lineexpand();
ppustate = 0;
if((reg[STAT] & IRQM0) != 0)
reg[IF] |= IRQLCDS;
--- a/sys/src/games/gba/ppu.c
+++ b/sys/src/games/gba/ppu.c
@@ -699,7 +699,7 @@
union { u16int w; u8int b[2]; } u;
int n;
- q = pic + y * 240 * 2 * scale;
+ q = pic + y * 240 * 2;
r = (u16int*)q;
n = 240;
while(n--){
@@ -706,24 +706,7 @@
v = *p++;
u.b[0] = v;
u.b[1] = v >> 8;
- switch(scale){
- case 16: *r++ = u.w;
- case 15: *r++ = u.w;
- case 14: *r++ = u.w;
- case 13: *r++ = u.w;
- case 12: *r++ = u.w;
- case 11: *r++ = u.w;
- case 10: *r++ = u.w;
- case 9: *r++ = u.w;
- case 8: *r++ = u.w;
- case 7: *r++ = u.w;
- case 6: *r++ = u.w;
- case 5: *r++ = u.w;
- case 4: *r++ = u.w;
- case 3: *r++ = u.w;
- case 2: *r++ = u.w;
- default: *r++ = u.w;
- }
+ *r++ = u.w;
}
}
--- a/sys/src/games/md/vdp.c
+++ b/sys/src/games/md/vdp.c
@@ -32,29 +32,11 @@
u32int *p;
union { u32int l; u8int b[4]; } u;
- p = (u32int *)pic + (x + y * 320) * scale;
u.b[0] = v >> 16;
u.b[1] = v >> 8;
u.b[2] = v;
u.b[3] = 0;
- switch(scale){
- case 16: *p++ = u.l;
- case 15: *p++ = u.l;
- case 14: *p++ = u.l;
- case 13: *p++ = u.l;
- case 12: *p++ = u.l;
- case 11: *p++ = u.l;
- case 10: *p++ = u.l;
- case 9: *p++ = u.l;
- case 8: *p++ = u.l;
- case 7: *p++ = u.l;
- case 6: *p++ = u.l;
- case 5: *p++ = u.l;
- case 4: *p++ = u.l;
- case 3: *p++ = u.l;
- case 2: *p++ = u.l; /* intla ignored */
- default: *p = u.l;
- }
+ *((u32int *)pic + (x + y * 320)) = u.l;
}
static u32int
--- a/sys/src/games/nes/ppu.c
+++ b/sys/src/games/nes/ppu.c
@@ -13,7 +13,6 @@
pixel(int x, int y, int val, int back)
{
union { u8int c[4]; u32int l; } u;
- u32int *p;
static u8int palred[64] = {
0x7C, 0x00, 0x00, 0x44, 0x94, 0xA8, 0xA8, 0x88,
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -49,31 +48,13 @@
u.c[1] = palgreen[val];
u.c[2] = palred[val];
u.c[3] = back ? 0 : 0xFF;
- p = (u32int *)pic + y * 256 * scale + x * scale;
- switch(scale){
- case 16: *p++ = u.l;
- case 15: *p++ = u.l;
- case 14: *p++ = u.l;
- case 13: *p++ = u.l;
- case 12: *p++ = u.l;
- case 11: *p++ = u.l;
- case 10: *p++ = u.l;
- case 9: *p++ = u.l;
- case 8: *p++ = u.l;
- case 7: *p++ = u.l;
- case 6: *p++ = u.l;
- case 5: *p++ = u.l;
- case 4: *p++ = u.l;
- case 3: *p++ = u.l;
- case 2: *p++ = u.l;
- default: *p = u.l;
- }
+ *((u32int *)pic + y * 256 + x) = u.l;
}
static int
iscolor(int x, int y)
{
- return pic[(scale * 4) * (y * 256 + x) + 3] != 0;
+ return pic[4 * (y * 256 + x) + 3] != 0;
}
static int
--- a/sys/src/games/snes/ppu.c
+++ b/sys/src/games/snes/ppu.c
@@ -40,32 +40,13 @@
static void
pixeldraw(int x, int y, u16int v, int s)
{
- u16int *p;
union { u16int w; u8int b[2]; } u;
if(bright != 0xf && s >= 0)
v = darken(v);
- p = (u16int *)pic + (x + y * 256) * scale;
u.b[0] = v;
u.b[1] = v >> 8;
- switch(scale){
- case 16: *p++ = u.w;
- case 15: *p++ = u.w;
- case 14: *p++ = u.w;
- case 13: *p++ = u.w;
- case 12: *p++ = u.w;
- case 11: *p++ = u.w;
- case 10: *p++ = u.w;
- case 9: *p++ = u.w;
- case 8: *p++ = u.w;
- case 7: *p++ = u.w;
- case 6: *p++ = u.w;
- case 5: *p++ = u.w;
- case 4: *p++ = u.w;
- case 3: *p++ = u.w;
- case 2: if(s < 1) *p++ = u.w;
- default: *p = u.w;
- }
+ *((u16int *)pic + (x + y * 256)) = u.w;
}
static int
--
⑨