1 // license:BSD-3-Clause
2 // copyright-holders:David Graves
3 #include "emu.h"
4 #include "includes/ninjaw.h"
5 
6 /************************************************************
7             SPRITE DRAW ROUTINE
8 ************************************************************/
9 
draw_sprites(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,int x_offs,int y_offs,int chip)10 void ninjaw_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int x_offs, int y_offs, int chip)
11 {
12 #ifdef MAME_DEBUG
13 	int unknown = 0;
14 #endif
15 
16 	static const u32 primask[2] =
17 	{
18 		GFX_PMASK_4, // draw sprites with priority 0 which are over the mid layer
19 		(GFX_PMASK_4 | GFX_PMASK_2) // draw sprites with priority 1 which are under the mid layer
20 	};
21 
22 	for (int offs = 0; offs < (m_spriteram.bytes() / 2); offs += 4)
23 	{
24 		int data = m_spriteram[offs + 2];
25 		const u32 tilenum = data & 0x7fff;
26 
27 		if (!tilenum)
28 			continue;
29 
30 		data = m_spriteram[offs + 0];
31 		int x = (data - 32) & 0x3ff;    /* aligns sprites on rock outcrops and sewer hole */
32 
33 		data = m_spriteram[offs + 1];
34 		int y = (data - 0) & 0x1ff;
35 
36 		/*
37 		    The purpose of the bit at data&0x8 (below) is unknown, but it is set
38 		    on Darius explosions, some enemy missiles and at least 1 boss.
39 		    It is most likely another priority bit but as there are no obvious
40 		    visual problems it will need checked against the original pcb.
41 
42 		    There is a report this bit is set when the player intersects
43 		    the tank sprite in Ninja Warriors however I was unable to repro
44 		    this or find any use of this bit in that game.
45 
46 		    Bit&0x8000 is set on some sprites in later levels of Darius
47 		    but is again unknown, and there is no obvious visual problem.
48 		*/
49 		data = m_spriteram[offs + 3];
50 		const bool flipx = (data & 0x1);
51 		const bool flipy = (data & 0x2) >> 1;
52 		const int priority = (data & 0x4) >> 2; // 1 = low
53 		/* data&0x8 - unknown */
54 		const u32 color = (data & 0x7f00) >> 8;
55 		/* data&0x8000 - unknown */
56 
57 #ifdef MAME_DEBUG
58 		if (data & 0x80f0)   unknown |= (data &0x80f0);
59 #endif
60 
61 		x -= x_offs;
62 		y += y_offs;
63 
64 		/* sprite wrap: coords become negative at high values */
65 		if (x > 0x3c0) x -= 0x400;
66 		if (y > 0x180) y -= 0x200;
67 
68 		const int curx = x;
69 		const int cury = y;
70 		const u32 code = tilenum;
71 
72 		m_gfxdecode[chip]->gfx(0)->prio_transpen(bitmap,cliprect,
73 				code, color,
74 				flipx, flipy,
75 				curx, cury,
76 				screen.priority(), primask[priority],
77 				0);
78 	}
79 
80 #ifdef MAME_DEBUG
81 	if (unknown)
82 		popmessage("unknown sprite bits: %04x",unknown);
83 #endif
84 }
85 
86 
87 /**************************************************************
88                 SCREEN REFRESH
89 **************************************************************/
90 
update_screen(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,int xoffs,int chip)91 u32 ninjaw_state::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int xoffs, int chip)
92 {
93 	tc0100scn_device *tc0100scn = m_tc0100scn[chip];
94 	xoffs *= chip;
95 	u8 layer[3];
96 
97 	tc0100scn->tilemap_update();
98 
99 	layer[0] = m_tc0100scn[0]->bottomlayer();
100 	layer[1] = layer[0] ^ 1;
101 	layer[2] = 2;
102 
103 	screen.priority().fill(0, cliprect);
104 	/* chip 0 does tilemaps on the left, chip 1 center, chip 2 the right */
105 	// draw bottom layer
106 	u8 nodraw = tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 1);    /* left */
107 
108 	/* Ensure screen blanked even when bottom layers not drawn due to disable bit */
109 	if (nodraw)
110 		bitmap.fill(m_tc0110pcr[chip]->black_pen(), cliprect);
111 
112 	// draw middle layer
113 	tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2);
114 
115 	// draw top(text) layer
116 	tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4);
117 
118 	/* Sprites can be under/over the layer below text layer */
119 	draw_sprites(screen, bitmap, cliprect, xoffs, 8, chip);
120 
121 	return 0;
122 }
123 
screen_update_left(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)124 u32 ninjaw_state::screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 36 * 8, 0); }
screen_update_middle(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)125 u32 ninjaw_state::screen_update_middle(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 36 * 8, 1); }
screen_update_right(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)126 u32 ninjaw_state::screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 36 * 8, 2); }
127