8 uchar pic[240*160*2*3*3];
9 u8int bldy, blda, bldb;
16 s32int rpx0, rpy0, rpx, rpy;
26 static bg bgst[4] = {{.n = 0}, {.n = 1}, {.n = 2}, {.n = 3}};
27 static u32int pixeldat[2], pixelpri[2];
29 static u8int objwin, objtrans;
31 typedef struct sprite sprite;
48 static sprite sprt[128], *sp = sprt;
63 pixeldraw(int x, int y, u16int v)
67 union { u16int w; u8int b[2]; } u;
70 p = pic + (x + y * 240) * 2;
78 q = (u16int*)pic + (x + y * 240) * 2;
82 q = (u16int*)pic + (x + y * 240) * 3;
90 pixel(u16int c, int n, int p)
93 pixeldat[1] = pixeldat[0];
94 pixelpri[1] = pixelpri[0];
96 pixeldat[0] = c | n << 16;
97 }else if(p < pixelpri[1]){
99 pixeldat[1] = c | n << 16;
106 u16int bgcnt, ta, tx, ty, y, t;
110 bgcnt = reg[BG0CNT + b->n];
114 ta = (bgcnt << 3 & 0xf800) + ((tx & 0x1f) << 1) + ((ty & 0x1f) << 6);
116 case 1: ta += tx << 6 & 0x800; break;
117 case 2: ta += ty << 6 & 0x800; break;
118 case 3: ta += tx << 6 & 0x800 | ty << 7 & 0x1000; break;
120 t = vram[ta] | vram[ta+1] << 8;
122 chr = vram + (bgcnt << 12 & 0xc000) + ((t & 0x3ff) << 5+d);
126 chr = chr + (y << 2+d);
131 b->pal = pram + (t >> 8 & 0xf0);
135 bginit(bg *b, int scal, int)
142 rr = reg + (b->n - 2 << 3);
144 b->rpx0 = (s32int)(rr[BG2XL] | rr[BG2XH] << 16) << 4 >> 4;
145 b->rpy0 = (s32int)(rr[BG2YL] | rr[BG2YH] << 16) << 4 >> 4;
149 b->rpx0 += (s16int)rr[BG2PB];
150 b->rpy0 += (s16int)rr[BG2PD];
156 b->depth = (cnt & 7) == 3;
165 rr = reg + (b->n << 1);
166 x = rr[BG0HOFS] & 0x1ff;
167 y = (rr[BG0VOFS] & 0x1ff) + ppuy;
179 mode = reg[DISPCNT] & 7;
182 bginit(&bgst[0], 0, 0);
183 bginit(&bgst[1], 0, 0);
184 bginit(&bgst[2], 0, 0);
185 bginit(&bgst[3], 0, 0);
188 bginit(&bgst[0], 0, 0);
189 bginit(&bgst[1], 0, 0);
190 bginit(&bgst[2], 1, 0);
193 bginit(&bgst[2], 1, 0);
194 bginit(&bgst[3], 1, 0);
199 bginit(&bgst[2], 1, 1);
214 rr = reg - 8 + (b->n << 3);
215 if((bgmask & 1<<b->n) == 0)
217 if(b->rpx >= 0 && b->rpy >= 0 && b->rpx <= b->sx && b->rpy <= b->sy){
219 if((cnt & FRAME) != 0 && (cnt & 7) != 3)
222 p = base + 2 * (b->rpx >> 8) + 480 * (b->rpy >> 8);
223 v = p[0] | p[1] << 8;
225 v = base[(b->rpx >> 8) + 240 * (b->rpy >> 8)];
234 pixel(v, b->n, reg[BG0CNT + b->n] & 3);
236 b->rpx += (s16int) rr[BG2PA];
237 b->rpy += (s16int) rr[BG2PC];
248 rr = reg - 8 + (b->n << 3);
249 if((bgmask & 1<<b->n) == 0)
251 bgcnt = reg[BG0CNT + b->n];
252 row = (bgcnt >> 14) + 4;
256 if((bgcnt & DISPWRAP) != 0){
259 }else if((uint)x >= sz || (uint)y >= sz)
261 ta = (bgcnt << 3 & 0xf800) + ((y >> 3) << row) + (x >> 3);
262 p = vram + (bgcnt << 12 & 0xc000) + (vram[ta] << 6);
263 p += (x & 7) + ((y & 7) << 3);
265 pixel(pram[v], b->n, bgcnt & 3);
267 b->rpx += (s16int) rr[BG2PA];
268 b->rpy += (s16int) rr[BG2PC];
277 bgcnt = reg[BG0CNT + b->n];
278 if((bgmask & 1<<b->n) == 0)
281 if((b->t & 1<<10) != 0)
283 if((bgcnt & BG8) != 0)
293 pixel(b->pal[v], b->n, bgcnt & 3);
336 uchar ws, h, hb, d, dy, s;
337 static uchar wss[16] = {3, 4, 5, 6, 4, 5, 5, 6, 3, 3, 4, 5};
338 static uchar hss[16] = {3, 4, 5, 6, 3, 3, 4, 5, 4, 5, 5, 6};
342 budg = (cnt & HBLFREE) != 0 ? 954 : 1210;
343 for(p = oam; p < oam + 512; p += 4){
345 if((t0 & (SPRROT|SPRDIS)) == SPRDIS)
348 s = t0 >> 30 & 3 | t0 >> 12 & 12;
349 hb = h = 1 << hss[s];
350 dy = ppuy - (u8int) t0;
351 if((t0 & (SPRROT|SPRDOUB)) == (SPRROT|SPRDOUB))
353 if(dy >= hb || (u8int)t0 + hb > 256 && ppuy + 256 - (u8int)t0 >= hb)
355 sp->x = (s32int)(t0 << 7) >> 23;
358 sp->wb = sp->w = 1<<ws;
361 sp->base = vram + 0x10000 + ((t1 & 0x3ff) << 5);
362 d = (t0 & SPR8) != 0;
363 sp->ysh = (cnt & OBJNOMAT) != 0 ? 2 + d + ws : 10;
364 if((t0 & SPRROT) != 0){
365 if((t0 & SPRDOUB) != 0)
367 budg -= 10 + sp->w*2;
368 pp = oam + 3 + (t0 >> 21 & 0x1f0);
371 sp->rx = (dy - hb/2) * (s16int) pp[4] + (sp->w << 7) - sp->dx * sp->wb/2;
372 sp->ry = (dy - hb/2) * (s16int)pp[12] + (sp->h << 7) - sp->dy * sp->wb/2;
374 sp->rx -= sp->x * sp->dx;
375 sp->ry -= sp->x * sp->dy;
379 if((t0 & SPRVFLIP) != 0)
381 sp->base += (dy & 7) << 2 + d;
382 sp->base += dy >> 3 << sp->ysh;
383 if((t0 & SPRHFLIP) != 0)
384 sp->base += sp->w - 7 << 2 + d;
385 sp->inc = (1 << 5 + d) - (1 << 2 + d);
387 if((t0 & SPRHFLIP) != 0){
388 sp->base -= ((-sp->x & 7) >> 1 - d) + (-sp->x >> 3 << 5 + d);
389 if((t0 & SPR8) == 0 && (sp->x & 1) != 0)
392 sp->base += ((-sp->x & 7) >> 1 - d) + (-sp->x >> 3 << 5 + d);
395 sp->pal = pram + 0x100;
397 sp->pal = pram + 0x100 + (t1 >> 8 & 0xf0);
419 for(s = sprt; s < sp; s++){
424 if((t0 & SPRROT) != 0){
427 if(x < s->w && y < s->h){
429 d = (t0 & SPR8) != 0;
430 b += (y & 7) << 2 + d;
431 b += y >> 3 << s->ysh;
432 b += (x & 7) >> 1 - d;
433 b += x >> 3 << 5 + d;
444 }else if((t0 & SPRHFLIP) != 0){
447 else if((dx & 1) != 0)
457 else if((dx & 1) != 0){
466 pri = s->t1 >> 10 & 3;
468 switch(s->t0 >> 10 & 3){
491 mix(u16int c1, u16int c2)
493 u16int r, g, b, eva, evb;
497 b = ((c1 & 0x7c00) * eva + (c2 & 0x7c00) * evb) >> 4;
498 g = ((c1 & 0x03e0) * eva + (c2 & 0x03e0) * evb) >> 4;
499 r = ((c1 & 0x001f) * eva + (c2 & 0x001f) * evb) >> 4;
500 if(b > 0x7c00) b = 0x7c00;
501 if(g > 0x03e0) g = 0x03e0;
502 if(r > 0x001f) r = 0x001f;
503 return b & 0x7c00 | g & 0x03e0 | r;
513 b = b + (0x7c00 - b) * y / 16;
515 g = g + (0x03e0 - g) * y / 16;
517 r = r + (0x001f - r) * y / 16;
518 if(b > 0x7c00) b = 0x7c00;
519 if(g > 0x03e0) g = 0x03e0;
520 if(r > 0x001f) r = 0x001f;
521 return b & 0x7c00 | g & 0x03e0 | r;
536 return b & 0x7c00 | g & 0x03e0 | r;
545 dispcnt = reg[DISPCNT];
546 bgmask = dispcnt >> 8 | 1<<5;
547 if((dispcnt >> 13) != 0){
548 if((dispcnt & 1<<13) != 0){
551 if(ppuy < (u8int)v && ppuy >= v >> 8 &&
552 ppux < (u8int)h && ppux >= h >> 8){
553 bgmask &= reg[WININ];
557 if((dispcnt & 1<<14) != 0){
560 if(ppuy < (u8int)v && ppuy >= v >> 8 &&
561 ppux < (u8int)h && ppux >= h >> 8){
562 bgmask &= reg[WININ] >> 8;
566 if((dispcnt & 1<<15) != 0 && objwin != 0){
567 bgmask &= reg[WINOUT] >> 8;
570 bgmask &= reg[WINOUT];
573 if(pixelpri[0] != 8 && (bgmask & 1<<4) == 0){
575 pixeldat[0] = pram[0] | 5 << 16;
585 if((bgmask & 1<<5) == 0)
587 bldcnt = reg[BLDCNT];
588 src0 = pixeldat[0] >> 16;
589 if(objtrans && src0 == 4)
591 if((bldcnt & 3<<6) == 0 || (bldcnt & 1<<src0) == 0)
593 switch(bldcnt >> 6 & 3){
596 if((bldcnt & 1<<8+(pixeldat[1]>>16)) == 0)
598 pixeldat[0] = mix(pixeldat[0], pixeldat[1]);
601 pixeldat[0] = brighten(pixeldat[0]);
604 pixeldat[0] = darken(pixeldat[0]);
615 stat = reg[DISPSTAT];
617 if(ppuy < 160 && ppux < 240)
618 if((cnt & FBLANK) == 0){
622 pixeldat[0] = pram[0] | 5 << 16;
623 if((cnt & 1<<12) != 0)
628 pixeldraw(ppux, ppuy, pixeldat[0]);
630 pixeldraw(ppux, ppuy, 0xffff);
631 if(ppux == 240 && ppuy < 160){
632 if((stat & IRQHBLEN) != 0)
642 if((stat & IRQVCTREN) != 0 && ppuy == stat >> 8)
647 }else if(ppuy == 160){
648 if((stat & IRQVBLEN) != 0)