1 /***************************************************************************
2 
3 Sega System 16 Video Hardware
4 
5 Each scrolling layer (foreground, background) is an arrangement
6 of 4 pages selected from 16 available pages, laid out as follows:
7 
8 	Page0  Page1
9 	Page2  Page3
10 
11 Each page is an arrangement of 8x8 tiles, 64 tiles wide, and 32 tiles high.
12 
13 ***************************************************************************/
14 void dump_tilemap(void);
15 
16 #include "driver.h"
17 
18 //#define SYS16_DEBUG
19 //#define SPACEHARRIER_OFFSETS
20 
21 // an attempt at fudging correct gamma for sys16 games, but I'm not sure that it's
22 // really worth using.
23 //#define GAMMA_ADJUST
24 #define TRANSPARENT_SHADOWS
25 #define MAXCOLOURS 8192
26 
27 #ifdef TRANSPARENT_SHADOWS
28 #define ShadowColorsShift 8
29 UINT16 shade_table[MAXCOLOURS];
30 int sys16_sh_shadowpal;
31 #endif
32 
33 int sys16_MaxShadowColors;
34 static int sys16_MaxShadowColors_Shift;
35 
36 #define NUM_SPRITES 128
37 
38 extern UINT8 *sys16_textram;
39 extern UINT8 *sys16_spriteram;
40 extern UINT8 *sys16_tileram; /* contains tilemaps for 16 pages */
41 
42 static struct sprite_list *sprite_list;
43 
44 /* video driver constants (potentially different for each game) */
45 int sys16_spritesystem;
46 int sys16_sprxoffset;
47 int sys16_bgxoffset;
48 int sys16_fgxoffset;
49 int *sys16_obj_bank;
50 int sys16_textmode;
51 int sys16_textlayer_lo_min;
52 int sys16_textlayer_lo_max;
53 int sys16_textlayer_hi_min;
54 int sys16_textlayer_hi_max;
55 int sys16_dactype;
56 int sys16_bg1_trans; // alien syn + sys18
57 int sys16_bg_priority_mode;
58 int sys16_fg_priority_mode;
59 int sys16_bg_priority_value;
60 int sys16_fg_priority_value;
61 int sys16_18_mode;
62 int sys16_spritelist_end;
63 int sys16_tilebank_switch;
64 int sys16_rowscroll_scroll;
65 int sys16_quartet_title_kludge;
66 extern void (* sys16_update_proc)( void );
67 
68 /* video registers */
69 int sys16_tile_bank1;
70 int sys16_tile_bank0;
71 int sys16_refreshenable;
72 int sys16_clear_screen;
73 int sys16_bg_scrollx, sys16_bg_scrolly;
74 int sys16_bg_page[4];
75 int sys16_fg_scrollx, sys16_fg_scrolly;
76 int sys16_fg_page[4];
77 
78 int sys16_bg2_scrollx, sys16_bg2_scrolly;
79 int sys16_bg2_page[4];
80 int sys16_fg2_scrollx, sys16_fg2_scrolly;
81 int sys16_fg2_page[4];
82 
83 int sys18_bg2_active;
84 int sys18_fg2_active;
85 unsigned char *sys18_splittab_bg_x;
86 unsigned char *sys18_splittab_bg_y;
87 unsigned char *sys18_splittab_fg_x;
88 unsigned char *sys18_splittab_fg_y;
89 
90 static int sys16_freezepalette;
91 static int sys16_palettedirty[MAXCOLOURS];
92 
93 #ifdef SPACEHARRIER_OFFSETS
94 unsigned char *spaceharrier_patternoffsets;
95 #endif
96 unsigned char *gr_ver;
97 unsigned char *gr_hor;
98 unsigned char *gr_pal;
99 unsigned char *gr_flip;
100 int gr_palette;
101 int gr_palette_default;
102 unsigned char gr_colorflip[2][4];
103 unsigned char *gr_second_road;
104 
105 static struct tilemap *background, *foreground, *text_layer;
106 static struct tilemap *background2, *foreground2;
107 static int old_bg_page[4],old_fg_page[4], old_tile_bank1, old_tile_bank0;
108 static int old_bg2_page[4],old_fg2_page[4];
109 
110 static void draw_quartet_title_screen( struct osd_bitmap *bitmap,int playfield );
111 
112 /***************************************************************************/
113 
sys16_bg_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)114 UINT32 sys16_bg_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
115 	int page = 0;
116 	if( row<32 ){ /* top */
117 		if( col<64 ) page = 0; else page = 1;
118 	}
119 	else { /* bottom */
120 		if( col<64 ) page = 2; else page = 3;
121 	}
122 	row = row%32;
123 	col = col%64;
124 	return page*64*32+row*64+col;
125 }
126 
sys16_text_map(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows)127 UINT32 sys16_text_map( UINT32 col, UINT32 row, UINT32 num_cols, UINT32 num_rows ){
128 	return row*64+col+(64-40);
129 }
130 
131 /***************************************************************************/
132 
WRITE_HANDLER(sys16_paletteram_w)133 WRITE_HANDLER( sys16_paletteram_w ){
134 	UINT16 oldword = READ_WORD (&paletteram[offset]);
135 	UINT16 newword = COMBINE_WORD (oldword, data);
136 	if( oldword!=newword ){
137 		/* we can do this, because we initialize palette RAM to all black in vh_start */
138 		/*	   byte 0    byte 1 */
139 		/*	GBGR BBBB GGGG RRRR */
140 		/*	5444 3210 3210 3210 */
141 		UINT8 r = (newword & 0x00f)<<1;
142 		UINT8 g = (newword & 0x0f0)>>2;
143 		UINT8 b = (newword & 0xf00)>>7;
144 		if( sys16_dactype == 0 ){
145 			/* dac_type == 0 (from GCS file) */
146 			if (newword&0x1000) r|=1;
147 			if (newword&0x2000) g|=2;
148 			if (newword&0x8000) g|=1;
149 			if (newword&0x4000) b|=1;
150 		}
151 		else if( sys16_dactype == 1 ){
152 			/* dac_type == 1 (from GCS file) Shinobi Only*/
153 			if (newword&0x1000) r|=1;
154 			if (newword&0x4000) g|=2;
155 			if (newword&0x8000) g|=1;
156 			if (newword&0x2000) b|=1;
157 		}
158 
159 #ifndef TRANSPARENT_SHADOWS
160 		if( !sys16_freezepalette ){
161 			palette_change_color( offset/2,
162 				(r << 3) | (r >> 2), /* 5 bits red */
163 				(g << 2) | (g >> 4), /* 6 bits green */
164 				(b << 3) | (b >> 2) /* 5 bits blue */
165 			);
166 		}
167 		else{
168 			r=(r << 3) | (r >> 2); /* 5 bits red */
169 			g=(g << 2) | (g >> 4); /* 6 bits green */
170 			b=(b << 3) | (b >> 2); /* 5 bits blue */
171 			sys16_palettedirty[offset/2]=0xff000000+(r<<16)+(g<<8)+b;
172 		}
173 #else
174 		if (Machine->scrbitmap->depth == 8){ /* 8 bit shadows */
175 			if(!sys16_freezepalette){
176 				palette_change_color( offset/2,
177 					(r << 3) | (r >> 3), /* 5 bits red */
178 					(g << 2) | (g >> 4), /* 6 bits green */
179 					(b << 3) | (b >> 3) /* 5 bits blue */
180 				);
181 			}
182 			else {
183 				r=(r << 3) | (r >> 3); /* 5 bits red */
184 				g=(g << 2) | (g >> 4); /* 6 bits green */
185 				b=(b << 3) | (b >> 3); /* 5 bits blue */
186 				sys16_palettedirty[offset/2]=0xff000000+(r<<16)+(g<<8)+b;
187 			}
188 		}
189 		else {
190 			if(!sys16_freezepalette){
191 				r=(r << 3) | (r >> 2); /* 5 bits red */
192 				g=(g << 2) | (g >> 4); /* 6 bits green */
193 				b=(b << 3) | (b >> 2); /* 5 bits blue */
194 
195 				palette_change_color( offset/2,r,g,b);
196 
197 				/* shadow color */
198 
199 				r= r * 160 / 256;
200 				g= g * 160 / 256;
201 				b= b * 160 / 256;
202 
203 				palette_change_color( offset/2+Machine->drv->total_colors/2,r,g,b);
204 			}
205 			else {
206 				r=(r << 3) | (r >> 3); /* 5 bits red */
207 				g=(g << 2) | (g >> 4); /* 6 bits green */
208 				b=(b << 3) | (b >> 3); /* 5 bits blue */
209 				sys16_palettedirty[offset/2]=0xff000000+(r<<16)+(g<<8)+b;
210 
211 				r= r * 160 / 256;
212 				g= g * 160 / 256;
213 				b= b * 160 / 256;
214 				sys16_palettedirty[offset/2+Machine->drv->total_colors/2]=0xff000000+(r<<16)+(g<<8)+b;
215 			}
216 		}
217 #endif
218 		WRITE_WORD (&paletteram[offset], newword);
219 	}
220 }
221 
sys16_refresh_palette(void)222 static void sys16_refresh_palette(void){
223 	UINT8 r,g,b;
224 	int i;
225 	for( i=0;i<Machine->drv->total_colors;i++ ){
226 		if( sys16_palettedirty[i] ){
227 			r=(sys16_palettedirty[i]&0x00ff0000) >> 16;
228 			g=(sys16_palettedirty[i]&0x0000ff00) >> 8;
229 			b=(sys16_palettedirty[i]&0x000000ff);
230 			palette_change_color(i,r,g,b);
231 			sys16_palettedirty[i]=0;
232 		}
233 	}
234 }
235 
update_page(void)236 static void update_page( void ){
237 	int all_dirty = 0;
238 	int i,offset;
239 	if( old_tile_bank1 != sys16_tile_bank1 ){
240 		all_dirty = 1;
241 		old_tile_bank1 = sys16_tile_bank1;
242 	}
243 	if( old_tile_bank0 != sys16_tile_bank0 ){
244 		all_dirty = 1;
245 		old_tile_bank0 = sys16_tile_bank0;
246 		tilemap_mark_all_tiles_dirty( text_layer );
247 	}
248 	if( all_dirty ){
249 		tilemap_mark_all_tiles_dirty( background );
250 		tilemap_mark_all_tiles_dirty( foreground );
251 		if( sys16_18_mode ){
252 			tilemap_mark_all_tiles_dirty( background2 );
253 			tilemap_mark_all_tiles_dirty( foreground2 );
254 		}
255 	}
256 	else {
257 		for(i=0;i<4;i++){
258 			int page0 = 64*32*i;
259 			if( old_bg_page[i]!=sys16_bg_page[i] ){
260 				old_bg_page[i] = sys16_bg_page[i];
261 				for( offset = page0; offset<page0+64*32; offset++ ){
262 					tilemap_mark_tile_dirty( background, offset );
263 				}
264 			}
265 			if( old_fg_page[i]!=sys16_fg_page[i] ){
266 				old_fg_page[i] = sys16_fg_page[i];
267 				for( offset = page0; offset<page0+64*32; offset++ ){
268 					tilemap_mark_tile_dirty( foreground, offset );
269 				}
270 			}
271 			if( sys16_18_mode ){
272 				if( old_bg2_page[i]!=sys16_bg2_page[i] ){
273 					old_bg2_page[i] = sys16_bg2_page[i];
274 					for( offset = page0; offset<page0+64*32; offset++ ){
275 						tilemap_mark_tile_dirty( background2, offset );
276 					}
277 				}
278 				if( old_fg2_page[i]!=sys16_fg2_page[i] ){
279 					old_fg2_page[i] = sys16_fg2_page[i];
280 					for( offset = page0; offset<page0+64*32; offset++ ){
281 						tilemap_mark_tile_dirty( foreground2, offset );
282 					}
283 				}
284 			}
285 		}
286 	}
287 }
288 
get_bg_tile_info(int offset)289 static void get_bg_tile_info( int offset ){
290 	const UINT16 *source = 64*32*sys16_bg_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
291 	int data = source[offset%(64*32)];
292 	int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
293 
294 	if(sys16_textmode==0){
295 		SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
296 	}
297 	else{
298 		SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
299 	}
300 
301 	switch(sys16_bg_priority_mode) {
302 	case 1: // Alien Syndrome
303 		tile_info.priority = (data&0x8000)?1:0;
304 		break;
305 	case 2: // Body Slam / wrestwar
306 		tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
307 		break;
308 	case 3: // sys18 games
309 		if( data&0x8000 ){
310 			tile_info.priority = 2;
311 		}
312 		else {
313 			tile_info.priority = ((data&0xff00) >= sys16_bg_priority_value)?1:0;
314 		}
315 		break;
316 	}
317 }
318 
get_fg_tile_info(int offset)319 static void get_fg_tile_info( int offset ){
320 	const UINT16 *source = 64*32*sys16_fg_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
321 	int data = source[offset%(64*32)];
322 	int tile_number = (data&0xfff) + 0x1000*((data&sys16_tilebank_switch)?sys16_tile_bank1:sys16_tile_bank0);
323 
324 	if(sys16_textmode==0){
325 		SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
326 	}
327 	else{
328 		SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
329 	}
330 	switch(sys16_fg_priority_mode){
331 	case 1: // alien syndrome
332 		tile_info.priority = (data&0x8000)?1:0;
333 		break;
334 
335 	case 3:
336 		tile_info.priority = ((data&0xff00) >= sys16_fg_priority_value)?1:0;
337 		break;
338 
339 	default:
340 		if( sys16_fg_priority_mode>=0 ){
341 			tile_info.priority = (data&0x8000)?1:0;
342 		}
343 		break;
344 	}
345 }
346 
get_bg2_tile_info(int offset)347 static void get_bg2_tile_info( int offset ){
348 	const UINT16 *source = 64*32*sys16_bg2_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
349 	int data = source[offset%(64*32)];
350 	int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
351 	if(sys16_textmode==0){
352 		SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
353 	}
354 	else{
355 		SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
356 	}
357 	tile_info.priority = 0;
358 }
359 
get_fg2_tile_info(int offset)360 static void get_fg2_tile_info( int offset ){
361 	const UINT16 *source = 64*32*sys16_fg2_page[offset/(64*32)] + (UINT16 *)sys16_tileram;
362 	int data = source[offset%(64*32)];
363 	int tile_number = (data&0xfff) + 0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
364 	if(sys16_textmode==0){
365 		SET_TILE_INFO( 0, tile_number, (data>>6)&0x7f );
366 	}
367 	else{
368 		SET_TILE_INFO( 0, tile_number, (data>>5)&0x7f );
369 	}
370 	if((data&0xff00) >= sys16_fg_priority_value) tile_info.priority = 1;
371 	else tile_info.priority = 0;
372 }
373 
WRITE_HANDLER(sys16_tileram_w)374 WRITE_HANDLER( sys16_tileram_w ){
375 	int oldword = READ_WORD(&sys16_tileram[offset]);
376 	int newword = COMBINE_WORD(oldword,data);
377 	if( oldword != newword ){
378 		int page;
379 		WRITE_WORD(&sys16_tileram[offset],newword);
380 		offset = offset/2;
381 		page = offset/(64*32);
382 		offset = offset%(64*32);
383 
384 		if( sys16_bg_page[0]==page ) tilemap_mark_tile_dirty( background, offset+64*32*0 );
385 		if( sys16_bg_page[1]==page ) tilemap_mark_tile_dirty( background, offset+64*32*1 );
386 		if( sys16_bg_page[2]==page ) tilemap_mark_tile_dirty( background, offset+64*32*2 );
387 		if( sys16_bg_page[3]==page ) tilemap_mark_tile_dirty( background, offset+64*32*3 );
388 
389 		if( sys16_fg_page[0]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*0 );
390 		if( sys16_fg_page[1]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*1 );
391 		if( sys16_fg_page[2]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*2 );
392 		if( sys16_fg_page[3]==page ) tilemap_mark_tile_dirty( foreground, offset+64*32*3 );
393 
394 		if( sys16_18_mode ){
395 			if( sys16_bg2_page[0]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*0 );
396 			if( sys16_bg2_page[1]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*1 );
397 			if( sys16_bg2_page[2]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*2 );
398 			if( sys16_bg2_page[3]==page ) tilemap_mark_tile_dirty( background2, offset+64*32*3 );
399 
400 			if( sys16_fg2_page[0]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*0 );
401 			if( sys16_fg2_page[1]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*1 );
402 			if( sys16_fg2_page[2]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*2 );
403 			if( sys16_fg2_page[3]==page ) tilemap_mark_tile_dirty( foreground2, offset+64*32*3 );
404 		}
405 	}
406 }
407 
READ_HANDLER(sys16_tileram_r)408 READ_HANDLER( sys16_tileram_r ){
409 	return READ_WORD (&sys16_tileram[offset]);
410 }
411 
412 /***************************************************************************/
413 
get_text_tile_info(int offset)414 static void get_text_tile_info( int offset ){
415 	const UINT16 *source = (UINT16 *)sys16_textram;
416 	int tile_number = source[offset];
417 	int pri = tile_number >> 8;
418 	if(sys16_textmode==0){
419 		SET_TILE_INFO( 0, (tile_number&0x1ff) + sys16_tile_bank0 * 0x1000, (tile_number>>9)%8 );
420 	}
421 	else{
422 		SET_TILE_INFO( 0, (tile_number&0xff)  + sys16_tile_bank0 * 0x1000, (tile_number>>8)%8 );
423 	}
424 	if(pri>=sys16_textlayer_lo_min && pri<=sys16_textlayer_lo_max)
425 		tile_info.priority = 1;
426 	if(pri>=sys16_textlayer_hi_min && pri<=sys16_textlayer_hi_max)
427 		tile_info.priority = 0;
428 }
429 
WRITE_HANDLER(sys16_textram_w)430 WRITE_HANDLER( sys16_textram_w ){
431 	int oldword = READ_WORD(&sys16_textram[offset]);
432 	int newword = COMBINE_WORD(oldword,data);
433 	if( oldword != newword ){
434 		WRITE_WORD(&sys16_textram[offset],newword);
435 		tilemap_mark_tile_dirty( text_layer, offset/2 );
436 	}
437 }
438 
READ_HANDLER(sys16_textram_r)439 READ_HANDLER( sys16_textram_r ){
440 	return READ_WORD (&sys16_textram[offset]);
441 }
442 
443 /***************************************************************************/
444 
sys16_vh_stop(void)445 void sys16_vh_stop( void ){
446 
447 #ifdef SPACEHARRIER_OFFSETS
448 	if(spaceharrier_patternoffsets) free(spaceharrier_patternoffsets);
449 	spaceharrier_patternoffsets=0;
450 #endif
451 }
452 
sys16_vh_start(void)453 int sys16_vh_start( void ){
454 	if( !sys16_bg1_trans )
455 		background = tilemap_create(
456 			get_bg_tile_info,
457 			sys16_bg_map,
458 			TILEMAP_OPAQUE,
459 			8,8,
460 			64*2,32*2 );
461 	else
462 		background = tilemap_create(
463 			get_bg_tile_info,
464 			sys16_bg_map,
465 			TILEMAP_TRANSPARENT,
466 			8,8,
467 			64*2,32*2 );
468 
469 	foreground = tilemap_create(
470 		get_fg_tile_info,
471 		sys16_bg_map,
472 		TILEMAP_TRANSPARENT,
473 		8,8,
474 		64*2,32*2 );
475 
476 	text_layer = tilemap_create(
477 		get_text_tile_info,
478 		sys16_text_map,
479 		TILEMAP_TRANSPARENT,
480 		8,8,
481 		40,28 );
482 
483 	sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
484 
485 #ifdef TRANSPARENT_SHADOWS
486 	sprite_set_shade_table(shade_table);
487 #endif
488 
489 	if( background && foreground && text_layer && sprite_list ){
490 		/* initialize all entries to black - needed for Golden Axe*/
491 		int i;
492 		for( i=0; i<Machine->drv->total_colors; i++ ){
493 			palette_change_color( i, 0,0,0 );
494 		}
495 #ifdef TRANSPARENT_SHADOWS
496 		memset(&palette_used_colors[0], PALETTE_COLOR_UNUSED, Machine->drv->total_colors);
497 		if (Machine->scrbitmap->depth == 8) /* 8 bit shadows */
498 		{
499 			int j,color;
500 			for(j = 0, i = Machine->drv->total_colors/2;j<sys16_MaxShadowColors;i++,j++)
501 			{
502 				color=j * 160 / (sys16_MaxShadowColors-1);
503 				color=color | 0x04;
504 				palette_change_color(i, color, color, color);
505 			}
506 		}
507 		if(sys16_MaxShadowColors==32)
508 			sys16_MaxShadowColors_Shift = ShadowColorsShift;
509 		else if(sys16_MaxShadowColors==16)
510 			sys16_MaxShadowColors_Shift = ShadowColorsShift+1;
511 
512 #endif
513 		for(i=0;i<MAXCOLOURS;i++){
514 			sys16_palettedirty[i]=0;
515 		}
516 		sys16_freezepalette=0;
517 
518 		sprite_list->max_priority = 3;
519 		sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
520 
521 		if(sys16_bg1_trans) background->transparent_pen = 0;
522 		foreground->transparent_pen = 0;
523 		text_layer->transparent_pen = 0;
524 
525 		sys16_tile_bank0 = 0;
526 		sys16_tile_bank1 = 1;
527 
528 		sys16_fg_scrollx = 0;
529 		sys16_fg_scrolly = 0;
530 
531 		sys16_bg_scrollx = 0;
532 		sys16_bg_scrolly = 0;
533 
534 		sys16_refreshenable = 1;
535 		sys16_clear_screen = 0;
536 
537 		/* common defaults */
538 		sys16_update_proc = 0;
539 		sys16_spritesystem = 1;
540 		sys16_sprxoffset = -0xb8;
541 		sys16_textmode = 0;
542 		sys16_bgxoffset = 0;
543 		sys16_dactype = 0;
544 		sys16_bg_priority_mode=0;
545 		sys16_fg_priority_mode=0;
546 		sys16_spritelist_end=0xffff;
547 		sys16_tilebank_switch=0x1000;
548 
549 		// Defaults for sys16 games
550 		sys16_textlayer_lo_min=0;
551 		sys16_textlayer_lo_max=0x7f;
552 		sys16_textlayer_hi_min=0x80;
553 		sys16_textlayer_hi_max=0xff;
554 
555 		sys16_18_mode=0;
556 
557 #ifdef GAMMA_ADJUST
558 		{
559 			static float sys16_orig_gamma=0;
560 			static float sys16_set_gamma=0;
561 			float cur_gamma=osd_get_gamma();
562 
563 			if(sys16_orig_gamma == 0)
564 			{
565 				sys16_orig_gamma = cur_gamma;
566 				sys16_set_gamma = cur_gamma - 0.35;
567 				if (sys16_set_gamma < 0.5) sys16_set_gamma = 0.5;
568 				if (sys16_set_gamma > 2.0) sys16_set_gamma = 2.0;
569 				osd_set_gamma(sys16_set_gamma);
570 			}
571 			else
572 			{
573 				if(sys16_orig_gamma == cur_gamma)
574 				{
575 					osd_set_gamma(sys16_set_gamma);
576 				}
577 			}
578 		}
579 #endif
580 		return 0;
581 	}
582 	return 1;
583 }
584 
sys16_ho_vh_start(void)585 int sys16_ho_vh_start( void ){
586 	int ret;
587 	sys16_bg1_trans=1;
588 	ret = sys16_vh_start();
589 	if(ret) return 1;
590 
591 	sys16_textlayer_lo_min=0;
592 	sys16_textlayer_lo_max=0;
593 	sys16_textlayer_hi_min=0;
594 	sys16_textlayer_hi_max=0xff;
595 
596 	sys16_bg_priority_mode=-1;
597 	sys16_bg_priority_value=0x1800;
598 	sys16_fg_priority_value=0x2000;
599 	return 0;
600 }
601 
sys16_or_vh_start(void)602 int sys16_or_vh_start( void ){
603 	int ret;
604 	sys16_bg1_trans=1;
605 	ret = sys16_vh_start();
606 	if(ret) return 1;
607 
608 	sys16_textlayer_lo_min=0;
609 	sys16_textlayer_lo_max=0;
610 	sys16_textlayer_hi_min=0;
611 	sys16_textlayer_hi_max=0xff;
612 
613 	sys16_bg_priority_mode=-1;
614 	sys16_bg_priority_value=0x1800;
615 	sys16_fg_priority_value=0x2000;
616 	return 0;
617 }
618 
619 
sys18_vh_start(void)620 int sys18_vh_start( void ){
621 	int ret;
622 	sys16_bg1_trans=1;
623 
624 	background2 = tilemap_create(
625 		get_bg2_tile_info,
626 		sys16_bg_map,
627 		TILEMAP_OPAQUE,
628 		8,8,
629 		64*2,32*2 );
630 
631 	foreground2 = tilemap_create(
632 		get_fg2_tile_info,
633 		sys16_bg_map,
634 		TILEMAP_TRANSPARENT,
635 		8,8,
636 		64*2,32*2 );
637 
638 	if( background2 && foreground2)
639 	{
640 		ret = sys16_vh_start();
641 		if(ret) return 1;
642 
643 		foreground2->transparent_pen = 0;
644 
645 		if(sys18_splittab_fg_x)
646 		{
647 			tilemap_set_scroll_rows( foreground , 64 );
648 			tilemap_set_scroll_rows( foreground2 , 64 );
649 		}
650 		if(sys18_splittab_bg_x)
651 		{
652 			tilemap_set_scroll_rows( background , 64 );
653 			tilemap_set_scroll_rows( background2 , 64 );
654 		}
655 
656 		sys16_textlayer_lo_min=0;
657 		sys16_textlayer_lo_max=0x1f;
658 		sys16_textlayer_hi_min=0x20;
659 		sys16_textlayer_hi_max=0xff;
660 
661 		sys16_18_mode=1;
662 		sys16_bg_priority_mode=3;
663 		sys16_fg_priority_mode=3;
664 		sys16_bg_priority_value=0x1800;
665 		sys16_fg_priority_value=0x2000;
666 		return 0;
667 	}
668 	return 1;
669 }
670 
671 
672 /***************************************************************************/
673 
get_sprite_info(void)674 static void get_sprite_info( void ){
675 	const unsigned short *base_pal = Machine->gfx[0]->colortable + 1024;
676 	const unsigned char *base_gfx = memory_region(REGION_GFX2);
677 
678 	UINT16 *source = (UINT16 *)sys16_spriteram;
679 	struct sprite *sprite = sprite_list->sprite;
680 	const struct sprite *finish = sprite + NUM_SPRITES;
681 
682 	int passshot_y=0;
683 	int passshot_width=0;
684 
685 #ifdef SYS16_DEBUG
686 	int dump_spritedata=0;
687 	if(keyboard_pressed_memory(KEYCODE_W))
688 	{
689 		dump_spritedata=1;
690 		logerror("sprites\n");
691 	}
692 #endif
693 	switch( sys16_spritesystem  ){
694 		case 1: /* standard sprite hardware (Shinobi, Altered Beast, Golden Axe, ...) */
695 /*
696 	0	bottom--	top-----	(screen coordinates)
697 	1	???????X	XXXXXXXX	(screen coordinate)
698 	2	???????F	FWWWWWWW	(flipx, flipy, logical width)
699 	3	TTTTTTTT	TTTTTTTT	(pen data)
700 	4	????BBBB	PPCCCCCC	(attributes: bank, priority, color)
701 	5	??????ZZ	ZZZZZZZZ	zoomx
702 	6	??????ZZ	ZZZZZZZZ	zoomy (defaults to zoomx)
703 	7	?						"sprite offset"
704 */
705 		while( sprite<finish ){
706 			UINT16 ypos = source[0];
707 			UINT16 width = source[2];
708 			int top = ypos&0xff;
709 			int bottom = ypos>>8;
710 
711 			if( bottom == 0xff || width ==sys16_spritelist_end){ /* end of spritelist marker */
712 				do {
713 					sprite->flags = 0;
714 					sprite++;
715 				} while( sprite<finish );
716 				break;
717 			}
718 			sprite->flags = 0;
719 
720 			if(bottom !=0 && bottom > top)
721 			{
722 				UINT16 attributes = source[4];
723 				UINT16 zoomx = source[5]&0x3ff;
724 				UINT16 zoomy = (source[6]&0x3ff);
725 				int gfx = source[3]*4;
726 
727 #ifdef SYS16_DEBUG
728 				if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
729 						source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
730 #endif
731 
732 				if( zoomy==0 || source[6]==0xffff ) zoomy = zoomx; /* if zoomy is 0, use zoomx instead */
733 
734 				sprite->x = source[1] + sys16_sprxoffset;
735 				sprite->y = top;
736 				sprite->priority = 3-((attributes>>6)&0x3);
737 				sprite->pal_data = base_pal + ((attributes&0x3f)<<4);
738 
739 				sprite->total_height = bottom-top;
740 				sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
741 
742 				sprite->line_offset = (width&0x7f)*4;
743 
744 				sprite->flags = SPRITE_VISIBLE;
745 				if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
746 				if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
747 
748 #ifdef TRANSPARENT_SHADOWS
749 				if ((attributes&0x3f)==0x3f)	// shadow sprite
750 					sprite->flags|= SPRITE_SHADOW;
751 #endif
752 
753 				if( sprite->flags&SPRITE_FLIPY ){
754 					sprite->line_offset = 512-sprite->line_offset;
755 					if( sprite->flags&SPRITE_FLIPX ){
756 						gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
757 					}
758 					else {
759 						gfx -= sprite->line_offset*sprite->tile_height;
760 					}
761 				}
762 				else {
763 					if( sprite->flags&SPRITE_FLIPX ){
764 						gfx += 4;
765 					}
766 					else {
767 						gfx += sprite->line_offset;
768 					}
769 				}
770 
771 				sprite->tile_width = sprite->line_offset;
772 				sprite->total_width = sprite->tile_width*(0x800-zoomx)/0x800;
773 				sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[(attributes>>8)&0xf] << 17);
774 
775 			}
776 
777 			sprite++;
778 			source += 8;
779 		}
780 		break;
781 
782 		case 8: /* Passing shot 4p */
783 			passshot_y=-0x23;
784 			passshot_width=1;
785 		case 0: /* Passing shot */
786 /*
787 	0	???????X	XXXXXXXX	(screen coordinate)
788 	1	bottom--	top-----	(screen coordinates)
789 	2	XTTTTTTT	YTTTTTTT	(pen data, flipx, flipy)
790 	3	????????	?WWWWWWW	(logical width)
791 	4	??????ZZ	ZZZZZZZZ	zoom
792 	5	PP???CCC	BBBB????	(attributes: bank, priority, color)
793 	6,7	(unused)
794 */
795 		while( sprite<finish ){
796 			UINT16 attributes = source[5];
797 			UINT16 ypos = source[1];
798 			int bottom = (ypos>>8)+passshot_y;
799 			int top = (ypos&0xff)+passshot_y;
800 			sprite->flags = 0;
801 
802 			if( bottom>top && ypos!=0xffff ){
803 				int bank = (attributes>>4)&0xf;
804 				UINT16 number = source[2];
805 				UINT16 width = source[3];
806 
807 				int zoom = source[4]&0x3ff;
808 				int xpos = source[0] + sys16_sprxoffset;
809 
810 #ifdef SYS16_DEBUG
811 				if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
812 						source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
813 #endif
814 				sprite->priority = 3-((attributes>>14)&0x3);
815 				if(passshot_width) /* 4 player bootleg version */
816 				{
817 					width=-width;
818 					number-=width*(bottom-top-1)-1;
819 				}
820 
821 				if( number & 0x8000 ) sprite->flags |= SPRITE_FLIPX;
822 				if( width  & 0x0080 ) sprite->flags |= SPRITE_FLIPY;
823 				sprite->flags |= SPRITE_VISIBLE;
824 				sprite->pal_data = base_pal + ((attributes>>4)&0x3f0);
825 				sprite->total_height = bottom - top;
826 				sprite->tile_height = sprite->total_height*(0x400+zoom)/0x400;
827 
828 #ifdef TRANSPARENT_SHADOWS
829 				if (((attributes>>8)&0x3f)==0x3f)	// shadow sprite
830 					sprite->flags|= SPRITE_SHADOW;
831 #endif
832 				width &= 0x7f;
833 
834 				if( sprite->flags&SPRITE_FLIPY ) width = 0x80-width;
835 
836 				sprite->tile_width = sprite->line_offset = width*4;
837 
838 				if( sprite->flags&SPRITE_FLIPX ){
839 					bank = (bank-1) & 0xf;
840 					if( sprite->flags&SPRITE_FLIPY ){
841 						xpos += 4;
842 					}
843 					else {
844 						number += 1-width;
845 					}
846 				}
847 				sprite->pen_data = base_gfx + number*4 + (sys16_obj_bank[bank] << 17);
848 
849 				if( sprite->flags&SPRITE_FLIPY ){
850 					sprite->pen_data -= sprite->tile_height*sprite->tile_width;
851 					if( sprite->flags&SPRITE_FLIPX ) sprite->pen_data += 2;
852 				}
853 
854 				sprite->x = xpos;
855 				sprite->y = top+2;
856 
857 				if( sprite->flags&SPRITE_FLIPY ){
858 					if( sprite->flags&SPRITE_FLIPX ){
859 						sprite->tile_width-=4;
860 						sprite->pen_data+=4;
861 					}
862 					else {
863 						sprite->pen_data += sprite->line_offset;
864 					}
865 				}
866 
867 				sprite->total_width = sprite->tile_width*(0x800-zoom)/0x800;
868 			}
869 			sprite++;
870 			source += 8;
871 		}
872 		break;
873 
874 		case 4: // Aurail
875 /*
876 	0	bottom--	top-----	(screen coordinates)
877 	1	???????X	XXXXXXXX	(screen coordinate)
878 	2	???????F	FWWWWWWW	(flipx, flipy, logical width)
879 	3	TTTTTTTT	TTTTTTTT	(pen data)
880 	4	????BBBB	PPCCCCCC	(attributes: bank, priority, color)
881 	5	??????ZZ	ZZZZZZZZ	zoomx
882 	6	??????ZZ	ZZZZZZZZ	zoomy (defaults to zoomx)
883 	7	?						"sprite offset"
884 */
885 		while( sprite<finish ){
886 			UINT16 ypos = source[0];
887 			UINT16 width = source[2];
888 			UINT16 attributes = source[4];
889 			int top = ypos&0xff;
890 			int bottom = ypos>>8;
891 
892 			if( width == sys16_spritelist_end) {
893 				do {
894 					sprite->flags = 0;
895 					sprite++;
896 				} while( sprite<finish );
897 				break;
898 			}
899 			sprite->flags = 0;
900 #ifdef TRANSPARENT_SHADOWS
901 			if(bottom !=0 && bottom > top)
902 #else
903 			if(bottom !=0 && bottom > top && (attributes&0x3f) !=0x3f)
904 #endif
905 			{
906 				UINT16 zoomx = source[5]&0x3ff;
907 				UINT16 zoomy = (source[6]&0x3ff);
908 				int gfx = source[3]*4;
909 
910 #ifdef SYS16_DEBUG
911 				if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
912 						source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
913 #endif
914 
915 				if( zoomy==0 ) zoomy = zoomx; /* if zoomy is 0, use zoomx instead */
916 				sprite->pal_data = base_pal + ((attributes&0x3f)<<4);
917 
918 				sprite->x = source[1] + sys16_sprxoffset;;
919 				sprite->y = top;
920 				sprite->priority = 3-((attributes>>6)&0x3);
921 
922 				sprite->total_height = bottom-top;
923 				sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
924 
925 				sprite->line_offset = (width&0x7f)*4;
926 
927 				sprite->flags = SPRITE_VISIBLE;
928 				if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
929 				if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
930 #ifdef TRANSPARENT_SHADOWS
931 				if ((attributes&0x3f)==0x3f)	// shadow sprite
932 					sprite->flags|= SPRITE_SHADOW;
933 #endif
934 
935 				if( sprite->flags&SPRITE_FLIPY ){
936 					sprite->line_offset = 512-sprite->line_offset;
937 					if( sprite->flags&SPRITE_FLIPX ){
938 						gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
939 					}
940 					else {
941 						gfx -= sprite->line_offset*sprite->tile_height;
942 					}
943 				}
944 				else {
945 					if( sprite->flags&SPRITE_FLIPX ){
946 						gfx += 4;
947 					}
948 					else {
949 						gfx += sprite->line_offset;
950 					}
951 				}
952 
953 				sprite->tile_width = sprite->line_offset;
954 				sprite->total_width = sprite->tile_width*(0x800-zoomx)/0x800;
955 				sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[(attributes>>8)&0xf] << 17);
956 
957 			}
958 			sprite++;
959 			source += 8;
960 		}
961 		break;
962 		case 3:	// Fantzone
963 			{
964 				int spr_no=0;
965 				while( sprite<finish ){
966 					UINT16 ypos = source[0];
967 					UINT16 pal=(source[4]>>8)&0x3f;
968 					int top = ypos&0xff;
969 					int bottom = ypos>>8;
970 
971 					if( bottom == 0xff ){ /* end of spritelist marker */
972 						do {
973 							sprite->flags = 0;
974 							sprite++;
975 						} while( sprite<finish );
976 						break;
977 					}
978 					sprite->flags = 0;
979 
980 #ifdef SYS16_DEBUG
981 					if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
982 							source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
983 #endif
984 #ifdef TRANSPARENT_SHADOWS
985 					if(bottom !=0 && bottom > top)
986 #else
987 					if(bottom !=0 && bottom > top && pal !=0x3f)
988 #endif
989 					{
990 						UINT16 spr_pri=(source[4])&0xf;
991 						UINT16 bank=(source[4]>>4) &0xf;
992 						UINT16 tsource[4];
993 						UINT16 width;
994 						int gfx;
995 
996 						if (spr_no==5 && (source[4]&0x00ff) == 0x0021 &&
997 							((source[3]&0xff00) == 0x5200 || (source[3]&0xff00) == 0x5300)) spr_pri=2; // tears fix for ending boss
998 
999 						tsource[2]=source[2];
1000 						tsource[3]=source[3];
1001 
1002 						if((tsource[3] & 0x7f80) == 0x7f80)
1003 						{
1004 							bank=(bank-1)&0xf;
1005 							tsource[3]^=0x8000;
1006 						}
1007 
1008 						tsource[2] &= 0x00ff;
1009 						if (tsource[3]&0x8000)
1010 						{ // reverse
1011 							tsource[2] |= 0x0100;
1012 							tsource[3] &= 0x7fff;
1013 						}
1014 
1015 						gfx = tsource[3]*4;
1016 						width = tsource[2];
1017 						top++;
1018 						bottom++;
1019 
1020 						sprite->x = source[1] + sys16_sprxoffset;
1021 						if(sprite->x > 0x140) sprite->x-=0x200;
1022 						sprite->y = top;
1023 						sprite->priority = 3-spr_pri;
1024 						sprite->pal_data = base_pal + (pal<<4);
1025 
1026 						sprite->total_height = bottom-top;
1027 						sprite->tile_height = sprite->total_height;
1028 
1029 						sprite->line_offset = (width&0x7f)*4;
1030 
1031 						sprite->flags = SPRITE_VISIBLE;
1032 						if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1033 						if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1034 #ifdef TRANSPARENT_SHADOWS
1035 						if (pal==0x3f)	// shadow sprite
1036 							sprite->flags|= SPRITE_SHADOW;
1037 #endif
1038 
1039 						if( sprite->flags&SPRITE_FLIPY ){
1040 							sprite->line_offset = 512-sprite->line_offset;
1041 							if( sprite->flags&SPRITE_FLIPX ){
1042 								gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
1043 							}
1044 							else {
1045 								gfx -= sprite->line_offset*sprite->tile_height;
1046 							}
1047 						}
1048 						else {
1049 							if( sprite->flags&SPRITE_FLIPX ){
1050 								gfx += 4;
1051 							}
1052 							else {
1053 								gfx += sprite->line_offset;
1054 							}
1055 						}
1056 
1057 						sprite->tile_width = sprite->line_offset;
1058 						if(width==0) sprite->tile_width=320;			// fixes laser
1059 						sprite->total_width = sprite->tile_width;
1060 						sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[bank] << 17);
1061 
1062 					}
1063 
1064 					source+=8;
1065 					sprite++;
1066 					spr_no++;
1067 				}
1068 			}
1069 			break;
1070 		case 2: // Quartet2 /Alexkidd + others
1071 		while( sprite<finish ){
1072 			UINT16 ypos = source[0];
1073 			int top = ypos&0xff;
1074 			int bottom = ypos>>8;
1075 
1076 			if( bottom == 0xff ){ /* end of spritelist marker */
1077 				do {
1078 					sprite->flags = 0;
1079 					sprite++;
1080 				} while( sprite<finish );
1081 				break;
1082 			}
1083 			sprite->flags = 0;
1084 
1085 			if(bottom !=0 && bottom > top)
1086 			{
1087 				UINT16 spr_pri=(source[4])&0xf;
1088 				UINT16 bank=(source[4]>>4) &0xf;
1089 				UINT16 pal=(source[4]>>8)&0x3f;
1090 				UINT16 tsource[4];
1091 				UINT16 width;
1092 				int gfx;
1093 
1094 #ifdef SYS16_DEBUG
1095 				if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
1096 						source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1097 #endif
1098 
1099 				tsource[2]=source[2];
1100 				tsource[3]=source[3];
1101 #ifndef TRANSPARENT_SHADOWS
1102 				if (pal==0x3f)	// shadow sprite
1103 					pal=(bank<<1);
1104 #endif
1105 
1106 				if((tsource[3] & 0x7f80) == 0x7f80)
1107 				{
1108 					bank=(bank-1)&0xf;
1109 					tsource[3]^=0x8000;
1110 				}
1111 
1112 				tsource[2] &= 0x00ff;
1113 				if (tsource[3]&0x8000)
1114 				{ // reverse
1115 					tsource[2] |= 0x0100;
1116 					tsource[3] &= 0x7fff;
1117 				}
1118 
1119 				gfx = tsource[3]*4;
1120 				width = tsource[2];
1121 				top++;
1122 				bottom++;
1123 
1124 				sprite->x = source[1] + sys16_sprxoffset;
1125 				if(sprite->x > 0x140) sprite->x-=0x200;
1126 				sprite->y = top;
1127 				sprite->priority = 3 - spr_pri;
1128 				sprite->pal_data = base_pal + (pal<<4);
1129 
1130 				sprite->total_height = bottom-top;
1131 				sprite->tile_height = sprite->total_height;
1132 
1133 				sprite->line_offset = (width&0x7f)*4;
1134 
1135 				sprite->flags = SPRITE_VISIBLE;
1136 				if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1137 				if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1138 #ifdef TRANSPARENT_SHADOWS
1139 				if (pal==0x3f)	// shadow sprite
1140 					sprite->flags|= SPRITE_SHADOW;
1141 #endif
1142 
1143 				if( sprite->flags&SPRITE_FLIPY ){
1144 					sprite->line_offset = 512-sprite->line_offset;
1145 					if( sprite->flags&SPRITE_FLIPX ){
1146 						gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
1147 					}
1148 					else {
1149 						gfx -= sprite->line_offset*sprite->tile_height;
1150 					}
1151 				}
1152 				else {
1153 					if( sprite->flags&SPRITE_FLIPX ){
1154 						gfx += 4;
1155 					}
1156 					else {
1157 						gfx += sprite->line_offset;
1158 					}
1159 				}
1160 
1161 				sprite->tile_width = sprite->line_offset;
1162 				sprite->total_width = sprite->tile_width;
1163 				sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[bank] << 17);
1164 			}
1165 
1166 			source+=8;
1167 			sprite++;
1168 		}
1169 		break;
1170 		case 5: // Hang-On
1171 		while( sprite<finish ){
1172 			UINT16 ypos = source[0];
1173 			int top = ypos&0xff;
1174 			int bottom = ypos>>8;
1175 
1176 			if( bottom == 0xff ){ /* end of spritelist marker */
1177 				do {
1178 					sprite->flags = 0;
1179 					sprite++;
1180 				} while( sprite<finish );
1181 				break;
1182 			}
1183 			sprite->flags = 0;
1184 
1185 			if(bottom !=0 && bottom > top)
1186 			{
1187 				UINT16 bank=(source[1]>>12);
1188 				UINT16 pal=(source[4]>>8)&0x3f;
1189 				UINT16 tsource[4];
1190 				UINT16 width;
1191 				int gfx;
1192 				int zoomx,zoomy;
1193 
1194 #ifdef SYS16_DEBUG
1195 				if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
1196 						source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1197 #endif
1198 
1199 				tsource[2]=source[2];
1200 				tsource[3]=source[3];
1201 
1202 				zoomx=((source[4]>>2) & 0x3f) *(1024/64);
1203 		        zoomy = (1060*zoomx)/(2048-zoomx);
1204 
1205 //				if (pal==0x3f)	// ????????????
1206 //					pal=(bank<<1);
1207 
1208 				if((tsource[3] & 0x7f80) == 0x7f80)
1209 				{
1210 					bank=(bank-1)&0xf;
1211 					tsource[3]^=0x8000;
1212 				}
1213 
1214 				if (tsource[3]&0x8000)
1215 				{ // reverse
1216 					tsource[2] |= 0x0100;
1217 					tsource[3] &= 0x7fff;
1218 				}
1219 
1220 				gfx = tsource[3]*4;
1221 				width = tsource[2];
1222 
1223 				sprite->x = ((source[1] & 0x3ff) + sys16_sprxoffset);
1224 				if(sprite->x >= 0x200) sprite->x-=0x200;
1225 				sprite->y = top;
1226 				sprite->priority = 0;
1227 				sprite->pal_data = base_pal + (pal<<4);
1228 
1229 				sprite->total_height = bottom-top;
1230 				sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
1231 
1232 				sprite->line_offset = (width&0x7f)*4;
1233 
1234 				sprite->flags = SPRITE_VISIBLE;
1235 				if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1236 				if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1237 
1238 
1239 //				sprite->flags|= SPRITE_PARTIAL_SHADOW;
1240 //				sprite->shadow_pen=10;
1241 
1242 				if( sprite->flags&SPRITE_FLIPY ){
1243 					sprite->line_offset = 512-sprite->line_offset;
1244 					if( sprite->flags&SPRITE_FLIPX ){
1245 						gfx += 4 - sprite->line_offset*(sprite->tile_height+1);
1246 					}
1247 					else {
1248 						gfx -= sprite->line_offset*sprite->tile_height;
1249 					}
1250 				}
1251 				else {
1252 					if( sprite->flags&SPRITE_FLIPX ){
1253 						gfx += 4;
1254 					}
1255 					else {
1256 						gfx += sprite->line_offset;
1257 					}
1258 				}
1259 
1260 				sprite->tile_width = sprite->line_offset;
1261 				sprite->total_width = sprite->tile_width*(0x0800 - zoomx)/0x800;
1262 				sprite->pen_data = base_gfx + (gfx &0x3ffff) + (sys16_obj_bank[bank] << 17);
1263 
1264 			}
1265 
1266 			source+=8;
1267 			sprite++;
1268 		}
1269 		break;
1270 		case 6: // Space Harrier
1271 		while( sprite<finish ){
1272 			UINT16 ypos = source[0];
1273 			int top = ypos&0xff;
1274 			int bottom = ypos>>8;
1275 
1276 			if( bottom == 0xff ){ /* end of spritelist marker */
1277 				do {
1278 					sprite->flags = 0;
1279 					sprite++;
1280 				} while( sprite<finish );
1281 				break;
1282 			}
1283 			sprite->flags = 0;
1284 
1285 			if(bottom !=0 && bottom > top)
1286 			{
1287 				UINT16 bank=(source[1]>>12);
1288 				UINT16 pal=(source[2]>>8)&0x3f;
1289 				UINT16 tsource[4];
1290 				UINT16 width;
1291 				int gfx;
1292 				int zoomx,zoomy;
1293 
1294 #ifdef SYS16_DEBUG
1295 				if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
1296 						source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1297 #endif
1298 
1299 				tsource[2]=source[2]&0xff;
1300 				tsource[3]=source[3];
1301 
1302 				zoomx=(source[4] & 0x3f) *(1024/64);
1303 		        zoomy = (1024*zoomx)/(2048-zoomx);
1304 
1305 #ifndef TRANSPARENT_SHADOWS
1306 				if (pal==0x3f)	// shadow sprite
1307 					pal=(bank<<1);
1308 #endif
1309 
1310 				if((tsource[3] & 0x7f80) == 0x7f80)
1311 				{
1312 					bank=(bank-1)&0xf;
1313 					tsource[3]^=0x8000;
1314 				}
1315 
1316 				if (tsource[3]&0x8000)
1317 				{ // reverse
1318 					tsource[2] |= 0x0100;
1319 					tsource[3] &= 0x7fff;
1320 				}
1321 
1322 				gfx = tsource[3]*4;
1323 				width = tsource[2];
1324 
1325 				sprite->x = ((source[1] & 0x3ff) + sys16_sprxoffset);
1326 				if(sprite->x >= 0x200) sprite->x-=0x200;
1327 				sprite->y = top+1;
1328 				sprite->priority = 0;
1329 				sprite->pal_data = base_pal + (pal<<4);
1330 
1331 				sprite->total_height = bottom-top;
1332 //				sprite->tile_height = sprite->total_height*(0x400+zoomy)/0x400;
1333 				sprite->tile_height = ((sprite->total_height)<<4|0xf)*(0x400+zoomy)/0x4000;
1334 
1335 				sprite->line_offset = (width&0x7f)*4;
1336 
1337 				sprite->flags = SPRITE_VISIBLE;
1338 				if( width&0x100 ) sprite->flags |= SPRITE_FLIPX;
1339 				if( width&0x080 ) sprite->flags |= SPRITE_FLIPY;
1340 
1341 #ifdef TRANSPARENT_SHADOWS
1342 				if (sys16_sh_shadowpal == 0)		// space harrier
1343 				{
1344 					if (pal==sys16_sh_shadowpal)	// shadow sprite
1345 						sprite->flags|= SPRITE_SHADOW;
1346 					// I think this looks better, but I'm sure it's wrong.
1347 //					else if(READ_WORD(&paletteram[2048+pal*2+20]) == 0)
1348 //					{
1349 //						sprite->flags|= SPRITE_PARTIAL_SHADOW;
1350 //						sprite->shadow_pen=10;
1351 //					}
1352 				}
1353 				else								// enduro
1354 				{
1355 					sprite->flags|= SPRITE_PARTIAL_SHADOW;
1356 					sprite->shadow_pen=10;
1357 				}
1358 #endif
1359 				if( sprite->flags&SPRITE_FLIPY ){
1360 					sprite->line_offset = 512-sprite->line_offset;
1361 					if( sprite->flags&SPRITE_FLIPX ){
1362 						gfx += 4 - sprite->line_offset*(sprite->tile_height+1) /*+4*/;
1363 					}
1364 					else {
1365 						gfx -= sprite->line_offset*sprite->tile_height;
1366 					}
1367 				}
1368 				else {
1369 					if( sprite->flags&SPRITE_FLIPX ){
1370 						gfx += 4 /*+ 4*/;		// +2 ???
1371 					}
1372 					else {
1373 						gfx += sprite->line_offset;
1374 					}
1375 				}
1376 
1377 				sprite->line_offset<<=1;
1378 				sprite->tile_width = sprite->line_offset;
1379 				sprite->total_width = sprite->tile_width*(0x0800 - zoomx)/0x800;
1380 
1381 				sprite->pen_data = base_gfx + (((gfx &0x3ffff) + (sys16_obj_bank[bank] << 17)) << 1);
1382 
1383 
1384 #ifdef SPACEHARRIER_OFFSETS
1385 // doesn't seem to work properly and I'm not sure why it's needed.
1386 				if( !(width & 0x180) && (width & 0x7f))
1387 				{
1388 					unsigned addr=tsource[3];
1389 					unsigned offset_addr= (bank<<12) | (addr>>4);
1390 					char rebuild = 0;
1391 
1392 					if (spaceharrier_patternoffsets[offset_addr]!=0x7f)
1393 					{
1394 						offset = spaceharrier_patternoffsets[offset_addr];
1395 					}
1396 					else
1397 					{ // build pattern offset
1398 						unsigned width2=width&0x7f;
1399 						UINT8 *p,*p0;
1400 						unsigned height=sprite->tile_height;
1401 						unsigned width_bytes;
1402 						int len_pattern;
1403 						int i,j;
1404 
1405 						len_pattern = height*width2;
1406 						if (len_pattern >= 16)
1407 						{
1408 
1409 							len_pattern >>= 4;
1410 
1411 							// 32 bit sprite hardware ///////////////////////////////////////////
1412 							width_bytes = width2<<3;
1413 							p0 = (UINT8 *)sprite->pen_data;
1414 							/////////////////////////////////////////////////////////////////////
1415 
1416 							offset=0xe;
1417 							for (i=0, p=p0; i<height; i++, p+=width_bytes)
1418 							{
1419 								for (j=0; j<width_bytes && j<offset; j++)
1420 								{
1421 									if ((p[j]!=0xff && p[j]!=0x00) /*|| (p[j+1]!=0xff && p[j+1]!=0x00 )*/) break;
1422 								}
1423 								if (j<offset) offset = j;
1424 							}
1425 
1426 							//              printf("rebuild %02x:%04x = %d\n", bank, addr, offset);
1427 
1428 							p=&spaceharrier_patternoffsets[offset_addr];
1429 
1430 							offset/=2;
1431 							for (i=0; i<len_pattern; i++,p++) *p = offset;
1432 
1433 						    logerror("addr=%04x offset=%4x bank=%02x offset=%d height=%d zoomy=%04x len_pattern=%d width=%d offset_addr=%04x\n", addr, offset, bank, offset, height, zoomy,  len_pattern, width2, offset_addr);
1434 						}
1435 					}
1436 				}
1437 				sprite->pen_data += offset*2;
1438 #endif
1439 			}
1440 
1441 			source+=8;
1442 			sprite++;
1443 		}
1444 		break;
1445 		case 7: // Out Run
1446 		while( sprite<finish ){
1447 
1448 			if( source[0] == 0xffff ){ /* end of spritelist marker */
1449 				do {
1450 					sprite->flags = 0;
1451 					sprite++;
1452 				} while( sprite<finish );
1453 				break;
1454 			}
1455 			sprite->flags = 0;
1456 
1457 			if (!(source[0]&0x4000))
1458 			{
1459 				UINT16 bank=(source[0]>>8)&7;
1460 				UINT16 pal=(source[5])&0x7f;
1461 				UINT16 width;
1462 				int gfx;
1463 				int zoom;
1464 				int x;
1465 
1466 #ifdef SYS16_DEBUG
1467 				if(dump_spritedata) logerror("0:%4x  1:%4x  2:%4x  3:%4x  4:%4x  5:%4x  6:%4x  7:%4x\n",
1468 						source[0],source[1],source[2],source[3],source[4],source[5],source[6],source[7]);
1469 #endif
1470 
1471 				zoom=source[4]&0xfff;
1472 //				if (zoom==0x32c) zoom=0x3cf;	//???
1473 
1474 				if(zoom==0) zoom=1;
1475 
1476 				if (source[1]&0x8000) bank=(bank+1)&0x7;
1477 
1478 				gfx = (source[1]&0x7fff)*4;
1479 				width = source[2]>>9;
1480 
1481 				x = (source[2] & 0x1ff);
1482 
1483 				// patch misplaced sprite on map
1484 //				if(zoom == 0x3f0 && source[1]==0x142e && (source[0]&0xff)==0x19)
1485 //					x-=2;
1486 
1487 				sprite->y = source[0]&0xff;
1488 				sprite->priority = 0;
1489 				sprite->pal_data = base_pal + (pal<<4) + 1024;
1490 
1491 				sprite->total_height = (source[5]>>8)+1;
1492 				sprite->tile_height = ((sprite->total_height<<4)| 0xf)*(zoom)/0x2000;
1493 
1494 				sprite->line_offset = (width&0x7f)*4;
1495 
1496 				sprite->flags = SPRITE_VISIBLE;
1497 #ifdef TRANSPARENT_SHADOWS
1498 				if(pal==0)
1499 					sprite->flags|= SPRITE_SHADOW;
1500 				else if(source[3]&0x4000)
1501 //				if(pal==0 || source[3]&0x4000)
1502 				{
1503 					sprite->flags|= SPRITE_PARTIAL_SHADOW;
1504 					sprite->shadow_pen=10;
1505 				}
1506 #endif
1507 				if(!(source[4]&0x2000))
1508 				{
1509 					if(!(source[4]&0x4000))
1510 					{
1511 						// Should be drawn right to left, but this should be ok.
1512 						x-=(sprite->line_offset*2)*0x200/zoom;
1513 						gfx+=4-sprite->line_offset;
1514 					}
1515 					else
1516 					{
1517 						int ofs=(sprite->line_offset*2)*0x200/zoom;
1518 						x-=ofs;
1519 						sprite->flags |= SPRITE_FLIPX;
1520 
1521 						// x position compensation for rocks in round2R and round4RRR
1522 /*						if((source[0]&0xff00)==0x0300)
1523 						{
1524 							if (source[1]==0xc027)
1525 							{
1526 								if ((source[2]>>8)==0x59) x += ofs/2;
1527 								else if ((source[2]>>8)>0x59) x += ofs;
1528 							}
1529 							else if (source[1]==0xcf73)
1530 							{
1531 								if ((source[2]>>8)==0x2d) x += ofs/2;
1532 								else if ((source[2]>>8)>0x2d) x += ofs;
1533 							}
1534 							else if (source[1]==0xd3046)
1535 							{
1536 								if ((source[2]>>8)==0x19) x += ofs/2;
1537 								else if ((source[2]>>8)>0x19) x += ofs;
1538 							}
1539 							else if (source[1]==0xd44e)
1540 							{
1541 								if ((source[2]>>8)==0x0d) x += ofs/2;
1542 								else if ((source[2]>>8)>0x0d) x += ofs;
1543 							}
1544 							else if (source[1]==0xd490)
1545 							{
1546 								if ((source[2]>>8)==0x09) x += ofs/2;
1547 								else if ((source[2]>>8)>0x09) x += ofs;
1548 							}
1549 						}
1550 */
1551 					}
1552 				}
1553 				else
1554 				{
1555 					if(!(source[4]&0x4000))
1556 					{
1557 						gfx-=sprite->line_offset-4;
1558 						sprite->flags |= SPRITE_FLIPX;
1559 					}
1560 					else
1561 					{
1562 						if (source[4]&0x8000)
1563 						{ // patch for car shadow position
1564 							if (source[4]==0xe1a9 && source[1]==0x5817)
1565 								x-=2;
1566 						}
1567 					}
1568 				}
1569 
1570 				sprite->x = x + sys16_sprxoffset;
1571 
1572 				sprite->line_offset<<=1;
1573 				sprite->tile_width = sprite->line_offset;
1574 				sprite->total_width = sprite->tile_width*0x200/zoom;
1575 				sprite->pen_data = base_gfx + (((gfx &0x3ffff) + (sys16_obj_bank[bank] << 17)) << 1);
1576 			}
1577 			source+=8;
1578 			sprite++;
1579 		}
1580 		break;
1581 	}
1582 }
1583 
1584 /***************************************************************************/
1585 
mark_sprite_colors(void)1586 static void mark_sprite_colors( void ){
1587 	unsigned short *source = (unsigned short *)sys16_spriteram;
1588 	unsigned short *finish = source+NUM_SPRITES*8;
1589 	int pal_start=1024,pal_size=64;
1590 
1591 	char used[128];
1592 	memset( used, 0, 128 );
1593 
1594 	switch( sys16_spritesystem ){
1595 		case 1: /* standard sprite hardware */
1596 			do{
1597 				if( source[0]>>8 == 0xff || source[2] == sys16_spritelist_end) break;
1598 				used[source[4]&0x3f] = 1;
1599 				source+=8;
1600 			}while( source<finish );
1601 			break;
1602 		case 4: /* Aurail */
1603 			do{
1604 				if( (source[2]) == sys16_spritelist_end) break;
1605 				used[source[4]&0x3f] = 1;
1606 				source+=8;
1607 			}while( source<finish );
1608 			break;
1609 
1610 		case 3:	/* Fantzone */
1611 		case 5:	/* Hang-On */
1612 		case 2: /* Quartet2 / alex kidd + others */
1613 			do{
1614 				if( (source[0]>>8) == 0xff ) break;;
1615 				used[(source[4]>>8)&0x3f] = 1;
1616 				source+=8;
1617 			}while( source<finish );
1618 			break;
1619 		case 6:	/* Space Harrier */
1620 			do{
1621 				if( (source[0]>>8) == 0xff ) break;;
1622 				used[(source[2]>>8)&0x3f] = 1;
1623 				source+=8;
1624 			}while( source<finish );
1625 			break;
1626 		case 7:	/* Out Run */
1627 			do{
1628 				if( (source[0]) == 0xffff ) break;;
1629 				used[(source[5])&0x7f] = 1;
1630 				source+=8;
1631 			}while( source<finish );
1632 			pal_start=2048;
1633 			pal_size=128;
1634 			break;
1635 		case 0: /* passing shot */
1636 		case 8: /* passing shot 4p */
1637 			do{
1638 				if( source[1]!=0xffff ) used[(source[5]>>8)&0x3f] = 1;
1639 				source+=8;
1640 			}while( source<finish );
1641 			break;
1642 	}
1643 
1644 	{
1645 		unsigned char *pal = &palette_used_colors[pal_start];
1646 		int i;
1647 		for (i = 0; i < pal_size; i++){
1648 			if ( used[i] ){
1649 				pal[0] = PALETTE_COLOR_UNUSED;
1650 				memset( &pal[1],PALETTE_COLOR_USED,14 );
1651 				pal[15] = PALETTE_COLOR_UNUSED;
1652 			}
1653 			else {
1654 				memset( pal, PALETTE_COLOR_UNUSED, 16 );
1655 			}
1656 			pal += 16;
1657 		}
1658 	}
1659 #ifdef TRANSPARENT_SHADOWS
1660 	if (Machine->scrbitmap->depth == 8) /* 8 bit shadows */
1661 	{
1662 		memset(&palette_used_colors[Machine->drv->total_colors/2], PALETTE_COLOR_USED, sys16_MaxShadowColors);
1663 	}
1664 	else if(sys16_MaxShadowColors != 0) /* 16 bit shadows */
1665 	{
1666 		/* Mark the shadowed versions of the used pens */
1667 		memcpy(&palette_used_colors[Machine->drv->total_colors/2], &palette_used_colors[0], Machine->drv->total_colors/2);
1668 	}
1669 #endif
1670 }
1671 
1672 #ifdef TRANSPARENT_SHADOWS
build_shadow_table(void)1673 static void build_shadow_table(void)
1674 {
1675 	int i,size;
1676 	int color_start=Machine->drv->total_colors/2;
1677 	/* build the shading lookup table */
1678 	if (Machine->scrbitmap->depth == 8) /* 8 bit shadows */
1679 	{
1680 		if(sys16_MaxShadowColors == 0) return;
1681 		for (i = 0; i < 256; i++)
1682 		{
1683 			unsigned char r, g, b;
1684 			int y;
1685 			osd_get_pen(i, &r, &g, &b);
1686 			y = (r * 10 + g * 18 + b * 4) >> sys16_MaxShadowColors_Shift;
1687 			shade_table[i] = Machine->pens[color_start + y];
1688 		}
1689 		for(i=0;i<sys16_MaxShadowColors;i++)
1690 		{
1691 			shade_table[Machine->pens[color_start + i]]=Machine->pens[color_start + i];
1692 		}
1693 	}
1694 	else
1695 	{
1696 		if(sys16_MaxShadowColors != 0)
1697 		{
1698 			size=Machine->drv->total_colors/2;
1699 			for(i=0;i<size;i++)
1700 			{
1701 				shade_table[Machine->pens[i]]=Machine->pens[size + i];
1702 				shade_table[Machine->pens[size+i]]=Machine->pens[size + i];
1703 			}
1704 		}
1705 		else
1706 		{
1707 			size=Machine->drv->total_colors;
1708 			for(i=0;i<size;i++)
1709 			{
1710 				shade_table[Machine->pens[i]]=Machine->pens[i];
1711 			}
1712 		}
1713 	}
1714 }
1715 #else
1716 #define build_shadow_table()
1717 #endif
1718 
sys16_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1719 void sys16_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
1720 	if( sys16_update_proc ) sys16_update_proc();
1721 	update_page();
1722 
1723 	// from sys16 emu (Not sure if this is the best place for this?)
1724 	{
1725 		static int freeze_counter=0;
1726 		if (!sys16_refreshenable)
1727 		{
1728 			freeze_counter=4;
1729 			sys16_freezepalette=1;
1730 		}
1731 		if (freeze_counter)
1732 		{
1733 			if( sys16_clear_screen)
1734 				fillbitmap(bitmap,palette_transparent_color,&Machine->visible_area);
1735 			freeze_counter--;
1736 			return;
1737 		}
1738 		else if(sys16_freezepalette)
1739 		{
1740 			sys16_refresh_palette();
1741 			sys16_freezepalette=0;
1742 		}
1743 	}
1744 
1745 	if( sys16_refreshenable ){
1746 
1747 		if(sys18_splittab_bg_x)
1748 		{
1749 			if((sys16_bg_scrollx&0xff00)  != sys16_rowscroll_scroll)
1750 			{
1751 				tilemap_set_scroll_rows( background , 1 );
1752 				tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1753 			}
1754 			else
1755 			{
1756 				int offset, scroll,i;
1757 
1758 				tilemap_set_scroll_rows( background , 64 );
1759 				offset = 32+((sys16_bg_scrolly&0x1f8) >> 3);
1760 
1761 				for(i=0;i<29;i++)
1762 				{
1763 					scroll = READ_WORD(&sys18_splittab_bg_x[i*2]);
1764 					tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1765 				}
1766 			}
1767 		}
1768 		else
1769 		{
1770 			tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
1771 		}
1772 
1773 		if(sys18_splittab_bg_y)
1774 		{
1775 			if((sys16_bg_scrolly&0xff00)  != sys16_rowscroll_scroll)
1776 			{
1777 				tilemap_set_scroll_cols( background , 1 );
1778 				tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1779 			}
1780 			else
1781 			{
1782 				int offset, scroll,i;
1783 
1784 				tilemap_set_scroll_cols( background , 128 );
1785 				offset = 127-((sys16_bg_scrollx&0x3f8) >> 3)-40+2;
1786 
1787 				for(i=0;i<41;i++)
1788 				{
1789 					scroll = READ_WORD(&sys18_splittab_bg_y[(i+24)&0xfffe]);
1790 					tilemap_set_scrolly( background , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1791 				}
1792 			}
1793 		}
1794 		else
1795 		{
1796 			tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
1797 		}
1798 
1799 		if(sys18_splittab_fg_x)
1800 		{
1801 			if((sys16_fg_scrollx&0xff00)  != sys16_rowscroll_scroll)
1802 			{
1803 				tilemap_set_scroll_rows( foreground , 1 );
1804 				tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1805 			}
1806 			else
1807 			{
1808 				int offset, scroll,i;
1809 
1810 				tilemap_set_scroll_rows( foreground , 64 );
1811 				offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
1812 
1813 				for(i=0;i<29;i++)
1814 				{
1815 					scroll = READ_WORD(&sys18_splittab_fg_x[i*2]);
1816 
1817 
1818 					tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
1819 				}
1820 			}
1821 		}
1822 		else
1823 		{
1824 			tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
1825 		}
1826 
1827 		if(sys18_splittab_fg_y)
1828 		{
1829 			if((sys16_fg_scrolly&0xff00)  != sys16_rowscroll_scroll)
1830 			{
1831 				tilemap_set_scroll_cols( foreground , 1 );
1832 				tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1833 			}
1834 			else
1835 			{
1836 				int offset, scroll,i;
1837 
1838 				tilemap_set_scroll_cols( foreground , 128 );
1839 				offset = 127-((sys16_fg_scrollx&0x3f8) >> 3)-40+2;
1840 
1841 				for(i=0;i<41;i++)
1842 				{
1843 					scroll = READ_WORD(&sys18_splittab_fg_y[(i+24)&0xfffe]);
1844 					tilemap_set_scrolly( foreground , (i+offset)&0x7f, -256+(scroll&0x3ff) );
1845 				}
1846 			}
1847 		}
1848 		else
1849 		{
1850 			tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
1851 		}
1852 
1853 		if(sys16_quartet_title_kludge)
1854 		{
1855 			int top,bottom,left,right;
1856 			int top2,bottom2,left2,right2;
1857 			struct rectangle clip;
1858 
1859 			left = background->clip_left;
1860 			right = background->clip_right;
1861 			top = background->clip_top;
1862 			bottom = background->clip_bottom;
1863 
1864 			left2 = foreground->clip_left;
1865 			right2 = foreground->clip_right;
1866 			top2 = foreground->clip_top;
1867 			bottom2 = foreground->clip_bottom;
1868 
1869 			clip.min_x=0;
1870 			clip.min_y=0;
1871 			clip.max_x=1024;
1872 			clip.max_y=512;
1873 
1874 			tilemap_set_clip( background, &clip );
1875 			tilemap_set_clip( foreground, &clip );
1876 
1877 			tilemap_update(  ALL_TILEMAPS  );
1878 
1879 			background->clip_left = left;
1880 			background->clip_right = right;
1881 			background->clip_top = top;
1882 			background->clip_bottom = bottom;
1883 
1884 			foreground->clip_left = left2;
1885 			foreground->clip_right = right2;
1886 			foreground->clip_top = top2;
1887 			foreground->clip_bottom = bottom2;
1888 
1889 		}
1890 		else
1891 			tilemap_update(  ALL_TILEMAPS  );
1892 
1893 
1894 		get_sprite_info();
1895 
1896 		palette_init_used_colors();
1897 		mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
1898 		sprite_update();
1899 
1900 		if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
1901 		build_shadow_table();
1902 		tilemap_render(  ALL_TILEMAPS  );
1903 
1904 		if(!sys16_quartet_title_kludge)
1905 		{
1906 			tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY );
1907 			if(sys16_bg_priority_mode) tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY | 1 );
1908 		}
1909 		else
1910 			draw_quartet_title_screen( bitmap, 0 );
1911 
1912 		sprite_draw(sprite_list,3); // needed for Aurail
1913 		if(sys16_bg_priority_mode==2) tilemap_draw( bitmap, background, 1 );		// body slam (& wrestwar??)
1914 		sprite_draw(sprite_list,2);
1915 		if(sys16_bg_priority_mode==1) tilemap_draw( bitmap, background, 1 );		// alien syndrome / aurail
1916 
1917 		if(!sys16_quartet_title_kludge)
1918 		{
1919 			tilemap_draw( bitmap, foreground, 0 );
1920 			sprite_draw(sprite_list,1);
1921 			tilemap_draw( bitmap, foreground, 1 );
1922 		}
1923 		else
1924 		{
1925 			draw_quartet_title_screen( bitmap, 1 );
1926 			sprite_draw(sprite_list,1);
1927 		}
1928 
1929 		if(sys16_textlayer_lo_max!=0) tilemap_draw( bitmap, text_layer, 1 ); // needed for Body Slam
1930 		sprite_draw(sprite_list,0);
1931 		tilemap_draw( bitmap, text_layer, 0 );
1932 	}
1933 #ifdef SYS16_DEBUG
1934 	dump_tilemap();
1935 #endif
1936 }
1937 
sys18_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1938 void sys18_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
1939 	int i;
1940 	if( sys16_update_proc ) sys16_update_proc();
1941 	update_page();
1942 
1943 	// from sys16 emu (Not sure if this is the best place for this?)
1944 	{
1945 		static int freeze_counter=0;
1946 		if (!sys16_refreshenable)
1947 		{
1948 			freeze_counter=4;
1949 			sys16_freezepalette=1;
1950 		}
1951 		if (freeze_counter)
1952 		{
1953 //			if( sys16_clear_screen)
1954 //				fillbitmap(bitmap,palette_transparent_color,&Machine->visible_area);
1955 			freeze_counter--;
1956 			return;
1957 		}
1958 		else if(sys16_freezepalette)
1959 		{
1960 			sys16_refresh_palette();
1961 			sys16_freezepalette=0;
1962 		}
1963 	}
1964 
1965 	if( sys16_refreshenable ){
1966 
1967 		if(sys18_splittab_bg_x)
1968 		{
1969 			int offset,offset2, scroll,scroll2,orig_scroll;
1970 
1971 			offset = 32+((sys16_bg_scrolly&0x1f8) >> 3);
1972 			offset2 = 32+((sys16_bg2_scrolly&0x1f8) >> 3);
1973 
1974 			for(i=0;i<29;i++)
1975 			{
1976 				orig_scroll = scroll2 = scroll = READ_WORD(&sys18_splittab_bg_x[i*2]);
1977 
1978 				if((sys16_bg_scrollx &0xff00) != 0x8000)
1979 					scroll = sys16_bg_scrollx;
1980 
1981 				if((sys16_bg2_scrollx &0xff00) != 0x8000)
1982 					scroll2 = sys16_bg2_scrollx;
1983 
1984 				if(orig_scroll&0x8000)
1985 				{
1986 					tilemap_set_scrollx( background , (i+offset)&0x3f, TILE_LINE_DISABLED );
1987 					tilemap_set_scrollx( background2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_bgxoffset );
1988 				}
1989 				else
1990 				{
1991 					tilemap_set_scrollx( background , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_bgxoffset );
1992 					tilemap_set_scrollx( background2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
1993 				}
1994 			}
1995 		}
1996 		else
1997 		{
1998 			tilemap_set_scrollx( background , 0, -320-(sys16_bg_scrollx&0x3ff)+sys16_bgxoffset );
1999 			tilemap_set_scrollx( background2, 0, -320-(sys16_bg2_scrollx&0x3ff)+sys16_bgxoffset );
2000 		}
2001 
2002 		tilemap_set_scrolly( background , 0, -256+sys16_bg_scrolly );
2003 		tilemap_set_scrolly( background2, 0, -256+sys16_bg2_scrolly );
2004 
2005 		if(sys18_splittab_fg_x)
2006 		{
2007 			int offset,offset2, scroll,scroll2,orig_scroll;
2008 
2009 			offset = 32+((sys16_fg_scrolly&0x1f8) >> 3);
2010 			offset2 = 32+((sys16_fg2_scrolly&0x1f8) >> 3);
2011 
2012 			for(i=0;i<29;i++)
2013 			{
2014 				orig_scroll = scroll2 = scroll = READ_WORD(&sys18_splittab_fg_x[i*2]);
2015 
2016 				if((sys16_fg_scrollx &0xff00) != 0x8000)
2017 					scroll = sys16_fg_scrollx;
2018 
2019 				if((sys16_fg2_scrollx &0xff00) != 0x8000)
2020 					scroll2 = sys16_fg2_scrollx;
2021 
2022 				if(orig_scroll&0x8000)
2023 				{
2024 					tilemap_set_scrollx( foreground , (i+offset)&0x3f, TILE_LINE_DISABLED );
2025 					tilemap_set_scrollx( foreground2, (i+offset2)&0x3f, -320-(scroll2&0x3ff)+sys16_fgxoffset );
2026 				}
2027 				else
2028 				{
2029 					tilemap_set_scrollx( foreground , (i+offset)&0x3f, -320-(scroll&0x3ff)+sys16_fgxoffset );
2030 					tilemap_set_scrollx( foreground2 , (i+offset2)&0x3f, TILE_LINE_DISABLED );
2031 				}
2032 			}
2033 		}
2034 		else
2035 		{
2036 			tilemap_set_scrollx( foreground , 0, -320-(sys16_fg_scrollx&0x3ff)+sys16_fgxoffset );
2037 			tilemap_set_scrollx( foreground2, 0, -320-(sys16_fg2_scrollx&0x3ff)+sys16_fgxoffset );
2038 		}
2039 
2040 
2041 		tilemap_set_scrolly( foreground , 0, -256+sys16_fg_scrolly );
2042 		tilemap_set_scrolly( foreground2, 0, -256+sys16_fg2_scrolly );
2043 
2044 		tilemap_set_enable( background2, sys18_bg2_active );
2045 		tilemap_set_enable( foreground2, sys18_fg2_active );
2046 
2047 		tilemap_update(  ALL_TILEMAPS  );
2048 		get_sprite_info();
2049 
2050 		palette_init_used_colors();
2051 		mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
2052 		sprite_update();
2053 
2054 		if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
2055 		build_shadow_table();
2056 		tilemap_render(  ALL_TILEMAPS  );
2057 
2058 		if(sys18_bg2_active)
2059 			tilemap_draw( bitmap, background2, 0 );
2060 		else
2061 			fillbitmap(bitmap,palette_transparent_color,&Machine->visible_area);
2062 
2063 		tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY );
2064 		tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY | 1 );	//??
2065 		tilemap_draw( bitmap, background, TILEMAP_IGNORE_TRANSPARENCY | 2 );	//??
2066 
2067 		sprite_draw(sprite_list,3);
2068 		tilemap_draw( bitmap, background, 1 );
2069 		sprite_draw(sprite_list,2);
2070 		tilemap_draw( bitmap, background, 2 );
2071 
2072 		if(sys18_fg2_active) tilemap_draw( bitmap, foreground2, 0 );
2073 		tilemap_draw( bitmap, foreground, 0 );
2074 		sprite_draw(sprite_list,1);
2075 		if(sys18_fg2_active) tilemap_draw( bitmap, foreground2, 1 );
2076 		tilemap_draw( bitmap, foreground, 1 );
2077 
2078 		tilemap_draw( bitmap, text_layer, 1 );
2079 		sprite_draw(sprite_list,0);
2080 		tilemap_draw( bitmap, text_layer, 0 );
2081 	}
2082 }
2083 
2084 extern int gr_bitmap_width;
2085 
gr_colors(void)2086 static void gr_colors(void)
2087 {
2088 	int i;
2089 	UINT16 ver_data;
2090 	int colorflip;
2091 	UINT8 *data_ver=gr_ver;
2092 
2093 	for(i=0;i<224;i++)
2094 	{
2095 		ver_data=READ_WORD(data_ver);
2096 		palette_used_colors[(READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff) + gr_palette] = PALETTE_COLOR_USED;
2097 
2098 		if(!((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200))
2099 		{
2100 			ver_data=ver_data & 0x00ff;
2101 			colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2102 
2103 			palette_used_colors[ gr_colorflip[colorflip][0] + gr_palette_default ] = PALETTE_COLOR_USED;
2104 			palette_used_colors[ gr_colorflip[colorflip][1] + gr_palette_default ] = PALETTE_COLOR_USED;
2105 			palette_used_colors[ gr_colorflip[colorflip][2] + gr_palette_default ] = PALETTE_COLOR_USED;
2106 			palette_used_colors[ gr_colorflip[colorflip][3] + gr_palette_default ] = PALETTE_COLOR_USED;
2107 		}
2108 		data_ver+=2;
2109 	}
2110 }
2111 
render_gr(struct osd_bitmap * bitmap,int priority)2112 static void render_gr(struct osd_bitmap *bitmap,int priority)
2113 {
2114 	int i,j;
2115 	UINT8 *data = memory_region(REGION_GFX3);
2116 	UINT8 *source;
2117 	UINT8 *line;
2118 	UINT16 *line16;
2119 	UINT32 *line32;
2120 	UINT8 *data_ver=gr_ver;
2121 	UINT32 ver_data,hor_pos;
2122 	UINT16 colors[5];
2123 //	UINT8 colors[5];
2124 	UINT32 fastfill;
2125 	int colorflip;
2126 	int yflip=0,ypos;
2127 	int dx=1,xoff=0;
2128 
2129 	UINT16 *paldata1 = Machine->gfx[0]->colortable + gr_palette;
2130 	UINT16 *paldata2 = Machine->gfx[0]->colortable + gr_palette_default;
2131 
2132 	priority=priority << 10;
2133 
2134 	if (Machine->scrbitmap->depth == 16) /* 16 bit */
2135 	{
2136 		if( Machine->orientation & ORIENTATION_SWAP_XY )
2137 		{
2138 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2139 				dx=-1;
2140 				xoff=319;
2141 			}
2142 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2143 				yflip=1;
2144 			}
2145 
2146 			for(i=0;i<224;i++)
2147 			{
2148 				if(yflip) ypos=223-i;
2149 				else ypos=i;
2150 				ver_data=READ_WORD(data_ver);
2151 				if((ver_data & 0x400) == priority)
2152 				{
2153 					colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2154 
2155 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2156 					{
2157 						// fill line
2158 						for(j=0;j<320;j++)
2159 						{
2160 							line16=(UINT16 *)bitmap->line[j]+ypos;
2161 							*line16=colors[0];
2162 						}
2163 					}
2164 					else
2165 					{
2166 						// copy line
2167 						ver_data=ver_data & 0x00ff;
2168 						colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2169 
2170 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2171 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2172 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2173 						colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2174 
2175 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2176 						ver_data = ver_data << gr_bitmap_width;
2177 
2178 						if(hor_pos & 0xf000)
2179 						{
2180 							// reverse
2181 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2182 						}
2183 						else
2184 						{
2185 							// normal
2186 							hor_pos=(hor_pos+0x200) & 0x3ff;
2187 						}
2188 
2189 						source = data + hor_pos + ver_data + 18 + 8;
2190 
2191 						for(j=0;j<320;j++)
2192 						{
2193 							line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
2194 							*line16 = colors[*source++];
2195 						}
2196 					}
2197 				}
2198 				data_ver+=2;
2199 			}
2200 		}
2201 		else
2202 		{
2203 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2204 				dx=-1;
2205 				xoff=319;
2206 			}
2207 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2208 				yflip=1;
2209 			}
2210 
2211 			for(i=0;i<224;i++)
2212 			{
2213 				if(yflip) ypos=223-i;
2214 				else ypos=i;
2215 				ver_data=READ_WORD(data_ver);
2216 				if((ver_data & 0x400) == priority)
2217 				{
2218 					colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2219 
2220 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2221 					{
2222 						line16=(UINT16 *)bitmap->line[ypos];
2223 						for(j=0;j<320;j++)
2224 						{
2225 							*line16++=colors[0];
2226 						}
2227 					}
2228 					else
2229 					{
2230 						// copy line
2231 						line16 = (UINT16 *)bitmap->line[ypos]+xoff;
2232 						ver_data=ver_data & 0x00ff;
2233 						colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2234 
2235 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2236 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2237 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2238 						colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2239 
2240 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2241 						ver_data = ver_data << gr_bitmap_width;
2242 
2243 						if(hor_pos & 0xf000)
2244 						{
2245 							// reverse
2246 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2247 						}
2248 						else
2249 						{
2250 							// normal
2251 							hor_pos=(hor_pos+0x200) & 0x3ff;
2252 						}
2253 
2254 						source = data + hor_pos + ver_data + 18 + 8;
2255 
2256 						for(j=0;j<320;j++)
2257 						{
2258 							*line16 = colors[*source++];
2259 							line16+=dx;
2260 						}
2261 					}
2262 				}
2263 				data_ver+=2;
2264 			}
2265 		}
2266 	}
2267 	else /* 8 bit */
2268 	{
2269 		if( Machine->orientation & ORIENTATION_SWAP_XY )
2270 		{
2271 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2272 				dx=-1;
2273 				xoff=319;
2274 			}
2275 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2276 				yflip=1;
2277 			}
2278 
2279 			for(i=0;i<224;i++)
2280 			{
2281 				if(yflip) ypos=223-i;
2282 				else ypos=i;
2283 				ver_data=READ_WORD(data_ver);
2284 				if((ver_data & 0x400) == priority)
2285 				{
2286 					colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2287 
2288 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2289 					{
2290 						// fill line
2291 						for(j=0;j<320;j++)
2292 						{
2293 							bitmap->line[j][ypos]=colors[0];
2294 						}
2295 					}
2296 					else
2297 					{
2298 						// copy line
2299 						ver_data=ver_data & 0x00ff;
2300 						colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2301 
2302 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2303 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2304 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2305 						colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2306 
2307 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2308 						ver_data = ver_data << gr_bitmap_width;
2309 
2310 						if(hor_pos & 0xf000)
2311 						{
2312 							// reverse
2313 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2314 						}
2315 						else
2316 						{
2317 							// normal
2318 							hor_pos=(hor_pos+0x200) & 0x3ff;
2319 						}
2320 
2321 						source = data + hor_pos + ver_data + 18 + 8;
2322 
2323 						for(j=0;j<320;j++)
2324 						{
2325 							bitmap->line[xoff+j*dx][ypos] = colors[*source++];
2326 						}
2327 					}
2328 				}
2329 				data_ver+=2;
2330 			}
2331 		}
2332 		else
2333 		{
2334 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2335 				dx=-1;
2336 				xoff=319;
2337 			}
2338 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2339 				yflip=1;
2340 			}
2341 
2342 			for(i=0;i<224;i++)
2343 			{
2344 				if(yflip) ypos=223-i;
2345 				else ypos=i;
2346 				ver_data=READ_WORD(data_ver);
2347 				if((ver_data & 0x400) == priority)
2348 				{
2349 					colors[0] = paldata1[ READ_WORD(&gr_pal[(ver_data<<1)&0x1fe])&0xff ];
2350 
2351 					if((ver_data & 0x500) == 0x100 || (ver_data & 0x300) == 0x200)
2352 					{
2353 						// fill line
2354 						line32 = (UINT32 *)bitmap->line[ypos];
2355 						fastfill = colors[0] + (colors[0] << 8) + (colors[0] << 16) + (colors[0] << 24);
2356 						for(j=0;j<320;j+=4)
2357 						{
2358 							*line32++ = fastfill;
2359 						}
2360 					}
2361 					else
2362 					{
2363 						// copy line
2364 						line = bitmap->line[ypos]+xoff;
2365 						ver_data=ver_data & 0x00ff;
2366 						colorflip = (READ_WORD(&gr_flip[ver_data<<1]) >> 3) & 1;
2367 
2368 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2369 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2370 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2371 						colors[4] = paldata2[ gr_colorflip[colorflip][3] ];
2372 
2373 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2374 						ver_data = ver_data << gr_bitmap_width;
2375 
2376 						if(hor_pos & 0xf000)
2377 						{
2378 							// reverse
2379 							hor_pos=((0-((hor_pos&0x7ff)^7))+0x9f8)&0x3ff;
2380 						}
2381 						else
2382 						{
2383 							// normal
2384 							hor_pos=(hor_pos+0x200) & 0x3ff;
2385 						}
2386 
2387 						source = data + hor_pos + ver_data + 18 + 8;
2388 
2389 						for(j=0;j<320;j++)
2390 						{
2391 							*line = colors[*source++];
2392 							line+=dx;
2393 						}
2394 					}
2395 				}
2396 				data_ver+=2;
2397 			}
2398 		}
2399 	}
2400 }
2401 
2402 
2403 
2404 
2405 // Refresh for hang-on, etc.
sys16_ho_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)2406 void sys16_ho_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
2407 	if( sys16_update_proc ) sys16_update_proc();
2408 	update_page();
2409 
2410 	// from sys16 emu (Not sure if this is the best place for this?)
2411 	{
2412 		static int freeze_counter=0;
2413 		if (!sys16_refreshenable)
2414 		{
2415 			freeze_counter=4;
2416 			sys16_freezepalette=1;
2417 		}
2418 		if (freeze_counter)
2419 		{
2420 			freeze_counter--;
2421 			return;
2422 		}
2423 		else if(sys16_freezepalette)
2424 		{
2425 			sys16_refresh_palette();
2426 			sys16_freezepalette=0;
2427 		}
2428 	}
2429 
2430 	if( sys16_refreshenable ){
2431 
2432 		tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
2433 		tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
2434 
2435 		tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
2436 		tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
2437 
2438 		tilemap_update(  ALL_TILEMAPS  );
2439 		get_sprite_info();
2440 
2441 		palette_init_used_colors();
2442 		mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
2443 		sprite_update();
2444 		gr_colors();
2445 
2446 		if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
2447 		build_shadow_table();
2448 		tilemap_render(  ALL_TILEMAPS  );
2449 
2450 		render_gr(bitmap,0);
2451 
2452 		tilemap_draw( bitmap, background, 0 );
2453 		tilemap_draw( bitmap, foreground, 0 );
2454 
2455 		render_gr(bitmap,1);
2456 
2457 		sprite_draw(sprite_list,0);
2458 		tilemap_draw( bitmap, text_layer, 0 );
2459 
2460 	}
2461 
2462 #ifdef SYS16_DEBUG
2463 	dump_tilemap();
2464 #endif
2465 }
2466 
2467 
grv2_colors(void)2468 static void grv2_colors(void)
2469 {
2470 	int i;
2471 	UINT16 ver_data;
2472 	int colorflip,colorflip_info;
2473 	UINT8 *data_ver=gr_ver;
2474 
2475 	for(i=0;i<224;i++)
2476 	{
2477 		ver_data=READ_WORD(data_ver);
2478 
2479 		if(!(ver_data & 0x800))
2480 		{
2481 			ver_data=ver_data & 0x01ff;
2482 			colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2483 
2484 			palette_used_colors[ (((colorflip_info >> 8) & 0x1f) + 0x20) + gr_palette_default] = PALETTE_COLOR_USED;
2485 
2486 			colorflip = (colorflip_info >> 3) & 1;
2487 
2488 			palette_used_colors[ gr_colorflip[colorflip][0] + gr_palette_default ] = PALETTE_COLOR_USED;
2489 			palette_used_colors[ gr_colorflip[colorflip][1] + gr_palette_default ] = PALETTE_COLOR_USED;
2490 			palette_used_colors[ gr_colorflip[colorflip][2] + gr_palette_default ] = PALETTE_COLOR_USED;
2491 		}
2492 		else
2493 		{
2494 			palette_used_colors[(ver_data&0x3f) + gr_palette] = PALETTE_COLOR_USED;
2495 		}
2496 		data_ver+=2;
2497 	}
2498 }
2499 
render_grv2(struct osd_bitmap * bitmap,int priority)2500 static void render_grv2(struct osd_bitmap *bitmap,int priority)
2501 {
2502 	int i,j;
2503 	UINT8 *data = memory_region(REGION_GFX3);
2504 	UINT8 *source,*source2,*temp;
2505 	UINT8 *line;
2506 	UINT16 *line16;
2507 	UINT32 *line32;
2508 	UINT8 *data_ver=gr_ver;
2509 	UINT32 ver_data,hor_pos,hor_pos2;
2510 	UINT16 colors[5];
2511 	UINT32 fastfill;
2512 	int colorflip,colorflip_info;
2513 	int yflip=0,ypos;
2514 	int dx=1,xoff=0;
2515 
2516 	int second_road = READ_WORD(gr_second_road);
2517 
2518 	UINT16 *paldata1 = Machine->gfx[0]->colortable + gr_palette;
2519 	UINT16 *paldata2 = Machine->gfx[0]->colortable + gr_palette_default;
2520 
2521 	priority=priority << 11;
2522 
2523 	if (Machine->scrbitmap->depth == 16) /* 16 bit */
2524 	{
2525 		if( Machine->orientation & ORIENTATION_SWAP_XY )
2526 		{
2527 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2528 				dx=-1;
2529 				xoff=319;
2530 			}
2531 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2532 				yflip=1;
2533 			}
2534 
2535 			for(i=0;i<224;i++)
2536 			{
2537 				if(yflip) ypos=223-i;
2538 				else ypos=i;
2539 				ver_data=READ_WORD(data_ver);
2540 				if((ver_data & 0x800) == priority)
2541 				{
2542 
2543 					if(ver_data & 0x800)
2544 					{
2545 						colors[0] = paldata1[ ver_data&0x3f ];
2546 						// fill line
2547 						for(j=0;j<320;j++)
2548 						{
2549 							line16=(UINT16 *)bitmap->line[j]+ypos;
2550 							*line16=colors[0];
2551 						}
2552 					}
2553 					else
2554 					{
2555 						// copy line
2556 						ver_data=ver_data & 0x01ff;		//???
2557 						colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2558 
2559 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
2560 
2561 						colorflip = (colorflip_info >> 3) & 1;
2562 
2563 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2564 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2565 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2566 
2567 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2568 						hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2569 
2570 						ver_data=ver_data>>1;
2571 						if( ver_data != 0 )
2572 						{
2573 							ver_data = (ver_data-1) << gr_bitmap_width;
2574 						}
2575 
2576 						source  = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2577 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2578 
2579 						switch(second_road)
2580 						{
2581 							case 0:	source2=source;	break;
2582 							case 2:	temp=source;source=source2;source2=temp; break;
2583 							case 3:	source=source2;	break;
2584 						}
2585 
2586 						source2++;
2587 
2588 						for(j=0;j<320;j++)
2589 						{
2590 							line16=(UINT16 *)bitmap->line[xoff+j*dx]+ypos;
2591 							if(*source2 <= *source)
2592 								*line16 = colors[*source];
2593 							else
2594 								*line16 = colors[*source2];
2595 							source++;
2596 							source2++;
2597 						}
2598 					}
2599 				}
2600 				data_ver+=2;
2601 			}
2602 		}
2603 		else
2604 		{
2605 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2606 				dx=-1;
2607 				xoff=319;
2608 			}
2609 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2610 				yflip=1;
2611 			}
2612 
2613 			for(i=0;i<224;i++)
2614 			{
2615 				if(yflip) ypos=223-i;
2616 				else ypos=i;
2617 				ver_data=READ_WORD(data_ver);
2618 				if((ver_data & 0x800) == priority)
2619 				{
2620 
2621 					if(ver_data & 0x800)
2622 					{
2623 						colors[0] = paldata1[ ver_data&0x3f ];
2624 						// fill line
2625 						line16 = (UINT16 *)bitmap->line[ypos];
2626 						for(j=0;j<320;j++)
2627 						{
2628 							*line16++ = colors[0];
2629 						}
2630 					}
2631 					else
2632 					{
2633 						// copy line
2634 						line16 = (UINT16 *)bitmap->line[ypos]+xoff;
2635 						ver_data=ver_data & 0x01ff;		//???
2636 						colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2637 
2638 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
2639 
2640 						colorflip = (colorflip_info >> 3) & 1;
2641 
2642 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2643 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2644 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2645 
2646 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2647 						hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2648 
2649 						ver_data=ver_data>>1;
2650 						if( ver_data != 0 )
2651 						{
2652 							ver_data = (ver_data-1) << gr_bitmap_width;
2653 						}
2654 
2655 						source  = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2656 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2657 
2658 						switch(second_road)
2659 						{
2660 							case 0:	source2=source;	break;
2661 							case 2:	temp=source;source=source2;source2=temp; break;
2662 							case 3:	source=source2;	break;
2663 						}
2664 
2665 						source2++;
2666 
2667 						for(j=0;j<320;j++)
2668 						{
2669 							if(*source2 <= *source)
2670 								*line16 = colors[*source];
2671 							else
2672 								*line16 = colors[*source2];
2673 							source++;
2674 							source2++;
2675 							line16+=dx;
2676 						}
2677 					}
2678 				}
2679 				data_ver+=2;
2680 			}
2681 		}
2682 	}
2683 	else
2684 	{
2685 		if( Machine->orientation & ORIENTATION_SWAP_XY )
2686 		{
2687 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2688 				dx=-1;
2689 				xoff=319;
2690 			}
2691 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2692 				yflip=1;
2693 			}
2694 
2695 			for(i=0;i<224;i++)
2696 			{
2697 				if(yflip) ypos=223-i;
2698 				else ypos=i;
2699 				ver_data=READ_WORD(data_ver);
2700 				if((ver_data & 0x800) == priority)
2701 				{
2702 
2703 					if(ver_data & 0x800)
2704 					{
2705 						colors[0] = paldata1[ ver_data&0x3f ];
2706 						// fill line
2707 						for(j=0;j<320;j++)
2708 						{
2709 							bitmap->line[j][ypos]=colors[0];
2710 						}
2711 					}
2712 					else
2713 					{
2714 						// copy line
2715 						ver_data=ver_data & 0x01ff;		//???
2716 						colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2717 
2718 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
2719 
2720 						colorflip = (colorflip_info >> 3) & 1;
2721 
2722 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2723 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2724 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2725 
2726 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2727 						hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2728 
2729 						ver_data=ver_data>>1;
2730 						if( ver_data != 0 )
2731 						{
2732 							ver_data = (ver_data-1) << gr_bitmap_width;
2733 						}
2734 
2735 						source  = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2736 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2737 
2738 						switch(second_road)
2739 						{
2740 							case 0:	source2=source;	break;
2741 							case 2:	temp=source;source=source2;source2=temp; break;
2742 							case 3:	source=source2;	break;
2743 						}
2744 
2745 						source2++;
2746 
2747 						for(j=0;j<320;j++)
2748 						{
2749 							if(*source2 <= *source)
2750 								bitmap->line[xoff+j*dx][ypos] = colors[*source];
2751 							else
2752 								bitmap->line[xoff+j*dx][ypos] = colors[*source2];
2753 							source++;
2754 							source2++;
2755 						}
2756 					}
2757 				}
2758 				data_ver+=2;
2759 			}
2760 		}
2761 		else
2762 		{
2763 			if( Machine->orientation & ORIENTATION_FLIP_X ){
2764 				dx=-1;
2765 				xoff=319;
2766 			}
2767 			if( Machine->orientation & ORIENTATION_FLIP_Y ){
2768 				yflip=1;
2769 			}
2770 
2771 			for(i=0;i<224;i++)
2772 			{
2773 				if(yflip) ypos=223-i;
2774 				else ypos=i;
2775 				ver_data=READ_WORD(data_ver);
2776 				if((ver_data & 0x800) == priority)
2777 				{
2778 
2779 					if(ver_data & 0x800)
2780 					{
2781 						colors[0] = paldata1[ ver_data&0x3f ];
2782 						// fill line
2783 						line32 = (UINT32 *)bitmap->line[ypos];
2784 						fastfill = colors[0] + (colors[0] << 8) + (colors[0] << 16) + (colors[0] << 24);
2785 						for(j=0;j<320;j+=4)
2786 						{
2787 							*line32++ = fastfill;
2788 						}
2789 					}
2790 					else
2791 					{
2792 						// copy line
2793 						line = bitmap->line[ypos]+xoff;
2794 						ver_data=ver_data & 0x01ff;		//???
2795 						colorflip_info = READ_WORD(&gr_flip[ver_data<<1]);
2796 
2797 						colors[0] = paldata2[ ((colorflip_info >> 8) & 0x1f) + 0x20 ];		//??
2798 
2799 						colorflip = (colorflip_info >> 3) & 1;
2800 
2801 						colors[1] = paldata2[ gr_colorflip[colorflip][0] ];
2802 						colors[2] = paldata2[ gr_colorflip[colorflip][1] ];
2803 						colors[3] = paldata2[ gr_colorflip[colorflip][2] ];
2804 
2805 						hor_pos = (READ_WORD(&gr_hor[ver_data<<1]) );
2806 						hor_pos2= (READ_WORD(&gr_hor[(ver_data<<1)+0x400]) );
2807 
2808 						ver_data=ver_data>>1;
2809 						if( ver_data != 0 )
2810 						{
2811 							ver_data = (ver_data-1) << gr_bitmap_width;
2812 						}
2813 
2814 						source  = data + ((hor_pos +0x200) & 0x7ff) + 768 + ver_data + 8;
2815 						source2 = data + ((hor_pos2+0x200) & 0x7ff) + 768 + ver_data + 8;
2816 
2817 						switch(second_road)
2818 						{
2819 							case 0:	source2=source;	break;
2820 							case 2:	temp=source;source=source2;source2=temp; break;
2821 							case 3:	source=source2;	break;
2822 						}
2823 
2824 						source2++;
2825 
2826 						for(j=0;j<320;j++)
2827 						{
2828 							if(*source2 <= *source)
2829 								*line = colors[*source];
2830 							else
2831 								*line = colors[*source2];
2832 							source++;
2833 							source2++;
2834 							line+=dx;
2835 						}
2836 					}
2837 				}
2838 				data_ver+=2;
2839 			}
2840 		}
2841 	}
2842 }
2843 
2844 // Refresh for Outrun
sys16_or_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)2845 void sys16_or_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
2846 	if( sys16_update_proc ) sys16_update_proc();
2847 	update_page();
2848 
2849 	// from sys16 emu (Not sure if this is the best place for this?)
2850 	{
2851 		static int freeze_counter=0;
2852 		if (!sys16_refreshenable)
2853 		{
2854 			freeze_counter=4;
2855 			sys16_freezepalette=1;
2856 		}
2857 		if (freeze_counter)
2858 		{
2859 			freeze_counter--;
2860 			return;
2861 		}
2862 		else if(sys16_freezepalette)
2863 		{
2864 			sys16_refresh_palette();
2865 			sys16_freezepalette=0;
2866 		}
2867 	}
2868 
2869 	if( sys16_refreshenable ){
2870 
2871 		tilemap_set_scrollx( background, 0, -320-sys16_bg_scrollx+sys16_bgxoffset );
2872 		tilemap_set_scrollx( foreground, 0, -320-sys16_fg_scrollx+sys16_fgxoffset );
2873 
2874 		tilemap_set_scrolly( background, 0, -256+sys16_bg_scrolly );
2875 		tilemap_set_scrolly( foreground, 0, -256+sys16_fg_scrolly );
2876 
2877 		tilemap_update(  ALL_TILEMAPS  );
2878 		get_sprite_info();
2879 
2880 		palette_init_used_colors();
2881 		mark_sprite_colors(); // custom; normally this would be handled by the sprite manager
2882 		sprite_update();
2883 		grv2_colors();
2884 
2885 		if( palette_recalc() ) tilemap_mark_all_pixels_dirty( ALL_TILEMAPS );
2886 		build_shadow_table();
2887 		tilemap_render(  ALL_TILEMAPS  );
2888 
2889 		render_grv2(bitmap,1);
2890 
2891 		tilemap_draw( bitmap, background, 0 );
2892 		tilemap_draw( bitmap, foreground, 0 );
2893 
2894 		render_grv2(bitmap,0);
2895 
2896 		sprite_draw(sprite_list,0);
2897 
2898 		tilemap_draw( bitmap, text_layer, 0 );
2899 
2900 	}
2901 
2902 #ifdef SYS16_DEBUG
2903 	dump_tilemap();
2904 #endif
2905 }
2906 
2907 
2908 // hideous kludge to display quartet title screen correctly
draw_quartet_title_screen(struct osd_bitmap * bitmap,int playfield)2909 static void draw_quartet_title_screen( struct osd_bitmap *bitmap,int playfield )
2910 {
2911 	unsigned char *xscroll,*yscroll;
2912 	int r,c,scroll;
2913 	struct tilemap *tilemap;
2914 	struct rectangle clip;
2915 
2916 	int top,bottom,left,right;
2917 
2918 
2919 	if(playfield==0) // background
2920 	{
2921 		xscroll=&sys16_textram[0x0fc0];
2922 		yscroll=&sys16_textram[0x0f58];
2923 		tilemap=background;
2924 	}
2925 	else
2926 	{
2927 		xscroll=&sys16_textram[0x0f80];
2928 		yscroll=&sys16_textram[0x0f30];
2929 		tilemap=foreground;
2930 	}
2931 
2932 	left = tilemap->clip_left;
2933 	right = tilemap->clip_right;
2934 	top = tilemap->clip_top;
2935 	bottom = tilemap->clip_bottom;
2936 
2937 	for(r=0;r<14;r++)
2938 	{
2939 		clip.min_y=r*16;
2940 		clip.max_y=r*16+15;
2941 		for(c=0;c<10;c++)
2942 		{
2943 			clip.min_x=c*32;
2944 			clip.max_x=c*32+31;
2945 			tilemap_set_clip( tilemap, &clip );
2946 			scroll = READ_WORD(&xscroll[r*4])&0x3ff;
2947 			tilemap_set_scrollx( tilemap, 0, (-320-scroll+sys16_bgxoffset)&0x3ff );
2948 			scroll = READ_WORD(&yscroll[c*4])&0x1ff;
2949 			tilemap_set_scrolly( tilemap, 0, (-256+scroll)&0x1ff );
2950 			tilemap_draw( bitmap, tilemap, 0 );
2951 		}
2952 	}
2953 /*
2954 	for(r=0;r<28;r++)
2955 	{
2956 		clip.min_y=r*8;
2957 		clip.max_y=r*8+7;
2958 		for(c=0;c<20;c++)
2959 		{
2960 			clip.min_x=c*16;
2961 			clip.max_x=c*16+15;
2962 			tilemap_set_clip( tilemap, &clip );
2963 			scroll = READ_WORD(&xscroll[r*2])&0x3ff;
2964 			tilemap_set_scrollx( tilemap, 0, (-320-scroll+sys16_bgxoffset)&0x3ff );
2965 			scroll = READ_WORD(&yscroll[c*2])&0x1ff;
2966 			tilemap_set_scrolly( tilemap, 0, (-256+scroll)&0x1ff );
2967 			tilemap_draw( bitmap, tilemap, 0 );
2968 		}
2969 	}
2970 */
2971 	tilemap->clip_left = left;
2972 	tilemap->clip_right = right;
2973 	tilemap->clip_top = top;
2974 	tilemap->clip_bottom = bottom;
2975 }
2976 
2977 
2978 #ifdef SYS16_DEBUG
dump_tilemap(void)2979 void dump_tilemap(void)
2980 {
2981 	const UINT16 *source;
2982 	int row,col,r,c;
2983 	int data;
2984 
2985 	if(!keyboard_pressed_memory(KEYCODE_Y)) return;
2986 
2987 	logerror("Back %2x %2x %2x %2x\n",sys16_bg_page[0],sys16_bg_page[1],sys16_bg_page[2],sys16_bg_page[3]);
2988 	for(r=0;r<64;r++)
2989 	{
2990 		for(c=0;c<128;c++)
2991 		{
2992 			source = (const UINT16 *)sys16_tileram;
2993 			row=r;col=c;
2994 			if( row<32 ){
2995 				if( col<64 ){
2996 					source += 64*32*sys16_bg_page[0];
2997 				}
2998 				else {
2999 					source += 64*32*sys16_bg_page[1];
3000 				}
3001 			}
3002 			else {
3003 				if( col<64 ){
3004 					source += 64*32*sys16_bg_page[2];
3005 				}
3006 				else {
3007 					source += 64*32*sys16_bg_page[3];
3008 				}
3009 			}
3010 			row = row%32;
3011 			col = col%64;
3012 
3013 			data = source[row*64+col];
3014 			logerror("%4x ",data);
3015 		}
3016 		logerror("\n");
3017 	}
3018 
3019 	logerror("Front %2x %2x %2x %2x\n",sys16_fg_page[0],sys16_fg_page[1],sys16_fg_page[2],sys16_fg_page[3]);
3020 	for(r=0;r<64;r++)
3021 	{
3022 		for(c=0;c<128;c++)
3023 		{
3024 			source = (const UINT16 *)sys16_tileram;
3025 			row=r;col=c;
3026 			if( row<32 ){
3027 				if( col<64 ){
3028 					source += 64*32*sys16_fg_page[0];
3029 				}
3030 				else {
3031 					source += 64*32*sys16_fg_page[1];
3032 				}
3033 			}
3034 			else {
3035 				if( col<64 ){
3036 					source += 64*32*sys16_fg_page[2];
3037 				}
3038 				else {
3039 					source += 64*32*sys16_fg_page[3];
3040 				}
3041 			}
3042 			row = row%32;
3043 			col = col%64;
3044 
3045 			data = source[row*64+col];
3046 			logerror("%4x ",data);
3047 		}
3048 		logerror("\n");
3049 	}
3050 
3051 	logerror("Text\n");
3052 	for(r=0;r<28;r++)
3053 	{
3054 		for(c=0;c<64;c++)
3055 		{
3056 			source = (const UINT16 *)sys16_textram;
3057 			data = source[r*64+c];
3058 			logerror("%4x ",data);
3059 		}
3060 		logerror("\n");
3061 	}
3062 }
3063 #endif
3064 
3065