1 /***************************************************************************
2
3 vidhrdw/toaplan1.c
4
5 Functions to emulate the video hardware of the machine.
6
7 There are 4 scrolling layers of graphics, stored in planes of 64x64 tiles.
8 Each tile in each plane is assigned a priority between 1 and 15, higher
9 numbers have greater priority.
10
11 Each tile takes up 32 bits, the format is:
12
13 0 1 2 3
14 ---- ---- ---- ---- -xxx xxxx xxxx xxxx = tile number (0 - $7fff)
15 ---- ---- ---- ---- ?--- ---- ---- ---- = unknown / unused
16 ---- ---- --xx xxxx ---- ---- ---- ---- = color (0 - $3f)
17 ---- ???? ??-- ---- ---- ---- ---- ---- = unknown / unused
18 xxxx ---- ---- ---- ---- ---- ---- ---- = priority (0-$f)
19
20 BG Scroll Reg
21
22 0 1 2 3
23 xxxx xxxx x--- ---- ---- ---- ---- ---- = x
24 ---- ---- ---- ---- yyyy yyyy ---- ---- = y
25
26
27 Sprite RAM format (except Rally Bike)
28
29 0 1 2 3
30 ---- ---- ---- ---- -xxx xxxx xxxx xxxx = tile number (0 - $7fff)
31 ---- ---- ---- ---- x--- ---- ---- ---- = hidden
32 ---- ---- --xx xxxx ---- ---- ---- ---- = color (0 - $3f)
33 ---- xxxx xx-- ---- ---- ---- ---- ---- = sprite number
34 xxxx ---- ---- ---- ---- ---- ---- ---- = priority (0-$f)
35
36 4 5 6 7
37 ---- ---- ---- ---- xxxx xxxx x--- ---- = x
38 yyyy yyyy y--- ---- ---- ---- ---- ---- = y
39
40 The tiles use a palette of 1024 colors, the sprites use a different palette
41 of 1024 colors.
42
43 ***************************************************************************/
44
45 #include "driver.h"
46 #include "palette.h"
47 #include "vidhrdw/generic.h"
48 #include "cpu/m68000/m68000.h"
49
50 #define VIDEORAM1_SIZE 0x1000 /* size in bytes - sprite ram */
51 #define VIDEORAM2_SIZE 0x100 /* size in bytes - sprite size ram */
52 #define VIDEORAM3_SIZE 0x4000 /* size in bytes - tile ram */
53
54 unsigned char *toaplan1_videoram1;
55 unsigned char *toaplan1_videoram2;
56 unsigned char *toaplan1_videoram3;
57 unsigned char *toaplan1_buffered_videoram1;
58 unsigned char *toaplan1_buffered_videoram2;
59
60 unsigned char *toaplan1_colorram1;
61 unsigned char *toaplan1_colorram2;
62
63 size_t colorram1_size;
64 size_t colorram2_size;
65
66 unsigned int scrollregs[8];
67 unsigned int vblank;
68 unsigned int num_tiles;
69
70 unsigned int video_ofs;
71 unsigned int video_ofs3;
72
73 int toaplan1_flipscreen;
74 int tiles_offsetx;
75 int tiles_offsety;
76 int layers_offset[4];
77
78
79 typedef struct
80 {
81 UINT16 tile_num;
82 UINT16 color;
83 char priority;
84 int xpos;
85 int ypos;
86 } tile_struct;
87
88 tile_struct *bg_list[4];
89
90 tile_struct *tile_list[32];
91 tile_struct *temp_list;
92 static int max_list_size[32];
93 static int tile_count[32];
94
95 struct osd_bitmap *tmpbitmap1;
96 static struct osd_bitmap *tmpbitmap2;
97 static struct osd_bitmap *tmpbitmap3;
98
99
rallybik_vh_start(void)100 int rallybik_vh_start(void)
101 {
102 int i;
103
104 if ((toaplan1_videoram3 = (unsigned char*)calloc(VIDEORAM3_SIZE * 4, 1)) == 0) /* 4 layers */
105 {
106 return 1;
107 }
108
109 //logerror("colorram_size: %08x\n", colorram1_size + colorram2_size);
110 if ((paletteram = (unsigned char*)calloc(colorram1_size + colorram2_size, 1)) == 0)
111 {
112 free(toaplan1_videoram3);
113 return 1;
114 }
115
116 for (i=0; i<4; i++)
117 {
118 if ((bg_list[i]=(tile_struct *)malloc( 33 * 44 * sizeof(tile_struct))) == 0)
119 {
120 free(paletteram);
121 free(toaplan1_videoram3);
122 return 1;
123 }
124 memset(bg_list[i], 0, 33 * 44 * sizeof(tile_struct));
125 }
126
127 for (i=0; i<16; i++)
128 {
129 max_list_size[i] = 8192;
130 if ((tile_list[i]=(tile_struct *)malloc(max_list_size[i]*sizeof(tile_struct))) == 0)
131 {
132 for (i=3; i>=0; i--)
133 free(bg_list[i]);
134 free(paletteram);
135 free(toaplan1_videoram3);
136 return 1;
137 }
138 memset(tile_list[i],0,max_list_size[i]*sizeof(tile_struct));
139 }
140
141 max_list_size[16] = 65536;
142 if ((tile_list[16]=(tile_struct *)malloc(max_list_size[16]*sizeof(tile_struct))) == 0)
143 {
144 for (i=15; i>=0; i--)
145 free(tile_list[i]);
146 for (i=3; i>=0; i--)
147 free(bg_list[i]);
148 free(paletteram);
149 free(toaplan1_videoram3);
150 return 1;
151 }
152 memset(tile_list[16],0,max_list_size[16]*sizeof(tile_struct));
153
154 num_tiles = (Machine->drv->screen_width/8+1)*(Machine->drv->screen_height/8) ;
155
156 video_ofs = video_ofs3 = 0;
157
158 return 0;
159 }
160
rallybik_vh_stop(void)161 void rallybik_vh_stop(void)
162 {
163 int i ;
164
165 for (i=16; i>=0; i--)
166 {
167 free(tile_list[i]);
168 //logerror("max_list_size[%d]=%08x\n",i,max_list_size[i]);
169 }
170
171 for (i=3; i>=0; i--)
172 free(bg_list[i]);
173
174 free(paletteram);
175 free(toaplan1_videoram3);
176 }
177
toaplan1_vh_start(void)178 int toaplan1_vh_start(void)
179 {
180 tmpbitmap1 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height);
181 tmpbitmap2 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height);
182 tmpbitmap3 = bitmap_alloc(Machine->drv->screen_width,Machine->drv->screen_height);
183
184
185 if ((toaplan1_videoram1 = (unsigned char*)calloc(VIDEORAM1_SIZE, 1)) == 0)
186 {
187 return 1;
188 }
189 if ((toaplan1_buffered_videoram1 = (unsigned char*)calloc(VIDEORAM1_SIZE, 1)) == 0)
190 {
191 free(toaplan1_videoram1);
192 return 1;
193 }
194 if ((toaplan1_videoram2 = (unsigned char*)calloc(VIDEORAM2_SIZE, 1)) == 0)
195 {
196 free(toaplan1_buffered_videoram1);
197 free(toaplan1_videoram1);
198 return 1;
199 }
200 if ((toaplan1_buffered_videoram2 = (unsigned char*)calloc(VIDEORAM2_SIZE, 1)) == 0)
201 {
202 free(toaplan1_videoram2);
203 free(toaplan1_buffered_videoram1);
204 free(toaplan1_videoram1);
205 return 1;
206 }
207
208 /* Also include all allocated stuff in Rally Bike startup */
209 return rallybik_vh_start();
210 }
211
toaplan1_vh_stop(void)212 void toaplan1_vh_stop(void)
213 {
214 rallybik_vh_stop();
215
216 free(toaplan1_buffered_videoram2);
217 free(toaplan1_videoram2);
218 free(toaplan1_buffered_videoram1);
219 free(toaplan1_videoram1);
220 bitmap_free(tmpbitmap3);
221 bitmap_free(tmpbitmap2);
222 bitmap_free(tmpbitmap1);
223 }
224
225
226
227
READ_HANDLER(toaplan1_vblank_r)228 READ_HANDLER( toaplan1_vblank_r )
229 {
230 return vblank ^= 1;
231 }
232
WRITE_HANDLER(toaplan1_flipscreen_w)233 WRITE_HANDLER( toaplan1_flipscreen_w )
234 {
235 toaplan1_flipscreen = data; /* 8000 flip, 0000 dont */
236 }
237
READ_HANDLER(video_ofs_r)238 READ_HANDLER( video_ofs_r )
239 {
240 return video_ofs ;
241 }
242
WRITE_HANDLER(video_ofs_w)243 WRITE_HANDLER( video_ofs_w )
244 {
245 video_ofs = data ;
246 }
247
248 /* tile palette */
READ_HANDLER(toaplan1_colorram1_r)249 READ_HANDLER( toaplan1_colorram1_r )
250 {
251 return READ_WORD (&toaplan1_colorram1[offset]);
252 }
253
WRITE_HANDLER(toaplan1_colorram1_w)254 WRITE_HANDLER( toaplan1_colorram1_w )
255 {
256 WRITE_WORD (&toaplan1_colorram1[offset], data);
257 paletteram_xBBBBBGGGGGRRRRR_word_w(offset,data);
258 }
259
260 /* sprite palette */
READ_HANDLER(toaplan1_colorram2_r)261 READ_HANDLER( toaplan1_colorram2_r )
262 {
263 return READ_WORD (&toaplan1_colorram2[offset]);
264 }
265
WRITE_HANDLER(toaplan1_colorram2_w)266 WRITE_HANDLER( toaplan1_colorram2_w )
267 {
268 WRITE_WORD (&toaplan1_colorram2[offset], data);
269 paletteram_xBBBBBGGGGGRRRRR_word_w(offset+colorram1_size,data);
270 }
271
READ_HANDLER(toaplan1_videoram1_r)272 READ_HANDLER( toaplan1_videoram1_r )
273 {
274 return READ_WORD (&toaplan1_videoram1[2*(video_ofs & (VIDEORAM1_SIZE-1))]);
275 }
276
WRITE_HANDLER(toaplan1_videoram1_w)277 WRITE_HANDLER( toaplan1_videoram1_w )
278 {
279 int oldword = READ_WORD (&toaplan1_videoram1[2*video_ofs & (VIDEORAM1_SIZE-1)]);
280 int newword = COMBINE_WORD (oldword, data);
281
282 #ifdef DEBUG
283 if (2*video_ofs >= VIDEORAM1_SIZE)
284 {
285 logerror("videoram1_w, %08x\n", 2*video_ofs);
286 return;
287 }
288 #endif
289
290 WRITE_WORD (&toaplan1_videoram1[2*video_ofs & (VIDEORAM1_SIZE-1)],newword);
291 video_ofs++;
292 }
293
READ_HANDLER(toaplan1_videoram2_r)294 READ_HANDLER( toaplan1_videoram2_r )
295 {
296 return READ_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)]);
297 }
298
WRITE_HANDLER(toaplan1_videoram2_w)299 WRITE_HANDLER( toaplan1_videoram2_w )
300 {
301 int oldword = READ_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)]);
302 int newword = COMBINE_WORD (oldword, data);
303
304 #ifdef DEBUG
305 if (2*video_ofs >= VIDEORAM2_SIZE)
306 {
307 logerror("videoram2_w, %08x\n", 2*video_ofs);
308 return;
309 }
310 #endif
311
312 WRITE_WORD (&toaplan1_videoram2[2*video_ofs & (VIDEORAM2_SIZE-1)],newword);
313 video_ofs++;
314 }
315
READ_HANDLER(video_ofs3_r)316 READ_HANDLER( video_ofs3_r )
317 {
318 return video_ofs3;
319 }
320
WRITE_HANDLER(video_ofs3_w)321 WRITE_HANDLER( video_ofs3_w )
322 {
323 video_ofs3 = data ;
324 }
325
READ_HANDLER(rallybik_videoram3_r)326 READ_HANDLER( rallybik_videoram3_r )
327 {
328 int rb_tmp_vid;
329
330 rb_tmp_vid = READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
331
332 if (offset == 0)
333 {
334 rb_tmp_vid |= ((rb_tmp_vid & 0xf000) >> 4);
335 rb_tmp_vid |= ((rb_tmp_vid & 0x0030) << 2);
336 }
337 return rb_tmp_vid;
338 }
339
READ_HANDLER(toaplan1_videoram3_r)340 READ_HANDLER( toaplan1_videoram3_r )
341 {
342 return READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
343 }
344
WRITE_HANDLER(toaplan1_videoram3_w)345 WRITE_HANDLER( toaplan1_videoram3_w )
346 {
347 int oldword = READ_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset]);
348 int newword = COMBINE_WORD (oldword, data);
349
350 #ifdef DEBUG
351 if ((video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset >= VIDEORAM3_SIZE*4)
352 {
353 logerror("videoram3_w, %08x\n", 2*video_ofs3);
354 return;
355 }
356 #endif
357
358 WRITE_WORD (&toaplan1_videoram3[(video_ofs3 & (VIDEORAM3_SIZE-1))*4 + offset],newword);
359 if ( offset == 2 ) video_ofs3++;
360 }
361
READ_HANDLER(scrollregs_r)362 READ_HANDLER( scrollregs_r )
363 {
364 return scrollregs[offset>>1];
365 }
366
WRITE_HANDLER(scrollregs_w)367 WRITE_HANDLER( scrollregs_w )
368 {
369 scrollregs[offset>>1] = data ;
370 }
371
WRITE_HANDLER(offsetregs_w)372 WRITE_HANDLER( offsetregs_w )
373 {
374 if ( offset == 0 )
375 tiles_offsetx = data ;
376 else
377 tiles_offsety = data ;
378 }
379
WRITE_HANDLER(layers_offset_w)380 WRITE_HANDLER( layers_offset_w )
381 {
382 switch (offset)
383 {
384 /* case 0:
385 layers_offset[0] = (data&0xff) - 0xdb ;
386 break ;
387 case 2:
388 layers_offset[1] = (data&0xff) - 0x14 ;
389 break ;
390 case 4:
391 layers_offset[2] = (data&0xff) - 0x85 ;
392 break ;
393 case 6:
394 layers_offset[3] = (data&0xff) - 0x07 ;
395 break ;
396 */
397 case 0:
398 layers_offset[0] = data;
399 break ;
400 case 2:
401 layers_offset[1] = data;
402 break ;
403 case 4:
404 layers_offset[2] = data;
405 break ;
406 case 6:
407 layers_offset[3] = data;
408 break ;
409 }
410
411 /*
412 logerror("layers_offset[0]:%08x\n",layers_offset[0]);
413 logerror("layers_offset[1]:%08x\n",layers_offset[1]);
414 logerror("layers_offset[2]:%08x\n",layers_offset[2]);
415 logerror("layers_offset[3]:%08x\n",layers_offset[3]);
416 */
417
418 }
419
420 /***************************************************************************
421
422 Draw the game screen in the given osd_bitmap.
423
424 ***************************************************************************/
425
426
toaplan1_update_palette(void)427 static void toaplan1_update_palette (void)
428 {
429 int i;
430 int priority;
431 int color;
432 unsigned short palette_map[64*2];
433
434 memset (palette_map, 0, sizeof (palette_map));
435
436 /* extract color info from priority layers in order */
437 for (priority = 0; priority < 17; priority++ )
438 {
439 tile_struct *tinfo;
440
441 tinfo = (tile_struct *)&(tile_list[priority][0]);
442 /* draw only tiles in list */
443 for ( i = 0; i < tile_count[priority]; i++ )
444 {
445 int bank;
446
447 bank = (tinfo->color >> 7) & 1;
448 color = (tinfo->color & 0x3f);
449 palette_map[color + bank*64] |= Machine->gfx[bank]->pen_usage[tinfo->tile_num & (Machine->gfx[bank]->total_elements-1)];
450
451 tinfo++;
452 }
453 }
454
455 /* Tell MAME about the color usage */
456 for (i = 0; i < 64*2; i++)
457 {
458 int usage = palette_map[i];
459 int j;
460
461 if (usage)
462 {
463 palette_used_colors[i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
464 for (j = 0; j < 16; j++)
465 {
466 if (usage & (1 << j))
467 palette_used_colors[i * 16 + j] = PALETTE_COLOR_USED;
468 else
469 palette_used_colors[i * 16 + j] = PALETTE_COLOR_UNUSED;
470 }
471 }
472 else
473 memset(&palette_used_colors[i * 16],PALETTE_COLOR_UNUSED,16);
474 }
475
476 palette_recalc ();
477 }
478
479
480
481 static int layer_scrollx[4];
482 static int layer_scrolly[4];
483
toaplan1_find_tiles(int xoffs,int yoffs)484 static void toaplan1_find_tiles(int xoffs,int yoffs)
485 {
486 int priority;
487 int layer;
488 tile_struct *tinfo;
489 unsigned char *t_info;
490
491 if(toaplan1_flipscreen){
492 layer_scrollx[0] = ((scrollregs[0]) >> 7) + (523 - xoffs);
493 layer_scrollx[1] = ((scrollregs[2]) >> 7) + (525 - xoffs);
494 layer_scrollx[2] = ((scrollregs[4]) >> 7) + (527 - xoffs);
495 layer_scrollx[3] = ((scrollregs[6]) >> 7) + (529 - xoffs);
496
497 layer_scrolly[0] = ((scrollregs[1]) >> 7) + (256 - yoffs);
498 layer_scrolly[1] = ((scrollregs[3]) >> 7) + (256 - yoffs);
499 layer_scrolly[2] = ((scrollregs[5]) >> 7) + (256 - yoffs);
500 layer_scrolly[3] = ((scrollregs[7]) >> 7) + (256 - yoffs);
501 }else{
502 layer_scrollx[0] = ((scrollregs[0]) >> 7) +(495 - xoffs + 6);
503 layer_scrollx[1] = ((scrollregs[2]) >> 7) +(495 - xoffs + 4);
504 layer_scrollx[2] = ((scrollregs[4]) >> 7) +(495 - xoffs + 2);
505 layer_scrollx[3] = ((scrollregs[6]) >> 7) +(495 - xoffs);
506
507 layer_scrolly[0] = ((scrollregs[1]) >> 7) + (0x101 - yoffs);
508 layer_scrolly[1] = ((scrollregs[3]) >> 7) + (0x101 - yoffs);
509 layer_scrolly[2] = ((scrollregs[5]) >> 7) + (0x101 - yoffs);
510 layer_scrolly[3] = ((scrollregs[7]) >> 7) + (0x101 - yoffs);
511 }
512
513 for ( layer = 3 ; layer >= 0 ; layer-- )
514 {
515 int scrolly,scrollx,offsetx,offsety;
516 int sx,sy,tattr;
517 int i;
518
519 t_info = (toaplan1_videoram3+layer * VIDEORAM3_SIZE);
520 scrollx = layer_scrollx[layer];
521 offsetx = scrollx / 8 ;
522 scrolly = layer_scrolly[layer];
523 offsety = scrolly / 8 ;
524
525 for ( sy = 0 ; sy < 32 ; sy++ )
526 {
527 for ( sx = 0 ; sx <= 40 ; sx++ )
528 {
529 i = ((sy+offsety)&0x3f)*256 + ((sx+offsetx)&0x3f)*4 ;
530 tattr = READ_WORD(&t_info[i]);
531 priority = (tattr >> 12);
532
533 tinfo = (tile_struct *)&(bg_list[layer][sy*41+sx]) ;
534 tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
535 tinfo->priority = priority ;
536 tinfo->color = tattr & 0x3f ;
537 tinfo->xpos = (sx*8)-(scrollx&0x7) ;
538 tinfo->ypos = (sy*8)-(scrolly&0x7) ;
539
540 if ( (priority) || (layer == 0) ) /* if priority 0 draw layer 0 only */
541 {
542
543 tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
544 tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
545 if ( (tinfo->tile_num & 0x8000) == 0 )
546 {
547 tinfo->priority = priority ;
548 tinfo->color = tattr & 0x3f ;
549 tinfo->color |= layer<<8;
550 tinfo->xpos = (sx*8)-(scrollx&0x7) ;
551 tinfo->ypos = (sy*8)-(scrolly&0x7) ;
552 tile_count[priority]++ ;
553 if(tile_count[priority]==max_list_size[priority])
554 {
555 /*reallocate tile_list[priority] to larger size */
556 temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
557 memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
558 max_list_size[priority]+=512;
559 free(tile_list[priority]);
560 tile_list[priority] = temp_list ;
561 }
562 }
563 }
564 }
565 }
566 }
567 for ( layer = 3 ; layer >= 0 ; layer-- )
568 {
569 layer_scrollx[layer] &= 0x7;
570 layer_scrolly[layer] &= 0x7;
571 }
572 }
573
rallybik_find_tiles(void)574 static void rallybik_find_tiles(void)
575 {
576 int priority;
577 int layer;
578 tile_struct *tinfo;
579 unsigned char *t_info;
580
581 for ( priority = 0 ; priority < 16 ; priority++ )
582 {
583 tile_count[priority]=0;
584 }
585
586 for ( layer = 3 ; layer >= 0 ; layer-- )
587 {
588 int scrolly,scrollx,offsetx,offsety;
589 int sx,sy,tattr;
590 int i;
591
592 t_info = (toaplan1_videoram3+layer * VIDEORAM3_SIZE);
593 scrollx = scrollregs[layer*2];
594 scrolly = scrollregs[(layer*2)+1];
595
596 scrollx >>= 7 ;
597 scrollx += 43 ;
598 if ( layer == 0 ) scrollx += 2 ;
599 if ( layer == 2 ) scrollx -= 2 ;
600 if ( layer == 3 ) scrollx -= 4 ;
601 offsetx = scrollx / 8 ;
602
603 scrolly >>= 7 ;
604 scrolly += 21 ;
605 offsety = scrolly / 8 ;
606
607 for ( sy = 0 ; sy < 32 ; sy++ )
608 {
609 for ( sx = 0 ; sx <= 40 ; sx++ )
610 {
611 i = ((sy+offsety)&0x3f)*256 + ((sx+offsetx)&0x3f)*4 ;
612 tattr = READ_WORD(&t_info[i]);
613 priority = tattr >> 12 ;
614 if ( (priority) || (layer == 0) ) /* if priority 0 draw layer 0 only */
615 {
616 tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
617 tinfo->tile_num = READ_WORD(&t_info[i+2]) ;
618
619 if ( !((priority) && (tinfo->tile_num & 0x8000)) )
620 {
621 tinfo->tile_num &= 0x3fff ;
622 tinfo->color = tattr & 0x3f ;
623 tinfo->xpos = (sx*8)-(scrollx&0x7) ;
624 tinfo->ypos = (sy*8)-(scrolly&0x7) ;
625 tile_count[priority]++ ;
626 if(tile_count[priority]==max_list_size[priority])
627 {
628 /*reallocate tile_list[priority] to larger size */
629 temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
630 memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
631 max_list_size[priority]+=512;
632 free(tile_list[priority]);
633 tile_list[priority] = temp_list ;
634 }
635 }
636 }
637 }
638 }
639 }
640 }
641
642 unsigned long toaplan_sp_ram_dump = 0;
643
toaplan1_find_sprites(void)644 static void toaplan1_find_sprites (void)
645 {
646 int priority;
647 int sprite;
648 unsigned char *s_info,*s_size;
649
650
651 for ( priority = 0 ; priority < 17 ; priority++ )
652 {
653 tile_count[priority]=0;
654 }
655
656
657 #if 0 // sp ram dump start
658 s_size = (toaplan1_buffered_videoram2); /* sprite block size */
659 s_info = (toaplan1_buffered_videoram1); /* start of sprite ram */
660 if( (toaplan_sp_ram_dump == 0)
661 && (keyboard_pressed(KEYCODE_N)) )
662 {
663 toaplan_sp_ram_dump = 1;
664 for ( sprite = 0 ; sprite < 256 ; sprite++ )
665 {
666 int tattr,tchar;
667 tchar = READ_WORD (&s_info[0]) & 0xffff;
668 tattr = READ_WORD (&s_info[2]);
669 logerror("%08x: %04x %04x\n", sprite, tattr, tchar);
670 s_info += 8 ;
671 }
672 }
673 #endif // end
674
675 s_size = (toaplan1_buffered_videoram2); /* sprite block size */
676 s_info = (toaplan1_buffered_videoram1); /* start of sprite ram */
677
678 for ( sprite = 0 ; sprite < 256 ; sprite++ )
679 {
680 int tattr,tchar;
681
682 tchar = READ_WORD (&s_info[0]) & 0xffff;
683 tattr = READ_WORD (&s_info[2]);
684
685 if ( (tattr & 0xf000) && ((tchar & 0x8000) == 0) )
686 {
687 int sx,sy,dx,dy,s_sizex,s_sizey;
688 int sprite_size_ptr;
689
690 sx=READ_WORD(&s_info[4]);
691 sx >>= 7 ;
692 if ( sx > 416 ) sx -= 512 ;
693
694 sy=READ_WORD(&s_info[6]);
695 sy >>= 7 ;
696 if ( sy > 416 ) sy -= 512 ;
697
698 priority = (tattr >> 12);
699
700 sprite_size_ptr = (tattr>>6)&0x3f ;
701 s_sizey = (READ_WORD(&s_size[2*sprite_size_ptr])>>4)&0xf ;
702 s_sizex = (READ_WORD(&s_size[2*sprite_size_ptr]))&0xf ;
703
704 for ( dy = s_sizey ; dy > 0 ; dy-- )
705 for ( dx = s_sizex; dx > 0 ; dx-- )
706 {
707 tile_struct *tinfo;
708
709 tinfo = (tile_struct *)&(tile_list[16][tile_count[16]]) ;
710 tinfo->priority = priority;
711 tinfo->tile_num = tchar;
712 tinfo->color = 0x80 | (tattr & 0x3f) ;
713 tinfo->xpos = sx-dx*8+s_sizex*8 ;
714 tinfo->ypos = sy-dy*8+s_sizey*8 ;
715 tile_count[16]++ ;
716 if(tile_count[16]==max_list_size[16])
717 {
718 /*reallocate tile_list[priority] to larger size */
719 temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[16]+512)) ;
720 memcpy(temp_list,tile_list[16],sizeof(tile_struct)*max_list_size[16]);
721 max_list_size[16]+=512;
722 free(tile_list[16]);
723 tile_list[16] = temp_list ;
724 }
725 tchar++;
726 }
727 }
728 s_info += 8 ;
729 }
730 }
731
rallybik_find_sprites(void)732 static void rallybik_find_sprites (void)
733 {
734 int offs;
735 int tattr;
736 int sx,sy,tchar;
737 int priority;
738 tile_struct *tinfo;
739
740 for (offs = 0;offs < spriteram_size;offs += 8)
741 {
742 tattr = READ_WORD(&buffered_spriteram[offs+2]);
743 if ( tattr ) /* no need to render hidden sprites */
744 {
745 sx=READ_WORD(&buffered_spriteram[offs+4]);
746 sx >>= 7 ;
747 sx &= 0x1ff ;
748 if ( sx > 416 ) sx -= 512 ;
749
750 sy=READ_WORD(&buffered_spriteram[offs+6]);
751 sy >>= 7 ;
752 sy &= 0x1ff ;
753 if ( sy > 416 ) sy -= 512 ;
754
755 priority = (tattr>>8) & 0xc ;
756 tchar = READ_WORD(&buffered_spriteram[offs+0]);
757 tinfo = (tile_struct *)&(tile_list[priority][tile_count[priority]]) ;
758 tinfo->tile_num = tchar & 0x7ff ;
759 tinfo->color = 0x80 | (tattr&0x3f) ;
760 tinfo->color |= (tattr & 0x0100) ;
761 tinfo->color |= (tattr & 0x0200) ;
762 if (tinfo->color & 0x0100) sx -= 15;
763
764 tinfo->xpos = sx-31 ;
765 tinfo->ypos = sy-16 ;
766 tile_count[priority]++ ;
767 if(tile_count[priority]==max_list_size[priority])
768 {
769 /*reallocate tile_list[priority] to larger size */
770 temp_list=(tile_struct *)malloc(sizeof(tile_struct)*(max_list_size[priority]+512)) ;
771 memcpy(temp_list,tile_list[priority],sizeof(tile_struct)*max_list_size[priority]);
772 max_list_size[priority]+=512;
773 free(tile_list[priority]);
774 tile_list[priority] = temp_list ;
775 }
776 } // if tattr
777 } // for sprite
778 }
779
780
toaplan1_fillbgmask(struct osd_bitmap * dest_bmp,struct osd_bitmap * source_bmp,const struct rectangle * clip,int transparent_color)781 void toaplan1_fillbgmask(struct osd_bitmap *dest_bmp, struct osd_bitmap *source_bmp,
782 const struct rectangle *clip,int transparent_color)
783 {
784 struct rectangle myclip;
785 int sx=0;
786 int sy=0;
787
788 if (Machine->orientation & ORIENTATION_SWAP_XY)
789 {
790 int temp;
791
792 /* clip and myclip might be the same, so we need a temporary storage */
793 temp = clip->min_x;
794 myclip.min_x = clip->min_y;
795 myclip.min_y = temp;
796 temp = clip->max_x;
797 myclip.max_x = clip->max_y;
798 myclip.max_y = temp;
799 clip = &myclip;
800 }
801 if (Machine->orientation & ORIENTATION_FLIP_X)
802 {
803 int temp;
804
805 sx = -sx;
806
807 /* clip and myclip might be the same, so we need a temporary storage */
808 temp = clip->min_x;
809 myclip.min_x = dest_bmp->width-1 - clip->max_x;
810 myclip.max_x = dest_bmp->width-1 - temp;
811 myclip.min_y = clip->min_y;
812 myclip.max_y = clip->max_y;
813 clip = &myclip;
814 }
815 if (Machine->orientation & ORIENTATION_FLIP_Y)
816 {
817 int temp;
818
819 sy = -sy;
820
821 myclip.min_x = clip->min_x;
822 myclip.max_x = clip->max_x;
823 /* clip and myclip might be the same, so we need a temporary storage */
824 temp = clip->min_y;
825 myclip.min_y = dest_bmp->height-1 - clip->max_y;
826 myclip.max_y = dest_bmp->height-1 - temp;
827 clip = &myclip;
828 }
829
830 if (dest_bmp->depth != 16)
831 {
832 int ex = sx+source_bmp->width;
833 int ey = sy+source_bmp->height;
834
835 if( sx < clip->min_x)
836 { /* clip left */
837 sx = clip->min_x;
838 }
839 if( sy < clip->min_y )
840 { /* clip top */
841 sy = clip->min_y;
842 }
843 if( ex > clip->max_x+1 )
844 { /* clip right */
845 ex = clip->max_x + 1;
846 }
847 if( ey > clip->max_y+1 )
848 { /* clip bottom */
849 ey = clip->max_y + 1;
850 }
851
852 if( ex>sx )
853 { /* skip if inner loop doesn't draw anything */
854 int y;
855 for( y=sy; y<ey; y++ )
856 {
857 unsigned char *dest = dest_bmp->line[y];
858 unsigned char *source = source_bmp->line[y];
859 int x;
860
861 for( x=sx; x<ex; x++ )
862 {
863 int c = source[x];
864 if( c != transparent_color )
865 dest[x] = transparent_color;
866 }
867 }
868 }
869 }
870
871 else
872 {
873 int ex = sx+source_bmp->width;
874 int ey = sy+source_bmp->height;
875
876 if( sx < clip->min_x)
877 { /* clip left */
878 sx = clip->min_x;
879 }
880 if( sy < clip->min_y )
881 { /* clip top */
882 sy = clip->min_y;
883 }
884 if( ex > clip->max_x+1 )
885 { /* clip right */
886 ex = clip->max_x + 1;
887 }
888 if( ey > clip->max_y+1 )
889 { /* clip bottom */
890 ey = clip->max_y + 1;
891 }
892
893 if( ex>sx )
894 { /* skip if inner loop doesn't draw anything */
895 int y;
896
897 for( y=sy; y<ey; y++ )
898 {
899 unsigned short *dest = (unsigned short *)dest_bmp->line[y];
900 unsigned char *source = source_bmp->line[y];
901 int x;
902
903 for( x=sx; x<ex; x++ )
904 {
905 int c = source[x];
906 if( c != transparent_color )
907 dest[x] = transparent_color;
908 }
909 }
910 }
911 }
912 }
913
914
915 //#define BGDBG
916 #ifdef BGDBG
917 int toaplan_dbg_priority = 0;
918 #endif
919
920
toaplan1_render(struct osd_bitmap * bitmap)921 static void toaplan1_render (struct osd_bitmap *bitmap)
922 {
923 int i,j;
924 int priority,pen;
925 int flip;
926 tile_struct *tinfo;
927 tile_struct *tinfo2;
928 struct rectangle sp_rect;
929
930 fillbitmap (bitmap, palette_transparent_pen, &Machine->visible_area);
931
932 #ifdef BGDBG
933
934 if (keyboard_pressed(KEYCODE_Q)) { toaplan_dbg_priority = 0; }
935 if (keyboard_pressed(KEYCODE_W)) { toaplan_dbg_priority = 1; }
936 if (keyboard_pressed(KEYCODE_E)) { toaplan_dbg_priority = 2; }
937 if (keyboard_pressed(KEYCODE_R)) { toaplan_dbg_priority = 3; }
938 if (keyboard_pressed(KEYCODE_T)) { toaplan_dbg_priority = 4; }
939 if (keyboard_pressed(KEYCODE_Y)) { toaplan_dbg_priority = 5; }
940 if (keyboard_pressed(KEYCODE_U)) { toaplan_dbg_priority = 6; }
941 if (keyboard_pressed(KEYCODE_I)) { toaplan_dbg_priority = 7; }
942 if (keyboard_pressed(KEYCODE_A)) { toaplan_dbg_priority = 8; }
943 if (keyboard_pressed(KEYCODE_S)) { toaplan_dbg_priority = 9; }
944 if (keyboard_pressed(KEYCODE_D)) { toaplan_dbg_priority = 10; }
945 if (keyboard_pressed(KEYCODE_F)) { toaplan_dbg_priority = 11; }
946 if (keyboard_pressed(KEYCODE_G)) { toaplan_dbg_priority = 12; }
947 if (keyboard_pressed(KEYCODE_H)) { toaplan_dbg_priority = 13; }
948 if (keyboard_pressed(KEYCODE_J)) { toaplan_dbg_priority = 14; }
949 if (keyboard_pressed(KEYCODE_K)) { toaplan_dbg_priority = 15; }
950
951 if( toaplan_dbg_priority != 0 ){
952
953 priority = toaplan_dbg_priority;
954 {
955 tinfo = (tile_struct *)&(tile_list[priority][0]) ;
956 /* hack to fix black blobs in Demon's World sky */
957 pen = TRANSPARENCY_NONE ;
958 for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
959 {
960 /* hack to fix blue blobs in Zero Wing attract mode */
961 // if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
962 // pen = TRANSPARENCY_PEN ;
963 drawgfx(bitmap,Machine->gfx[0],
964 tinfo->tile_num,
965 (tinfo->color&0x3f),
966 0,0, /* flipx,flipy */
967 tinfo->xpos,tinfo->ypos,
968 &Machine->visible_area,pen,0);
969 tinfo++ ;
970 }
971 }
972
973 }else{
974
975 #endif
976
977 // if(toaplan1_flipscreen)
978 // flip = 1;
979 // else
980 flip = 0;
981 //
982 priority = 0;
983 while ( priority < 16 ) /* draw priority layers in order */
984 {
985 int layer;
986
987 tinfo = (tile_struct *)&(tile_list[priority][0]) ;
988 layer = (tinfo->color >> 8);
989 if ( (layer < 3) && (priority < 2))
990 pen = TRANSPARENCY_NONE ;
991 else
992 pen = TRANSPARENCY_PEN ;
993
994 for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
995 {
996 int xpos,ypos;
997
998 /* hack to fix blue blobs in Zero Wing attract mode */
999 // if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
1000 // pen = TRANSPARENCY_PEN ;
1001
1002 // if ( flip ){
1003 // xpos = tinfo->xpos;
1004 // ypos = tinfo->ypos;
1005 // }
1006 // else{
1007 xpos = tinfo->xpos;
1008 ypos = tinfo->ypos;
1009 // }
1010
1011 drawgfx(bitmap,Machine->gfx[0],
1012 tinfo->tile_num,
1013 (tinfo->color&0x3f),
1014 flip,flip, /* flipx,flipy */
1015 tinfo->xpos,tinfo->ypos,
1016 &Machine->visible_area,pen,0);
1017 tinfo++ ;
1018 }
1019 priority++;
1020 }
1021
1022 tinfo2 = (tile_struct *)&(tile_list[16][0]) ;
1023 for ( i = 0; i < tile_count[16]; i++ ) /* draw sprite No. in order */
1024 {
1025 int flipx,flipy;
1026
1027 sp_rect.min_x = tinfo2->xpos;
1028 sp_rect.min_y = tinfo2->ypos;
1029 sp_rect.max_x = tinfo2->xpos + 7;
1030 sp_rect.max_y = tinfo2->ypos + 7;
1031
1032 fillbitmap (tmpbitmap2, palette_transparent_pen, &sp_rect);
1033
1034 flipx = (tinfo2->color & 0x0100);
1035 flipy = (tinfo2->color & 0x0200);
1036 // if(toaplan1_flipscreen){
1037 // flipx = !flipx;
1038 // flipy = !flipy;
1039 // }
1040 drawgfx(tmpbitmap2,Machine->gfx[1],
1041 tinfo2->tile_num,
1042 (tinfo2->color&0x3f), /* bit 7 not for colour */
1043 flipx,flipy, /* flipx,flipy */
1044 tinfo2->xpos,tinfo2->ypos,
1045 &Machine->visible_area,TRANSPARENCY_PEN,0);
1046
1047 priority = tinfo2->priority;
1048 {
1049 int ix0,ix1,ix2,ix3;
1050 int dirty;
1051
1052 dirty = 0;
1053 fillbitmap (tmpbitmap3, palette_transparent_pen, &sp_rect);
1054 for ( j = 0 ; j < 4 ; j++ )
1055 {
1056 int x,y;
1057
1058 y = tinfo2->ypos+layer_scrolly[j];
1059 x = tinfo2->xpos+layer_scrollx[j];
1060 ix0 = ( y /8) * 41 + x /8;
1061 ix1 = ( y /8) * 41 + (x+7)/8;
1062 ix2 = ((y+7)/8) * 41 + x /8;
1063 ix3 = ((y+7)/8) * 41 + (x+7)/8;
1064
1065 if( (ix0 >= 0) && (ix0 < 32*41) ){
1066 tinfo = (tile_struct *)&(bg_list[j][ix0]) ;
1067 if( (tinfo->priority >= tinfo2->priority) ){
1068 drawgfx(tmpbitmap3,Machine->gfx[0],
1069 // drawgfx(tmpbitmap2,Machine->gfx[0],
1070 tinfo->tile_num,
1071 (tinfo->color&0x3f),
1072 flip,flip,
1073 tinfo->xpos,tinfo->ypos,
1074 &sp_rect,TRANSPARENCY_PEN,0);
1075 dirty=1;
1076 }
1077 }
1078 if( (ix1 >= 0) && (ix1 < 32*41) ){
1079 tinfo = (tile_struct *)&(bg_list[j][ix1]) ;
1080 // tinfo++;
1081 if( (ix0 != ix1)
1082 && (tinfo->priority >= tinfo2->priority) ){
1083 drawgfx(tmpbitmap3,Machine->gfx[0],
1084 // drawgfx(tmpbitmap2,Machine->gfx[0],
1085 tinfo->tile_num,
1086 (tinfo->color&0x3f),
1087 flip,flip,
1088 tinfo->xpos,tinfo->ypos,
1089 &sp_rect,TRANSPARENCY_PEN,0);
1090 dirty=1;
1091 }
1092 }
1093 if( (ix2 >= 0) && (ix2 < 32*41) ){
1094 tinfo = (tile_struct *)&(bg_list[j][ix2]) ;
1095 // tinfo += 40;
1096 if( (ix0 != ix2)
1097 && (tinfo->priority >= tinfo2->priority) ){
1098 drawgfx(tmpbitmap3,Machine->gfx[0],
1099 // drawgfx(tmpbitmap2,Machine->gfx[0],
1100 tinfo->tile_num,
1101 (tinfo->color&0x3f),
1102 flip,flip,
1103 tinfo->xpos,tinfo->ypos,
1104 &sp_rect,TRANSPARENCY_PEN,0);
1105 dirty=1;
1106 }
1107 }
1108 if( (ix3 >= 0) && (ix3 < 32*41) ){
1109 tinfo = (tile_struct *)&(bg_list[j][ix3]) ;
1110 // tinfo++;
1111 if( (ix0 != ix3) && (ix1 != ix3) && (ix2 != ix3)
1112 && (tinfo->priority >= tinfo2->priority) ){
1113 drawgfx(tmpbitmap3,Machine->gfx[0],
1114 // drawgfx(tmpbitmap2,Machine->gfx[0],
1115 tinfo->tile_num,
1116 (tinfo->color&0x3f),
1117 flip,flip,
1118 tinfo->xpos,tinfo->ypos,
1119 &sp_rect,TRANSPARENCY_PEN,0);
1120 dirty=1;
1121 }
1122 }
1123 }
1124 if( dirty != 0 )
1125 {
1126 toaplan1_fillbgmask(
1127 tmpbitmap2, // dist
1128 tmpbitmap3, // mask
1129 &sp_rect,
1130 palette_transparent_pen
1131 );
1132 }
1133 copybitmap(bitmap, tmpbitmap2, 0, 0, 0, 0, &sp_rect, TRANSPARENCY_PEN, palette_transparent_pen);
1134 tinfo2++;
1135 }
1136 }
1137
1138 #ifdef BGDBG
1139 }
1140 #endif
1141
1142 }
1143
1144
rallybik_render(struct osd_bitmap * bitmap)1145 static void rallybik_render (struct osd_bitmap *bitmap)
1146 {
1147 int i;
1148 int priority,pen;
1149 tile_struct *tinfo;
1150
1151 fillbitmap (bitmap, palette_transparent_pen, &Machine->visible_area);
1152
1153 for ( priority = 0 ; priority < 16 ; priority++ ) /* draw priority layers in order */
1154 {
1155 tinfo = (tile_struct *)&(tile_list[priority][0]) ;
1156 /* hack to fix black blobs in Demon's World sky */
1157 if ( priority == 1 )
1158 pen = TRANSPARENCY_NONE ;
1159 else
1160 pen = TRANSPARENCY_PEN ;
1161 for ( i = 0 ; i < tile_count[priority] ; i++ ) /* draw only tiles in list */
1162 {
1163 /* hack to fix blue blobs in Zero Wing attract mode */
1164 if ((pen == TRANSPARENCY_NONE) && ((tinfo->color&0x3f)==0))
1165 pen = TRANSPARENCY_PEN ;
1166
1167 drawgfx(bitmap,Machine->gfx[(tinfo->color>>7)&1], /* bit 7 set for sprites */
1168 tinfo->tile_num,
1169 (tinfo->color&0x3f), /* bit 7 not for colour */
1170 (tinfo->color & 0x0100),(tinfo->color & 0x0200), /* flipx,flipy */
1171 tinfo->xpos,tinfo->ypos,
1172 &Machine->visible_area,pen,0);
1173 tinfo++ ;
1174 }
1175 }
1176 }
1177
1178
toaplan1_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1179 void toaplan1_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1180 {
1181 /* discover what data will be drawn */
1182 toaplan1_find_sprites();
1183 toaplan1_find_tiles(tiles_offsetx,tiles_offsety);
1184
1185 toaplan1_update_palette();
1186 toaplan1_render(bitmap);
1187 }
1188
rallybik_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)1189 void rallybik_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
1190 {
1191 /* discover what data will be drawn */
1192 rallybik_find_tiles();
1193 rallybik_find_sprites();
1194
1195 toaplan1_update_palette();
1196 rallybik_render(bitmap);
1197 }
1198
1199
1200
1201 /****************************************************************************
1202 Spriteram is always 1 frame ahead, suggesting spriteram buffering.
1203 There are no CPU output registers that control this so we
1204 assume it happens automatically every frame, at the end of vblank
1205 ****************************************************************************/
1206
toaplan1_eof_callback(void)1207 void toaplan1_eof_callback(void)
1208 {
1209 memcpy(toaplan1_buffered_videoram1,toaplan1_videoram1,VIDEORAM1_SIZE);
1210 memcpy(toaplan1_buffered_videoram2,toaplan1_videoram2,VIDEORAM2_SIZE);
1211 }
1212
rallybik_eof_callback(void)1213 void rallybik_eof_callback(void)
1214 {
1215 buffer_spriteram_w(0,0);
1216 }
1217
samesame_eof_callback(void)1218 void samesame_eof_callback(void)
1219 {
1220 memcpy(toaplan1_buffered_videoram1,toaplan1_videoram1,VIDEORAM1_SIZE);
1221 memcpy(toaplan1_buffered_videoram2,toaplan1_videoram2,VIDEORAM2_SIZE);
1222 cpu_set_irq_line(0, MC68000_IRQ_2, HOLD_LINE); /* Frame done */
1223 }
1224
1225