#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,
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
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;
}
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;
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++){
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();
}
}
if(ppux > 340){
ppux = 0;
ppuy++;
- if(ppuy > 261)
+ if(ppuy > 261){
ppuy = 0;
+ if(odd && (mem[PPUMASK] & (BGDISP | SPRITEDISP)) != 0)
+ ppux++;
+ odd ^= 1;
+ }
}
}