1 // license:GPL-2.0+
2 // copyright-holders:Jarek Burczynski
3 /*
4 * Video Driver for Tank Busters
5 */
6
7 #include "emu.h"
8 #include "includes/tankbust.h"
9
10
11 /***************************************************************************
12
13 Callbacks for the TileMap code
14
15 ***************************************************************************/
16
17 /* background tilemap :
18
19 0xc000-0xc7ff: xxxx xxxx tile code: 8 lsb bits
20
21 0xc800-0xcfff: .... .xxx tile code: 3 msb bits
22 .... x... tile priority ON TOP of sprites (roofs and part of the rails)
23 .xxx .... tile color code
24 x... .... ?? set on *all* roofs (a different bg/sprite priority ?)
25
26 note:
27 - seems that the only way to get color test right is to swap bit 1 and bit 0 of color code
28
29 */
30
TILE_GET_INFO_MEMBER(tankbust_state::get_bg_tile_info)31 TILE_GET_INFO_MEMBER(tankbust_state::get_bg_tile_info)
32 {
33 int code = m_videoram[tile_index];
34 int attr = m_colorram[tile_index];
35
36 int color = ((attr>>4) & 0x07);
37
38 code |= (attr&0x07) * 256;
39
40
41 #if 0
42 if (attr&0x08) //priority bg/sprites (1 = this bg tile on top of sprites)
43 {
44 color = ((int)machine().rand()) & 0x0f;
45 }
46 if (attr&0x80) //all the roofs of all buildings have this bit set. What's this ???
47 {
48 color = ((int)machine().rand()) & 0x0f;
49 }
50 #endif
51
52 /* priority bg/sprites (1 = this bg tile on top of sprites) */
53 tileinfo.category = (attr & 0x08) >> 3;
54
55 tileinfo.set(1,
56 code,
57 (color&4) | ((color&2)>>1) | ((color&1)<<1),
58 0);
59 }
60
TILE_GET_INFO_MEMBER(tankbust_state::get_txt_tile_info)61 TILE_GET_INFO_MEMBER(tankbust_state::get_txt_tile_info)
62 {
63 int code = m_txtram[tile_index];
64 int color = ((code>>6) & 0x03);
65
66 tileinfo.set(2,
67 code & 0x3f,
68 ((color&2)>>1) | ((color&1)<<1),
69 0);
70 }
71
72
73 /***************************************************************************
74
75 Start the video hardware emulation.
76
77 ***************************************************************************/
78
video_start()79 void tankbust_state::video_start()
80 {
81 /* not scrollable */
82 m_txt_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tankbust_state::get_txt_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
83
84 /* scrollable */
85 m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tankbust_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
86
87 m_txt_tilemap->set_transparent_pen(0);
88
89 save_item(NAME(m_xscroll));
90 save_item(NAME(m_yscroll));
91 }
92
93
94 /***************************************************************************
95
96 Memory handlers
97
98 ***************************************************************************/
99
background_videoram_w(offs_t offset,uint8_t data)100 void tankbust_state::background_videoram_w(offs_t offset, uint8_t data)
101 {
102 m_videoram[offset] = data;
103 m_bg_tilemap->mark_tile_dirty(offset);
104 }
105
background_colorram_w(offs_t offset,uint8_t data)106 void tankbust_state::background_colorram_w(offs_t offset, uint8_t data)
107 {
108 m_colorram[offset] = data;
109 m_bg_tilemap->mark_tile_dirty(offset);
110 }
111
txtram_w(offs_t offset,uint8_t data)112 void tankbust_state::txtram_w(offs_t offset, uint8_t data)
113 {
114 m_txtram[offset] = data;
115 m_txt_tilemap->mark_tile_dirty(offset);
116 }
117
xscroll_w(offs_t offset,uint8_t data)118 void tankbust_state::xscroll_w(offs_t offset, uint8_t data)
119 {
120 if( m_xscroll[offset] != data )
121 {
122 int x;
123
124 m_xscroll[offset] = data;
125
126 x = m_xscroll[0] + 256 * (m_xscroll[1]&1);
127 if (x>=0x100) x-=0x200;
128 m_bg_tilemap->set_scrollx(0, x );
129 }
130 //popmessage("x=%02x %02x", m_xscroll[0], m_xscroll[1]);
131 }
132
133
yscroll_w(offs_t offset,uint8_t data)134 void tankbust_state::yscroll_w(offs_t offset, uint8_t data)
135 {
136 if( m_yscroll[offset] != data )
137 {
138 int y;
139
140 m_yscroll[offset] = data;
141 y = m_yscroll[0];
142 if (y>=0x80) y-=0x100;
143 m_bg_tilemap->set_scrolly(0, y );
144 }
145 //popmessage("y=%02x %02x", m_yscroll[0], m_yscroll[1]);
146 }
147
148 /***************************************************************************
149
150 Display refresh
151
152 ***************************************************************************/
153 /*
154 spriteram format (4 bytes per sprite):
155
156 offset 0 x....... flip X
157 offset 0 .x...... flip Y
158 offset 0 ..xxxxxx gfx code (6 bits)
159
160 offset 1 xxxxxxxx y position
161
162 offset 2 ??????.. not used ?
163 offset 2 ......?. used but unknown ??? (color code ? or x ?)
164 offset 2 .......x x position (1 MSB bit)
165
166 offset 3 xxxxxxxx x position (8 LSB bits)
167 */
168
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)169 void tankbust_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
170 {
171 for (int offs = 0; offs < m_spriteram.bytes(); offs += 4)
172 {
173 int code,color,sx,sy,flipx,flipy;
174
175 code = m_spriteram[offs+0] & 0x3f;
176 flipy = m_spriteram[offs+0] & 0x40;
177 flipx = m_spriteram[offs+0] & 0x80;
178
179 sy = (240- m_spriteram[offs+1]) - 14;
180 sx = (m_spriteram[offs+2] & 0x01) * 256 + m_spriteram[offs+3] - 7;
181
182 color = 0;
183
184 //0x02 - don't know (most of the time this bit is set in tank sprite and others but not all and not always)
185 //0x04 - not used
186 //0x08 - not used
187 //0x10 - not used
188 //0x20 - not used
189 //0x40 - not used
190 //0x80 - not used
191 #if 0
192 if ((m_spriteram[offs+2] & 0x02))
193 {
194 code = ((int)machine().rand()) & 63;
195 }
196 #endif
197
198 if ((m_spriteram[offs+1]!=4)) //otherwise - ghost sprites
199 {
200 m_gfxdecode->gfx(0)->transpen(bitmap,cliprect,
201 code, color,
202 flipx,flipy,
203 sx,sy,0);
204 }
205 }
206 }
207
208
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)209 uint32_t tankbust_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
210 {
211 #if 0
212 for (int i=0; i<0x800; i++)
213 {
214 int tile_attrib = m_colorram[i];
215
216 if ( (tile_attrib&8) || (tile_attrib&0x80) )
217 {
218 m_bg_tilemap->mark_tile_dirty(i);
219 }
220 }
221 #endif
222
223 m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
224 draw_sprites(bitmap, cliprect);
225 m_bg_tilemap->draw(screen, bitmap, cliprect, 1, 0);
226
227 m_txt_tilemap->draw(screen, bitmap, cliprect, 0,0);
228 return 0;
229 }
230