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