1 /***************************************************************************
2 
3 Sega System 16 Video Hardware
4 
5 Known issues:
6 - better abstraction of tilemap hardware is needed; a lot of this mess could and should
7 	be consolidated further
8 - many games have ROM patches - why?  let's emulate protection when possible
9 - several games fail their RAM self-test because of hacks in the drivers
10 - many registers are suspiciously plucked from working RAM
11 - several games have nvram according to the self test, but we aren't yet saving it
12 - many games suffer from sys16_refreshenable register not being mapped
13 - hangon road isn't displayed(!) emulation bug?
14 - road-rendering routines need to be cleaned up or at least better described
15 - logical sprite height computation isn't quite right - garbage pixels are drawn
16 - screen orientation support for sprite drawing
17 - sprite drawing is unoptimized
18 - end-of-sprite marker support will fix some glitches
19 - shadow and partial shadow sprite support
20 - to achieve sprite-tilemap orthogonality we must draw sprites from front to back;
21 	this will also allow us to avoid processing the same shadowed pixel twice.
22 
23 The System16 video hardware consists of:
24 
25 - Road Layer (present only for certain games)
26 
27 - Two scrolling tilemap layers
28 
29 - Two alternate scrolling tilemap layers, normally invisible.
30 
31 - A fixed tilemap layer, normally used for score, lives display
32 
33 Each scrolling layer (foreground, background) is an arrangement
34 of 4 pages selected from 16 available pages, laid out as follows:
35 
36 	Page0  Page1
37 	Page2  Page3
38 
39 Each page is an arrangement of 8x8 tiles, 64 tiles wide, and 32 tiles high.
40 
41 Layers normally scroll as a whole, with xscroll and yscroll.
42 
43 However, layers can also be configured with screenwise rowscroll, if the most significant
44 bit of xscroll is set.  When a layer is in this mode, the splittable is used.
45 
46 When rowscroll is in effect, the most significant bit of rowscroll selects between the
47 default layer and an alternate layer associated with it.
48 
49 The foreground layer's tiles may be flagged as high-priority; this is used to mask
50 sprites, i.e. the grass in Altered Beast.
51 
52 The background layer's tiles may also be flagged as high-priority.  In this case,
53 it's really a transparency_pen effect rather.  Aurail uses this.
54 
55 Most games map Video Registers in textram as follows:
56 
57 type0:
58 most games
59 
60 type1:
61 alexkidd,fantzone,shinobl,hangon
62 mjleague
63 
64 others:
65 	shangon, shdancbl,
66 	dduxbl,eswat,
67 	passsht,passht4b
68 	quartet,quartet2,
69 	tetris,tturfbl,wb3bl
70 
71 sys16_textram:
72 type1		type0			function
73 ---------------------------------------
74 0x74f		0x740			sys16_fg_page
75 0x74e		0x741			sys16_bg_page
76 			0x742			sys16_fg2_page
77 			0x743			sys16_bg2_page
78 
79 0x792		0x748			sys16_fg_scrolly
80 0x793		0x749			sys16_bg_scrolly
81 			0x74a			sys16_fg2_scrolly
82 			0x74b			sys16_bg2_scrolly
83 
84 0x7fc		0x74c			sys16_fg_scrollx
85 0x7fd		0x74d			sys16_bg_scrollx
86 			0x74e			sys16_fg2_scrollx
87 			0x74f			sys16_bg2_scrollx
88 
89 			0x7c0..0x7df	sys18_splittab_fg_x
90 			0x7e0..0x7ff	sys18_splittab_bg_x
91 
92 ***************************************************************************/
93 #include "driver.h"
94 #include "system16.h"
95 
96 /*
97 static void debug_draw( struct mame_bitmap *bitmap, int x, int y, unsigned int data ){
98 	int digit;
99 	for( digit=0; digit<4; digit++ ){
100 		drawgfx( bitmap, Machine->uifont,
101 			"0123456789abcdef"[data>>12],
102 			0,
103 			0,0,
104 			x+digit*6,y,
105 			&Machine->visible_area,TRANSPARENCY_NONE,0);
106 		data = (data<<4)&0xffff;
107 	}
108 }
109 
110 static void debug_vreg( struct mame_bitmap *bitmap ){
111 	int g = 0x740;
112 	int i;
113 
114 	if( keyboard_pressed( KEYCODE_Q ) ) g+=0x10;
115 	if( keyboard_pressed( KEYCODE_W ) ) g+=0x20;
116 	if( keyboard_pressed( KEYCODE_E ) ) g+=0x40;
117 	if( keyboard_pressed( KEYCODE_R ) ) g+=0x80;
118 
119 	for( i=0; i<16; i++ ){
120 		debug_draw( bitmap, 8,8*i,sys16_textram[g+i] );
121 	}
122 }
123 */
124 
125 /* callback to poll video registers */
126 void (* sys16_update_proc)( void );
127 
128 data16_t *sys16_tileram;
129 data16_t *sys16_textram;
130 data16_t *sys16_spriteram;
131 data16_t *sys16_roadram;
132 
133 static int num_sprites;
134 
135 #define MAXCOLOURS 0x2000 /* 8192 */
136 
137 int sys16_sh_shadowpal;
138 int sys16_MaxShadowColors;
139 
140 /* video driver constants (potentially different for each game) */
141 int sys16_gr_bitmap_width;
142 int (*sys16_spritesystem)( struct sys16_sprite_attributes *sprite, const UINT16 *source, int bJustGetColor );
143 int *sys16_obj_bank;
144 int sys16_sprxoffset;
145 int sys16_bgxoffset;
146 int sys16_fgxoffset;
147 int sys16_textmode;
148 int sys16_textlayer_lo_min;
149 int sys16_textlayer_lo_max;
150 int sys16_textlayer_hi_min;
151 int sys16_textlayer_hi_max;
152 int sys16_dactype;
153 int sys16_bg1_trans; // alien syn + sys18
154 int sys16_bg_priority_mode;
155 int sys16_fg_priority_mode;
156 int sys16_bg_priority_value;
157 int sys16_fg_priority_value;
158 int sys16_18_mode;
159 int sys16_spritelist_end;
160 int sys16_tilebank_switch;
161 int sys16_rowscroll_scroll;
162 int sys16_quartet_title_kludge;
163 
164 /* video registers */
165 int sys16_tile_bank1;
166 int sys16_tile_bank0;
167 int sys16_refreshenable;
168 
169 int sys16_bg_scrollx, sys16_bg_scrolly;
170 int sys16_bg2_scrollx, sys16_bg2_scrolly;
171 int sys16_fg_scrollx, sys16_fg_scrolly;
172 int sys16_fg2_scrollx, sys16_fg2_scrolly;
173 
174 int sys16_bg_page[4];
175 int sys16_bg2_page[4];
176 int sys16_fg_page[4];
177 int sys16_fg2_page[4];
178 
179 int sys18_bg2_active;
180 int sys18_fg2_active;
181 data16_t *sys18_splittab_bg_x;
182 data16_t *sys18_splittab_bg_y;
183 data16_t *sys18_splittab_fg_x;
184 data16_t *sys18_splittab_fg_y;
185 
186 data16_t *sys16_gr_ver;
187 data16_t *sys16_gr_hor;
188 data16_t *sys16_gr_pal;
189 data16_t *sys16_gr_flip;
190 int sys16_gr_palette;
191 int sys16_gr_palette_default;
192 unsigned char sys16_gr_colorflip[2][4];
193 data16_t *sys16_gr_second_road;
194 
195 static struct tilemap *background, *foreground, *text_layer;
196 static struct tilemap *background2, *foreground2;
197 static int old_bg_page[4],old_fg_page[4], old_tile_bank1, old_tile_bank0;
198 static int old_bg2_page[4],old_fg2_page[4];
199 
200 /***************************************************************************/
201 
READ16_HANDLER(sys16_textram_r)202 READ16_HANDLER( sys16_textram_r ){
203 	return sys16_textram[offset];
204 }
205 
READ16_HANDLER(sys16_tileram_r)206 READ16_HANDLER( sys16_tileram_r ){
207 	return sys16_tileram[offset];
208 }
209 
210 /***************************************************************************/
211 
212 /*
213 	We mark the priority buffer as follows:
214 		text	(0xf)
215 		fg (hi) (0x7)
216 		fg (lo) (0x3)
217 		bg (hi) (0x1)
218 		bg (lo) (0x0)
219 
220 	Each sprite has 4 levels of priority, specifying where they are placed between bg(lo) and text.
221 */
222 
draw_sprite(struct mame_bitmap * bitmap,const struct rectangle * cliprect,const unsigned char * addr,int pitch,const pen_t * paldata,int x0,int y0,int screen_width,int screen_height,int width,int height,int flipx,int flipy,int priority,int shadow,int shadow_pen,int eos)223 static void draw_sprite( //*
224 	struct mame_bitmap *bitmap,
225 	const struct rectangle *cliprect,
226 	const unsigned char *addr, int pitch,
227 	const pen_t *paldata,
228 	int x0, int y0, int screen_width, int screen_height,
229 	int width, int height,
230 	int flipx, int flipy,
231 	int priority,
232 	int shadow,
233 	int shadow_pen, int eos )
234 {
235 	const pen_t *shadow_base = Machine->gfx[0]->colortable + (Machine->drv->total_colors/2);
236 	const UINT8 *source;
237 	int full_shadow=shadow&SYS16_SPR_SHADOW;
238 	int partial_shadow=shadow&SYS16_SPR_PARTIAL_SHADOW;
239 	int shadow_mask=(Machine->drv->total_colors/2)-1;
240 	int sx, x, xcount;
241 	int sy, y, ycount = 0;
242 	int dx,dy;
243 	UINT16 *dest;
244 	UINT8 *pri;
245 	unsigned pen, data;
246 
247 	priority = 1<<priority;
248 
249 	if( flipy ){
250 		dy = -1;
251 		y0 += screen_height-1;
252 	}
253 	else {
254 		dy = 1;
255 	}
256 
257 	if( flipx ){
258 		dx = -1;
259 		x0 += screen_width-1;
260 	}
261 	else {
262 		dx = 1;
263 	}
264 
265 	if (!eos)
266 	{
267 		sy = y0;
268 		for( y=height; y; y-- ){
269 			ycount += screen_height;
270 			while( ycount>=height ){
271 				if( sy>=cliprect->min_y && sy<=cliprect->max_y ){
272 					source = addr;
273 					dest = (UINT16 *)bitmap->line[sy];
274 					pri = priority_bitmap->line[sy];
275 					sx = x0;
276 					xcount = 0;
277 					for( x=width; x; x-=2 ){
278 						data = (unsigned)*source++; /* next 2 pixels */
279 						pen = data>>4;
280 						xcount += screen_width;
281 						while( xcount>=width )
282 						{
283 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
284 								if(!(pri[sx]&priority)){
285 									if (full_shadow)
286 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
287 									else if (partial_shadow && pen==shadow_pen)
288 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
289 									else
290 										dest[sx] = paldata[pen];
291 								}
292 							}
293 							xcount -= width;
294 							sx+=dx;
295 						}
296 						pen = data&0xf;
297 						xcount += screen_width;
298 						while( xcount>=width )
299 						{
300 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
301 								if(!(pri[sx]&priority)){
302 									if (full_shadow)
303 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
304 									else if (partial_shadow && pen==shadow_pen)
305 										dest[sx] = shadow_base[dest[sx]&shadow_mask];
306 									else
307 										dest[sx] = paldata[pen];
308 								}
309 							}
310 							xcount -= width;
311 							sx+=dx;
312 						}
313 					}
314 				}
315 				ycount -= height;
316 				sy+=dy;
317 			}
318 			addr += pitch;
319 		}
320 	}
321 	else
322 	{
323 		sy = y0;
324 		for( y=height; y; y-- ){
325 			ycount += screen_height;
326 			while( ycount>=height ){
327 				if( sy>=cliprect->min_y && sy<=cliprect->max_y ){
328 					source = addr;
329 					dest = (UINT16 *)bitmap->line[sy];
330 					pri = priority_bitmap->line[sy];
331 					sx = x0;
332 					xcount = 0;
333 					for( x=width; x; x-=2 ){
334 						data = (unsigned)*source++; /* next 2 pixels */
335 						pen = data>>4;
336 						if (pen==0xf) break;
337 						xcount += screen_width;
338 						while( xcount>=width )
339 						{
340 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x )
341 								if(!(pri[sx]&priority)) dest[sx] = paldata[pen];
342 							xcount -= width;
343 							sx+=dx;
344 						}
345 						pen = data&0xf;
346 						xcount += screen_width;
347 						while( xcount>=width )
348 						{
349 							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x )
350 								if(!(pri[sx]&priority)) dest[sx] = paldata[pen];
351 							xcount -= width;
352 							sx+=dx;
353 						}
354 					}
355 				}
356 				ycount -= height;
357 				sy+=dy;
358 			}
359 			addr += pitch;
360 		}
361 	}
362 }
363 
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int b3d)364 static void draw_sprites( struct mame_bitmap *bitmap, const struct rectangle *cliprect, int b3d ) //*
365 {
366 	const pen_t *base_pal = Machine->gfx[0]->colortable;
367 	const unsigned char *base_gfx = memory_region(REGION_GFX2);
368 	const int gfx_rom_size = memory_region_length(REGION_GFX2);
369 	const data16_t *source = sys16_spriteram;
370 	struct sys16_sprite_attributes sprite;
371 	int xpos, ypos, screen_width, width, logical_height, pitch, flipy, flipx;
372 	int i, mod_h, mod_x, eos;
373 	unsigned gfx;
374 
375 	memset(&sprite, 0x00, sizeof(sprite));
376 
377 	for(i=0; i<num_sprites; i++)
378 	{
379 		sprite.flags = 0;
380 		if (sys16_spritesystem(&sprite, source, 0)) return; /* end-of-spritelist */
381 		source += 8;
382 
383 		if( sprite.flags & SYS16_SPR_VISIBLE )
384 		{
385 			xpos = sprite.x;
386 			flipx = sprite.flags & SYS16_SPR_FLIPX;
387 			ypos = sprite.y;
388 			pitch = sprite.pitch;
389 			flipy = pitch & 0x80;
390 			width = pitch & 0x7f;
391 			if (pitch & 0x80) width = 0x80 - width;
392 			pitch = width << 1;
393 			width <<= 2;
394 			eos = 0;
395 
396 			if( b3d ) // outrun/aburner
397 			{
398 				if (b3d == 2) eos = 1;
399 				if (xpos < 0 && flipx) continue;
400 				if (ypos >= 240) ypos -= 256;
401 				sprite.screen_height++;
402 				logical_height = (sprite.screen_height<<4)*sprite.zoomy/0x2000;
403 				screen_width = width*0x200/sprite.zoomx;
404 
405 				if (flipx && flipy) { mod_h = -logical_height;   mod_x = 4; }
406 				else if     (flipx) { mod_h = -1; xpos++;        mod_x = 4; }
407 				else if     (flipy) { mod_h = -logical_height;   mod_x = 0; }
408 				else                { mod_h = 0;                 mod_x = 0; }
409 
410 				if( sprite.flags & SYS16_SPR_DRAW_TO_TOP )
411 				{
412 					ypos -= sprite.screen_height;
413 					flipy = !flipy;
414 				}
415 
416 				if( sprite.flags & SYS16_SPR_DRAW_TO_LEFT )
417 				{
418 					xpos -= screen_width;
419 					flipx = !flipx;
420 				}
421 			}
422 			else if( sys16_spritesystem==sys16_sprite_sharrier )
423 			{
424 				logical_height = (sprite.screen_height<<4)*(0x400+sprite.zoomy)/0x4000;
425 				screen_width = width*(0x800-sprite.zoomx)/0x800;
426 
427 				if (flipx && flipy) { mod_h = -logical_height-1; mod_x = 4; }
428 				else if     (flipx) { mod_h = 0;                 mod_x = 4; }
429 				else if     (flipy) { mod_h = -logical_height;   mod_x = 0; }
430 				else                { mod_h = 1;                 mod_x = 0; }
431 			}
432 			else
433 			{
434 				if (!width) { width = 512; eos = 1; } // used by fantasy zone for laser
435 				screen_width = width;
436 				logical_height = sprite.screen_height;
437 
438 				if (sprite.zoomy) logical_height = logical_height*(0x400 + sprite.zoomy)/0x400 - 1;
439 				if (sprite.zoomx) screen_width = screen_width*(0x800 - sprite.zoomx)/0x800 + 2;
440 
441 				if (flipx && flipy) { mod_h = -logical_height-1; mod_x = 2; }
442 				else if     (flipx) { mod_h = 0;                 mod_x = 2; }
443 				else if     (flipy) { mod_h = -logical_height;   mod_x = 0; }
444 				else                { mod_h = 1;                 mod_x = 0; }
445 			}
446 
447 			gfx = sprite.gfx + pitch * mod_h + mod_x;
448 			if (gfx >= gfx_rom_size) gfx %= gfx_rom_size;
449 
450 			draw_sprite(
451 				bitmap,cliprect,
452 				base_gfx + gfx, pitch,
453 				base_pal + (sprite.color<<4),
454 				xpos, ypos, screen_width, sprite.screen_height,
455 				width, logical_height,
456 				flipx, flipy,
457 				sprite.priority,
458 				sprite.flags,
459 				sprite.shadow_pen, eos);
460 		}
461 	}
462 }
463 
464 /***************************************************************************/
465 
sys16_bg_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)466 UINT32 sys16_bg_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
467 	int page = 0;
468 	if( row<32 ){ /* top */
469 		if( col<64 ) page = 0; else page = 1;
470 	}
471 	else { /* bottom */
472 		if( col<64 ) page = 2; else page = 3;
473 	}
474 	row = row%32;
475 	col = col%64;
476 	return page*64*32+row*64+col;
477 }
478 
sys16_text_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)479 UINT32 sys16_text_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
480 	return row*64+col+(64-40);
481 }
482 
483 /***************************************************************************/
484 
WRITE16_HANDLER(sys16_paletteram_w)485 WRITE16_HANDLER( sys16_paletteram_w ){
486 	data16_t oldword = paletteram16[offset];
487 	data16_t newword;
488 	COMBINE_DATA( &paletteram16[offset] );
489 	newword = paletteram16[offset];
490 	if( oldword!=newword ){ /* we can do this, because we initialize palette RAM to all black in vh_start */
491 		/*	   byte 0    byte 1 */
492 		/*	GBGR BBBB GGGG RRRR */
493 		/*	5444 3210 3210 3210 */
494 		UINT8 r = (newword & 0x00f)<<1;
495 		UINT8 g = (newword & 0x0f0)>>2;
496 		UINT8 b = (newword & 0xf00)>>7;
497 		if( sys16_dactype == 0 ){ /* we should really use two distinct paletteram_w handlers */
498 			/* dac_type == 0 (from GCS file) */
499 			if (newword&0x1000) r|=1;
500 			if (newword&0x2000) g|=2;
501 			if (newword&0x8000) g|=1;
502 			if (newword&0x4000) b|=1;
503 		}
504 		else if( sys16_dactype == 1 ){
505 			/* dac_type == 1 (from GCS file) Shinobi Only*/
506 			if (newword&0x1000) r|=1;
507 			if (newword&0x4000) g|=2;
508 			if (newword&0x8000) g|=1;
509 			if (newword&0x2000) b|=1;
510 		}
511 
512 #ifndef TRANSPARENT_SHADOWS
513 		palette_set_color( offset,
514 				(r << 3) | (r >> 2), /* 5 bits red */
515 				(g << 2) | (g >> 4), /* 6 bits green */
516 				(b << 3) | (b >> 2) /* 5 bits blue */
517 			);
518 #else
519 		{   extern struct GameDriver driver_aburner, driver_aburner2; //JUN
520 			r=(r << 3) | (r >> 2); /* 5 bits red */
521 			g=(g << 2) | (g >> 4); /* 6 bits green */
522 			b=(b << 3) | (b >> 2); /* 5 bits blue */
523 
524 			palette_set_color( offset,r,g,b);
525 			if (Machine->gamedrv != &driver_aburner && Machine->gamedrv != &driver_aburner2) { //JUN
526 			/* shadow color */
527 			r= r * 160 / 256;
528 			g= g * 160 / 256;
529 			b= b * 160 / 256;
530 
531 			palette_set_color( offset+Machine->drv->total_colors/2,r,g,b); }
532 		}
533 #endif
534 	}
535 }
536 
update_page(void)537 static void update_page( void ){
538 	int all_dirty = 0;
539 	int i,offset;
540 	if( old_tile_bank1 != sys16_tile_bank1 ){
541 		all_dirty = 1;
542 		old_tile_bank1 = sys16_tile_bank1;
543 	}
544 	if( old_tile_bank0 != sys16_tile_bank0 ){
545 		all_dirty = 1;
546 		old_tile_bank0 = sys16_tile_bank0;
547 		tilemap_mark_all_tiles_dirty( text_layer );
548 	}
549 	if( all_dirty ){
550 		tilemap_mark_all_tiles_dirty( background );
551 		tilemap_mark_all_tiles_dirty( foreground );
552 		if( sys16_18_mode ){
553 			tilemap_mark_all_tiles_dirty( background2 );
554 			tilemap_mark_all_tiles_dirty( foreground2 );
555 		}
556 	}
557 	else {
558 		for(i=0;i<4;i++){
559 			int page0 = 64*32*i;
560 			if( old_bg_page[i]!=sys16_bg_page[i] ){
561 				old_bg_page[i] = sys16_bg_page[i];
562 				for( offset = page0; offset<page0+64*32; offset++ ){
563 					tilemap_mark_tile_dirty( background, offset );
564 				}
565 			}
566 			if( old_fg_page[i]!=sys16_fg_page[i] ){
567 				old_fg_page[i] = sys16_fg_page[i];
568 				for( offset = page0; offset<page0+64*32; offset++ ){
569 					tilemap_mark_tile_dirty( foreground, offset );
570 				}
571 			}
572 			if( sys16_18_mode ){
573 				if( old_bg2_page[i]!=sys16_bg2_page[i] ){
574 					old_bg2_page[i] = sys16_bg2_page[i];
575 					for( offset = page0; offset<page0+64*32; offset++ ){
576 						tilemap_mark_tile_dirty( background2, offset );
577 					}
578 				}
579 				if( old_fg2_page[i]!=sys16_fg2_page[i] ){
580 					old_fg2_page[i] = sys16_fg2_page[i];
581 					for( offset = page0; offset<page0+64*32; offset++ ){
582 						tilemap_mark_tile_dirty( foreground2, offset );
583 					}
584 				}
585 			}
586 		}
587 	}
588 }
589 
get_bg_tile_info(int offset)590 static void get_bg_tile_info( int offset ){
591 	const UINT16 *source = 64*32*sys16_bg_page[offset/(64*32)] + sys16_tileram;
592 	int data = source[offset%(64*32)];
593 	int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
594 
595 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
596 		SET_TILE_INFO(
597 				0,
598 				tile_number,
599 				512+384+((data>>6)&0x7f),
600 				0)
601 	}
602 	else if(sys16_textmode==0){
603 		SET_TILE_INFO(
604 				0,
605 				tile_number,
606 				(data>>6)&0x7f,
607 				0)
608 	}
609 	else{
610 		SET_TILE_INFO(
611 				0,
612 				tile_number,
613 				(data>>5)&0x7f,
614 				0)
615 	}
616 
617 	switch(sys16_bg_priority_mode) {
618 	case 1: // Alien Syndrome
619 		tile_info.priority = (data&0x8000)?1:0;
620 		break;
621 	case 2: // Body Slam / wrestwar
622 		tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
623 		break;
624 	case 3: // sys18 games
625 		if( data&0x8000 ){
626 			tile_info.priority = 2;
627 		}
628 		else {
629 			tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
630 		}
631 		break;
632 	}
633 }
634 
get_fg_tile_info(int offset)635 static void get_fg_tile_info( int offset ){
636 	const UINT16 *source = 64*32*sys16_fg_page[offset/(64*32)] + sys16_tileram;
637 	int data = source[offset%(64*32)];
638 	int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
639 
640 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
641 		SET_TILE_INFO(
642 				0,
643 				tile_number,
644 				512+384+((data>>6)&0x7f),
645 				0)
646 	}
647 	else if(sys16_textmode==0){
648 		SET_TILE_INFO(
649 				0,
650 				tile_number,
651 				(data>>6)&0x7f,
652 				0)
653 	}
654 	else{
655 		SET_TILE_INFO(
656 				0,
657 				tile_number,
658 				(data>>5)&0x7f,
659 				0)
660 	}
661 	switch(sys16_fg_priority_mode){
662 	case 1: // alien syndrome
663 		tile_info.priority = (data&0x8000)?1:0;
664 		break;
665 
666 	case 3:
667 		tile_info.priority = ((data&0xff00) >= sys16_fg_priority_value)?1:0;
668 		break;
669 
670 	default:
671 		if( sys16_fg_priority_mode>=0 ){
672 			tile_info.priority = (data&0x8000)?1:0;
673 		}
674 		break;
675 	}
676 }
677 
get_bg2_tile_info(int offset)678 static void get_bg2_tile_info( int offset ){
679 	const UINT16 *source = 64*32*sys16_bg2_page[offset/(64*32)] + sys16_tileram;
680 	int data = source[offset%(64*32)];
681 	int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
682 
683 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
684 		SET_TILE_INFO(
685 				0,
686 				tile_number,
687 				512+384+((data>>6)&0x7f),
688 				0)
689 	}
690 	else if(sys16_textmode==0){
691 		SET_TILE_INFO(
692 				0,
693 				tile_number,
694 				(data>>6)&0x7f,
695 				0)
696 	}
697 	else{
698 		SET_TILE_INFO(
699 				0,
700 				tile_number,
701 				(data>>5)&0x7f,
702 				0)
703 	}
704 	tile_info.priority = 0;
705 }
706 
get_fg2_tile_info(int offset)707 static void get_fg2_tile_info( int offset ){
708 	const UINT16 *source = 64*32*sys16_fg2_page[offset/(64*32)] + sys16_tileram;
709 	int data = source[offset%(64*32)];
710 	int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
711 
712 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
713 		SET_TILE_INFO(
714 				0,
715 				tile_number,
716 				512+384+((data>>6)&0x7f),
717 				0)
718 	}
719 	else if(sys16_textmode==0){
720 		SET_TILE_INFO(
721 				0,
722 				tile_number,
723 				(data>>6)&0x7f,
724 				0)
725 	}
726 	else{
727 		SET_TILE_INFO(
728 				0,
729 				tile_number,
730 				(data>>5)&0x7f,
731 				0)
732 	}
733 	if((data&0xff00) >= sys16_fg_priority_value) tile_info.priority = 1;
734 	else tile_info.priority = 0;
735 }
736 
WRITE16_HANDLER(sys16_tileram_w)737 WRITE16_HANDLER( sys16_tileram_w ){
738 	data16_t oldword = sys16_tileram[offset];
739 	COMBINE_DATA( &sys16_tileram[offset] );
740 	if( oldword != sys16_tileram[offset] ){
741 		int page = offset/(64*32);
742 		offset = offset%(64*32);
743 
744 		if( sys16_bg_page[0]==page ) tilemap_mark_tile_dirty( background, offset+64*32*0 );
745 		if( sys16_bg_page[1]==page ) tilemap_mark_tile_dirty( background, offset+64*32*1 );
746 		if( sys16_bg_page[2]==page ) tilemap_mark_tile_dirty( background, offset+64*32*2 );
747 		if( sys16_bg_page[3]==page ) tilemap_mark_tile_dirty( background, offset+64*32*3 );
748 
749 		if( sys16_fg_page[0]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*0 );
750 		if( sys16_fg_page[1]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*1 );
751 		if( sys16_fg_page[2]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*2 );
752 		if( sys16_fg_page[3]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*3 );
753 
754 		if( sys16_18_mode ){
755 			if( sys16_bg2_page[0]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*0 );
756 			if( sys16_bg2_page[1]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*1 );
757 			if( sys16_bg2_page[2]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*2 );
758 			if( sys16_bg2_page[3]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*3 );
759 
760 			if( sys16_fg2_page[0]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*0 );
761 			if( sys16_fg2_page[1]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*1 );
762 			if( sys16_fg2_page[2]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*2 );
763 			if( sys16_fg2_page[3]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*3 );
764 		}
765 	}
766 }
767 
768 /***************************************************************************/
769 
get_text_tile_info(int offset)770 static void get_text_tile_info( int offset ){
771 	const data16_t *source = sys16_textram;
772 	int tile_number = source[offset];
773 	int pri = tile_number >> 8;
774 	if( sys16_textmode==2 ){ /* afterburner: ?---CCCT TTTTTTTT */
775 		SET_TILE_INFO(
776 				0,
777 				(tile_number&0x1ff) + sys16_tile_bank0 * 0x1000,
778 				512+384+((tile_number>>9)&0x7),
779 				0)
780 	}
781 	else if(sys16_textmode==0){
782 		SET_TILE_INFO(
783 				0,
784 				(tile_number&0x1ff) + sys16_tile_bank0 * 0x1000,
785 				(tile_number>>9)%8,
786 				0)
787 	}
788 	else{
789 		SET_TILE_INFO(
790 				0,
791 				(tile_number&0xff)  + sys16_tile_bank0 * 0x1000,
792 				(tile_number>>8)%8,
793 				0)
794 	}
795 	if(pri>=sys16_textlayer_lo_min && pri<=sys16_textlayer_lo_max)
796 		tile_info.priority = 1;
797 	if(pri>=sys16_textlayer_hi_min && pri<=sys16_textlayer_hi_max)
798 		tile_info.priority = 0;
799 }
800 
WRITE16_HANDLER(sys16_textram_w)801 WRITE16_HANDLER( sys16_textram_w ){
802 	int oldword = sys16_textram[offset];
803 	COMBINE_DATA( &sys16_textram[offset] );
804 	if( oldword!=sys16_textram[offset] ){
805 		tilemap_mark_tile_dirty( text_layer, offset );
806 	}
807 }
808 
809 /***************************************************************************/
810 
VIDEO_START(system16)811 VIDEO_START( system16 ){
812 	static int bank_default[16] = {
813 		0x0,0x1,0x2,0x3,
814 		0x4,0x5,0x6,0x7,
815 		0x8,0x9,0xa,0xb,
816 		0xc,0xd,0xe,0xf
817 	};
818 	sys16_obj_bank = bank_default;
819 
820 	if( !sys16_bg1_trans )
821 		background = tilemap_create(
822 			get_bg_tile_info,
823 			sys16_bg_map,
824 			TILEMAP_OPAQUE,
825 			8,8,
826 			64*2,32*2 );
827 	else
828 		background = tilemap_create(
829 			get_bg_tile_info,
830 			sys16_bg_map,
831 			TILEMAP_TRANSPARENT,
832 			8,8,
833 			64*2,32*2 );
834 
835 	foreground = tilemap_create(
836 		get_fg_tile_info,
837 		sys16_bg_map,
838 		TILEMAP_TRANSPARENT,
839 		8,8,
840 		64*2,32*2 );
841 
842 	text_layer = tilemap_create(
843 		get_text_tile_info,
844 		sys16_text_map,
845 		TILEMAP_TRANSPARENT,
846 		8,8,
847 		40,28 );
848 
849 	num_sprites = 128*2; /* only 128 for most games; aburner uses 256 */
850 
851 	if( background && foreground && text_layer ){
852 		/* initialize all entries to black - needed for Golden Axe*/
853 		int i;
854 		for( i=0; i<Machine->drv->total_colors; i++ ){
855 			palette_set_color( i, 0,0,0 );
856 		}
857 
858 		if(sys16_bg1_trans) tilemap_set_transparent_pen( background, 0 );
859 		tilemap_set_transparent_pen( foreground, 0 );
860 		tilemap_set_transparent_pen( text_layer, 0 );
861 
862 		sys16_tile_bank0 = 0;
863 		sys16_tile_bank1 = 1;
864 
865 		sys16_fg_scrollx = 0;
866 		sys16_fg_scrolly = 0;
867 
868 		sys16_bg_scrollx = 0;
869 		sys16_bg_scrolly = 0;
870 
871 		sys16_refreshenable = 1;
872 
873 		/* common defaults */
874 		sys16_update_proc = 0;
875 		sys16_spritesystem = sys16_sprite_shinobi;
876 		sys16_sprxoffset = -0xb8;
877 		sys16_textmode = 0;
878 		sys16_bgxoffset = 0;
879 		sys16_dactype = 0;
880 		sys16_bg_priority_mode=0;
881 		sys16_fg_priority_mode=0;
882 		sys16_spritelist_end=0xffff;
883 		sys16_tilebank_switch=0x1000;
884 
885 		// Defaults for sys16 games
886 		sys16_textlayer_lo_min=0;
887 		sys16_textlayer_lo_max=0x7f;
888 		sys16_textlayer_hi_min=0x80;
889 		sys16_textlayer_hi_max=0xff;
890 
891 		sys16_18_mode=0;
892 
893 #ifdef GAMMA_ADJUST
894 		{
895 			static float sys16_orig_gamma=0;
896 			static float sys16_set_gamma=0;
897 			float cur_gamma=osd_get_gamma();
898 
899 			if(sys16_orig_gamma == 0)
900 			{
901 				sys16_orig_gamma = cur_gamma;
902 				sys16_set_gamma = cur_gamma - 0.35;
903 				if (sys16_set_gamma < 0.5) sys16_set_gamma = 0.5;
904 				if (sys16_set_gamma > 2.0) sys16_set_gamma = 2.0;
905 				osd_set_gamma(sys16_set_gamma);
906 			}
907 			else
908 			{
909 				if(sys16_orig_gamma == cur_gamma)
910 				{
911 					osd_set_gamma(sys16_set_gamma);
912 				}
913 			}
914 		}
915 #endif
916 		return 0;
917 	}
918 	return 1;
919 }
920 
VIDEO_START(hangon)921 VIDEO_START( hangon ){
922 	int ret;
923 	sys16_bg1_trans=1;
924 	ret = video_start_system16();
925 	if(ret) return 1;
926 
927 	sys16_textlayer_lo_min=0;
928 	sys16_textlayer_lo_max=0;
929 	sys16_textlayer_hi_min=0;
930 	sys16_textlayer_hi_max=0xff;
931 
932 	sys16_bg_priority_mode=-1;
933 	sys16_bg_priority_value=0x1800;
934 	sys16_fg_priority_value=0x2000;
935 	return 0;
936 }
937 
VIDEO_START(system18)938 VIDEO_START( system18 ){
939 	sys16_bg1_trans=1;
940 
941 	background2 = tilemap_create(
942 		get_bg2_tile_info,
943 		sys16_bg_map,
944 		TILEMAP_OPAQUE,
945 		8,8,
946 		64*2,32*2 );
947 
948 	foreground2 = tilemap_create(
949 		get_fg2_tile_info,
950 		sys16_bg_map,
951 		TILEMAP_TRANSPARENT,
952 		8,8,
953 		64*2,32*2 );
954 
955 	if( background2 && foreground2 ){
956 		if( video_start_system16()==0 ){
957 			tilemap_set_transparent_pen( foreground2, 0 );
958 
959 			if(sys18_splittab_fg_x){
960 				tilemap_set_scroll_rows( foreground , 64 );
961 				tilemap_set_scroll_rows( foreground2 , 64 );
962 			}
963 			if(sys18_splittab_bg_x){
964 				tilemap_set_scroll_rows( background , 64 );
965 				tilemap_set_scroll_rows( background2 , 64 );
966 			}
967 
968 			sys16_textlayer_lo_min=0;
969 			sys16_textlayer_lo_max=0x1f;
970 			sys16_textlayer_hi_min=0x20;
971 			sys16_textlayer_hi_max=0xff;
972 
973 			sys16_18_mode=1;
974 			sys16_bg_priority_mode=3;
975 			sys16_fg_priority_mode=3;
976 			sys16_bg_priority_value=0x1800;
977 			sys16_fg_priority_value=0x2000;
978 
979 			return 0;
980 		}
981 	}
982 	return 1;
983 }
984 
985 /***************************************************************************/
986 
sys16_vh_refresh_helper(void)987 static void sys16_vh_refresh_helper( void ){
988 	if( sys18_splittab_bg_x ){
989 		if( (sys16_bg_scrollx&0xff00)  != sys16_rowscroll_scroll ){
990 			tilemap_set_scroll_rows( background , 1 );
991 			tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
992 		}
993 		else {
994 			int offset, scroll,i;
995 
996 			tilemap_set_scroll_rows( background , 64 );
997 			offset = 32+((sys16_bg_scrolly&0x1f8) >> 3);
998 
999 			for( i=0; i<29; i++ ){
1000 				scroll = sys18_splittab_bg_x[i];
1001 				tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1002 			}
1003 		}
1004 	}
1005 	else {
1006 		tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1007 	}
1008 
1009 	if( sys18_splittab_bg_y ){
1010 		if( (sys16_bg_scrolly&0xff00)  != sys16_rowscroll_scroll ){
1011 			tilemap_set_scroll_cols( background , 1 );
1012 			tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1013 		}
1014 		else {
1015 			int offset, scroll,i;
1016 
1017 			tilemap_set_scroll_cols( background , 128 );
1018 			offset = 127-((sys16_bg_scrollx&0x3f8) >> 3)-40+2;
1019 
1020 			for( i=0;i<41;i++ ){
1021 				scroll = sys18_splittab_bg_y[(i+24)>>1];
1022 				tilemap_set_scrolly( background , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1023 			}
1024 		}
1025 	}
1026 	else {
1027 		tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1028 	}
1029 
1030 	if( sys18_splittab_fg_x ){
1031 		if( (sys16_fg_scrollx&0xff00)  != sys16_rowscroll_scroll ){
1032 			tilemap_set_scroll_rows( foreground , 1 );
1033 			tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1034 		}
1035 		else {
1036 			int offset, scroll,i;
1037 
1038 			tilemap_set_scroll_rows( foreground , 64 );
1039 			offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1040 
1041 			for(i=0;i<29;i++){
1042 				scroll = sys18_splittab_fg_x[i];
1043 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1044 			}
1045 		}
1046 	}
1047 	else {
1048 		tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1049 	}
1050 
1051 	if( sys18_splittab_fg_y ){
1052 		if( (sys16_fg_scrolly&0xff00)  != sys16_rowscroll_scroll ){
1053 			tilemap_set_scroll_cols( foreground , 1 );
1054 			tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1055 		}
1056 		else {
1057 			int offset, scroll,i;
1058 
1059 			tilemap_set_scroll_cols( foreground , 128 );
1060 			offset = 127-((sys16_fg_scrollx&0x3f8) >> 3)-40+2;
1061 
1062 			for( i=0; i<41; i++ ){
1063 				scroll = sys18_splittab_fg_y[(i+24)>>1];
1064 				tilemap_set_scrolly( foreground , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1065 			}
1066 		}
1067 	}
1068 	else {
1069 		tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1070 	}
1071 }
1072 
sys18_vh_screenrefresh_helper(void)1073 static void sys18_vh_screenrefresh_helper( void ){
1074 	int i;
1075 	if( sys18_splittab_bg_x ){ // screenwise rowscroll?
1076 		int offset,offset2, scroll,scroll2,orig_scroll;
1077 
1078 		offset = 32+((sys16_bg_scrolly&0x1f8) >> 3); // 0x00..0x3f
1079 		offset2 = 32+((sys16_bg2_scrolly&0x1f8) >> 3); // 0x00..0x3f
1080 
1081 		for( i=0;i<29;i++ ){
1082 			orig_scroll = scroll2 = scroll = sys18_splittab_bg_x[i];
1083 			if((sys16_bg_scrollx  &0xff00) != 0x8000) scroll = sys16_bg_scrollx;
1084 			if((sys16_bg2_scrollx &0xff00) != 0x8000) scroll2 = sys16_bg2_scrollx;
1085 
1086 			if(orig_scroll&0x8000){ // background2
1087 				tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1088 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1089 			}
1090 			else{ // background
1091 				tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1092 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, TILE_LINE_DISABLED );
1093 			}
1094 		}
1095 	}
1096 	else {
1097 		tilemap_set_scrollx( background , 0, -320-(sys16_bg_scrollx&0x3ff)+sys16_bgxoffset );
1098 		tilemap_set_scrollx( background2, 0, -320-(sys16_bg2_scrollx&0x3ff)+sys16_bgxoffset );
1099 	}
1100 
1101 	tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
1102 	tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
1103 
1104 	if( sys18_splittab_fg_x ){
1105 		int offset,offset2, scroll,scroll2,orig_scroll;
1106 
1107 		offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1108 		offset2 = 32+((sys16_fg2_scrolly&0x1f8) >> 3);
1109 
1110 		for( i=0;i<29;i++ ){
1111 			orig_scroll = scroll2 = scroll = sys18_splittab_fg_x[i];
1112 			if( (sys16_fg_scrollx &0xff00) != 0x8000 ) scroll = sys16_fg_scrollx;
1113 
1114 			if( (sys16_fg2_scrollx &0xff00) != 0x8000 ) scroll2 = sys16_fg2_scrollx;
1115 
1116 			if( orig_scroll&0x8000 ){
1117 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
1118 				tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
1119 			}
1120 			else {
1121 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1122 				tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1123 			}
1124 		}
1125 	}
1126 	else {
1127 		tilemap_set_scrollx( foreground , 0, -320-(sys16_fg_scrollx&0x3ff)+sys16_fgxoffset );
1128 		tilemap_set_scrollx( foreground2, 0, -320-(sys16_fg2_scrollx&0x3ff)+sys16_fgxoffset );
1129 	}
1130 
1131 
1132 	tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
1133 	tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
1134 
1135 	tilemap_set_enable( background2, sys18_bg2_active );
1136 	tilemap_set_enable( foreground2, sys18_fg2_active );
1137 }
1138 
VIDEO_UPDATE(system16)1139 VIDEO_UPDATE( system16 ){
1140 	if (!sys16_refreshenable) return;
1141 
1142 	if( sys16_update_proc ) sys16_update_proc();
1143 	update_page();
1144 	sys16_vh_refresh_helper(); /* set scroll registers */
1145 
1146 	fillbitmap(priority_bitmap,0,cliprect);
1147 
1148 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY, 0x00 );
1149 	if(sys16_bg_priority_mode) tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 1, 0x00 );
1150 //	sprite_draw(sprite_list,3); // needed for Aurail
1151 	if( sys16_bg_priority_mode==2 ) tilemap_draw( bitmap,cliprect, background, 1, 0x01 );// body slam (& wrestwar??)
1152 //	sprite_draw(sprite_list,2);
1153 	else if( sys16_bg_priority_mode==1 ) tilemap_draw( bitmap,cliprect, background, 1, 0x03 );// alien syndrome / aurail
1154 	tilemap_draw( bitmap,cliprect, foreground, 0, 0x03 );
1155 //	sprite_draw(sprite_list,1);
1156 	tilemap_draw( bitmap,cliprect, foreground, 1, 0x07 );
1157 	if( sys16_textlayer_lo_max!=0 ) tilemap_draw( bitmap,cliprect, text_layer, 1, 7 );// needed for Body Slam
1158 //	sprite_draw(sprite_list,0);
1159 	tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1160 
1161 	draw_sprites( bitmap,cliprect,0 );
1162 }
1163 
VIDEO_UPDATE(system18)1164 VIDEO_UPDATE( system18 ){
1165 	if (!sys16_refreshenable) return;
1166 	if( sys16_update_proc ) sys16_update_proc();
1167 	update_page();
1168 	sys18_vh_screenrefresh_helper(); /* set scroll registers */
1169 
1170 	fillbitmap(priority_bitmap,0,NULL);
1171 	if(sys18_bg2_active)
1172 		tilemap_draw( bitmap,cliprect, background2, 0, 0 );
1173 	else
1174 		fillbitmap(bitmap,Machine->pens[0],cliprect);
1175 
1176 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY, 0 );
1177 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 1, 0 );	//??
1178 	tilemap_draw( bitmap,cliprect, background, TILEMAP_IGNORE_TRANSPARENCY | 2, 0 );	//??
1179 
1180 //	sprite_draw(sprite_list,3);
1181 	tilemap_draw( bitmap,cliprect, background, 1, 0x1 );
1182 //	sprite_draw(sprite_list,2);
1183 	tilemap_draw( bitmap,cliprect, background, 2, 0x3 );
1184 
1185 	if(sys18_fg2_active) tilemap_draw( bitmap,cliprect, foreground2, 0, 0x3 );
1186 	tilemap_draw( bitmap,cliprect, foreground, 0, 0x3 );
1187 //	sprite_draw(sprite_list,1);
1188 	if(sys18_fg2_active) tilemap_draw( bitmap,cliprect, foreground2, 1, 0x7 );
1189 	tilemap_draw( bitmap,cliprect, foreground, 1, 0x7 );
1190 
1191 	tilemap_draw( bitmap,cliprect, text_layer, 1, 0x7 );
1192 //	sprite_draw(sprite_list,0);
1193 	tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1194 
1195 	draw_sprites( bitmap,cliprect, 0 );
1196 }
1197 
1198 
render_gr(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)1199 static void render_gr(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority){
1200 	/* the road is a 4 color bitmap */
1201 	int i,j;
1202 	UINT8 *data = memory_region(REGION_GFX3);
1203 	UINT8 *source;
1204 	UINT16 *line16;
1205 	UINT16 *data_ver=sys16_gr_ver;
1206 	UINT32 ver_data,hor_pos;
1207 	UINT16 colors[5];
1208 	int colorflip;
1209 	int yflip=0, ypos;
1210 	int dx=1,xoff=0;
1211 
1212 	pen_t *paldata1 = Machine->gfx[0]->colortable + sys16_gr_palette;
1213 	pen_t *paldata2 = Machine->gfx[0]->colortable + sys16_gr_palette_default;
1214 
1215 #if 0
1216 if( keyboard_pressed( KEYCODE_S ) ){
1217 	FILE *f;
1218 	int i;
1219 	char fname[64];
1220 	static int fcount = 0;
1221 	while( keyboard_pressed( KEYCODE_S ) ){}
1222 	sprintf( fname, "road%d.txt",fcount );
1223 	fcount++;
1224 	f = fopen( fname,"w" );
1225 	if( f ){
1226 		const UINT16 *source = sys16_gr_ver;
1227 		for( i=0; i<0x1000; i++ ){
1228 			if( (i&0x1f)==0 ) fprintf( f, "\n %04x: ", i );
1229 			fprintf( f, "%04x ", source[i] );
1230 		}
1231 		fclose( f );
1232 	}
1233 }
1234 #endif
1235 
1236 	priority=priority << 10;
1237 
1238 	if (Machine->scrbitmap->depth == 16) /* 16 bit */
1239 	{
1240 		if( Machine->orientation & ORIENTATION_SWAP_XY ){
1241 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1242 				dx=-1;
1243 				xoff=319;
1244 			}
1245 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1246 				yflip=1;
1247 			}
1248 
1249 			for(i=cliprect->min_y;i<=cliprect->max_y;i++){
1250 				if(yflip) ypos=223-i;
1251 				else ypos=i;
1252 				ver_data=*data_ver;
1253 				if((ver_data & 0x400) == priority)
1254 				{
1255 					colors[0] = paldata1[ sys16_gr_pal[(ver_data)&0xff]&0xff ];
1256 
1257 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
1258 					{
1259 						// fill line
1260 						for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1261 						{
1262 							line16=(UINT16 *)bitmap->line[j]+ypos;
1263 							*line16=colors[0];
1264 						}
1265 					}
1266 					else
1267 					{
1268 						// copy line
1269 						ver_data=ver_data & 0x00ff;
1270 						colorflip = (sys16_gr_flip[ver_data] >> 3) & 1;
1271 
1272 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1273 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1274 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1275 						colors[4] = paldata2[ sys16_gr_colorflip[colorflip][3] ];
1276 
1277 						hor_pos = sys16_gr_hor[ver_data];
1278 						ver_data = ver_data << sys16_gr_bitmap_width;
1279 
1280 						if(hor_pos & 0xf000)
1281 						{
1282 							// reverse
1283 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
1284 						}
1285 						else
1286 						{
1287 							// normal
1288 							hor_pos=(hor_pos+0x200) & 0x3ff;
1289 						}
1290 
1291 						source = data + hor_pos + ver_data + 18 + 8;
1292 
1293 						for(j=cliprect->min_x;j<cliprect->max_x;j++)
1294 						{
1295 							line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
1296 							*line16 = colors[*source++];
1297 						}
1298 					}
1299 				}
1300 				data_ver++;
1301 			}
1302 		}
1303 		else
1304 		{ /* 16 bpp, normal screen orientation */
1305 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1306 				dx=-1;
1307 				xoff=319;
1308 			}
1309 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1310 				yflip=1;
1311 			}
1312 
1313 			for(i=cliprect->min_y;i<=cliprect->max_y;i++){ /* with each scanline */
1314 				if( yflip ) ypos=223-i; else ypos=i;
1315 				ver_data= *data_ver; /* scanline parameters */
1316 				/*
1317 					gr_ver:
1318 						---- -x-- ---- ----	priority
1319 						---- --x- ---- ---- ?
1320 						---- ---x ---- ---- ?
1321 						---- ---- xxxx xxxx ypos (source bitmap)
1322 
1323 					gr_flip:
1324 						---- ---- ---- x--- flip colors
1325 
1326 					gr_hor:
1327 						xxxx xxxx xxxx xxxx	xscroll
1328 
1329 					gr_pal:
1330 						---- ---- xxxx xxxx palette
1331 				*/
1332 				if( (ver_data & 0x400) == priority ){
1333 					colors[0] = paldata1[ sys16_gr_pal[ver_data&0xff]&0xff ];
1334 
1335 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200){
1336 						line16 = (UINT16 *)bitmap->line[ypos]; /* dest for drawing */
1337 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1338 							*line16++=colors[0]; /* opaque fill with background color */
1339 						}
1340 					}
1341 					else {
1342 						// copy line
1343 						line16 = (UINT16 *)bitmap->line[ypos]+xoff; /* dest for drawing */
1344 						ver_data &= 0xff;
1345 
1346 						colorflip = (sys16_gr_flip[ver_data] >> 3) & 1;
1347 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1348 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1349 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1350 						colors[4] = paldata2[ sys16_gr_colorflip[colorflip][3] ];
1351 
1352 						hor_pos = sys16_gr_hor[ver_data];
1353 						if( hor_pos & 0xf000 ){ // reverse (precalculated)
1354 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
1355 						}
1356 						else { // normal
1357 							hor_pos=(hor_pos+0x200) & 0x3ff;
1358 						}
1359 
1360 						ver_data <<= sys16_gr_bitmap_width;
1361 						source = data + hor_pos + ver_data + 18 + 8;
1362 
1363 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1364 							*line16 = colors[*source++];
1365 							line16+=dx;
1366 						}
1367 					}
1368 				}
1369 				data_ver++;
1370 			}
1371 		}
1372 	}
1373 }
1374 
VIDEO_UPDATE(hangon)1375 VIDEO_UPDATE( hangon ){
1376 	if (!sys16_refreshenable) return;
1377 	if( sys16_update_proc ) sys16_update_proc();
1378 	update_page();
1379 
1380 	tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1381 	tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1382 	tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1383 	tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1384 
1385 	fillbitmap(priority_bitmap,0,cliprect);
1386 
1387 	render_gr(bitmap,cliprect,0); /* sky */
1388 	tilemap_draw( bitmap,cliprect, background, 0, 0 );
1389 	tilemap_draw( bitmap,cliprect, foreground, 0, 0 );
1390 	render_gr(bitmap,cliprect,1); /* floor */
1391 	tilemap_draw( bitmap,cliprect, text_layer, 0, 0xf );
1392 
1393 	draw_sprites( bitmap,cliprect, 0 );
1394 }
1395 
render_grv2(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)1396 static void render_grv2(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority)
1397 {
1398 	int i,j;
1399 	UINT8 *data = memory_region(REGION_GFX3);
1400 	UINT8 *source,*source2,*temp;
1401 	UINT16 *line16;
1402 	UINT16 *data_ver=sys16_gr_ver;
1403 	UINT32 ver_data,hor_pos,hor_pos2;
1404 	UINT16 colors[5];
1405 	int colorflip,colorflip_info;
1406 	int yflip=0,ypos;
1407 	int dx=1,xoff=0;
1408 
1409 	int second_road = sys16_gr_second_road[0];
1410 
1411 	pen_t *paldata1 = Machine->gfx[0]->colortable + sys16_gr_palette;
1412 	pen_t *paldata2 = Machine->gfx[0]->colortable + sys16_gr_palette_default;
1413 
1414 	priority=priority << 11;
1415 
1416 	if (Machine->scrbitmap->depth == 16) /* 16 bit */
1417 	{
1418 		if( Machine->orientation & ORIENTATION_SWAP_XY )
1419 		{
1420 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1421 				dx=-1;
1422 				xoff=319;
1423 			}
1424 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1425 				yflip=1;
1426 			}
1427 
1428 			for(i=cliprect->min_y;i<=cliprect->max_y;i++)
1429 			{
1430 				if(yflip) ypos=223-i;
1431 				else ypos=i;
1432 				ver_data = *data_ver;
1433 				if((ver_data & 0x800) == priority)
1434 				{
1435 
1436 					if(ver_data & 0x800) /* disable */
1437 					{
1438 						colors[0] = paldata1[ ver_data&0x3f ];
1439 						// fill line
1440 						for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1441 						{
1442 							line16=(UINT16 *)bitmap->line[j]+ypos;
1443 							*line16=colors[0];
1444 						}
1445 					}
1446 					else
1447 					{
1448 						// copy line
1449 						ver_data=ver_data & 0x01ff;		//???
1450 						colorflip_info = sys16_gr_flip[ver_data];
1451 
1452 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
1453 
1454 						colorflip = (colorflip_info >> 3) & 1;
1455 
1456 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1457 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1458 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1459 
1460 						hor_pos = sys16_gr_hor[ver_data];
1461 						hor_pos2= sys16_gr_hor[ver_data+0x200];
1462 
1463 						ver_data=ver_data>>1;
1464 						if( ver_data != 0 )
1465 						{
1466 							ver_data = (ver_data-1) << sys16_gr_bitmap_width;
1467 						}
1468 						source  = data + ((hor_pos +0x200) & 0x7ff) + 0x300 + ver_data + 8;
1469 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 0x300 + ver_data + 8;
1470 
1471 						switch(second_road)
1472 						{
1473 							case 0:	source2=source;	break;
1474 							case 2:	temp=source;source=source2;source2=temp; break;
1475 							case 3:	source=source2;	break;
1476 						}
1477 
1478 						source2++;
1479 
1480 						for(j=cliprect->min_x;j<=cliprect->max_x;j++)
1481 						{
1482 							line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
1483 							if(*source2 <= *source)
1484 								*line16 = colors[*source];
1485 							else
1486 								*line16 = colors[*source2];
1487 							source++;
1488 							source2++;
1489 						}
1490 					}
1491 				}
1492 				data_ver++;
1493 			}
1494 		}
1495 		else
1496 		{
1497 			if( Machine->orientation & ORIENTATION_FLIP_X ){
1498 				dx=-1;
1499 				xoff=319;
1500 			}
1501 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
1502 				yflip=1;
1503 			}
1504 
1505 			for(i=cliprect->min_y;i<=cliprect->max_y;i++){
1506 				if(yflip) ypos=223-i;
1507 				else ypos=i;
1508 				ver_data= *data_ver;
1509 				if((ver_data & 0x800) == priority){
1510 					if(ver_data & 0x800){
1511 						colors[0] = paldata1[ ver_data&0x3f ];
1512 						// fill line
1513 						line16 = (UINT16 *)bitmap->line[ypos];
1514 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1515 							*line16++ = colors[0];
1516 						}
1517 					}
1518 					else {
1519 						// copy line
1520 						line16 = (UINT16 *)bitmap->line[ypos]+xoff;
1521 						ver_data &= 0x01ff;		//???
1522 						colorflip_info = sys16_gr_flip[ver_data];
1523 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
1524 						colorflip = (colorflip_info >> 3) & 1;
1525 						colors[1] = paldata2[ sys16_gr_colorflip[colorflip][0] ];
1526 						colors[2] = paldata2[ sys16_gr_colorflip[colorflip][1] ];
1527 						colors[3] = paldata2[ sys16_gr_colorflip[colorflip][2] ];
1528 						hor_pos = sys16_gr_hor[ver_data];
1529 						hor_pos2= sys16_gr_hor[ver_data+0x200];
1530 						ver_data=ver_data>>1;
1531 						if( ver_data != 0 ){
1532 							ver_data = (ver_data-1) << sys16_gr_bitmap_width;
1533 						}
1534 						source  = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
1535 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
1536 						switch(second_road){
1537 							case 0:	source2=source;	break;
1538 							case 2:	temp=source;source=source2;source2=temp; break;
1539 							case 3:	source=source2;	break;
1540 						}
1541 						source2++;
1542 						for(j=cliprect->min_x;j<=cliprect->max_x;j++){
1543 							if(*source2 <= *source) *line16 = colors[*source]; else *line16 = colors[*source2];
1544 							source++;
1545 							source2++;
1546 							line16+=dx;
1547 						}
1548 					}
1549 				}
1550 				data_ver++;
1551 			}
1552 		}
1553 	}
1554 }
1555 
1556 
VIDEO_START(outrun)1557 VIDEO_START( outrun ){
1558 	int ret;
1559 	sys16_bg1_trans=1;
1560 	ret = video_start_system16();
1561 	if(ret) return 1;
1562 
1563 	sys16_textlayer_lo_min=0;
1564 	sys16_textlayer_lo_max=0;
1565 	sys16_textlayer_hi_min=0;
1566 	sys16_textlayer_hi_max=0xff;
1567 
1568 	sys16_bg_priority_mode=-1;
1569 	sys16_bg_priority_value=0x1800;
1570 	sys16_fg_priority_value=0x2000;
1571 	return 0;
1572 }
1573 
VIDEO_UPDATE(outrun)1574 VIDEO_UPDATE( outrun ){
1575 	if( sys16_refreshenable ){
1576 		if( sys16_update_proc ) sys16_update_proc();
1577 		update_page();
1578 
1579 		tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1580 		tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1581 
1582 		tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1583 		tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1584 
1585 		render_grv2(bitmap,cliprect,1);
1586 		tilemap_draw( bitmap,cliprect, background, 0, 0 );
1587 		tilemap_draw( bitmap,cliprect, foreground, 0, 0 );
1588 		render_grv2(bitmap,cliprect,0);
1589 
1590 		draw_sprites( bitmap,cliprect, 1 );
1591 
1592 		tilemap_draw( bitmap,cliprect, text_layer, 0, 0 );
1593 	}
1594 }
1595 
1596 /***************************************************************************/
1597 
1598 static UINT8 *aburner_backdrop;
1599 
aburner_unpack_backdrop(const UINT8 * baseaddr)1600 UINT8 *aburner_unpack_backdrop( const UINT8 *baseaddr ){
1601 	UINT8 *result = auto_malloc(512*256*2);
1602 	if( result ){
1603 		int page;
1604 		for( page=0; page<2; page++ ){
1605 			UINT8 *dest = result + 512*256*page;
1606 			const UINT8 *source = baseaddr + 0x8000*page;
1607 			int y;
1608 			for( y=0; y<256; y++ ){
1609 				int x;
1610 				for( x=0; x<512; x++ ){
1611 					int data0 = source[x/8];
1612 					int data1 = source[x/8 + 0x4000];
1613 					int bit = 0x80>>(x&7);
1614 					int pen = 0;
1615 					if( data0 & bit ) pen+=1;
1616 					if( data1 & bit ) pen+=2;
1617 					dest[x] = pen;
1618 				}
1619 
1620 				{
1621 					int edge_color = dest[0];
1622 					for( x=0; x<512; x++ ){
1623 						if( dest[x]==edge_color ) dest[x] = 4; else break;
1624 					}
1625 					edge_color = dest[511];
1626 					for( x=511; x>=0; x-- ){
1627 						if( dest[x]==edge_color ) dest[x] = 4; else break;
1628 					}
1629 				}
1630 
1631 				source += 0x40;
1632 				dest += 512;
1633 			}
1634 		}
1635 	}
1636 	return result;
1637 }
1638 
VIDEO_START(aburner)1639 VIDEO_START( aburner ){
1640 	int ret;
1641 
1642 	aburner_backdrop = aburner_unpack_backdrop( memory_region(REGION_GFX3) );
1643 
1644 	sys16_bg1_trans=1;
1645 	ret = video_start_system16();
1646 	if(ret) return 1;
1647 
1648 	foreground2 = tilemap_create(
1649 		get_fg2_tile_info,
1650 		sys16_bg_map,
1651 		TILEMAP_TRANSPARENT,
1652 		8,8,
1653 		64*2,32*2 );
1654 
1655 	background2 = tilemap_create(
1656 		get_bg2_tile_info,
1657 		sys16_bg_map,
1658 		TILEMAP_TRANSPARENT,
1659 		8,8,
1660 		64*2,32*2 );
1661 
1662 	if( foreground2 && background2 ){
1663 		ret = video_start_system16();
1664 		if(ret) return 1;
1665 		tilemap_set_transparent_pen( foreground2, 0 );
1666 		sys16_18_mode = 1;
1667 
1668 		tilemap_set_scroll_rows( foreground , 64 );
1669 		tilemap_set_scroll_rows( foreground2 , 64 );
1670 		tilemap_set_scroll_rows( background , 64 );
1671 		tilemap_set_scroll_rows( background2 , 64 );
1672 
1673 		return 0;
1674 	}
1675 	return 1;
1676 }
1677 
aburner_draw_road(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1678 static void aburner_draw_road( struct mame_bitmap *bitmap, const struct rectangle *cliprect ){
1679 	/*
1680 		sys16_roadram[0x1000]:
1681 			0x04: flying (sky/horizon)
1682 			0x43: (flying->landing)
1683 			0xc3: runway landing
1684 			0xe3: (landing -> flying)
1685 			0x03: rocky canyon
1686 
1687 			Thunderblade: 0x04, 0xfe
1688 	*/
1689 
1690 	/*	Palette:
1691 	**		0x1700	ground(8), road(4), road(4)
1692 	**		0x1720	sky(16)
1693 	**		0x1730	road edge(2)
1694 	**		0x1780	background color(16)
1695 	*/
1696 
1697 	const UINT16 *vreg = sys16_roadram;
1698 	/*	0x000..0x0ff: 0x800: disable; 0x100: enable
1699 		0x100..0x1ff: color/line_select
1700 		0x200..0x2ff: xscroll
1701 		0x400..0x4ff: 0x5b0?
1702 		0x600..0x6ff: flip colors
1703 	*/
1704 	int page = sys16_roadram[0x1000];
1705 	int sy;
1706 
1707 	for( sy=cliprect->min_y; sy<=cliprect->max_y; sy++ ){
1708 		UINT16 *dest = (UINT16 *)bitmap->line[sy] + cliprect->min_x; /* assume 16bpp */
1709 		int sx;
1710 		UINT16 line = vreg[0x100+sy];
1711 
1712 		if( page&4 ){ /* flying */
1713 			int xscroll = vreg[0x200+sy] - 0x552;
1714 			UINT16 sky = Machine->pens[0x1720];
1715 			UINT16 ground = Machine->pens[0x1700];
1716 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1717 				int temp = xscroll+sx;
1718 				if( temp<0 ){
1719 					*dest++ = sky;
1720 				}
1721 				else if( temp < 0x200 ){
1722 					*dest++ = ground;
1723 				}
1724 				else {
1725 					*dest++ = sky;
1726 				}
1727 			}
1728 		}
1729 		else if( line&0x800 ){
1730 			/* opaque fill; the least significant nibble selects color */
1731 			unsigned short color = Machine->pens[0x1780+(line&0xf)];
1732 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1733 				*dest++ = color;
1734 			}
1735 		}
1736 		else if( page&0xc0 ){ /* road */
1737 			const UINT8 *source = aburner_backdrop+(line&0xff)*512 + 512*256*(page&1);
1738 			UINT16 xscroll = (512-320)/2;
1739 			// 040d 04b0 0552: normal: sky,horizon,sea
1740 
1741 			UINT16 flip = vreg[0x600+sy];
1742 			int clut[5];
1743 			{
1744 				int road_color = 0x1708+(flip&0x1);
1745 				clut[0] = Machine->pens[road_color];
1746 				clut[1] = Machine->pens[road_color+2];
1747 				clut[2] = Machine->pens[road_color+4];
1748 				clut[3] = Machine->pens[road_color+6];
1749 				clut[4] = Machine->pens[(flip&0x100)?0x1730:0x1731]; /* edge of road */
1750 			}
1751 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1752 				int xpos = (sx + xscroll)&0x1ff;
1753 				*dest++ = clut[source[xpos]];
1754 			}
1755 		}
1756 		else { /* rocky canyon */
1757 			UINT16 flip = vreg[0x600+sy];
1758 			unsigned short color = Machine->pens[(flip&0x100)?0x1730:0x1731];
1759 			for( sx=cliprect->min_x; sx<=cliprect->max_x; sx++ ){
1760 				*dest++ = color;
1761 			}
1762 		}
1763 	}
1764 #if 0
1765 	if( keyboard_pressed( KEYCODE_S ) ){ /* debug */
1766 		FILE *f;
1767 		int i;
1768 		char fname[64];
1769 		static int fcount = 0;
1770 		while( keyboard_pressed( KEYCODE_S ) ){}
1771 		sprintf( fname, "road%d.txt",fcount );
1772 		fcount++;
1773 		f = fopen( fname,"w" );
1774 		if( f ){
1775 			const UINT16 *source = sys16_roadram;
1776 			for( i=0; i<0x1000; i++ ){
1777 				if( (i&0x1f)==0 ) fprintf( f, "\n %04x: ", i );
1778 				fprintf( f, "%04x ", source[i] );
1779 			}
1780 			fclose( f );
1781 		}
1782 	}
1783 #endif
1784 }
1785 
sys16_aburner_vh_screenrefresh_helper(void)1786 static void sys16_aburner_vh_screenrefresh_helper( void ){
1787 	const data16_t *vreg = &sys16_textram[0x740];
1788 	int i;
1789 
1790 	{
1791 		UINT16 data = vreg[0];
1792 		sys16_fg_page[0] = data>>12;
1793 		sys16_fg_page[1] = (data>>8)&0xf;
1794 		sys16_fg_page[2] = (data>>4)&0xf;
1795 		sys16_fg_page[3] = data&0xf;
1796 		sys16_fg_scrolly = vreg[8];
1797 		sys16_fg_scrollx = vreg[12];
1798 	}
1799 
1800 	{
1801 		UINT16 data = vreg[0+1];
1802 		sys16_bg_page[0] = data>>12;
1803 		sys16_bg_page[1] = (data>>8)&0xf;
1804 		sys16_bg_page[2] = (data>>4)&0xf;
1805 		sys16_bg_page[3] = data&0xf;
1806 		sys16_bg_scrolly = vreg[8+1];
1807 		sys16_bg_scrollx = vreg[12+1];
1808 	}
1809 
1810 	{
1811 		UINT16 data = vreg[0+2];
1812 		sys16_fg2_page[0] = data>>12;
1813 		sys16_fg2_page[1] = (data>>8)&0xf;
1814 		sys16_fg2_page[2] = (data>>4)&0xf;
1815 		sys16_fg2_page[3] = data&0xf;
1816 		sys16_fg2_scrolly = vreg[8+2];
1817 		sys16_fg2_scrollx = vreg[12+2];
1818 	}
1819 
1820 	{
1821 		UINT16 data = vreg[0+3];
1822 		sys16_bg2_page[0] = data>>12;
1823 		sys16_bg2_page[1] = (data>>8)&0xf;
1824 		sys16_bg2_page[2] = (data>>4)&0xf;
1825 		sys16_bg2_page[3] = data&0xf;
1826 		sys16_bg2_scrolly = vreg[8+3];
1827 		sys16_bg2_scrollx = vreg[12+3];
1828 	}
1829 
1830 	sys18_splittab_fg_x = &sys16_textram[0x7c0];
1831 	sys18_splittab_bg_x = &sys16_textram[0x7e0];
1832 
1833 	{
1834 		int offset,offset2, scroll,scroll2,orig_scroll;
1835 		offset  = 32+((sys16_bg_scrolly >>3)&0x3f ); // screenwise rowscroll
1836 		offset2 = 32+((sys16_bg2_scrolly>>3)&0x3f ); // screenwise rowscroll
1837 
1838 		for( i=0;i<29;i++ ){
1839 			orig_scroll = scroll2 = scroll = sys18_splittab_bg_x[i];
1840 			if((sys16_bg_scrollx  &0xff00) != 0x8000) scroll = sys16_bg_scrollx;
1841 			if((sys16_bg2_scrollx &0xff00) != 0x8000) scroll2 = sys16_bg2_scrollx;
1842 
1843 			if( orig_scroll&0x8000 ){ // background2
1844 				tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1845 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1846 			}
1847 			else{ // background1
1848 				tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1849 				tilemap_set_scrollx( background2, (i+offset2)&0x3f, TILE_LINE_DISABLED );
1850 			}
1851 		}
1852 	}
1853 
1854 	tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
1855 	tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
1856 
1857 	{
1858 		int offset,offset2, scroll,scroll2,orig_scroll;
1859 		offset  = 32+((sys16_fg_scrolly >>3)&0x3f ); // screenwise rowscroll
1860 		offset2 = 32+((sys16_fg2_scrolly>>3)&0x3f ); // screenwise rowscroll
1861 
1862 		for( i=0;i<29;i++ ){
1863 			orig_scroll = scroll2 = scroll = sys18_splittab_fg_x[i];
1864 			if( (sys16_fg_scrollx &0xff00) != 0x8000 ) scroll = sys16_fg_scrollx;
1865 
1866 			if( (sys16_fg2_scrollx &0xff00) != 0x8000 ) scroll2 = sys16_fg2_scrollx;
1867 
1868 			if( orig_scroll&0x8000 ){ // foreground2
1869 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
1870 				tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
1871 			}
1872 			else { // foreground
1873 				tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1874 				tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1875 			}
1876 		}
1877 	}
1878 
1879 	tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
1880 	tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
1881 }
1882 
VIDEO_UPDATE(aburner)1883 VIDEO_UPDATE( aburner ){
1884 	sys16_aburner_vh_screenrefresh_helper();
1885 	update_page();
1886 
1887 	fillbitmap(priority_bitmap,0,cliprect);
1888 
1889 	aburner_draw_road( bitmap,cliprect );
1890 
1891 //	tilemap_draw( bitmap,cliprect, background2, 0, 7 );
1892 //	tilemap_draw( bitmap,cliprect, background2, 1, 7 );
1893 
1894 	/* speed indicator, high score header */
1895 	tilemap_draw( bitmap,cliprect, background, 0, 7 );
1896 	tilemap_draw( bitmap,cliprect, background, 1, 7 );
1897 
1898 	/* radar view */
1899 	tilemap_draw( bitmap,cliprect, foreground2, 0, 7 );
1900 	tilemap_draw( bitmap,cliprect, foreground2, 1, 7 );
1901 
1902 	/* hand, scores */
1903 	tilemap_draw( bitmap,cliprect, foreground, 0, 7 );
1904 	tilemap_draw( bitmap,cliprect, foreground, 1, 7 );
1905 
1906 	tilemap_draw( bitmap,cliprect, text_layer, 0, 7 );
1907 	draw_sprites( bitmap,cliprect, 2 );
1908 
1909 //	debug_draw( bitmap,cliprect, 8,8,sys16_roadram[0x1000] );
1910 }
1911