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