1 /***************************************************************************
2 						WEC Le Mans 24  &   Hot Chase
3 
4 					      (C)   1986 & 1988 Konami
5 
6 					driver by	Luca Elia (eliavit@unina.it)
7 
8 
9 Note:	if MAME_DEBUG is defined, pressing Z with:
10 
11 		Q		shows background layer
12 		W		shows foreground layer
13 		E		shows text layer
14 		R		shows road layer
15 		A		shows sprites
16 		B		toggles the custom gfx browser on/off
17 
18 		Keys can be used togheter!
19 
20 							[WEC Le Mans 24]
21 
22 [ 2 Scrolling Layers ]
23 	[Background]
24 	[Foreground]
25 		Tile Size:				8x8
26 
27 		Tile Format:
28 										Colour?
29 				---- ba98 7654 3210		Code
30 
31 		Layer Size:				4 Pages -	Page0 Page1
32 											Page2 Page3
33 								each page is 512 x 256 (64 x 32 tiles)
34 
35 		Page Selection Reg.:	108efe	[Bg]
36 								108efc	[Fg]
37 								4 pages to choose from
38 
39 		Scrolling Columns:		1
40 		Scrolling Columns Reg.:	108f26	[Bg]
41 								108f24	[Fg]
42 
43 		Scrolling Rows:			224 / 8 (Screen-wise scrolling)
44 		Scrolling Rows Reg.:	108f82/4/6..	[Bg]
45 								108f80/2/4..	[Fg]
46 
47 [ 1 Text Layer ]
48 		Tile Size:				8x8
49 
50 		Tile Format:
51 				fedc ba9- ---- ----		Colour: ba9 fedc
52 				---- ba98 7654 3210		Code
53 
54 		Layer Size:				1 Page: 512 x 256 (64 x 32 tiles)
55 
56 		Scrolling:				-
57 
58 [ 1 Road Layer ]
59 
60 [ 256 Sprites ]
61 	Zooming Sprites, see below
62 
63 
64 
65 								[Hot Chase]
66 
67 [ 3 Zooming Layers ]
68 	[Background]
69 	[Foreground (text)]
70 	[Road]
71 
72 [ 256 Sprites ]
73 	Zooming Sprites, see below
74 
75 
76 **************************************************************************/
77 
78 #include "vidhrdw/generic.h"
79 #include "vidhrdw/konamiic.h"
80 
81 /* Variables only used here: */
82 
83 static struct tilemap *bg_tilemap, *fg_tilemap, *txt_tilemap;
84 static struct sprite_list *sprite_list;
85 
86 
87 /* Variables that driver has acces to: */
88 
89 unsigned char *wecleman_pageram, *wecleman_txtram, *wecleman_roadram, *wecleman_unknown;
90 size_t wecleman_roadram_size;
91 int wecleman_bgpage[4], wecleman_fgpage[4], *wecleman_gfx_bank;
92 
93 
94 
95 /* Variables defined in driver: */
96 
97 extern int wecleman_selected_ip, wecleman_irqctrl;
98 
99 
100 
101 /***************************************************************************
102 							Common routines
103 ***************************************************************************/
104 
105 /* Useful defines - for debug */
106 #define KEY(_k_,_action_) \
107 	if (keyboard_pressed(KEYCODE_##_k_))	{ while (keyboard_pressed(KEYCODE_##_k_)); _action_ }
108 #define KEY_SHIFT(_k_,_action_) \
109 	if ( (keyboard_pressed(KEYCODE_LSHIFT)||keyboard_pressed(KEYCODE_RSHIFT)) && \
110 	      keyboard_pressed(KEYCODE_##_k_) )	{ while (keyboard_pressed(KEYCODE_##_k_)); _action_ }
111 #define KEY_FAST(_k_,_action_) \
112 	if (keyboard_pressed(KEYCODE_##_k_))	{ _action_ }
113 
114 
115 /* WEC Le Mans 24 and Hot Chase share the same sprite hardware */
116 #define NUM_SPRITES 256
117 
118 
WRITE_HANDLER(paletteram_SBGRBBBBGGGGRRRR_word_w)119 WRITE_HANDLER( paletteram_SBGRBBBBGGGGRRRR_word_w )
120 {
121 	/*	byte 0    	byte 1		*/
122 	/*	SBGR BBBB 	GGGG RRRR	*/
123 	/*	S000 4321 	4321 4321	*/
124 	/*  S = Shade				*/
125 
126 	int oldword = READ_WORD (&paletteram[offset]);
127 	int newword = COMBINE_WORD (oldword, data);
128 
129 	int r = ((newword << 1) & 0x1E ) | ((newword >> 12) & 0x01);
130 	int g = ((newword >> 3) & 0x1E ) | ((newword >> 13) & 0x01);
131 	int b = ((newword >> 7) & 0x1E ) | ((newword >> 14) & 0x01);
132 
133 	/* This effect can be turned on/off actually ... */
134 	if (newword & 0x8000)	{ r /= 2;	 g /= 2;	 b /= 2; }
135 
136 	palette_change_color( offset/2,	 (r * 0xFF) / 0x1F,
137 									 (g * 0xFF) / 0x1F,
138 									 (b * 0xFF) / 0x1F	 );
139 
140 	WRITE_WORD (&paletteram[offset], newword);
141 }
142 
143 
144 
145 
146 /***************************************************************************
147 
148 					  Callbacks for the TileMap code
149 
150 ***************************************************************************/
151 
152 
153 
154 /***************************************************************************
155 								WEC Le Mans 24
156 ***************************************************************************/
157 
158 #define PAGE_NX  		(0x40)
159 #define PAGE_NY  		(0x20)
160 #define PAGE_GFX		(0)
161 #define TILEMAP_DIMY	(PAGE_NY * 2 * 8)
162 
163 /*------------------------------------------------------------------------
164 				[ Frontmost (text) layer + video registers ]
165 ------------------------------------------------------------------------*/
166 
167 
168 
wecleman_get_txt_tile_info(int tile_index)169 void wecleman_get_txt_tile_info( int tile_index )
170 {
171 	int code 		=	READ_WORD(&wecleman_txtram[tile_index*2]);
172 	SET_TILE_INFO(PAGE_GFX, code & 0xfff, (code >> 12) + ((code >> 5) & 0x70) );
173 }
174 
175 
176 
177 
READ_HANDLER(wecleman_txtram_r)178 READ_HANDLER( wecleman_txtram_r )
179 {
180 	return READ_WORD(&wecleman_txtram[offset]);
181 }
182 
183 
184 
185 
WRITE_HANDLER(wecleman_txtram_w)186 WRITE_HANDLER( wecleman_txtram_w )
187 {
188 	int old_data = READ_WORD(&wecleman_txtram[offset]);
189 	int new_data = COMBINE_WORD(old_data,data);
190 
191 	if ( old_data != new_data )
192 	{
193 		WRITE_WORD(&wecleman_txtram[offset], new_data);
194 
195 		if (offset >= 0xE00 )	/* Video registers */
196 		{
197 			/* pages selector for the background */
198 			if (offset == 0xEFE)
199 			{
200 				wecleman_bgpage[0] = (new_data >> 0x4) & 3;
201 				wecleman_bgpage[1] = (new_data >> 0x0) & 3;
202 				wecleman_bgpage[2] = (new_data >> 0xc) & 3;
203 				wecleman_bgpage[3] = (new_data >> 0x8) & 3;
204 				tilemap_mark_all_tiles_dirty(bg_tilemap);
205 			}
206 
207 			/* pages selector for the foreground */
208 			if (offset == 0xEFC)
209 			{
210 				wecleman_fgpage[0] = (new_data >> 0x4) & 3;
211 				wecleman_fgpage[1] = (new_data >> 0x0) & 3;
212 				wecleman_fgpage[2] = (new_data >> 0xc) & 3;
213 				wecleman_fgpage[3] = (new_data >> 0x8) & 3;
214 				tilemap_mark_all_tiles_dirty(fg_tilemap);
215 			}
216 
217 			/* Parallactic horizontal scroll registers follow */
218 
219 		}
220 		else
221 			tilemap_mark_tile_dirty(txt_tilemap, offset / 2);
222 	}
223 }
224 
225 
226 
227 
228 /*------------------------------------------------------------------------
229 							[ Background ]
230 ------------------------------------------------------------------------*/
231 
232 
233 
wecleman_get_bg_tile_info(int tile_index)234 void wecleman_get_bg_tile_info( int tile_index )
235 {
236 	int page = wecleman_bgpage[(tile_index%(PAGE_NX*2))/PAGE_NX+2*(tile_index/(PAGE_NX*PAGE_NY*2))];
237 	int code = READ_WORD(&wecleman_pageram[( (tile_index%PAGE_NX) + PAGE_NX*((tile_index/(PAGE_NX*2))%PAGE_NY) + page*PAGE_NX*PAGE_NY ) * 2]);
238 	SET_TILE_INFO(PAGE_GFX, code & 0xfff, (code >> 12) + ((code >> 5) & 0x70) );
239 }
240 
241 
242 
243 /*------------------------------------------------------------------------
244 							[ Foreground ]
245 ------------------------------------------------------------------------*/
246 
247 
248 
wecleman_get_fg_tile_info(int tile_index)249 void wecleman_get_fg_tile_info( int tile_index )
250 {
251 	int page = wecleman_fgpage[(tile_index%(PAGE_NX*2))/PAGE_NX+2*(tile_index/(PAGE_NX*PAGE_NY*2))];
252 	int code = READ_WORD(&wecleman_pageram[( (tile_index%PAGE_NX) + PAGE_NX*((tile_index/(PAGE_NX*2))%PAGE_NY) + page*PAGE_NX*PAGE_NY ) * 2]);
253 	SET_TILE_INFO(PAGE_GFX, code & 0xfff, (code >> 12) + ((code >> 5) & 0x70) );
254 }
255 
256 
257 
258 
259 
260 
261 /*------------------------------------------------------------------------
262 					[ Pages (Background & Foreground) ]
263 ------------------------------------------------------------------------*/
264 
265 
266 
267 /* Pages that compose both the background and the foreground */
READ_HANDLER(wecleman_pageram_r)268 READ_HANDLER( wecleman_pageram_r )
269 {
270 	return READ_WORD(&wecleman_pageram[offset]);
271 }
272 
273 
WRITE_HANDLER(wecleman_pageram_w)274 WRITE_HANDLER( wecleman_pageram_w )
275 {
276 	int old_data = READ_WORD(&wecleman_pageram[offset]);
277 	int new_data = COMBINE_WORD(old_data,data);
278 
279 	if ( old_data != new_data )
280 	{
281 		int page,col,row;
282 
283 		WRITE_WORD(&wecleman_pageram[offset], new_data);
284 
285 		page	=	( offset / 2 ) / (PAGE_NX * PAGE_NY);
286 
287 		col		=	( offset / 2 )           % PAGE_NX;
288 		row		=	( offset / 2 / PAGE_NX ) % PAGE_NY;
289 
290 		/* background */
291 		if (wecleman_bgpage[0] == page)	tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*0)*PAGE_NX*2 );
292 		if (wecleman_bgpage[1] == page)	tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*0)*PAGE_NX*2 );
293 		if (wecleman_bgpage[2] == page)	tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*1)*PAGE_NX*2 );
294 		if (wecleman_bgpage[3] == page)	tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*1)*PAGE_NX*2 );
295 
296 		/* foreground */
297 		if (wecleman_fgpage[0] == page)	tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*0)*PAGE_NX*2 );
298 		if (wecleman_fgpage[1] == page)	tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*0)*PAGE_NX*2 );
299 		if (wecleman_fgpage[2] == page)	tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*1)*PAGE_NX*2 );
300 		if (wecleman_fgpage[3] == page)	tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*1)*PAGE_NX*2 );
301 	}
302 }
303 
304 
305 
306 /*------------------------------------------------------------------------
307 						[ Video Hardware Start ]
308 ------------------------------------------------------------------------*/
309 
wecleman_vh_start(void)310 int wecleman_vh_start(void)
311 {
312 
313 /*
314  Sprite banking - each bank is 0x20000 bytes (we support 0x40 bank codes)
315  This game has ROMs for 16 banks
316 */
317 
318 	static int bank[0x40] = {	0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,
319 								8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,
320 								0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,
321 								8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15	};
322 
323 	wecleman_gfx_bank = bank;
324 
325 
326 	bg_tilemap = tilemap_create(wecleman_get_bg_tile_info,
327 								tilemap_scan_rows,
328 								TILEMAP_TRANSPARENT,	/* We draw part of the road below */
329 								8,8,
330 								PAGE_NX * 2, PAGE_NY * 2 );
331 
332 	fg_tilemap = tilemap_create(wecleman_get_fg_tile_info,
333 								tilemap_scan_rows,
334 								TILEMAP_TRANSPARENT,
335 								8,8,
336 								PAGE_NX * 2, PAGE_NY * 2);
337 
338 	txt_tilemap = tilemap_create(wecleman_get_txt_tile_info,
339 								 tilemap_scan_rows,
340 								 TILEMAP_TRANSPARENT,
341 								 8,8,
342 								 PAGE_NX * 1, PAGE_NY * 1);
343 
344 
345 	sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
346 
347 
348 	if (bg_tilemap && fg_tilemap && txt_tilemap && sprite_list)
349 	{
350 		tilemap_set_scroll_rows(bg_tilemap, TILEMAP_DIMY);	/* Screen-wise scrolling */
351 		tilemap_set_scroll_cols(bg_tilemap, 1);
352 		bg_tilemap->transparent_pen = 0;
353 
354 		tilemap_set_scroll_rows(fg_tilemap, TILEMAP_DIMY);	/* Screen-wise scrolling */
355 		tilemap_set_scroll_cols(fg_tilemap, 1);
356 		fg_tilemap->transparent_pen = 0;
357 
358 		tilemap_set_scroll_rows(txt_tilemap, 1);
359 		tilemap_set_scroll_cols(txt_tilemap, 1);
360 		txt_tilemap->transparent_pen = 0;
361 		tilemap_set_scrollx(txt_tilemap,0, 512-320-16 );	/* fixed scrolling? */
362 		tilemap_set_scrolly(txt_tilemap,0, 0 );
363 
364 		sprite_list->max_priority = 0;
365 		sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
366 
367 		return 0;
368 	}
369 	else return 1;
370 }
371 
372 
373 
374 
375 
376 
377 
378 
379 
380 
381 
382 
383 
384 /***************************************************************************
385 								Hot Chase
386 ***************************************************************************/
387 
388 
389 /***************************************************************************
390 
391   Callbacks for the K051316
392 
393 ***************************************************************************/
394 
395 #define ZOOMROM0_MEM_REGION REGION_GFX2
396 #define ZOOMROM1_MEM_REGION REGION_GFX3
397 
zoom_callback_0(int * code,int * color)398 static void zoom_callback_0(int *code,int *color)
399 {
400 	*code |= (*color & 0x03) << 8;
401 	*color = (*color & 0xfc) >> 2;
402 }
403 
zoom_callback_1(int * code,int * color)404 static void zoom_callback_1(int *code,int *color)
405 {
406 	*code |= (*color & 0x01) << 8;
407 	*color = ((*color & 0x3f) << 1) | ((*code & 0x80) >> 7);
408 }
409 
410 
411 
412 /*------------------------------------------------------------------------
413 						[ Video Hardware Start ]
414 ------------------------------------------------------------------------*/
415 
416 /* for the zoomed layers we support: road and fg */
417 static struct osd_bitmap *temp_bitmap, *temp_bitmap2;
418 
hotchase_vh_start(void)419 int hotchase_vh_start(void)
420 {
421 /*
422  Sprite banking - each bank is 0x20000 bytes (we support 0x40 bank codes)
423  This game has ROMs for 0x30 banks
424 */
425 	static int bank[0x40] = {	0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
426 								16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
427 								32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
428 								0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15	};
429 	wecleman_gfx_bank = bank;
430 
431 
432 	if (K051316_vh_start_0(ZOOMROM0_MEM_REGION,4,zoom_callback_0))
433 		return 1;
434 
435 	if (K051316_vh_start_1(ZOOMROM1_MEM_REGION,4,zoom_callback_1))
436 	{
437 		K051316_vh_stop_0();
438 		return 1;
439 	}
440 
441 	temp_bitmap  = bitmap_alloc(512,512);
442 	temp_bitmap2 = bitmap_alloc(512,256);
443 
444 	sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
445 
446 	if (temp_bitmap && temp_bitmap2 && sprite_list)
447 	{
448 		K051316_wraparound_enable(0,1);
449 //		K051316_wraparound_enable(1,1);
450 		K051316_set_offset(0,-96,-16);
451 		K051316_set_offset(1,-96,-16);
452 
453 		sprite_list->max_priority = 0;
454 		sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
455 
456 		return 0;
457 	}
458 	else return 1;
459 }
460 
hotchase_vh_stop(void)461 void hotchase_vh_stop(void)
462 {
463 	if (temp_bitmap)	bitmap_free(temp_bitmap);
464 	if (temp_bitmap2)	bitmap_free(temp_bitmap2);
465 	K051316_vh_stop_0();
466 	K051316_vh_stop_1();
467 }
468 
469 
470 
471 
472 
473 
474 
475 /***************************************************************************
476 
477 								Road Drawing
478 
479 ***************************************************************************/
480 
481 
482 /***************************************************************************
483 								WEC Le Mans 24
484 ***************************************************************************/
485 
486 #define ROAD_COLOR(x)	(0x00 + ((x)&0xff))
487 
wecleman_mark_road_colors(void)488 void wecleman_mark_road_colors(void)
489 {
490 	int y					=	Machine->visible_area.min_y;
491 	int ymax				=	Machine->visible_area.max_y;
492 	int color_codes_start	=	Machine->drv->gfxdecodeinfo[1].color_codes_start;
493 
494 	for (; y <= ymax; y++)
495 	{
496 		int color = ROAD_COLOR( READ_WORD(&wecleman_roadram[0x400 + y * 2]) );
497 		memset(&palette_used_colors[color_codes_start + color*8],PALETTE_COLOR_USED,8);	// no transparency
498 	}
499 }
500 
501 
502 /*
503 
504 	This layer is composed of horizontal lines gfx elements
505 	There are 256 lines in ROM, each is 512 pixels wide
506 
507 	Offset:		Elements:	Data:
508 
509 	0000-01ff	100 Words	Code
510 
511 		fedcba98--------	Priority?
512 		--------76543210	Line Number
513 
514 	0200-03ff	100 Words	Horizontal Scroll
515 	0400-05ff	100 Words	Color
516 	0600-07ff	100 Words	??
517 
518 	We draw each line using a bunch of 64x1 tiles
519 
520 */
521 
wecleman_draw_road(struct osd_bitmap * bitmap,int priority)522 void wecleman_draw_road(struct osd_bitmap *bitmap,int priority)
523 {
524 	struct rectangle rect = Machine->visible_area;
525 	int curr_code, sx,sy;
526 
527 /* Referred to what's in the ROMs */
528 #define XSIZE 512
529 #define YSIZE 256
530 
531 	/* Let's draw from the top to the bottom of the visible screen */
532 	for (sy = rect.min_y ; sy <= rect.max_y ; sy ++)
533 	{
534 		int code		=	READ_WORD(&wecleman_roadram[(YSIZE*0+sy)*2]);
535 		int scrollx 	=	READ_WORD(&wecleman_roadram[(YSIZE*1+sy)*2]) + 24;	// fudge factor :)
536 		int attr		=	READ_WORD(&wecleman_roadram[(YSIZE*2+sy)*2]);
537 
538 		/* high byte is a priority information? */
539 		if ((code>>8) != priority)	continue;
540 
541 		/* line number converted to tile number (each tile is 64x1) */
542 		code		=	(code % YSIZE) * (XSIZE/64);
543 
544 		/* Scroll value applies to a "picture" twice as wide as the gfx
545 		   in ROM: left half is color 15, right half is the gfx */
546 		scrollx %= XSIZE * 2;
547 
548 		if (scrollx >= XSIZE)	{curr_code = code+(scrollx-XSIZE)/64;	code = 0;}
549 		else					{curr_code = 0   + scrollx/64;}
550 
551 		for (sx = -(scrollx % 64) ; sx <= rect.max_x ; sx += 64)
552 		{
553 			drawgfx(bitmap,Machine->gfx[1],
554 				curr_code++,
555 				ROAD_COLOR(attr),
556 				0,0,
557 				sx,sy,
558 				&rect,
559 				TRANSPARENCY_NONE,0);
560 
561 			if ( (curr_code % (XSIZE/64)) == 0)	curr_code = code;
562 		}
563 	}
564 
565 #undef XSIZE
566 #undef YSIZE
567 }
568 
569 
570 
571 
572 
573 
574 /***************************************************************************
575 							Hot Chase
576 ***************************************************************************/
577 
578 
579 
580 
hotchase_mark_road_colors(void)581 void hotchase_mark_road_colors(void)
582 {
583 	int y					=	Machine->visible_area.min_y;
584 	int ymax				=	Machine->visible_area.max_y;
585 	int color_codes_start	=	Machine->drv->gfxdecodeinfo[0].color_codes_start;
586 
587 	for (; y <= ymax; y++)
588 	{
589 		int color = (READ_WORD(&wecleman_roadram[y * 4]) >> 4 ) & 0xf;
590 		palette_used_colors[color_codes_start + color*16 + 0] = PALETTE_COLOR_TRANSPARENT;	// pen 0 transparent
591 		memset(&palette_used_colors[color_codes_start + color*16 + 1],PALETTE_COLOR_USED,16-1);
592 	}
593 
594 }
595 
596 
597 
598 
599 /*
600 	This layer is composed of horizontal lines gfx elements
601 	There are 512 lines in ROM, each is 512 pixels wide
602 
603 	Offset:		Elements:	Data:
604 
605 	0000-03ff	00-FF		Code (4 bytes)
606 
607 	Code:
608 
609 		00.w
610 				fedc ba98 ---- ----		Unused?
611 				---- ---- 7654 ----		color
612 				---- ---- ---- 3210		scroll x
613 
614 		02.w	fedc ba-- ---- ----		scroll x
615 				---- --9- ---- ----		?
616 				---- ---8 7654 3210		code
617 
618 	We draw each line using a bunch of 64x1 tiles
619 
620 */
621 
hotchase_draw_road(struct osd_bitmap * bitmap,int priority,struct rectangle * clip)622 void hotchase_draw_road(struct osd_bitmap *bitmap,int priority, struct rectangle *clip)
623 {
624 struct rectangle rect = *clip;
625 int sy;
626 
627 
628 /* Referred to what's in the ROMs */
629 #define XSIZE 512
630 #define YSIZE 512
631 
632 
633 	/* Let's draw from the top to the bottom of the visible screen */
634 	for (sy = rect.min_y ; sy <= rect.max_y ; sy ++)
635 	{
636 		int curr_code,sx;
637 		int code	=	  READ_WORD(&wecleman_roadram[0x0000+sy*4+2]) +
638 						( READ_WORD(&wecleman_roadram[0x0000+sy*4+0]) << 16 );
639 		int color	=	(( code & 0x00f00000 ) >> 20 ) + 0x70;
640 		int scrollx =	 ( code & 0x000ffc00 ) >> 10;
641 		code		=	 ( code & 0x000003ff ) >>  0;
642 
643 		/* convert line number in gfx element number: */
644 		/* code is the tile code of the start of this line */
645 		code	= ( code % YSIZE ) * ( XSIZE / 64 );
646 
647 //		if (scrollx < 0) scrollx += XSIZE * 2 ;
648 		scrollx %= XSIZE * 2;
649 
650 		if (scrollx < XSIZE)	{curr_code = code + scrollx/64;	code = 0;}
651 		else					{curr_code = 0    + scrollx/64;}
652 
653 		for (sx = -(scrollx % 64) ; sx <= rect.max_x ; sx += 64)
654 		{
655 			drawgfx(bitmap,Machine->gfx[0],
656 				curr_code++,
657 				color,
658 				0,0,
659 				sx,sy,
660 				&rect,
661 				TRANSPARENCY_PEN,0);
662 
663 			/* Maybe after the end of a line of gfx we shouldn't
664 			   wrap around, but pad with a value */
665 			if ((curr_code % (XSIZE/64)) == 0)	curr_code = code;
666 		}
667 	}
668 
669 #undef XSIZE
670 #undef YSIZE
671 }
672 
673 
674 
675 
676 /***************************************************************************
677 
678 							Sprites Drawing
679 
680 ***************************************************************************/
681 
682 /* Hot Chase: shadow of trees is pen 0x0a - Should it be black like it is now */
683 
mark_sprites_colors(void)684 static void mark_sprites_colors(void)
685 {
686 	int offs;
687 
688 	for (offs = 0; offs < (NUM_SPRITES * 0x10); offs += 0x10)
689 	{
690 		int dest_y, dest_h, color;
691 
692 		dest_y = READ_WORD(&spriteram[offs + 0x00]);
693 		if (dest_y == 0xFFFF)	break;
694 
695 		dest_h = (dest_y >> 8) - (dest_y & 0x00FF);
696 		if (dest_h < 1) continue;
697 
698 		color = (READ_WORD(&spriteram[offs + 0x04]) >> 8) & 0x7f;
699 		memset(&palette_used_colors[color*16 + 1], PALETTE_COLOR_USED, 16 - 2 );
700 
701 		// pens 0 & 15 are transparent
702 		palette_used_colors[color*16 + 0] = palette_used_colors[color*16 + 15] = PALETTE_COLOR_TRANSPARENT;
703 	}
704 }
705 
706 
707 
708 
709 /*
710 
711 	Sprites: 256 entries, 16 bytes each, first ten bytes used (and tested)
712 
713 	Offset	Bits					Meaning
714 
715 	00.w	fedc ba98 ---- ----		Screen Y start
716 			---- ---- 7654 3210		Screen Y stop
717 
718 	02.w	fedc ba-- ---- ----		High bits of sprite "address"
719 			---- --9- ---- ----		Flip Y ?
720 			---- ---8 7654 3210		Screen X start
721 
722 	04.w	fedc ba98 ---- ----		Color
723 			---- ---- 7654 3210		Source Width / 8
724 
725 	06.w	f--- ---- ---- ----		Flip X
726 			-edc ba98 7654 3210		Low bits of sprite "address"
727 
728 	08.w	--dc ba98 ---- ----		Y? Shrink Factor
729 			---- ---- --54 3210		X? Shrink Factor
730 
731 Sprite "address" is the index of the pixel the hardware has to start
732 fetching data from, divided by 8. Only on screen height and source data
733 width are provided, along with two shrinking factors. So on screen width
734 and source height are calculated by the hardware using the shrink factors.
735 The factors are in the range 0 (no shrinking) - 3F (half size).
736 
737 */
738 
get_sprite_info(void)739 static void get_sprite_info(void)
740 {
741 	const unsigned short *base_pal	= Machine->remapped_colortable;
742 	const unsigned char  *base_gfx	= memory_region(REGION_GFX1);
743 
744 	const int gfx_max = memory_region_length(REGION_GFX1);
745 
746 	unsigned char *source		=	spriteram;
747 	struct sprite *sprite		=	sprite_list->sprite;
748 	const struct sprite *finish	=	sprite + NUM_SPRITES;
749 
750 	int visibility = SPRITE_VISIBLE;
751 
752 
753 #define SHRINK_FACTOR(x) \
754 	(1.0 - ( ( (x) & 0x3F ) / 63.0) * 0.5)
755 
756 	for (; sprite < finish; sprite++,source+=0x10)
757 	{
758 		int code, gfx, zoom;
759 
760 		sprite->priority = 0;
761 
762 		sprite->y	= READ_WORD(&source[0x00]);
763 		if (sprite->y == 0xFFFF)	{ visibility = 0; }
764 
765 		sprite->flags = visibility;
766 		if (visibility==0) continue;
767 
768 		sprite->total_height = (sprite->y >> 8) - (sprite->y & 0xFF);
769 		if (sprite->total_height < 1) {sprite->flags = 0;	continue;}
770 
771 		sprite->x	 		=	READ_WORD(&source[0x02]);
772 		sprite->tile_width	=	READ_WORD(&source[0x04]);
773 		code				=	READ_WORD(&source[0x06]);
774 		zoom				=	READ_WORD(&source[0x08]);
775 
776 		gfx	= (wecleman_gfx_bank[(sprite->x >> 10) & 0x3f] << 15) +  (code & 0x7fff);
777 		sprite->pal_data = base_pal + ( (sprite->tile_width >> 4) & 0x7f0 );	// 16 colors = 16 shorts
778 
779 		if (code & 0x8000)
780 		{	sprite->flags |= SPRITE_FLIPX;	gfx += 1 - (sprite->tile_width & 0xFF);	};
781 
782 		if (sprite->x & 0x0200)		/* ?flip y? */
783 		{	sprite->flags |= SPRITE_FLIPY; }
784 
785 		gfx *= 8;
786 
787 		sprite->pen_data = base_gfx + gfx;
788 
789 		sprite->tile_width	= (sprite->tile_width & 0xFF) * 8;
790 		if (sprite->tile_width < 1) {sprite->flags = 0;	continue;}
791 
792 		sprite->tile_height = sprite->total_height * ( 1.0 / SHRINK_FACTOR(zoom>>8) );
793 		sprite->x   = (sprite->x & 0x1ff) - 0xc0;
794 		sprite->y   = (sprite->y & 0xff);
795 		sprite->total_width = sprite->tile_width * SHRINK_FACTOR(zoom & 0xFF);
796 
797 		sprite->line_offset = sprite->tile_width;
798 
799 		/* Bound checking */
800 		if ((gfx + sprite->tile_width * sprite->tile_height - 1) >= gfx_max )
801 			{sprite->flags = 0;	continue;}
802 	}
803 }
804 
805 
806 
807 /***************************************************************************
808 
809 							Browse the graphics
810 
811 ***************************************************************************/
812 
813 /*
814 	Browse the sprites
815 
816 	Use:
817 	* LEFT, RIGHT, UP, DOWN and PGUP/PGDN to move around
818 	* SHIFT + PGUP/PGDN to move around faster
819 	* SHIFT + LEFT/RIGHT to change the width of the graphics
820 	* SHIFT + RCTRL to go back to the start of the gfx
821 
822 */
browser(struct osd_bitmap * bitmap)823 void browser(struct osd_bitmap *bitmap)
824 {
825 	const unsigned short *base_pal	=	Machine->gfx[0]->colortable + 0;
826 	const unsigned char  *base_gfx	=	memory_region(REGION_GFX1);
827 
828 	const int gfx_max				=	memory_region_length(REGION_GFX1);
829 
830 	struct sprite *sprite			=	sprite_list->sprite;
831 	const struct sprite *finish		=	sprite + NUM_SPRITES;
832 
833 	static int w = 32, gfx;
834 	char buf[80];
835 
836 	for ( ; sprite < finish ; sprite++)	sprite->flags = 0;
837 
838 	sprite = sprite_list->sprite;
839 
840 	sprite->flags = SPRITE_VISIBLE;
841 	sprite->x = 0;
842 	sprite->y = 0;
843 	sprite->tile_height = sprite->total_height = 224;
844 	sprite->pal_data = base_pal;
845 
846 	KEY_FAST(LEFT,	gfx-=8;)
847 	KEY_FAST(RIGHT,	gfx+=8;)
848 	KEY_FAST(UP,	gfx-=w;)
849 	KEY_FAST(DOWN,	gfx+=w;)
850 
851 	KEY_SHIFT(PGDN,	gfx -= 0x100000;)
852 	KEY_SHIFT(PGUP,	gfx += 0x100000;)
853 
854 	KEY(PGDN,gfx+=w*sprite->tile_height;)
855 	KEY(PGUP,gfx-=w*sprite->tile_height;)
856 
857 	KEY_SHIFT(RCONTROL,	gfx = 0;)
858 
859 	gfx %= gfx_max;
860 	if (gfx < 0)	gfx += gfx_max;
861 
862 	KEY_SHIFT(LEFT,		w-=8;)
863 	KEY_SHIFT(RIGHT,	w+=8;)
864 	w &= 0x1ff;
865 
866 	sprite->pen_data = base_gfx + gfx;
867 	sprite->tile_width = sprite->total_width = sprite->line_offset = w;
868 
869 	/* Bound checking */
870 	if ((gfx + sprite->tile_width * sprite->tile_height - 1) >= gfx_max )
871 		sprite->flags = 0;
872 
873 	sprite_draw( sprite_list, 0 );
874 
875 	sprintf(buf,"W:%02X GFX/8: %X",w,gfx / 8);
876 	usrintf_showmessage(buf);
877 }
878 
879 
880 
881 
882 
883 
884 
885 
886 
887 
888 
889 
890 /***************************************************************************
891 
892 							Screen Drawing
893 
894 ***************************************************************************/
895 
896 #define WECLEMAN_TVKILL \
897 	if ((wecleman_irqctrl & 0x40)==0) layers_ctrl = 0;	// TV-KILL
898 
899 #define WECLEMAN_LAMPS \
900 	osd_led_w(0,(wecleman_selected_ip >> 2)& 1); 		// Start lamp
901 
902 /***************************************************************************
903 							WEC Le Mans 24
904 ***************************************************************************/
905 
wecleman_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)906 void wecleman_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
907 {
908 	int i, layers_ctrl = 0xFFFF;
909 
910 
911 	WECLEMAN_LAMPS
912 
913 	WECLEMAN_TVKILL
914 
915 {
916 /* Set the scroll values for the scrolling layers */
917 
918 	/* y values */
919 	int bg_y = READ_WORD(&wecleman_txtram[0x0F24+2]) & (TILEMAP_DIMY - 1);
920 	int fg_y = READ_WORD(&wecleman_txtram[0x0F24+0]) & (TILEMAP_DIMY - 1);
921 
922 	tilemap_set_scrolly(bg_tilemap, 0, bg_y );
923 	tilemap_set_scrolly(fg_tilemap, 0, fg_y );
924 
925 	/* x values */
926 	for ( i = 0 ; i < 28; i++ )
927 	{
928 		int j;
929 		int bg_x = 0xB0 + READ_WORD(&wecleman_txtram[0xF80+i*4+2]);
930 		int fg_x = 0xB0 + READ_WORD(&wecleman_txtram[0xF80+i*4+0]);
931 
932 		for ( j = 0 ; j < 8; j++ )
933 		{
934 			tilemap_set_scrollx(bg_tilemap, (bg_y + i*8 + j) & (TILEMAP_DIMY - 1), bg_x );
935 			tilemap_set_scrollx(fg_tilemap, (fg_y + i*8 + j) & (TILEMAP_DIMY - 1), fg_x );
936 		}
937 	}
938 }
939 
940 
941 	tilemap_update(ALL_TILEMAPS);
942 	get_sprite_info();
943 
944 	palette_init_used_colors();
945 
946 	wecleman_mark_road_colors();
947 	mark_sprites_colors();
948 
949 	sprite_update();
950 
951 	if (palette_recalc())	tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
952 
953 
954 	osd_clearbitmap(Machine->scrbitmap);
955 
956 	/* Draw the road (lines which have "priority" 0x02) */
957 	if (layers_ctrl & 16)	wecleman_draw_road(bitmap,0x02);
958 
959 	/* Draw the background */
960 	if (layers_ctrl & 1)
961 	{
962 		tilemap_render(bg_tilemap);
963 		tilemap_draw(bitmap, bg_tilemap,  0);
964 	}
965 
966 	/* Draw the foreground */
967 	if (layers_ctrl & 2)
968 	{
969 		tilemap_render(fg_tilemap);
970 		tilemap_draw(bitmap, fg_tilemap,  0);
971 	}
972 
973 	/* Draw the road (lines which have "priority" 0x04) */
974 	if (layers_ctrl & 16)	wecleman_draw_road(bitmap,0x04);
975 
976 	/* Draw the sprites */
977 	if (layers_ctrl & 8)	sprite_draw(sprite_list,0);
978 
979 	/* Draw the text layer */
980 	if (layers_ctrl & 4)
981 	{
982 		tilemap_render(txt_tilemap);
983 		tilemap_draw(bitmap, txt_tilemap,  0);
984 	}
985 
986 }
987 
988 
989 
990 
991 
992 
993 
994 
995 /***************************************************************************
996 								Hot Chase
997 ***************************************************************************/
998 
hotchase_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)999 void hotchase_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1000 {
1001 	int i;
1002 	int layers_ctrl = 0xFFFF;
1003 
1004 	WECLEMAN_LAMPS
1005 
1006 	WECLEMAN_TVKILL
1007 
1008 	K051316_tilemap_update_0();
1009 	K051316_tilemap_update_1();
1010 	get_sprite_info();
1011 
1012 	palette_init_used_colors();
1013 
1014 	hotchase_mark_road_colors();
1015 	mark_sprites_colors();
1016 	sprite_update();
1017 
1018 	/* set transparent pens for the K051316 */
1019 	for (i = 0;i < 128;i++)
1020 	{
1021 		palette_used_colors[i * 16] = PALETTE_COLOR_TRANSPARENT;
1022 		palette_used_colors[i * 16] = PALETTE_COLOR_TRANSPARENT;
1023 		palette_used_colors[i * 16] = PALETTE_COLOR_TRANSPARENT;
1024 	}
1025 
1026 	if (palette_recalc())
1027 		tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
1028 
1029 	tilemap_render(ALL_TILEMAPS);
1030 
1031 	fillbitmap(bitmap,palette_transparent_pen,&Machine->visible_area);
1032 
1033 	/* Draw the background */
1034 	if (layers_ctrl & 1)
1035 		K051316_zoom_draw_0(bitmap,0);
1036 
1037 	/* Draw the road */
1038 	if (layers_ctrl & 16)
1039 	{
1040 		struct rectangle clip = {0, 512-1, 0, 256-1};
1041 
1042 		fillbitmap(temp_bitmap2,palette_transparent_pen,0);
1043 		hotchase_draw_road(temp_bitmap2,0,&clip);
1044 
1045 		copyrozbitmap( bitmap, temp_bitmap2,
1046 				11*16*0x10000,0,	/* start coordinates */
1047 				0x08000,0,0,0x10000,	/* double horizontally */
1048 				0,	/* no wraparound */
1049 				&Machine->visible_area,TRANSPARENCY_PEN,palette_transparent_pen,0);
1050 	}
1051 
1052 	/* Draw the sprites */
1053 	if (layers_ctrl & 8)	sprite_draw(sprite_list,0);
1054 
1055 	/* Draw the foreground (text) */
1056 	if (layers_ctrl & 4)
1057 		K051316_zoom_draw_1(bitmap,0);
1058 }
1059