241
/*****************************************
244
* Draw tiles with 2 bit planes(4 colors)
245
*****************************************/
246
INLINE void snes_draw_tile_2(UINT8 screen, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal )
248
UINT8 mask, plane[2];
252
plane[0] = snes_vram[tileaddr];
253
plane[1] = snes_vram[tileaddr + 1];
260
for( ii = x; ii < (x + 8); ii++ )
262
register UINT8 colour;
265
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0);
270
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0);
274
#ifdef SNES_DBG_video
275
if( !debug_options.windows_disabled )
276
#endif /* SNES_DBG_video */
277
/* Clip to windows */
278
if( (screen == MAINSCREEN && (snes_ram[TMW] & (0x1 << layer))) || (screen == SUBSCREEN && (snes_ram[TSW] & (0x1 << layer))))
279
colour &= snes_ppu.clipmasks[layer][ii];
281
/* Only draw if we have a colour (0 == transparent) */
284
if( (scanlines[screen].zbuf[ii] <= priority) && (ii >= 0) )
286
c = snes_cgram[pal + colour];
287
if( screen == MAINSCREEN ) /* Only blend main screens */
288
snes_draw_blend(ii, &c, snes_ppu.layer[layer].blend, (snes_ram[CGWSEL] & 0x30) >> 4 );
289
scanlines[screen].buffer[ii] = c;
290
scanlines[screen].zbuf[ii] = priority;
296
/*****************************************
297
* snes_draw_tile_2x2()
299
* Draw 2 tiles with 2 bit planes(4 colors)
300
*****************************************/
301
INLINE void snes_draw_tile_2x2(UINT8 screen, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal )
305
snes_draw_tile_2(screen, layer, tileaddr + 16, x, priority, flip, pal );
306
snes_draw_tile_2(screen, layer, tileaddr, x + 8, priority, flip, pal );
310
snes_draw_tile_2(screen, layer, tileaddr, x, priority, flip, pal );
311
snes_draw_tile_2(screen, layer, tileaddr + 16, x + 8, priority, flip, pal );
315
/*****************************************
318
* Draw tiles with 4 bit planes(16 colors)
319
*****************************************/
320
INLINE void snes_draw_tile_4(UINT8 screen, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal )
322
UINT8 mask, plane[4];
326
plane[0] = snes_vram[tileaddr];
327
plane[1] = snes_vram[tileaddr + 1];
328
plane[2] = snes_vram[tileaddr + 16];
329
plane[3] = snes_vram[tileaddr + 17];
336
for( ii = x; ii < (x + 8); ii++ )
338
register UINT8 colour;
341
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
342
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
347
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
348
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
352
#ifdef SNES_DBG_video
353
if( !debug_options.windows_disabled )
354
#endif /* SNES_DBG_video */
355
/* Clip to windows */
356
if( (screen == MAINSCREEN && (snes_ram[TMW] & (0x1 << layer))) || (screen == SUBSCREEN && (snes_ram[TSW] & (0x1 << layer))))
357
colour &= snes_ppu.clipmasks[layer][ii];
359
/* Only draw if we have a colour (0 == transparent) */
362
if( (scanlines[screen].zbuf[ii] <= priority) && (ii >= 0) )
364
c = snes_cgram[pal + colour];
365
if( screen == MAINSCREEN ) /* Only blend main screens */
366
snes_draw_blend(ii, &c, snes_ppu.layer[layer].blend, (snes_ram[CGWSEL] & 0x30) >> 4 );
367
scanlines[screen].buffer[ii] = c;
368
scanlines[screen].zbuf[ii] = priority;
374
/*****************************************
375
* snes_draw_tile_4x2()
377
* Draw 2 tiles with 4 bit planes(16 colors)
378
*****************************************/
379
INLINE void snes_draw_tile_4x2(UINT8 screen, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal )
383
snes_draw_tile_4(screen, layer, tileaddr + 32, x, priority, flip, pal );
384
snes_draw_tile_4(screen, layer, tileaddr, x + 8, priority, flip, pal );
388
snes_draw_tile_4(screen, layer, tileaddr, x, priority, flip, pal );
389
snes_draw_tile_4(screen, layer, tileaddr + 32, x + 8, priority, flip, pal );
393
/*****************************************
396
* Draw tiles with 8 bit planes(256 colors)
397
*****************************************/
398
INLINE void snes_draw_tile_8(UINT8 screen, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip )
400
UINT8 mask, plane[8];
404
plane[0] = snes_vram[tileaddr];
405
plane[1] = snes_vram[tileaddr + 1];
406
plane[2] = snes_vram[tileaddr + 16];
407
plane[3] = snes_vram[tileaddr + 17];
408
plane[4] = snes_vram[tileaddr + 32];
409
plane[5] = snes_vram[tileaddr + 33];
410
plane[6] = snes_vram[tileaddr + 48];
411
plane[7] = snes_vram[tileaddr + 49];
418
for( ii = x; ii < (x + 8); ii++ )
420
register UINT8 colour;
423
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
424
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0) |
425
(plane[4] & mask ? 16 : 0) | (plane[5] & mask ? 32 : 0) |
426
(plane[6] & mask ? 64 : 0) | (plane[7] & mask ? 128 : 0);
431
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
432
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0) |
433
(plane[4] & mask ? 16 : 0) | (plane[5] & mask ? 32 : 0) |
434
(plane[6] & mask ? 64 : 0) | (plane[7] & mask ? 128 : 0);
438
#ifdef SNES_DBG_video
439
if( !debug_options.windows_disabled )
440
#endif /* SNES_DBG_video */
441
/* Clip to windows */
442
if( (screen == MAINSCREEN && (snes_ram[TMW] & (0x1 << layer))) || (screen == SUBSCREEN && (snes_ram[TSW] & (0x1 << layer))))
443
colour &= snes_ppu.clipmasks[layer][ii];
445
/* Only draw if we have a colour (0 == transparent) */
448
if( (scanlines[screen].zbuf[ii] <= priority) && (ii >= 0) )
450
c = snes_cgram[colour];
451
if( screen == MAINSCREEN ) /* Only blend main screens */
452
snes_draw_blend(ii, &c, snes_ppu.layer[layer].blend, (snes_ram[CGWSEL] & 0x30) >> 4 );
453
scanlines[screen].buffer[ii] = c;
454
scanlines[screen].zbuf[ii] = priority;
460
/*****************************************
461
* snes_draw_tile_8x2()
463
* Draw 2 tiles with 8 bit planes(256 colors)
464
*****************************************/
465
INLINE void snes_draw_tile_8x2(UINT8 screen, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip )
469
snes_draw_tile_8(screen, layer, tileaddr + 64, x, priority, flip );
470
snes_draw_tile_8(screen, layer, tileaddr, x + 8, priority, flip );
474
snes_draw_tile_8(screen, layer, tileaddr, x, priority, flip );
475
snes_draw_tile_8(screen, layer, tileaddr + 64, x + 8, priority, flip );
236
/*****************************************
239
* Draw tiles with variable bit planes
240
*****************************************/
241
INLINE void snes_draw_tile(UINT8 screen, UINT8 planes, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal, UINT8 direct_colors )
243
UINT8 mask, plane[8], window_enabled = 0;
247
for (ii = 0; ii < planes / 2; ii++)
249
plane[2 * ii] = snes_vram[tileaddr + 16 * ii];
250
plane[2 * ii + 1] = snes_vram[tileaddr + 16 * ii + 1];
258
for (ii = x; ii < (x + 8); ii++)
263
for (jj = 0; jj < planes; jj++)
264
colour |= plane[jj] & mask ? (1 << jj) : 0;
270
for (jj = 0; jj < planes; jj++)
271
colour |= plane[jj] & mask ? (1 << jj) : 0;
277
if(!debug_options.windows_disabled)
278
#endif /* MAME_DEBUG */
279
/* Clip to windows */
280
window_enabled = (screen == MAINSCREEN) ? snes_ppu.layer[layer].main_window_enabled : snes_ppu.layer[layer].sub_window_enabled;
282
colour &= snes_ppu.clipmasks[layer][ii];
284
/* Only draw if we have a colour (0 == transparent) */
287
if ((scanlines[screen].zbuf[ii] <= priority) && (ii >= 0))
291
/* format is 0 | BBb00 | GGGg0 | RRRr0, HW confirms that the data is zero padded. */
292
c = ((colour & 0x07) << 2) | ((colour & 0x38) << 4) | ((colour & 0xc0) << 7);
293
c |= ((pal & 0x04) >> 1) | ((pal & 0x08) << 3) | ((pal & 0x10) << 8);
296
c = snes_cgram[pal + colour];
298
if (screen == MAINSCREEN) /* Only blend main screens */
299
snes_draw_blend(ii/snes_htmult, &c, snes_ppu.layer[layer].blend, snes_ppu.sub_color_mask, snes_ppu.main_color_mask);
300
if (snes_ppu.layer[layer].mosaic_enabled) // handle horizontal mosaic
304
//TODO: 512 modes has the h values doubled.
305
for (x_mos = 0; x_mos < (snes_ppu.mosaic_size + 1) ; x_mos++)
307
scanlines[screen].buffer[ii + x_mos] = c;
308
scanlines[screen].zbuf[ii + x_mos] = priority;
314
scanlines[screen].buffer[ii] = c;
315
scanlines[screen].zbuf[ii] = priority;
322
/*****************************************
323
* snes_draw_tile_x2()
325
* Draw 2 tiles with variable bit planes
326
*****************************************/
327
INLINE void snes_draw_tile_x2(UINT8 screen, UINT8 planes, UINT8 layer, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal, UINT8 direct_colors )
331
snes_draw_tile(screen, planes, layer, tileaddr + (8 * planes), x, priority, flip, pal, direct_colors);
332
snes_draw_tile(screen, planes, layer, tileaddr, x + 8, priority, flip, pal, direct_colors);
336
snes_draw_tile(screen, planes, layer, tileaddr, x, priority, flip, pal, direct_colors);
337
snes_draw_tile(screen, planes, layer, tileaddr + (8 * planes), x + 8, priority, flip, pal, direct_colors);
483
345
* The same as snes_draw_tile_4() except
484
346
* that it takes a blend parameter.
485
347
*****************************************/
486
INLINE void snes_draw_tile_object(UINT8 screen, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal, UINT8 blend )
488
UINT8 mask, plane[4];
492
plane[0] = snes_vram[tileaddr];
493
plane[1] = snes_vram[tileaddr + 1];
494
plane[2] = snes_vram[tileaddr + 16];
495
plane[3] = snes_vram[tileaddr + 17];
502
for( ii = x; ii < (x + 8); ii++ )
504
register UINT8 colour;
507
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
508
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
513
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
514
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
518
#ifdef SNES_DBG_video
519
if( !debug_options.windows_disabled )
520
#endif /* SNES_DBG_video */
521
/* Clip to windows */
522
if( (screen == MAINSCREEN && (snes_ram[TMW] & 0x10)) || (screen == SUBSCREEN && (snes_ram[TSW] & 0x10)))
523
colour &= snes_ppu.clipmasks[4][ii];
525
/* Only draw if we have a colour (0 == transparent) */
530
c = snes_cgram[pal + colour];
531
if( blend && screen == MAINSCREEN ) /* Only blend main screens */
532
snes_draw_blend(ii, &c, snes_ppu.layer[4].blend, (snes_ram[CGWSEL] & 0x30) >> 4 );
534
scanlines[screen].buffer[ii] = c;
535
scanlines[screen].zbuf[ii] = priority;
541
/*****************************************
542
* snes_draw_tile_object_w()
544
* Draw tiles with 4 bit planes(16 colors)
545
* The same as snes_draw_tile_4() except
546
* that it takes a blend parameter.
548
*****************************************/
549
INLINE void snes_draw_tile_object_w(UINT8 screen, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal, UINT8 blend )
551
UINT8 mask, plane[4];
555
plane[0] = snes_vram[tileaddr];
556
plane[1] = snes_vram[tileaddr + 1];
557
plane[2] = snes_vram[tileaddr + 16];
558
plane[3] = snes_vram[tileaddr + 17];
566
for( ii = x; ii < (x + 16); ii += 2 )
568
register UINT8 colour;
571
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
572
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
577
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
578
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
582
#ifdef SNES_DBG_video
583
if( !debug_options.windows_disabled )
584
#endif /* SNES_DBG_video */
585
/* Clip to windows */
586
if( (screen == MAINSCREEN && (snes_ram[TMW] & 0x10)) || (screen == SUBSCREEN && (snes_ram[TSW] & 0x10)))
587
colour &= snes_ppu.clipmasks[4][ii];
589
/* Only draw if we have a colour (0 == transparent) */
594
c = snes_cgram[pal + colour];
595
if( blend && screen == MAINSCREEN ) /* Only blend main screens */
596
snes_draw_blend(ii, &c, snes_ppu.layer[4].blend, (snes_ram[CGWSEL] & 0x30) >> 4 );
598
scanlines[screen].buffer[ii] = c;
599
scanlines[screen].zbuf[ii] = priority;
600
scanlines[screen].buffer[ii + 1] = c;
601
scanlines[screen].zbuf[ii + 1] = priority;
607
/*********************************************
608
* snes_update_line_2()
610
* Update an entire line of 2 bit plane tiles.
611
*********************************************/
612
static void snes_update_line_2(UINT8 screen, UINT8 layer, UINT16 curline )
615
UINT16 ii, vflip, hflip, pal;
616
INT8 line, tile_line;
620
UINT16 vscroll, hscroll, vtilescroll;
621
UINT8 vshift, hshift, tile_size;
624
#ifdef SNES_DBG_video
625
if( debug_options.bg_disabled[layer] )
627
#endif /* SNES_DBG_video */
629
/* set special priority bit */
630
if( snes_ppu.mode == 1 && snes_ram[BGMODE] & 0x8 )
633
/* Handle Mosaic effects */
634
if( snes_ram[MOSAIC] & (1 << layer) )
635
curline -= (curline % ((snes_ram[MOSAIC] >> 4) + 1));
637
/* Find the size of the tiles (8x8 or 16x16) */
638
tile_size = snes_ppu.layer[layer].tile_size;
639
/* Find scroll info */
640
vscroll = snes_ppu.layer[layer].offset.tile_vert;
641
vshift = snes_ppu.layer[layer].offset.shift_vert;
642
hscroll = snes_ppu.layer[layer].offset.tile_horz;
643
hshift = snes_ppu.layer[layer].offset.shift_horz;
645
/* Find vertical scroll amount */
646
vtilescroll = vscroll + (curline >> (3 + tile_size));
647
/* figure out which line to draw */
648
line = (curline % (8 << tile_size)) + vshift;
649
if( line > ((8 << tile_size) - 1) ) /* scrolled into the next tile */
651
vtilescroll++; /* pretend we scrolled by 1 tile line */
652
line -= (8 << tile_size);
654
if( vtilescroll >= 128 )
657
/* Jump to base map address */
658
tmap = snes_ppu.layer[layer].map;
659
/* Offset vertically */
660
tmap += table_vscroll[snes_ppu.layer[layer].map_size][vtilescroll >> 5];
661
/* Scroll vertically */
662
tmap += (vtilescroll & 0x1f) << 6;
663
/* Remember this position */
665
/* Offset horizontally */
666
tmap += table_hscroll[snes_ppu.layer[layer].map_size & 3][(hscroll >> 5) & 3];
667
/* Scroll horizontally */
668
tmap += (hscroll & 0x1f) << 1;
670
for( ii = 0; ii < (66 >> tile_size); ii += 2 )
672
/* Have we scrolled into the next map? */
673
if( hscroll && ((ii >> 1) >= 32 - (hscroll & 0x1f)) )
675
tmap = basevmap + table_hscroll[snes_ppu.layer[layer].map_size & 3][((hscroll >> 5) + 1) & 3];
677
hscroll = 0; /* Make sure we don't do this again */
679
if (tmap > 0x10000) tmap %= 0x10000;
680
vflip = (snes_vram[tmap + ii + 1] & 0x80);
681
hflip = snes_vram[tmap + ii + 1] & 0x40;
682
priority = table_bgd_pty[snes_ppu.mode > 1][layer][(snes_vram[tmap + ii + 1] & 0x20) >> 5];
683
pal = (snes_vram[tmap + ii + 1] & 0x1c); /* 8 palettes of 4 colours */
684
tile = (snes_vram[tmap + ii + 1] & 0x3) << 8;
685
tile |= snes_vram[tmap + ii];
687
/* Mode 0 palettes are layer specific */
688
if( snes_ppu.mode == 0 )
707
tile_line = -tile_line + 7;
719
/* Special case for bg3 */
720
if( layer == 2 && bg3_pty && (snes_vram[tmap + ii + 1] & 0x20) )
721
priority = table_obj_pty[3] + 1; /* We want to have the highest priority here */
725
snes_draw_tile_2x2(screen, layer, snes_ppu.layer[layer].data + (tile << 4) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip, pal );
729
snes_draw_tile_2(screen, layer, snes_ppu.layer[layer].data + (tile << 4) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip, pal );
734
/*********************************************
735
* snes_update_line_2_hi()
737
* Update an entire line of 2 bit plane tiles.
738
* This is the hires version.
739
*********************************************/
740
static void snes_update_line_2_hi(UINT8 screen, UINT8 layer, UINT16 curline )
743
UINT16 ii, vflip, hflip, pal;
744
INT8 line, tile_line;
748
UINT16 vscroll, hscroll, vtilescroll;
749
UINT8 vshift, hshift, tile_size;
752
#ifdef SNES_DBG_video
753
if( debug_options.bg_disabled[layer] )
755
#endif /* SNES_DBG_video */
757
/* set special priority bit */
758
if( snes_ppu.mode == 1 && snes_ram[BGMODE] & 0x8 )
761
/* Handle Mosaic effects */
762
if( snes_ram[MOSAIC] & (1 << layer) )
763
curline -= (curline % ((snes_ram[MOSAIC] >> 4) + 1));
765
/* Find the size of the tiles (8x8 or 16x16) */
766
tile_size = snes_ppu.layer[layer].tile_size;
767
/* Find scroll info */
768
vscroll = snes_ppu.layer[layer].offset.tile_vert;
769
vshift = snes_ppu.layer[layer].offset.shift_vert;
770
hscroll = snes_ppu.layer[layer].offset.tile_horz;
771
hshift = snes_ppu.layer[layer].offset.shift_horz;
773
/* Find vertical scroll amount */
774
vtilescroll = vscroll + (curline >> (3 + tile_size));
775
/* figure out which line to draw */
776
line = (curline % (8 << tile_size)) + vshift;
777
if( line > ((8 << tile_size) - 1) ) /* scrolled into the next tile */
779
vtilescroll++; /* pretend we scrolled by 1 tile line */
780
line -= (8 << tile_size);
782
if( vtilescroll >= 128 )
785
/* Jump to base map address */
786
tmap = snes_ppu.layer[layer].map;
787
/* Offset vertically */
788
tmap += table_vscroll[snes_ppu.layer[layer].map_size][vtilescroll >> 5];
789
/* Scroll vertically */
790
tmap += (vtilescroll & 0x1f) << 6;
791
/* Remember this position */
793
/* Offset horizontally */
794
tmap += table_hscroll[snes_ppu.layer[layer].map_size & 3][(hscroll >> 5) & 3];
795
/* Scroll horizontally */
796
tmap += (hscroll & 0x1f) << 1;
798
for( ii = 0; ii < (66 >> tile_size); ii += 2 )
800
/* Have we scrolled into the next map? */
801
if( hscroll && ((ii >> 1) >= 32 - (hscroll & 0x1f)) )
803
tmap = basevmap + table_hscroll[snes_ppu.layer[layer].map_size & 3][((hscroll >> 5) + 1) & 3];
805
hscroll = 0; /* Make sure we don't do this again */
807
if (tmap > 0x10000) tmap %= 0x10000;
808
vflip = (snes_vram[tmap + ii + 1] & 0x80);
809
hflip = snes_vram[tmap + ii + 1] & 0x40;
810
priority = table_bgd_pty[snes_ppu.mode > 1][layer][(snes_vram[tmap + ii + 1] & 0x20) >> 5];
811
pal = (snes_vram[tmap + ii + 1] & 0x1c); /* 8 palettes of 4 colours */
812
tile = (snes_vram[tmap + ii + 1] & 0x3) << 8;
813
tile |= snes_vram[tmap + ii];
815
/* Mode 0 palettes are layer specific */
816
if( snes_ppu.mode == 0 )
835
tile_line = -tile_line + 7;
847
/* Special case for bg3 */
848
if( layer == 2 && bg3_pty && (snes_vram[tmap + ii + 1] & 0x20) )
849
priority = table_obj_pty[3] + 1; /* We want to have the highest priority here */
855
snes_draw_tile_2x2(screen, layer, snes_ppu.layer[layer].data + (tile << 4) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1) + 16, priority, hflip, pal );
856
snes_draw_tile_2x2(screen, layer, snes_ppu.layer[layer].data + ((tile + 2) << 4) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal );
860
snes_draw_tile_2x2(screen, layer, snes_ppu.layer[layer].data + (tile << 4) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal );
861
snes_draw_tile_2x2(screen, layer, snes_ppu.layer[layer].data + ((tile + 2) << 4) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1) + 16, priority, hflip, pal );
866
snes_draw_tile_2x2(screen, layer, snes_ppu.layer[layer].data + (tile << 4) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal );
871
/*********************************************
872
* snes_update_line_4()
874
* Update an entire line of 4 bit plane tiles.
875
*********************************************/
876
static void snes_update_line_4(UINT8 screen, UINT8 layer, UINT16 curline )
879
UINT16 ii, vflip, hflip, pal;
880
INT8 line, tile_line;
884
UINT16 vscroll, hscroll, vtilescroll;
885
UINT8 vshift, hshift, tile_size;
887
#ifdef SNES_DBG_video
888
if( debug_options.bg_disabled[layer] )
890
#endif /* SNES_DBG_video */
892
/* Handle Mosaic effects */
893
if( snes_ram[MOSAIC] & (1 << layer) )
894
curline -= (curline % ((snes_ram[MOSAIC] >> 4) + 1));
896
/* Find the size of the tiles (8x8 or 16x16) */
897
tile_size = snes_ppu.layer[layer].tile_size;
898
/* Find scroll info */
899
vscroll = snes_ppu.layer[layer].offset.tile_vert;
900
vshift = snes_ppu.layer[layer].offset.shift_vert;
901
hscroll = snes_ppu.layer[layer].offset.tile_horz;
902
hshift = snes_ppu.layer[layer].offset.shift_horz;
904
/* Jump to base map address */
905
tmap = snes_ppu.layer[layer].map;
907
/* Find vertical scroll amount */
908
vtilescroll = vscroll + (curline >> (3 + tile_size));
909
/* figure out which line to draw */
910
line = (curline % (8 << tile_size)) + vshift;
911
if( line > ((8 << tile_size) - 1) ) /* scrolled into the next tile */
913
vtilescroll++; /* pretend we scrolled by 1 tile line */
914
line -= (8 << tile_size);
916
if( vtilescroll >= 128 )
919
/* Offset vertically */
920
tmap += table_vscroll[snes_ppu.layer[layer].map_size][vtilescroll >> 5];
921
/* Scroll vertically */
922
tmap += (vtilescroll & 0x1f) << 6;
923
/* Remember this position */
925
/* Offset horizontally */
926
tmap += table_hscroll[snes_ppu.layer[layer].map_size & 3][(hscroll >> 5) & 3];
927
/* Scroll horizontally */
928
tmap += (hscroll & 0x1f) << 1;
930
for( ii = 0; ii < (66 >> tile_size); ii += 2 )
932
/* Have we scrolled into the next map? */
933
if( hscroll && ((ii >> 1) >= 32 - (hscroll & 0x1f)) )
935
tmap = basevmap + table_hscroll[snes_ppu.layer[layer].map_size & 3][((hscroll >> 5) + 1) & 3];
937
hscroll = 0; /* Make sure we don't do this again */
939
if (tmap > 0x10000) tmap %= 0x10000;
940
vflip = snes_vram[tmap + ii + 1] & 0x80;
941
hflip = snes_vram[tmap + ii + 1] & 0x40;
942
priority = table_bgd_pty[snes_ppu.mode > 1][layer][(snes_vram[tmap + ii + 1] & 0x20) >> 5]; /* is this even right??? */
943
pal = (snes_vram[tmap + ii + 1] & 0x1c) << 2; /* 8 palettes of 16 colours */
944
tile = (snes_vram[tmap + ii + 1] & 0x3) << 8;
945
tile |= snes_vram[tmap + ii];
961
tile_line = -tile_line + 7;
975
snes_draw_tile_4x2(screen, layer, snes_ppu.layer[layer].data + (tile << 5) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip, pal );
979
snes_draw_tile_4(screen, layer, snes_ppu.layer[layer].data + (tile << 5) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip, pal );
984
/*********************************************
985
* snes_update_line_4_hi()
987
* Update an entire line of 4 bit plane tiles.
988
* This is the hires version
989
*********************************************/
990
static void snes_update_line_4_hi(UINT8 screen, UINT8 layer, UINT16 curline )
993
UINT16 ii, vflip, hflip, pal;
994
INT8 line, tile_line;
998
UINT16 vscroll, hscroll, vtilescroll;
999
UINT8 vshift, hshift, tile_size;
1001
#ifdef SNES_DBG_video
1002
if( debug_options.bg_disabled[layer] )
1004
#endif /* SNES_DBG_video */
1006
/* Handle Mosaic effects */
1007
if( snes_ram[MOSAIC] & (1 << layer) )
1008
curline -= (curline % ((snes_ram[MOSAIC] >> 4) + 1));
1010
/* Find the size of the tiles (8x8 or 16x16) */
1011
tile_size = snes_ppu.layer[layer].tile_size;
1012
/* Find scroll info */
1013
vscroll = snes_ppu.layer[layer].offset.tile_vert;
1014
vshift = snes_ppu.layer[layer].offset.shift_vert;
1015
hscroll = snes_ppu.layer[layer].offset.tile_horz;
1016
hshift = snes_ppu.layer[layer].offset.shift_horz;
1018
/* Find vertical scroll amount */
1019
vtilescroll = vscroll + (curline >> (3 + tile_size));
1020
/* figure out which line to draw */
1021
line = (curline % (8 << tile_size)) + vshift;
1022
if( line > ((8 << tile_size) - 1) ) /* scrolled into the next tile */
1024
vtilescroll++; /* pretend we scrolled by 1 tile line */
1025
line -= (8 << tile_size);
1027
if( vtilescroll >= 128 )
1030
/* Jump to base map address */
1031
tmap = snes_ppu.layer[layer].map;
1032
/* Offset vertically */
1033
tmap += table_vscroll[snes_ppu.layer[layer].map_size][vtilescroll >> 5];
1034
/* Scroll vertically */
1035
tmap += (vtilescroll & 0x1f) << 6;
1036
/* Remember this position */
1038
/* Offset horizontally */
1039
tmap += table_hscroll[snes_ppu.layer[layer].map_size & 3][(hscroll >> 5) & 3];
1040
/* Scroll horizontally */
1041
tmap += (hscroll & 0x1f) << 1;
1043
for( ii = 0; ii < (66 >> tile_size); ii += 2 )
1045
/* Have we scrolled into the next map? */
1046
if( hscroll && ((ii >> 1) >= 32 - (hscroll & 0x1f)) )
1048
tmap = basevmap + table_hscroll[snes_ppu.layer[layer].map_size & 3][((hscroll >> 5) + 1) & 3];
1050
hscroll = 0; /* Make sure we don't do this again */
1052
if (tmap > 0x10000) tmap %= 0x10000;
1054
vflip = snes_vram[tmap + ii + 1] & 0x80;
1055
hflip = snes_vram[tmap + ii + 1] & 0x40;
1056
priority = table_bgd_pty[snes_ppu.mode > 1][layer][(snes_vram[tmap + ii + 1] & 0x20) >> 5]; /* is this even right??? */
1057
pal = (snes_vram[tmap + ii + 1] & 0x1c) << 2; /* 8 palettes of 16 colours */
1058
tile = (snes_vram[tmap + ii + 1] & 0x3) << 8;
1059
tile |= snes_vram[tmap + ii];
1075
tile_line = -tile_line + 7;
1087
/* Does hi-res support the tile-size option? */
1092
snes_draw_tile_4x2(screen, layer, snes_ppu.layer[layer].data + (tile << 5) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1) + 16, priority, hflip, pal );
1093
snes_draw_tile_4x2(screen, layer, snes_ppu.layer[layer].data + ((tile + 2) << 5) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal );
1097
snes_draw_tile_4x2(screen, layer, snes_ppu.layer[layer].data + (tile << 5) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal );
1098
snes_draw_tile_4x2(screen, layer, snes_ppu.layer[layer].data + ((tile + 2) << 5) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1) + 16, priority, hflip, pal );
1103
snes_draw_tile_4x2(screen, layer, snes_ppu.layer[layer].data + (tile << 5) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal );
1108
/*********************************************
1109
* snes_update_line_8()
1111
* Update an entire line of 8 bit plane tiles.
1112
*********************************************/
1113
static void snes_update_line_8(UINT8 screen, UINT8 layer, UINT16 curline )
1116
UINT16 ii, vflip, hflip, pal;
1117
INT8 line, tile_line;
1121
UINT16 vscroll, hscroll, vtilescroll;
1122
UINT8 vshift, hshift, tile_size;
1124
#ifdef SNES_DBG_video
1125
if( debug_options.bg_disabled[layer] )
1127
#endif /* SNES_DBG_video */
1129
/* Handle Mosaic effects */
1130
if( snes_ram[MOSAIC] & (1 << layer) )
1131
curline -= (curline % ((snes_ram[MOSAIC] >> 4) + 1));
1133
/* Find the size of the tiles (8x8 or 16x16) */
1134
tile_size = snes_ppu.layer[layer].tile_size;
1135
/* Find scroll info */
1136
vscroll = snes_ppu.layer[layer].offset.tile_vert;
1137
vshift = snes_ppu.layer[layer].offset.shift_vert;
1138
hscroll = snes_ppu.layer[layer].offset.tile_horz;
1139
hshift = snes_ppu.layer[layer].offset.shift_horz;
1141
/* Find vertical scroll amount */
1142
vtilescroll = vscroll + (curline >> (3 + tile_size));
1143
/* figure out which line to draw */
1144
line = (curline % (8 << tile_size)) + vshift;
1145
if( line > ((8 << tile_size) - 1) ) /* scrolled into the next tile */
1147
vtilescroll++; /* pretend we scrolled by 1 tile line */
1148
line -= (8 << tile_size);
1150
if( vtilescroll >= 128 )
1153
/* Jump to base map address */
1154
tmap = snes_ppu.layer[layer].map;
1155
/* Offset vertically */
1156
tmap += table_vscroll[snes_ppu.layer[layer].map_size][vtilescroll >> 5];
1157
/* Scroll vertically */
1158
tmap += (vtilescroll & 0x1f) << 6;
1159
/* Remember this position */
1161
/* Offset horizontally */
1162
tmap += table_hscroll[snes_ppu.layer[layer].map_size & 3][(hscroll >> 5) & 3];
1163
/* Scroll horizontally */
1164
tmap += (hscroll & 0x1f) << 1;
1166
for( ii = 0; ii < (66 >> tile_size); ii += 2 )
1168
/* Have we scrolled into the next map? */
1169
if( hscroll && ((ii >> 1) >= 32 - (hscroll & 0x1f)) )
1171
tmap = basevmap + table_hscroll[snes_ppu.layer[layer].map_size & 3][((hscroll >> 5) + 1) & 3];
1173
hscroll = 0; /* Make sure we don't do this again */
1175
if (tmap > 0x10000) tmap %= 0x10000;
1176
vflip = (snes_vram[tmap + ii + 1] & 0x80);
1177
hflip = snes_vram[tmap + ii + 1] & 0x40;
1178
priority = table_bgd_pty[snes_ppu.mode > 1][layer][(snes_vram[tmap + ii + 1] & 0x20) >> 5];
1179
pal = (snes_vram[tmap + ii + 1] & 0x1c); /* what does this do for 8 bit screen? */
1180
tile = (snes_vram[tmap + ii + 1] & 0x3) << 8;
1181
tile |= snes_vram[tmap + ii];
1197
tile_line = -tile_line + 7;
1211
snes_draw_tile_8x2(screen, layer, snes_ppu.layer[layer].data + (tile << 6) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip );
1215
snes_draw_tile_8(screen, layer, snes_ppu.layer[layer].data + (tile << 6) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip );
348
INLINE void snes_draw_tile_object(UINT8 screen, UINT16 tileaddr, INT16 x, UINT8 priority, UINT8 flip, UINT16 pal, UINT8 blend, UINT8 wide )
350
UINT8 mask, plane[4], window_enabled = 0;
353
UINT8 x_shift = wide ? 1 : 0;
354
UINT8 size = wide ? 16 : 8;
355
UINT8 step = wide ? 1 : 0;
357
plane[0] = snes_vram[tileaddr];
358
plane[1] = snes_vram[tileaddr + 1];
359
plane[2] = snes_vram[tileaddr + 16];
360
plane[3] = snes_vram[tileaddr + 17];
368
for (ii = x; ii < (x + size); ii += 1 + step)
373
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
374
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
379
colour = (plane[0] & mask ? 1 : 0) | (plane[1] & mask ? 2 : 0) |
380
(plane[2] & mask ? 4 : 0) | (plane[3] & mask ? 8 : 0);
385
if (!debug_options.windows_disabled)
386
#endif /* MAME_DEBUG */
387
/* Clip to windows */
388
window_enabled = (screen == MAINSCREEN) ? snes_ppu.layer[4].main_window_enabled : snes_ppu.layer[4].sub_window_enabled;
390
colour &= snes_ppu.clipmasks[4][ii];
392
/* Only draw if we have a colour (0 == transparent) */
397
c = snes_cgram[pal + colour];
398
if (blend && screen == MAINSCREEN) /* Only blend main screens */
399
snes_draw_blend(ii/snes_htmult, &c, snes_ppu.layer[4].blend, snes_ppu.sub_color_mask, snes_ppu.main_color_mask);
401
scanlines[screen].buffer[ii] = c;
402
scanlines[screen].zbuf[ii] = priority;
405
scanlines[screen].buffer[ii + 1] = c;
406
scanlines[screen].zbuf[ii + 1] = priority;
413
/*********************************************
416
* Update an entire line of tiles.
417
*********************************************/
418
INLINE void snes_update_line( UINT8 screen, UINT8 color_depth, UINT8 hires, UINT8 priority_a, UINT8 priority_b, UINT8 layer, UINT16 curline, UINT8 offset_per_tile, UINT8 direct_colors )
421
UINT16 ii, vflip, hflip, pal;
422
INT8 line, tile_line;
426
UINT16 vscroll, hscroll, vtilescroll;
427
// UINT16 offset_per_tile_valid;
428
// UINT8 offset_per_tile_mode;
429
UINT8 vshift, hshift, tile_size;
430
/* variables depending on color_depth */
431
UINT8 color_shift = 0;
432
UINT8 color_planes = 2;
433
UINT8 tile_divider = 1;
434
UINT8 wrap_around_x; //helper for wrap-around
437
if (debug_options.bg_disabled[layer])
440
if (debug_options.mode_disabled[snes_ppu.mode])
442
#endif /* MAME_DEBUG */
444
/* Handle Mosaic effects */
445
if (snes_ppu.layer[layer].mosaic_enabled)
446
curline -= (curline % (snes_ppu.mosaic_size + 1));
448
if((snes_ppu.interlace == 2) && !hires)
451
/* Find the size of the tiles (8x8 or 16x16) */
452
tile_size = snes_ppu.layer[layer].tile_size;
453
/* Find scroll info */
454
vscroll = snes_ppu.layer[layer].offset.tile_vert;
455
vshift = snes_ppu.layer[layer].offset.shift_vert;
456
hscroll = snes_ppu.layer[layer].offset.tile_horz;
457
hshift = snes_ppu.layer[layer].offset.shift_horz;
459
/* Find vertical scroll amount */
460
vtilescroll = vscroll + (curline >> (3 + tile_size));
461
/* figure out which line to draw */
462
line = (curline % (8 << tile_size)) + vshift;
463
if (line > ((8 << tile_size) - 1)) /* scrolled into the next tile */
465
vtilescroll++; /* pretend we scrolled by 1 tile line */
466
line -= (8 << tile_size);
468
if( vtilescroll >= 128 )
471
/* Jump to base map address */
472
tmap = snes_ppu.layer[layer].map;
474
/* Offset vertically */
475
tmap += table_vscroll[snes_ppu.layer[layer].map_size & 3][(vtilescroll >> 5) & 3];
476
/* Scroll vertically */
477
tmap += (vtilescroll & 0x1f) << 6;
478
/* Remember this position */
480
/* Offset horizontally */
481
tmap += table_hscroll[snes_ppu.layer[layer].map_size & 3][(hscroll >> 5) & 3];
482
/* Scroll horizontally */
483
tmap += (hscroll & 0x1f) << 1;
485
/* set a couple of variables depending on color_dept */
488
case SNES_COLOR_DEPTH_2BPP:
493
case SNES_COLOR_DEPTH_4BPP:
498
case SNES_COLOR_DEPTH_8BPP:
499
color_shift = 0; //n/a, pal offset is always zero
507
for (ii = 0; ii < (66*(hires+1) >> tile_size); ii += 2)
509
/* Have we scrolled into the next map? */
510
if (wrap_around_x && ((ii >> 1) >= 32 - (hscroll & 0x1f)))
512
tmap = basevmap + table_hscroll[snes_ppu.layer[layer].map_size & 3][((hscroll >> 5) + 1) & 3];
514
wrap_around_x = 0; /* Make sure we don't do this again */
516
//if (tmap > 0x10000)
519
vflip = snes_vram[tmap + ii + 1] & 0x80;
520
hflip = snes_vram[tmap + ii + 1] & 0x40;
521
priority = ((snes_vram[tmap + ii + 1] & 0x20) >> 5) ? priority_b : priority_a;
522
pal = (color_depth == SNES_COLOR_DEPTH_8BPP && direct_colors == 0) ? 0 : (snes_vram[tmap + ii + 1] & 0x1c) << color_shift; /* 8 palettes of (4 * color_shift) colours */
523
tile = (snes_vram[tmap + ii + 1] & 0x3) << 8;
524
tile |= snes_vram[tmap + ii] & 0xff;
526
/* Mode 0 palettes are layer specific */
527
if (snes_ppu.mode == 0)
543
tile += 32 / tile_divider;
546
tile_line = -tile_line + 7;
552
tile += 32 / tile_divider;
558
/* below, only color_planes depends on color_depth */
562
/* Bishoujo Janshi SuchiiPai and Desert Fighter sets this in hires, no noticeable difference apart that x must be doubled somehow... */
563
if (hires) /* Hi-Res: 2bpp & 4bpp */
567
snes_draw_tile_x2(screen, color_planes, layer, snes_ppu.layer[layer].data + (tile * 8 * color_planes) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1) + 16, priority, hflip, pal);
568
snes_draw_tile_x2(screen, color_planes, layer, snes_ppu.layer[layer].data + ((tile + 2) * 8 * color_planes) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal);
572
snes_draw_tile_x2(screen, color_planes, layer, snes_ppu.layer[layer].data + (tile * 8 * color_planes) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal);
573
snes_draw_tile_x2(screen, color_planes, layer, snes_ppu.layer[layer].data + ((tile + 2) * 8 * color_planes) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1) + 16, priority, hflip, pal);
576
else /* No Hi-Res: 2bpp, 4bpp & 8bpp */
579
snes_draw_tile_x2(screen, color_planes, layer, snes_ppu.layer[layer].data + (tile * 8 * color_planes) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip, pal, direct_colors);
582
else /* tile_size = 0 */
584
if (hires) /* Hi-Res: 2bpp & 4bpp */
585
snes_draw_tile_x2(screen, color_planes, layer, snes_ppu.layer[layer].data + (tile * 8 * color_planes) + tile_line, ((ii >> 1) * (8 << (tile_size + 1))) - (hshift << 1), priority, hflip, pal, direct_colors);
586
else /* No Hi-Res: 2bpp, 4bpp & 8bpp */
587
snes_draw_tile(screen, color_planes, layer, snes_ppu.layer[layer].data + (tile * 8 * color_planes) + tile_line, ((ii >> 1) * (8 << tile_size)) - hshift, priority, hflip, pal, direct_colors);
1220
593
/*********************************************
1221
594
* snes_update_line_mode7()
1223
596
* Update an entire line of mode7 tiles.
1224
597
*********************************************/
1225
static void snes_update_line_mode7(UINT8 screen, UINT8 layer, UINT16 curline )
598
#define MODE7_CLIP(x) (((x) & 0x2000) ? ((x) | ~0x03ff) : ((x) & 0x03ff))
600
static void snes_update_line_mode7(UINT8 screen, UINT8 priority_a, UINT8 priority_b, UINT8 layer, UINT16 curline )
1228
603
INT16 ma, mb, mc, md;
1229
INT16 xc, yc, tx, ty, sx, sy, hs, vs, xpos, xdir;
1231
register UINT8 colour = 0;
1233
#ifdef SNES_DBG_video
1234
if( debug_options.bg_disabled[0] )
1236
#endif /* SNES_DBG_video */
604
INT32 xc, yc, tx, ty, sx, sy, hs, vs, xpos, xdir, x0, y0;
605
UINT8 priority = priority_a;
606
UINT8 colour = 0, window_enabled = 0;
607
UINT16 *mosaic_x, *mosaic_y;
610
if (debug_options.bg_disabled[layer])
613
if (debug_options.mode_disabled[snes_ppu.mode])
615
#endif /* MAME_DEBUG */
1238
617
ma = snes_ppu.mode7.matrix_a;
1239
618
mb = snes_ppu.mode7.matrix_b;
878
/*********************************************
879
* snes_update_mode_X()
881
* Update Mode X line.
882
*********************************************/
883
static void snes_update_mode_0( UINT8 screen, UINT16 curline )
886
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
888
if (bg_enabled[4]) snes_update_objects(screen, 0, curline);
889
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 0, 7, 10, 0, curline, 0, 0);
890
if (bg_enabled[1]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 0, 6, 9, 1, curline, 0, 0);
891
if (bg_enabled[2]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 0, 1, 4, 2, curline, 0, 0);
892
if (bg_enabled[3]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 0, 0, 3, 3, curline, 0, 0);
895
static void snes_update_mode_1( UINT8 screen, UINT16 curline )
898
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
900
if (!snes_ppu.bg3_priority_bit)
902
if (bg_enabled[4]) snes_update_objects(screen, 1, curline);
903
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 0, 5, 8, 0, curline, 0, 0);
904
if (bg_enabled[1]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 0, 4, 7, 1, curline, 0, 0);
905
if (bg_enabled[2]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 0, 0, 2, 2, curline, 0, 0);
909
if (bg_enabled[4]) snes_update_objects(screen, 9, curline);
910
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 0, 4, 7, 0, curline, 0, 0);
911
if (bg_enabled[1]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 0, 3, 6, 1, curline, 0, 0);
912
if (bg_enabled[2]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 0, 0, 9, 2, curline, 0, 0);
916
static void snes_update_mode_2( UINT8 screen, UINT16 curline )
919
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
921
if (bg_enabled[4]) snes_update_objects(screen, 2, curline);
922
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 0, 2, 6, 0, curline, 1, 0);
923
if (bg_enabled[1]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 0, 0, 4, 1, curline, 1, 0);
926
static void snes_update_mode_3( UINT8 screen, UINT16 curline )
929
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
931
if (bg_enabled[4]) snes_update_objects(screen, 3, curline);
932
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_8BPP, 0, 2, 6, 0, curline, 0, snes_ppu.direct_color);
933
if (bg_enabled[1]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 0, 0, 4, 1, curline, 0, 0);
936
static void snes_update_mode_4( UINT8 screen, UINT16 curline )
939
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
941
if (bg_enabled[4]) snes_update_objects(screen, 4, curline);
942
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_8BPP, 0, 2, 6, 0, curline, 0, snes_ppu.direct_color);
943
if (bg_enabled[1]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 0, 0, 4, 1, curline, 0, 0);
946
static void snes_update_mode_5( UINT8 screen, UINT16 curline )
949
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
951
if (bg_enabled[4]) snes_update_objects(screen, 5, curline);
952
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 1, 2, 6, 0, curline, 0, 0);
953
if (bg_enabled[1]) snes_update_line(screen, SNES_COLOR_DEPTH_2BPP, 1, 0, 4, 1, curline, 0, 0);
956
static void snes_update_mode_6( UINT8 screen, UINT16 curline )
959
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
961
if (bg_enabled[4]) snes_update_objects(screen, 6, curline);
962
if (bg_enabled[0]) snes_update_line(screen, SNES_COLOR_DEPTH_4BPP, 1, 1, 4, 0, curline, 1, 0);
965
static void snes_update_mode_7( UINT8 screen, UINT16 curline )
967
UINT8 extbg_mode = snes_ram[SETINI] & 0x40;
969
bg_enabled = (screen == MAINSCREEN) ? snes_ppu.main_bg_enabled : snes_ppu.sub_bg_enabled;
973
if (bg_enabled[4]) snes_update_objects(screen, 7, curline);
974
if (bg_enabled[0]) snes_update_line_mode7(screen, 1, 1, 0, curline);
978
if (bg_enabled[4]) snes_update_objects(screen, 8, curline);
979
if (bg_enabled[0]) snes_update_line_mode7(screen, 2, 2, 0, curline);
980
if (bg_enabled[1]) snes_update_line_mode7(screen, 0, 4, 1, curline);
984
/*********************************************
987
* Draw the whole screen (Mode 0 -> 7).
988
*********************************************/
989
static void snes_draw_screen( UINT8 screen, UINT16 curline )
991
switch (snes_ppu.mode)
993
case 0: snes_update_mode_0(screen, curline); break; /* Mode 0 */
994
case 1: snes_update_mode_1(screen, curline); break; /* Mode 1 */
995
case 2: snes_update_mode_2(screen, curline); break; /* Mode 2 - Supports offset per tile */
996
case 3: snes_update_mode_3(screen, curline); break; /* Mode 3 - Supports direct colour */
997
case 4: snes_update_mode_4(screen, curline); break; /* Mode 4 - Supports offset per tile and direct colour */
998
case 5: snes_update_mode_5(screen, curline); break; /* Mode 5 - Supports hires */
999
case 6: snes_update_mode_6(screen, curline); break; /* Mode 6 - Supports offset per tile and hires */
1000
case 7: snes_update_mode_7(screen, curline); break; /* Mode 7 - Supports direct colour */
1464
1004
/*********************************************
1465
1005
* snes_update_windowmasks()
1475
1015
*********************************************/
1476
1016
static void snes_update_windowmasks(void)
1481
1021
snes_ppu.update_windows = 0; /* reset the flag */
1483
for( ii = 0; ii < SNES_SCR_WIDTH; ii++ )
1023
for (ii = 0; ii < SNES_SCR_WIDTH + 8; ii++)
1486
snes_ppu.clipmasks[0][ii] = 0xff;
1488
if( snes_ram[W12SEL] & 0x2 )
1490
if( (ii < snes_ram[WH0]) || (ii > snes_ram[WH1]) )
1494
if( snes_ram[W12SEL] & 0x1 )
1497
if( snes_ram[W12SEL] & 0x8 )
1499
if( (ii < snes_ram[WH2]) || (ii > snes_ram[WH3]) )
1503
if( snes_ram[W12SEL] & 0x4 )
1506
if( w1 >= 0 && w2 >= 0 )
1508
switch( snes_ram[WBGLOG] & 0x3 )
1511
snes_ppu.clipmasks[0][ii] = w1 | w2 ? 0x00 : 0xff;
1514
snes_ppu.clipmasks[0][ii] = w1 & w2 ? 0x00 : 0xff;
1517
snes_ppu.clipmasks[0][ii] = w1 ^ w2 ? 0x00 : 0xff;
1519
case 0x3: /* XNOR */
1520
snes_ppu.clipmasks[0][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1525
snes_ppu.clipmasks[0][ii] = w1 ? 0x00 : 0xff;
1527
snes_ppu.clipmasks[0][ii] = w2 ? 0x00 : 0xff;
1530
snes_ppu.clipmasks[1][ii] = 0xff;
1532
if( snes_ram[W12SEL] & 0x20 )
1534
if( (ii < snes_ram[WH0]) || (ii > snes_ram[WH1]) )
1538
if( snes_ram[W12SEL] & 0x10 )
1541
if( snes_ram[W12SEL] & 0x80 )
1543
if( (ii < snes_ram[WH2]) || (ii > snes_ram[WH3]) )
1547
if( snes_ram[W12SEL] & 0x40 )
1550
if( w1 >= 0 && w2 >= 0 )
1552
switch( snes_ram[WBGLOG] & 0xc )
1555
snes_ppu.clipmasks[1][ii] = w1 | w2 ? 0x00 : 0xff;
1558
snes_ppu.clipmasks[1][ii] = w1 & w2 ? 0x00 : 0xff;
1561
snes_ppu.clipmasks[1][ii] = w1 ^ w2 ? 0x00 : 0xff;
1563
case 0xc: /* XNOR */
1564
snes_ppu.clipmasks[1][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1569
snes_ppu.clipmasks[1][ii] = w1 ? 0x00 : 0xff;
1571
snes_ppu.clipmasks[1][ii] = w2 ? 0x00 : 0xff;
1574
snes_ppu.clipmasks[2][ii] = 0xff;
1576
if( snes_ram[W34SEL] & 0x2 )
1578
if( (ii < snes_ram[WH0]) || (ii > snes_ram[WH1]) )
1582
if( snes_ram[W34SEL] & 0x1 )
1585
if( snes_ram[W34SEL] & 0x8 )
1587
if( (ii < snes_ram[WH2]) || (ii > snes_ram[WH3]) )
1591
if( snes_ram[W34SEL] & 0x4 )
1594
if( w1 >= 0 && w2 >= 0 )
1596
switch( snes_ram[WBGLOG] & 0x30 )
1599
snes_ppu.clipmasks[2][ii] = w1 | w2 ? 0x00 : 0xff;
1601
case 0x10: /* AND */
1602
snes_ppu.clipmasks[2][ii] = w1 & w2 ? 0x00 : 0xff;
1604
case 0x20: /* XOR */
1605
snes_ppu.clipmasks[2][ii] = w1 ^ w2 ? 0x00 : 0xff;
1607
case 0x30: /* XNOR */
1608
snes_ppu.clipmasks[2][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1613
snes_ppu.clipmasks[2][ii] = w1 ? 0x00 : 0xff;
1615
snes_ppu.clipmasks[2][ii] = w2 ? 0x00 : 0xff;
1618
snes_ppu.clipmasks[3][ii] = 0xff;
1620
if( snes_ram[W34SEL] & 0x20 )
1622
if( (ii < snes_ram[WH0]) || (ii > snes_ram[WH1]) )
1626
if( snes_ram[W34SEL] & 0x10 )
1629
if( snes_ram[W34SEL] & 0x80 )
1631
if( (ii < snes_ram[WH2]) || (ii > snes_ram[WH3]) )
1635
if( snes_ram[W34SEL] & 0x40 )
1638
if( w1 >= 0 && w2 >= 0 )
1640
switch( snes_ram[WBGLOG] & 0xc0 )
1643
snes_ppu.clipmasks[3][ii] = w1 | w2 ? 0x00 : 0xff;
1645
case 0x40: /* AND */
1646
snes_ppu.clipmasks[3][ii] = w1 & w2 ? 0x00 : 0xff;
1648
case 0x80: /* XOR */
1649
snes_ppu.clipmasks[3][ii] = w1 ^ w2 ? 0x00 : 0xff;
1651
case 0xc0: /* XNOR */
1652
snes_ppu.clipmasks[3][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1657
snes_ppu.clipmasks[3][ii] = w1 ? 0x00 : 0xff;
1659
snes_ppu.clipmasks[3][ii] = w2 ? 0x00 : 0xff;
1661
/* update objects */
1662
snes_ppu.clipmasks[4][ii] = 0xff;
1664
if( snes_ram[WOBJSEL] & 0x2 )
1666
if( (ii < snes_ram[WH0]) || (ii > snes_ram[WH1]) )
1670
if( snes_ram[WOBJSEL] & 0x1 )
1673
if( snes_ram[WOBJSEL] & 0x8 )
1675
if( (ii < snes_ram[WH2]) || (ii > snes_ram[WH3]) )
1679
if( snes_ram[WOBJSEL] & 0x4 )
1682
if( w1 >= 0 && w2 >= 0 )
1684
switch( snes_ram[WOBJLOG] & 0x3 )
1687
snes_ppu.clipmasks[4][ii] = w1 | w2 ? 0x00 : 0xff;
1690
snes_ppu.clipmasks[4][ii] = w1 & w2 ? 0x00 : 0xff;
1693
snes_ppu.clipmasks[4][ii] = w1 ^ w2 ? 0x00 : 0xff;
1695
case 0x3: /* XNOR */
1696
snes_ppu.clipmasks[4][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1701
snes_ppu.clipmasks[4][ii] = w1 ? 0x00 : 0xff;
1703
snes_ppu.clipmasks[4][ii] = w2 ? 0x00 : 0xff;
1025
/* update bg 1, 2, 3, 4 & obj */
1027
for (jj = 0; jj < 5; jj++)
1029
snes_ppu.clipmasks[jj][ii] = 0xff;
1031
if (snes_ppu.layer[jj].window1_enabled)
1033
if ((ii < snes_ppu.window1_left) || (ii > snes_ppu.window1_right))
1037
if (snes_ppu.layer[jj].window1_invert)
1040
if (snes_ppu.layer[jj].window2_enabled)
1042
if ((ii < snes_ppu.window2_left) || (ii > snes_ppu.window2_right))
1046
if (snes_ppu.layer[jj].window2_invert)
1049
if (w1 >= 0 && w2 >= 0)
1051
switch (snes_ppu.layer[jj].wlog_mask)
1054
snes_ppu.clipmasks[jj][ii] = w1 | w2 ? 0x00 : 0xff;
1056
case 0x01: /* AND */
1057
snes_ppu.clipmasks[jj][ii] = w1 & w2 ? 0x00 : 0xff;
1059
case 0x02: /* XOR */
1060
snes_ppu.clipmasks[jj][ii] = w1 ^ w2 ? 0x00 : 0xff;
1062
case 0x03: /* XNOR */
1063
snes_ppu.clipmasks[jj][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1068
snes_ppu.clipmasks[jj][ii] = w1 ? 0x00 : 0xff;
1070
snes_ppu.clipmasks[jj][ii] = w2 ? 0x00 : 0xff;
1705
1073
/* update colour window */
1706
/* FIXME: Why is the colour window different to the other windows? *
1707
* Have I overlooked something or done something wrong? */
1708
1074
snes_ppu.clipmasks[5][ii] = 0xff;
1710
if( snes_ram[WOBJSEL] & 0x20 )
1076
if (snes_ppu.colour.window1_enabled)
1712
1078
/* Default to mask area inside */
1713
if( (ii < snes_ram[WH0]) || (ii > snes_ram[WH1]) )
1079
if ((ii < snes_ppu.window1_left) || (ii > snes_ppu.window1_right))
1717
1083
/* If mask area is outside then swap */
1718
if( snes_ram[WOBJSEL] & 0x10 )
1084
if (snes_ppu.colour.window1_invert)
1721
if( snes_ram[WOBJSEL] & 0x80 )
1087
if (snes_ppu.colour.window2_enabled)
1723
/* Default to mask area inside */
1724
if( (ii < snes_ram[WH2]) || (ii > snes_ram[WH3]) )
1089
if ((ii < snes_ppu.window2_left) || (ii > snes_ppu.window2_right))
1728
/* If mask area is outside then swap */
1729
if( snes_ram[WOBJSEL] & 0x40 )
1093
if (snes_ppu.colour.window2_invert)
1732
1096
if( w1 >= 0 && w2 >= 0 )
1734
switch( snes_ram[WOBJLOG] & 0xc )
1098
switch (snes_ppu.colour.wlog_mask)
1736
1100
case 0x0: /* OR */
1737
snes_ppu.clipmasks[5][ii] = w1 | w2 ? 0xff : 0x00;
1738
/* snes_ppu.clipmasks[5][ii] = w1 | w2 ? 0x00 : 0xff;*/
1101
snes_ppu.clipmasks[5][ii] = w1 | w2 ? 0x00 : 0xff;
1740
1103
case 0x4: /* AND */
1741
snes_ppu.clipmasks[5][ii] = w1 & w2 ? 0xff : 0x00;
1742
/* snes_ppu.clipmasks[5][ii] = w1 & w2 ? 0x00 : 0xff;*/
1104
snes_ppu.clipmasks[5][ii] = w1 & w2 ? 0x00 : 0xff;
1744
1106
case 0x8: /* XOR */
1745
snes_ppu.clipmasks[5][ii] = w1 ^ w2 ? 0xff : 0x00;
1746
/* snes_ppu.clipmasks[5][ii] = w1 ^ w2 ? 0x00 : 0xff;*/
1107
snes_ppu.clipmasks[5][ii] = w1 ^ w2 ? 0x00 : 0xff;
1748
1109
case 0xc: /* XNOR */
1749
snes_ppu.clipmasks[5][ii] = !(w1 ^ w2) ? 0xff : 0x00;
1750
/* snes_ppu.clipmasks[5][ii] = !(w1 ^ w2) ? 0x00 : 0xff;*/
1110
snes_ppu.clipmasks[5][ii] = !(w1 ^ w2) ? 0x00 : 0xff;
1754
1114
else if( w1 >= 0 )
1755
snes_ppu.clipmasks[5][ii] = w1 ? 0xff : 0x00;
1756
/* snes_ppu.clipmasks[5][ii] = w1 ? 0x00 : 0xff;*/
1115
snes_ppu.clipmasks[5][ii] = w1 ? 0x00 : 0xff;
1757
1116
else if( w2 >= 0 )
1758
snes_ppu.clipmasks[5][ii] = w2 ? 0xff : 0x00;
1759
/* snes_ppu.clipmasks[5][ii] = w2 ? 0x00 : 0xff;*/
1117
snes_ppu.clipmasks[5][ii] = w2 ? 0x00 : 0xff;