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