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