1 // license:BSD-3-Clause
2 // copyright-holders:Nicola Salmoria
3 #include "emu.h"
4 #include "includes/aerofgt.h"
5 #include "screen.h"
6 
7 /***************************************************************************
8 
9   Callbacks for the TileMap code
10 
11 ***************************************************************************/
12 
TILE_GET_INFO_MEMBER(aerofgt_state::get_pspikes_tile_info)13 TILE_GET_INFO_MEMBER(aerofgt_state::get_pspikes_tile_info)
14 {
15 	uint16_t code = m_vram[0][tile_index];
16 	int bank = (code & 0x1000) >> 12;
17 	tileinfo.set(0,
18 			(code & 0x0fff) | (m_gfxbank[bank] << 12),
19 			((code & 0xe000) >> 13) + 8 * m_charpalettebank,
20 			0);
21 }
22 
23 /* also spinlbrk */
24 template<int Layer>
TILE_GET_INFO_MEMBER(aerofgt_state::karatblz_tile_info)25 TILE_GET_INFO_MEMBER(aerofgt_state::karatblz_tile_info)
26 {
27 	uint16_t code = m_vram[Layer][tile_index];
28 	tileinfo.set(Layer,
29 			(code & 0x1fff) | (m_gfxbank[Layer] << 13),
30 			(code & 0xe000) >> 13,
31 			0);
32 }
33 
34 template<int Layer>
TILE_GET_INFO_MEMBER(aerofgt_state::spinlbrk_tile_info)35 TILE_GET_INFO_MEMBER(aerofgt_state::spinlbrk_tile_info)
36 {
37 	uint16_t code = m_vram[Layer][tile_index];
38 	tileinfo.set(Layer,
39 			(code & 0x0fff) | (m_gfxbank[Layer] << 12),
40 			(code & 0xf000) >> 12,
41 			0);
42 }
43 
44 template<int Layer>
TILE_GET_INFO_MEMBER(aerofgt_state::get_tile_info)45 TILE_GET_INFO_MEMBER(aerofgt_state::get_tile_info)
46 {
47 	uint16_t code = m_vram[Layer][tile_index];
48 	int bank = (Layer << 2) | (code & 0x1800) >> 11;
49 	tileinfo.set(Layer,
50 			(code & 0x07ff) | (m_gfxbank[bank] << 11),
51 			(code & 0xe000) >> 13,
52 			0);
53 }
54 
55 
56 /***************************************************************************
57 
58   Start the video hardware emulation.
59 
60 ***************************************************************************/
61 
62 
aerofgt_register_state_globals()63 void aerofgt_state::aerofgt_register_state_globals(  )
64 {
65 	save_item(NAME(m_gfxbank));
66 	save_item(NAME(m_bank));
67 	save_item(NAME(m_scrollx));
68 	save_item(NAME(m_scrolly));
69 	save_item(NAME(m_flip_screen));
70 	save_item(NAME(m_charpalettebank));
71 	save_item(NAME(m_spritepalettebank));
72 }
73 
VIDEO_START_MEMBER(aerofgt_state,pspikes)74 VIDEO_START_MEMBER(aerofgt_state,pspikes)
75 {
76 	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::get_pspikes_tile_info)), TILEMAP_SCAN_ROWS, 8,8, 64,32);
77 	/* no bg2 in this game */
78 
79 	m_sprite_gfx = 1;
80 
81 	aerofgt_register_state_globals();
82 	save_item(NAME(m_spikes91_lookup));
83 }
84 
VIDEO_START_MEMBER(aerofgt_state,karatblz)85 VIDEO_START_MEMBER(aerofgt_state,karatblz)
86 {
87 	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::karatblz_tile_info<0>)), TILEMAP_SCAN_ROWS, 8,8, 64,64);
88 	m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::karatblz_tile_info<1>)), TILEMAP_SCAN_ROWS, 8,8, 64,64);
89 
90 	m_tilemap[1]->set_transparent_pen(15);
91 	m_spritepalettebank = 0;
92 	m_sprite_gfx = 2;
93 
94 	aerofgt_register_state_globals();
95 }
96 
VIDEO_START_MEMBER(aerofgt_state,spinlbrk)97 VIDEO_START_MEMBER(aerofgt_state,spinlbrk)
98 {
99 	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::spinlbrk_tile_info<0>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
100 	m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::karatblz_tile_info<1>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
101 
102 	m_tilemap[1]->set_transparent_pen(15);
103 
104 	m_spritepalettebank = 0;
105 	m_sprite_gfx = 2;
106 
107 	/* sprite maps are hardcoded in this game */
108 
109 	aerofgt_register_state_globals();
110 }
111 
VIDEO_START_MEMBER(aerofgt_state,turbofrc)112 VIDEO_START_MEMBER(aerofgt_state,turbofrc)
113 {
114 	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
115 	m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
116 
117 	m_tilemap[1]->set_transparent_pen(15);
118 
119 	m_spritepalettebank = 0;
120 	m_sprite_gfx = 2;
121 
122 	aerofgt_register_state_globals();
123 }
124 
125 
126 /* new hw type */
aerofgt_tile_callback(uint32_t code)127 uint32_t aerofgt_state::aerofgt_tile_callback( uint32_t code )
128 {
129 	return m_sprlookupram[0][code&0x7fff];
130 }
131 
132 
133 /* old hw type */
aerofgt_old_tile_callback(uint32_t code)134 uint32_t aerofgt_state::aerofgt_old_tile_callback( uint32_t code )
135 {
136 	return m_sprlookupram[0][code % (m_sprlookupram[0].bytes()/2)];
137 }
138 
aerofgt_ol2_tile_callback(uint32_t code)139 uint32_t aerofgt_state::aerofgt_ol2_tile_callback( uint32_t code )
140 {
141 	return m_sprlookupram[1][code % (m_sprlookupram[1].bytes()/2)];
142 }
143 
spinbrk_tile_callback(uint32_t code)144 uint32_t aerofgt_state::spinbrk_tile_callback( uint32_t code )
145 {
146 	/* enemy sprites use ROM instead of RAM */
147 	return m_sprlookuprom[code % m_sprlookuprom.length()];
148 }
149 
150 
151 /***************************************************************************
152 
153   Memory handlers
154 
155 ***************************************************************************/
156 
setbank(int layer,int num,int bank)157 void aerofgt_state::setbank( int layer, int num, int bank )
158 {
159 	if (m_gfxbank[num] != bank)
160 	{
161 		m_gfxbank[num] = bank;
162 		m_tilemap[layer]->mark_all_dirty();
163 	}
164 }
165 
pspikes_gfxbank_w(uint8_t data)166 void aerofgt_state::pspikes_gfxbank_w(uint8_t data)
167 {
168 	setbank(0, 0, (data & 0xf0) >> 4);
169 	setbank(0, 1, data & 0x0f);
170 }
171 
karatblz_gfxbank_w(uint8_t data)172 void aerofgt_state::karatblz_gfxbank_w(uint8_t data)
173 {
174 	setbank(0, 0, (data & 0x01));
175 	setbank(1, 1, (data & 0x08) >> 3);
176 }
177 
spinlbrk_gfxbank_w(uint8_t data)178 void aerofgt_state::spinlbrk_gfxbank_w(uint8_t data)
179 {
180 	setbank(0, 0, (data & 0x07));
181 	setbank(1, 1, (data & 0x38) >> 3);
182 }
183 
turbofrc_gfxbank_w(offs_t offset,uint16_t data,uint16_t mem_mask)184 void aerofgt_state::turbofrc_gfxbank_w(offs_t offset, uint16_t data, uint16_t mem_mask)
185 {
186 	data = COMBINE_DATA(&m_bank[offset]);
187 
188 	setbank(offset, 4 * offset + 0, (data >> 0) & 0x0f);
189 	setbank(offset, 4 * offset + 1, (data >> 4) & 0x0f);
190 	setbank(offset, 4 * offset + 2, (data >> 8) & 0x0f);
191 	setbank(offset, 4 * offset + 3, (data >> 12) & 0x0f);
192 }
193 
aerofgt_gfxbank_w(offs_t offset,uint16_t data,uint16_t mem_mask)194 void aerofgt_state::aerofgt_gfxbank_w(offs_t offset, uint16_t data, uint16_t mem_mask)
195 {
196 	data = COMBINE_DATA(&m_bank[offset]);
197 
198 	setbank(offset >> 1, 2 * offset + 0, (data >> 8) & 0xff);
199 	setbank(offset >> 1, 2 * offset + 1, (data >> 0) & 0xff);
200 }
201 
kickball_gfxbank_w(uint8_t data)202 void aerofgt_state::kickball_gfxbank_w(uint8_t data)
203 {
204 	// I strongly doubt this logic is correct
205 	setbank(0, 0, (data & 0x0f)&~0x01);
206 	setbank(0, 1, (data & 0x0f));
207 }
208 
pspikes_palette_bank_w(uint8_t data)209 void aerofgt_state::pspikes_palette_bank_w(uint8_t data)
210 {
211 	m_spritepalettebank = data & 0x03;
212 	if (m_charpalettebank != (data & 0x1c) >> 2)
213 	{
214 		m_charpalettebank = (data & 0x1c) >> 2;
215 		m_tilemap[0]->mark_all_dirty();
216 	}
217 
218 	m_flip_screen = BIT(data, 7);
219 	m_tilemap[0]->set_flip(m_flip_screen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
220 }
221 
spinlbrk_flip_screen_w(uint8_t data)222 void aerofgt_state::spinlbrk_flip_screen_w(uint8_t data)
223 {
224 	m_flip_screen = BIT(data, 7);
225 	m_tilemap[0]->set_flip(m_flip_screen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
226 	m_tilemap[1]->set_flip(m_flip_screen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
227 }
228 
turbofrc_flip_screen_w(uint8_t data)229 void aerofgt_state::turbofrc_flip_screen_w(uint8_t data)
230 {
231 	m_flip_screen = BIT(data, 7);
232 	m_tilemap[0]->set_flip(m_flip_screen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
233 	m_tilemap[1]->set_flip(m_flip_screen ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
234 
235 	// bit 6 = ?
236 }
237 
238 
239 /***************************************************************************
240 
241   Display refresh
242 
243 ***************************************************************************/
244 
245 
screen_update_pspikes(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)246 uint32_t aerofgt_state::screen_update_pspikes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
247 {
248 	int i, scrolly;
249 
250 	m_tilemap[0]->set_scroll_rows(256);
251 	scrolly = m_scrolly[0];
252 	for (i = 0; i < 256; i++)
253 		m_tilemap[0]->set_scrollx((i + scrolly) & 0xff, m_rasterram[i]);
254 	m_tilemap[0]->set_scrolly(0, scrolly);
255 
256 	screen.priority().fill(0, cliprect);
257 
258 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
259 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram,m_spriteram.bytes(),m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen);
260 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram,m_spriteram.bytes(),m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen);
261 	return 0;
262 }
263 
264 
screen_update_karatblz(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)265 uint32_t aerofgt_state::screen_update_karatblz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
266 {
267 	m_tilemap[0]->set_scrollx(0, m_scrollx[0] - 8);
268 	m_tilemap[0]->set_scrolly(0, m_scrolly[0]);
269 	m_tilemap[1]->set_scrollx(0, m_scrollx[1] - 4);
270 	m_tilemap[1]->set_scrolly(0, m_scrolly[1]);
271 
272 	screen.priority().fill(0, cliprect);
273 
274 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
275 	m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
276 
277 	/* we use the priority buffer so sprites are drawn front to back */
278 	m_spr_old[1]->turbofrc_draw_sprites(m_spriteram+0x200,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen);
279 	m_spr_old[1]->turbofrc_draw_sprites(m_spriteram+0x200,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen);
280 
281 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram+0x000,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen);
282 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram+0x000,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen);
283 	return 0;
284 }
285 
screen_update_spinlbrk(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)286 uint32_t aerofgt_state::screen_update_spinlbrk(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
287 {
288 	int i, scrolly;
289 
290 	m_tilemap[0]->set_scroll_rows(512);
291 	scrolly = 0;
292 	for (i = 0; i < 256; i++)
293 		m_tilemap[0]->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[i] - 8);
294 //  m_tilemap[0]->set_scrolly(0, m_scrolly[0]);
295 	m_tilemap[1]->set_scrollx(0, m_scrollx[1] - 4);
296 //  m_tilemap[1]->set_scrolly(0, m_scrolly[1]);
297 
298 	screen.priority().fill(0, cliprect);
299 
300 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
301 	m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 1);
302 
303 	/* we use the priority buffer so sprites are drawn front to back */
304 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram+0x000,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen);
305 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram+0x000,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen);
306 
307 	m_spr_old[1]->turbofrc_draw_sprites(m_spriteram+0x200,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen);
308 	m_spr_old[1]->turbofrc_draw_sprites(m_spriteram+0x200,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen);
309 	return 0;
310 }
311 
screen_update_turbofrc(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)312 uint32_t aerofgt_state::screen_update_turbofrc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
313 {
314 	int i, scrolly;
315 
316 	m_tilemap[0]->set_scroll_rows(512);
317 	scrolly = m_scrolly[0] + 2;
318 	for (i = 0; i < 256; i++)
319 //      m_tilemap[0]->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[i] - 11);
320 		m_tilemap[0]->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[7] - 11 - (m_flip_screen ? 188 : 0));
321 	m_tilemap[0]->set_scrolly(0, scrolly - (m_flip_screen ? 2 : 0));
322 	m_tilemap[1]->set_scrollx(0, m_scrollx[1] - (m_flip_screen ? 185 : 7));
323 	m_tilemap[1]->set_scrolly(0, m_scrolly[1] + (m_flip_screen ? 0 : 2));
324 
325 	screen.priority().fill(0, cliprect);
326 
327 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
328 	m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 1);
329 
330 	/* we use the priority buffer so sprites are drawn front to back */
331 	m_spr_old[1]->turbofrc_draw_sprites(m_spriteram+0x200,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen); //ship
332 	m_spr_old[1]->turbofrc_draw_sprites(m_spriteram+0x200,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen); //intro
333 
334 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram+0x000,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen); //enemy
335 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram+0x000,m_spriteram.bytes()/2,m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen); //enemy
336 	return 0;
337 }
338 
screen_update_aerofgt(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)339 uint32_t aerofgt_state::screen_update_aerofgt(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
340 {
341 	m_tilemap[0]->set_scrollx(0, m_rasterram[0x0000] - 18);
342 	m_tilemap[0]->set_scrolly(0, m_scrolly[0]);
343 	m_tilemap[1]->set_scrollx(0, m_rasterram[0x0200] - 20);
344 	m_tilemap[1]->set_scrolly(0, m_scrolly[1]);
345 
346 	screen.priority().fill(0, cliprect);
347 
348 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
349 
350 	m_spr->draw_sprites(m_spriteram, m_spriteram.bytes(), screen, bitmap, cliprect, 0x03, 0x00);
351 	m_spr->draw_sprites(m_spriteram, m_spriteram.bytes(), screen, bitmap, cliprect, 0x03, 0x01);
352 
353 	m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
354 
355 	m_spr->draw_sprites(m_spriteram, m_spriteram.bytes(), screen, bitmap, cliprect, 0x03, 0x02);
356 	m_spr->draw_sprites(m_spriteram, m_spriteram.bytes(), screen, bitmap, cliprect, 0x03, 0x03);
357 	return 0;
358 }
359 
360 
361 /***************************************************************************
362 
363   BOOTLEG SUPPORT
364 
365 ***************************************************************************/
366 
367 // BOOTLEG
VIDEO_START_MEMBER(aerofgt_state,wbbc97)368 VIDEO_START_MEMBER(aerofgt_state,wbbc97)
369 {
370 	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(aerofgt_state::get_pspikes_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
371 	/* no bg2 in this game */
372 
373 	m_tilemap[0]->set_transparent_pen(15);
374 
375 	m_sprite_gfx = 1;
376 
377 	aerofgt_register_state_globals();
378 
379 	save_item(NAME(m_wbbc97_bitmap_enable));
380 }
381 
382 // BOOTLEG
pspikesb_gfxbank_w(offs_t offset,uint16_t data,uint16_t mem_mask)383 void aerofgt_state::pspikesb_gfxbank_w(offs_t offset, uint16_t data, uint16_t mem_mask)
384 {
385 	COMBINE_DATA(&m_rasterram[0x200 / 2]);
386 
387 	setbank(0, 0, (data & 0xf000) >> 12);
388 	setbank(0, 1, (data & 0x0f00) >> 8);
389 }
390 
391 // BOOTLEG
spikes91_lookup_w(uint16_t data)392 void aerofgt_state::spikes91_lookup_w(uint16_t data)
393 {
394 	m_spikes91_lookup = data & 1;
395 }
396 
397 // BOOTLEG
wbbc97_bitmap_enable_w(offs_t offset,uint16_t data,uint16_t mem_mask)398 void aerofgt_state::wbbc97_bitmap_enable_w(offs_t offset, uint16_t data, uint16_t mem_mask)
399 {
400 	COMBINE_DATA(&m_wbbc97_bitmap_enable);
401 }
402 
403 // BOOTLEG
aerfboo2_draw_sprites(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,int chip,int chip_disabled_pri)404 void aerofgt_state::aerfboo2_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, int chip_disabled_pri )
405 {
406 	int attr_start, base, first;
407 
408 	base = chip * 0x0200;
409 //  first = 4 * m_spriteram[0x1fe + base];
410 	first = 0;
411 
412 	for (attr_start = base + 0x0200 - 4; attr_start >= first + base; attr_start -= 4)
413 	{
414 		int map_start;
415 		int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color, pri;
416 // some other drivers still use this wrong table, they have to be upgraded
417 //      int zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 };
418 
419 		if (!(m_spriteram[attr_start + 2] & 0x0080))
420 			continue;
421 
422 		pri = m_spriteram[attr_start + 2] & 0x0010;
423 
424 		if ( chip_disabled_pri && !pri)
425 			continue;
426 		if ((!chip_disabled_pri) && (pri >> 4))
427 			continue;
428 		ox = m_spriteram[attr_start + 1] & 0x01ff;
429 		xsize = (m_spriteram[attr_start + 2] & 0x0700) >> 8;
430 		zoomx = (m_spriteram[attr_start + 1] & 0xf000) >> 12;
431 		oy = m_spriteram[attr_start + 0] & 0x01ff;
432 		ysize = (m_spriteram[attr_start + 2] & 0x7000) >> 12;
433 		zoomy = (m_spriteram[attr_start + 0] & 0xf000) >> 12;
434 		flipx = m_spriteram[attr_start + 2] & 0x0800;
435 		flipy = m_spriteram[attr_start + 2] & 0x8000;
436 		color = (m_spriteram[attr_start + 2] & 0x000f) + 16 * m_spritepalettebank;
437 
438 		map_start = m_spriteram[attr_start + 3];
439 
440 // aerofgt has this adjustment, but doing it here would break turbo force title screen
441 //      ox += (xsize*zoomx+2)/4;
442 //      oy += (ysize*zoomy+2)/4;
443 
444 		zoomx = 32 - zoomx;
445 		zoomy = 32 - zoomy;
446 
447 		for (y = 0; y <= ysize; y++)
448 		{
449 			int sx, sy;
450 
451 			if (flipy)
452 				sy = ((oy + zoomy * (ysize - y)/2 + 16) & 0x1ff) - 16;
453 			else
454 				sy = ((oy + zoomy * y / 2 + 16) & 0x1ff) - 16;
455 
456 			for (x = 0; x <= xsize; x++)
457 			{
458 				int code;
459 
460 				if (flipx)
461 					sx = ((ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff) - 16;
462 				else
463 					sx = ((ox + zoomx * x / 2 + 16) & 0x1ff) - 16;
464 
465 				code = m_sprlookupram[chip][map_start % (m_sprlookupram[chip].bytes()/2)];
466 
467 				m_gfxdecode->gfx(m_sprite_gfx + chip)->prio_zoom_transpen(bitmap,cliprect,
468 								code,
469 								color,
470 								flipx,flipy,
471 								sx,sy,
472 								zoomx << 11, zoomy << 11,
473 								screen.priority(),pri ? 0 : 2,15);
474 				map_start++;
475 			}
476 
477 			if (xsize == 2) map_start += 1;
478 			if (xsize == 4) map_start += 3;
479 			if (xsize == 5) map_start += 2;
480 			if (xsize == 6) map_start += 1;
481 		}
482 	}
483 }
484 
485 // BOOTLEG
pspikesb_draw_sprites(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)486 void aerofgt_state::pspikesb_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
487 {
488 	int i;
489 
490 	for (i = 4; i < m_spriteram.bytes() / 2; i += 4)
491 	{
492 		int xpos, ypos, color, flipx, flipy, code;
493 
494 		if (m_spriteram[i + 3 - 4] & 0x8000)
495 			break;
496 
497 		xpos = (m_spriteram[i + 2] & 0x1ff) - 34;
498 		ypos = 256 - (m_spriteram[i + 3 - 4] & 0x1ff) - 33;
499 		code = m_spriteram[i + 0] & 0x1fff;
500 		flipy = 0;
501 		flipx = m_spriteram[i + 1] & 0x0800;
502 		color = m_spriteram[i + 1] & 0x000f;
503 
504 		m_gfxdecode->gfx(m_sprite_gfx)->transpen(bitmap,cliprect,
505 				code,
506 				color,
507 				flipx,flipy,
508 				xpos,ypos,15);
509 
510 		/* wrap around y */
511 		m_gfxdecode->gfx(m_sprite_gfx)->transpen(bitmap,cliprect,
512 				code,
513 				color,
514 				flipx,flipy,
515 				xpos,ypos + 512,15);
516 
517 	}
518 }
519 
520 // BOOTLEG
spikes91_draw_sprites(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)521 void aerofgt_state::spikes91_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
522 {
523 	int i;
524 	m_spritepalettebank = 1;
525 
526 	for (i = m_spriteram.bytes() / 2 - 4; i >= 4; i -= 4)
527 	{
528 		int xpos, ypos, color, flipx, flipy, code;
529 
530 		code = m_spriteram[i + 0] & 0x1fff;
531 
532 		if (!code)
533 			continue;
534 
535 		xpos = (m_spriteram[i + 2] & 0x01ff) - 16;
536 		ypos = 256 - (m_spriteram[i + 1] & 0x00ff) - 26;
537 		flipy = 0;
538 		flipx = m_spriteram[i + 3] & 0x8000;
539 		color = ((m_spriteram[i + 3] & 0x00f0) >> 4);
540 
541 		code |= m_spikes91_lookup * 0x2000;
542 
543 		m_gfxdecode->gfx(m_sprite_gfx)->transpen(bitmap,cliprect,
544 				m_sprlookuprom[code],
545 				color,
546 				flipx,flipy,
547 				xpos,ypos,15);
548 
549 		/* wrap around y */
550 		m_gfxdecode->gfx(m_sprite_gfx)->transpen(bitmap,cliprect,
551 				m_sprlookuprom[code],
552 				color,
553 				flipx,flipy,
554 				xpos,ypos + 512,15);
555 	}
556 }
557 
558 // BOOTLEG
aerfboot_draw_sprites(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)559 void aerofgt_state::aerfboot_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
560 {
561 	int attr_start, last;
562 
563 	last = ((m_rasterram[0x404 / 2] << 5) - 0x8000) / 2;
564 
565 	for (attr_start = m_spriteram.bytes() / 2 - 4; attr_start >= last; attr_start -= 4)
566 	{
567 		int code;
568 		int ox, oy, sx, sy, zoomx, zoomy, flipx, flipy, color, pri;
569 
570 		ox = m_spriteram[attr_start + 1] & 0x01ff;
571 		oy = m_spriteram[attr_start + 0] & 0x01ff;
572 		flipx = m_spriteram[attr_start + 2] & 0x0800;
573 		flipy = m_spriteram[attr_start + 2] & 0x8000;
574 		color = m_spriteram[attr_start + 2] & 0x000f;
575 
576 		zoomx = (m_spriteram[attr_start + 1] & 0xf000) >> 12;
577 		zoomy = (m_spriteram[attr_start + 0] & 0xf000) >> 12;
578 		pri = m_spriteram[attr_start + 2] & 0x0010;
579 		code = m_spriteram[attr_start + 3] & 0x1fff;
580 
581 		if (!(m_spriteram[attr_start + 2] & 0x0040))
582 			code |= 0x2000;
583 
584 		zoomx = 32 + zoomx;
585 		zoomy = 32 + zoomy;
586 
587 		sy = ((oy + 16 - 1) & 0x1ff) - 16;
588 
589 		sx = ((ox + 16 + 3) & 0x1ff) - 16;
590 
591 		m_gfxdecode->gfx(m_sprite_gfx + (code >= 0x1000 ? 0 : 1))->prio_zoom_transpen(bitmap,cliprect,
592 				code,
593 				color,
594 				flipx,flipy,
595 				sx,sy,
596 				zoomx << 11,zoomy << 11,
597 				screen.priority(),pri ? 0 : 2,15);
598 
599 	}
600 
601 	last = ((m_rasterram[0x402 / 2] << 5) - 0x8000) / 2;
602 
603 	for (attr_start = ((m_spriteram.bytes() / 2) / 2) - 4; attr_start >= last; attr_start -= 4)
604 	{
605 		int code;
606 		int ox, oy, sx, sy, zoomx, zoomy, flipx, flipy, color, pri;
607 
608 		ox = m_spriteram[attr_start + 1] & 0x01ff;
609 		oy = m_spriteram[attr_start + 0] & 0x01ff;
610 		flipx = m_spriteram[attr_start + 2] & 0x0800;
611 		flipy = m_spriteram[attr_start + 2] & 0x8000;
612 		color = m_spriteram[attr_start + 2] & 0x000f;
613 
614 		zoomx = (m_spriteram[attr_start + 1] & 0xf000) >> 12;
615 		zoomy = (m_spriteram[attr_start + 0] & 0xf000) >> 12;
616 		pri = m_spriteram[attr_start + 2] & 0x0010;
617 		code = m_spriteram[attr_start + 3] & 0x1fff;
618 
619 		if (!(m_spriteram[attr_start + 2] & 0x0040))
620 			code |= 0x2000;
621 
622 		zoomx = 32 + zoomx;
623 		zoomy = 32 + zoomy;
624 
625 		sy = ((oy + 16 - 1) & 0x1ff) - 16;
626 
627 		sx = ((ox + 16 + 3) & 0x1ff) - 16;
628 
629 		m_gfxdecode->gfx(m_sprite_gfx + (code >= 0x1000 ? 0 : 1))->prio_zoom_transpen(bitmap,cliprect,
630 				code,
631 				color,
632 				flipx,flipy,
633 				sx,sy,
634 				zoomx << 11,zoomy << 11,
635 				screen.priority(),pri ? 0 : 2,15);
636 
637 	}
638 }
639 
640 // BOOTLEG
wbbc97_draw_bitmap(bitmap_rgb32 & bitmap)641 void aerofgt_state::wbbc97_draw_bitmap( bitmap_rgb32 &bitmap )
642 {
643 	int count = 16; // weird, the bitmap doesn't start at 0?
644 	for (int y = 0; y < 256; y++)
645 		for (int x = 0; x < 512; x++)
646 		{
647 			int color = m_bitmapram[count] >> 1;
648 
649 			/* data is GRB; convert to RGB */
650 			rgb_t pen = rgb_t(pal5bit((color & 0x3e0) >> 5), pal5bit((color & 0x7c00) >> 10), pal5bit(color & 0x1f));
651 			bitmap.pix(y, (10 + x - m_rasterram[(y & 0x7f)]) & 0x1ff) = pen;
652 
653 			count++;
654 			count &= 0x1ffff;
655 		}
656 }
657 
658 // BOOTLEG
screen_update_pspikesb(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)659 uint32_t aerofgt_state::screen_update_pspikesb(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
660 {
661 	m_tilemap[0]->set_scroll_rows(256);
662 	int scrolly = m_scrolly[0];
663 	for (int i = 0; i < 256; i++)
664 		m_tilemap[0]->set_scrollx((i + scrolly) & 0xff, m_rasterram[i] + 22);
665 	m_tilemap[0]->set_scrolly(0, scrolly);
666 
667 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
668 	pspikesb_draw_sprites(screen, bitmap, cliprect);
669 	return 0;
670 }
671 
672 // BOOTLEG
screen_update_spikes91(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)673 uint32_t aerofgt_state::screen_update_spikes91(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
674 {
675 	int i, scrolly;
676 	int y, x;
677 	int count;
678 	gfx_element *gfx = m_gfxdecode->gfx(0);
679 
680 	m_tilemap[0]->set_scroll_rows(256);
681 	scrolly = m_scrolly[0];
682 
683 	for (i = 0; i < 256; i++)
684 		m_tilemap[0]->set_scrollx((i + scrolly) & 0xff, m_rasterram[i + 0x01f0 / 2] + 0x96 + 0x16);
685 	m_tilemap[0]->set_scrolly(0, scrolly);
686 
687 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
688 	spikes91_draw_sprites(screen, bitmap, cliprect);
689 
690 	/* we could use a tilemap, but it's easier to just do it here */
691 	count = 0;
692 	for (y = 0; y < 32; y++)
693 	{
694 		for (x = 0; x < 64; x++)
695 		{
696 			uint16_t tileno = m_tx_tilemap_ram[count] & 0x1fff;
697 			uint16_t colour = m_tx_tilemap_ram[count] & 0xe000;
698 			gfx->transpen(bitmap,cliprect,
699 					tileno,
700 					colour>>13,
701 					0,0,
702 					(x*8)+24,(y*8)+8,15);
703 
704 			count++;
705 
706 		}
707 
708 	}
709 
710 	return 0;
711 }
712 
713 // BOOTLEG
screen_update_aerfboot(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)714 uint32_t aerofgt_state::screen_update_aerfboot(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
715 {
716 	int i, scrolly;
717 
718 	m_tilemap[0]->set_scroll_rows(512);
719 	scrolly = m_scrolly[0] + 2;
720 	for (i = 0; i < 256; i++)
721 		m_tilemap[0]->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[7] + 174);
722 	m_tilemap[0]->set_scrolly(0, scrolly);
723 	m_tilemap[1]->set_scrollx(0, m_scrollx[1] + 172);
724 	m_tilemap[1]->set_scrolly(0, m_scrolly[1] + 2);
725 
726 	screen.priority().fill(0, cliprect);
727 
728 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
729 	m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 1);
730 
731 	/* we use the priority buffer so sprites are drawn front to back */
732 	aerfboot_draw_sprites(screen, bitmap, cliprect);
733 	return 0;
734 }
735 
736 // BOOTLEG
screen_update_aerfboo2(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)737 uint32_t aerofgt_state::screen_update_aerfboo2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
738 {
739 	int i, scrolly;
740 
741 	m_tilemap[0]->set_scroll_rows(512);
742 	scrolly = m_scrolly[0] + 2;
743 	for (i = 0; i < 256; i++)
744 //      m_tilemap[0]->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[i] - 11);
745 		m_tilemap[0]->set_scrollx((i + scrolly) & 0x1ff, m_rasterram[7] - 11);
746 	m_tilemap[0]->set_scrolly(0, scrolly);
747 	m_tilemap[1]->set_scrollx(0, m_scrollx[1] - 7);
748 	m_tilemap[1]->set_scrolly(0, m_scrolly[1] + 2);
749 
750 	screen.priority().fill(0, cliprect);
751 
752 	m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
753 	m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 1);
754 
755 	/* we use the priority buffer so sprites are drawn front to back */
756 	aerfboo2_draw_sprites(screen, bitmap, cliprect, 1, -1); //ship
757 	aerfboo2_draw_sprites(screen, bitmap, cliprect, 1, 0); //intro
758 	aerfboo2_draw_sprites(screen, bitmap, cliprect, 0, -1); //enemy
759 	aerfboo2_draw_sprites(screen, bitmap, cliprect, 0, 0); //enemy
760 	return 0;
761 }
762 
763 // BOOTLEG (still uses original sprite type)
screen_update_wbbc97(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)764 uint32_t aerofgt_state::screen_update_wbbc97(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
765 {
766 	int i, scrolly;
767 
768 	m_tilemap[0]->set_scroll_rows(256);
769 	scrolly = m_scrolly[0];
770 	for (i = 0; i < 256; i++)
771 		m_tilemap[0]->set_scrollx((i + scrolly) & 0xff, m_rasterram[i]);
772 	m_tilemap[0]->set_scrolly(0, scrolly);
773 
774 	screen.priority().fill(0, cliprect);
775 
776 	if (m_wbbc97_bitmap_enable)
777 	{
778 		wbbc97_draw_bitmap(bitmap);
779 		m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
780 	}
781 	else
782 	{
783 		m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
784 	}
785 
786 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram,m_spriteram.bytes(),m_spritepalettebank, bitmap, cliprect, screen.priority(), 1, m_flip_screen);
787 	m_spr_old[0]->turbofrc_draw_sprites(m_spriteram,m_spriteram.bytes(),m_spritepalettebank, bitmap, cliprect, screen.priority(), 0, m_flip_screen);
788 	return 0;
789 }
790