]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/games/nes/ppu.c
demote libemu to common code
[plan9front.git] / sys / src / games / nes / ppu.c
index cb1e7b7a094043d05ac125a9e4bb0f9312334ecd..0f7010198b6112111337105a8509c5be09b8e465 100644 (file)
@@ -2,19 +2,18 @@
 #include <libc.h>
 #include <thread.h>
 #include <draw.h>
+#include <mouse.h>
+#include "../eui.h"
 #include "dat.h"
 #include "fns.h"
 
-int ppuy, ppux;
-uchar pic[256*240*4*9];
-extern uchar oam[256];
+int ppuy, ppux, odd;
 
 static void
 pixel(int x, int y, int val, int back)
 {
-       int Y;
        union { u8int c[4]; u32int l; } u;
-       u32int *p, l;
+       u32int *p;
        static u8int palred[64] = {
                0x7C, 0x00, 0x00, 0x44, 0x94, 0xA8, 0xA8, 0x88, 
                0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
@@ -50,32 +49,31 @@ pixel(int x, int y, int val, int back)
        u.c[1] = palgreen[val];
        u.c[2] = palred[val];
        u.c[3] = back ? 0 : 0xFF;
-       l = u.l;
-       if(scale == 3){
-               p = ((u32int*)pic) + y * 3 * 3 * 256 + 3 * x;
-               for(Y = 0; Y < 3; Y++){
-                       *p++ = l;
-                       *p++ = l;
-                       *p = l;
-                       p += 3 * 256 - 2;
-               }
-       }else if(scale == 2){
-               p = ((u32int*)pic) + y * 2 * 2 * 256 + 2 * x;
-               *p++ = l;
-               *p = l;
-               p += 2 * 256 - 1;
-               *p++ = l;
-               *p = l;
-       }else{
-               p = ((u32int*)pic) + y * 256 + x;
-               *p = l;
+       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;
        }
 }
 
 static int
 iscolor(int x, int y)
 {
-       return pic[y * scale * scale * 256 * 4 + x * scale * 4 + 3] != 0;
+       return pic[(scale * 4) * (y * 256 + x) + 3] != 0;
 }
 
 static int
@@ -109,13 +107,14 @@ drawbg(void)
        static int t;
        u8int c, a;
        static u8int nr1, nr2, na;
-       static u32int r1, r2, a1, a2;
+       static u16int r1, r2, a1, a2;
        
        if(ppux >= 2 && ppux <= 257 || ppux >= 322 && ppux <= 337){
                c = (r1 >> (15-ppusx)) & 1 | (r2 >> (14-ppusx)) & 2;
-               a = (a1 >> (15-ppusx)) & 1 | (a2 >> (14-ppusx)) & 2;
-               if(ppuy < 240 && ppux <= 257)
+               if(ppuy < 240 && ppux <= 257){
+                       a = (a1 >> (15-ppusx)) & 1 | (a2 >> (14-ppusx)) & 2;
                        pixel(ppux-2, ppuy, pal(c, a, 0), c == 0);
+               }
                r1 <<= 1;
                r2 <<= 1;
                a1 <<= 1;
@@ -164,10 +163,10 @@ drawbg(void)
 }
 
 static void
-drawsprites(void)
+drawsprites(int show)
 {
        uchar *p;
-       int big, dx, dy, i, x;
+       int big, dx, dy, i, x, cc, pri;
        u8int r1, r2, c;
        static int n, m, nz, s0, t0;
        static struct { u8int x, a; u16int t; } s[8], *sp;
@@ -208,22 +207,26 @@ drawsprites(void)
                x = ppux - 2;
                dx = x - t[0].x;
                if(t0 && dx >= 0 && dx < 8 && ppux != 257){
-                       if((nz & 1) != 0 && iscolor(x, ppuy))
+                       if((nz & 1) != 0 && iscolor(x, ppuy) && show)
                                mem[PPUSTATUS] |= SPRITE0HIT;
                        nz >>= 1;
                }
+               cc = -1;
+               pri = 0;
                for(i = m - 1; i >= 0; i--){
                        dx = x - t[i].x;
                        if(dx < 0 || dx > 7)
                                continue;
                        c = (t[i].r1 & 1) | (t[i].r2 & 1) << 1;
                        if(c != 0){
-                               if((t[i].a & (1<<5)) == 0 || !iscolor(x, ppuy))
-                                       pixel(x, ppuy, pal(c, t[i].a & 3, 1), 0);
+                               cc = pal(c, t[i].a & 3, 1);
+                               pri = (t[i].a & (1<<5)) == 0;
                        }
                        t[i].r1 >>= 1;
                        t[i].r2 >>= 1;
                }
+               if(cc != -1 && show && (pri || !iscolor(x, ppuy)))
+                       pixel(x, ppuy, cc, 0);
        }
        if(ppux == 257){
                for(i = 0; i < n; i++){
@@ -247,41 +250,38 @@ drawsprites(void)
 static void
 flush(void)
 {
-       extern Rectangle picr;
-       extern Image *tmp;
-
-       if(tmp){
-               loadimage(tmp, tmp->r, pic, 256*240*4*scale*scale);
-               draw(screen, picr, tmp, nil, ZP);
-       }else
-               loadimage(screen, picr, pic, 256*240*4*scale*scale);
-       flushimage(display, 1);
-       memset(pic, sizeof pic, 0);
+       flushmouse(1);
+       flushscreen();
+       flushaudio(audioout);
 }
 
 void
 ppustep(void)
 {
        extern int nmi;
-       int bg;
+       int mask;
 
        if(ppuy < 240 || ppuy == 261){
-               bg = (mem[PPUMASK] & BGDISP) != 0;
-               if(bg)
+               mask = mem[PPUMASK];
+               if((mask & BGDISP) != 0)
                        drawbg();
-               if((mem[PPUMASK] & SPRITEDISP) != 0 && ppuy != 261)
-                       drawsprites();
+               if((((mask & BGDISP) == 0 && ppux <= 257 || ppux < 10 && (mask & BG8DISP) == 0) && ppux >= 2) && ppuy != 261)
+                       pixel(ppux - 2, ppuy, ppuread(0x3F00), 1);
+               if((mask & SPRITEDISP) != 0 && ppuy != 261)
+                       drawsprites(ppux >= 10 || (mask & SPRITE8DISP) != 0);
+               if(ppux == 240 && (mask & SPRITEDISP) != 0)
+                       mapper[map](SCAN, 0);
                if(ppuy == 261){
                        if(ppux == 1)
                                mem[PPUSTATUS] &= ~(PPUVBLANK|SPRITE0HIT);
-                       else if(ppux >= 280 && ppux <= 304 && bg)
+                       else if(ppux >= 280 && ppux <= 304 && (mask & BGDISP) != 0)
                                ppuv = (pput & 0x7BE0) | (ppuv & 0x041F);
                }
        }else if(ppuy == 241){
                if(ppux == 1){
                        mem[PPUSTATUS] |= PPUVBLANK;
                        if((mem[PPUCTRL] & PPUNMI) != 0)
-                               nmi = 1;
+                               nmi = 2;
                        flush();
                }
        }
@@ -289,7 +289,11 @@ ppustep(void)
        if(ppux > 340){
                ppux = 0;
                ppuy++;
-               if(ppuy > 261)
+               if(ppuy > 261){
                        ppuy = 0;
+                       if(odd && (mem[PPUMASK] & (BGDISP | SPRITEDISP)) != 0)
+                               ppux++;
+                       odd ^= 1;
+               }
        }
 }