1 #include "driver.h"
2 #include "state.h"
3 #include "vidhrdw/generic.h"
4 #include "vidhrdw/taitoic.h"
5
6 #define TC0100SCN_GFX_NUM 1
7 #define TC0480SCP_GFX_NUM 1
8 #define TC0280GRD_GFX_NUM 2
9 #define TC0430GRW_GFX_NUM 2
10
11 extern UINT8 TC0360PRI_regs[16];
12
13 struct tempsprite
14 {
15 int code,color;
16 int flipx,flipy;
17 int x,y;
18 int zoomx,zoomy;
19 int primask;
20 };
21 static struct tempsprite *spritelist;
22
23 static data16_t *spriteram_buffered,*spriteram_delayed;
24
25
26 /************************************************************
27 SPRITE BANKING
28
29 Four sprite banking methods are used for games with more
30 than $2000 sprite tiles, because the sprite ram only has
31 13 bits available for tile numbers.
32
33 0 = standard (only a limited selection of sprites are
34 available for display at a given time)
35 1 = use sprite extension area lo bytes for hi 6 bits
36 2 = use sprite extension area hi bytes
37 3 = use sprite extension area lo bytes as hi bytes
38 (sprite extension areas mean all sprite
39 tiles are always accessible)
40 ************************************************************/
41
42 int f2_sprite_type = 0;
43 data16_t *f2_sprite_extension;
44 size_t f2_spriteext_size;
45
46 static UINT16 spritebank[8];
47 //static UINT16 spritebank_eof[8];
48 static UINT16 spritebank_buffered[8];
49 static UINT16 koshien_spritebank;
50
51 int sprites_disabled,sprites_active_area,sprites_master_scrollx,sprites_master_scrolly;
52 /* remember flip status over frames because driftout can fail to set it */
53 static int sprites_flipscreen = 0;
54
55
56 /* On the left hand screen edge (assuming horiz screen, no
57 screenflip: in screenflip it is the right hand edge etc.)
58 there may be 0-3 unwanted pixels in both tilemaps *and*
59 sprites. To erase this we use f2_hide_pixels (0 to +3). */
60
61 static int f2_hide_pixels;
62 static int f2_flip_hide_pixels; /* Different in some games */
63
64 static int f2_pivot_xdisp = 0; /* Needed in games with a pivot layer */
65 static int f2_pivot_ydisp = 0;
66
67 static int f2_tilemap_xoffs = 0; /* Needed in TC0480SCP games */
68 static int f2_tilemap_yoffs = 0;
69 static int f2_text_xoffs = 0;
70
71 int f2_tilemap_col_base = 0;
72
73 static int f2_game = 0;
74 static int FOOTCHMP = 1;
75
76
77
78 /***********************************************************************************/
79
taitof2_core_vh_start(int sprite_type,int hide,int flip_hide,int x_offs,int y_offs,int flip_xoffs,int flip_yoffs,int flip_text_x_offs,int flip_text_yoffs)80 int taitof2_core_vh_start (int sprite_type,int hide,int flip_hide,int x_offs,int y_offs,
81 int flip_xoffs,int flip_yoffs,int flip_text_x_offs,int flip_text_yoffs)
82 {
83 int i,chips;
84 f2_sprite_type = sprite_type;
85 f2_hide_pixels = hide;
86 f2_flip_hide_pixels = flip_hide;
87
88 spriteram_delayed = auto_malloc(spriteram_size);
89 spriteram_buffered = auto_malloc(spriteram_size);
90 spritelist = auto_malloc(0x400 * sizeof(*spritelist));
91 if (!spriteram_delayed || !spriteram_buffered || !spritelist)
92 return 1;
93
94 chips = number_of_TC0100SCN();
95
96 if (chips < 0) /* we have an erroneous TC0100SCN configuration */
97 return 1;
98
99 if (has_TC0480SCP()) /* it's a tc0480scp game */
100 {
101 if (TC0480SCP_vh_start(TC0480SCP_GFX_NUM,f2_hide_pixels,f2_tilemap_xoffs,
102 f2_tilemap_yoffs,f2_text_xoffs,0,-1,0,f2_tilemap_col_base))
103 return 1;
104 }
105 else /* it's a tc0100scn game */
106 {
107 if (TC0100SCN_vh_start(chips,TC0100SCN_GFX_NUM,f2_hide_pixels,0,
108 flip_xoffs,flip_yoffs,flip_text_x_offs,flip_text_yoffs,TC0100SCN_SINGLE_VDU))
109 return 1;
110 }
111
112 if (has_TC0110PCR())
113 if (TC0110PCR_vh_start())
114 return 1;
115
116 if (has_TC0280GRD())
117 if (TC0280GRD_vh_start(TC0280GRD_GFX_NUM))
118 return 1;
119
120 if (has_TC0430GRW())
121 if (TC0430GRW_vh_start(TC0430GRW_GFX_NUM))
122 return 1;
123
124 if (has_TC0360PRI())
125 TC0360PRI_vh_start(); /* Purely for save-state purposes */
126
127 for (i = 0; i < 8; i ++)
128 {
129 spritebank_buffered[i] = 0x400 * i;
130 spritebank[i] = spritebank_buffered[i];
131 }
132
133 sprites_disabled = 1;
134 sprites_active_area = 0;
135
136 f2_game = 0; /* means NOT footchmp */
137
138 state_save_register_int ("main1", 0, "control", &f2_hide_pixels);
139 state_save_register_int ("main2", 0, "control", &f2_sprite_type);
140 state_save_register_UINT16("main3", 0, "control", spritebank, 8);
141 state_save_register_UINT16("main4", 0, "control", &koshien_spritebank, 1);
142 state_save_register_int ("main5", 0, "control", &sprites_disabled);
143 state_save_register_int ("main6", 0, "control", &sprites_active_area);
144 state_save_register_UINT16("main7", 0, "memory", spriteram_delayed, spriteram_size/2);
145 state_save_register_UINT16("main8", 0, "memory", spriteram_buffered, spriteram_size/2);
146
147 return 0;
148 }
149
150
151 /**************************************************************************************/
152 /* ( spritetype, hide, hideflip, xoffs, yoffs, flipx, flipy, textflipx, textflipy) */
153 /**************************************************************************************/
154
VIDEO_START(taitof2_default)155 VIDEO_START( taitof2_default )
156 {
157 return (taitof2_core_vh_start(0,0,0,0,0,0,0,0,0));
158 }
159
VIDEO_START(taitof2_megab)160 VIDEO_START( taitof2_megab ) /* Megab, Liquidk */
161 {
162 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
163 }
164
VIDEO_START(taitof2_quiz)165 VIDEO_START( taitof2_quiz ) /* Quiz Crayons, Quiz Jinsei */
166 {
167 return (taitof2_core_vh_start(3,3,3,0,0,0,0,0,0));
168 }
169
VIDEO_START(taitof2_finalb)170 VIDEO_START( taitof2_finalb )
171 {
172 return (taitof2_core_vh_start(0,1,1,0,0,0,0,0,0));
173 }
174
VIDEO_START(taitof2_ssi)175 VIDEO_START( taitof2_ssi )
176 {
177 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
178 }
179
VIDEO_START(taitof2_growl)180 VIDEO_START( taitof2_growl )
181 {
182 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
183 }
184
VIDEO_START(taitof2_ninjak)185 VIDEO_START( taitof2_ninjak )
186 {
187 return (taitof2_core_vh_start(0,0,0,0,0,0,0,1,2));
188 }
189
VIDEO_START(taitof2_qzchikyu)190 VIDEO_START( taitof2_qzchikyu )
191 {
192 return (taitof2_core_vh_start(0,0,4,0,0,-4,0,-11,0));
193 }
194
VIDEO_START(taitof2_solfigtr)195 VIDEO_START( taitof2_solfigtr )
196 {
197 return (taitof2_core_vh_start(0,3,-3,0,0,6,0,6,0));
198 }
199
VIDEO_START(taitof2_koshien)200 VIDEO_START( taitof2_koshien )
201 {
202 return (taitof2_core_vh_start(0,1,-1,0,0,2,0,0,0));
203 }
204
VIDEO_START(taitof2_gunfront)205 VIDEO_START( taitof2_gunfront )
206 {
207 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
208 }
209
VIDEO_START(taitof2_thundfox)210 VIDEO_START( taitof2_thundfox )
211 {
212 return (taitof2_core_vh_start(0,3,-3,0,0,5,0,4,1));
213 }
214
VIDEO_START(taitof2_mjnquest)215 VIDEO_START( taitof2_mjnquest )
216 {
217 int failed = (taitof2_core_vh_start(0,0,0,0,0,0,0,0,0)); /* non-zero = failure */
218 if (!failed) TC0100SCN_set_bg_tilemask(0x7fff);
219
220 return failed;
221 }
222
VIDEO_START(taitof2_footchmp)223 VIDEO_START( taitof2_footchmp )
224 {
225 int failed;
226 f2_tilemap_xoffs = 0x1d;
227 f2_tilemap_yoffs = 0x08;
228 f2_text_xoffs = -1;
229 f2_tilemap_col_base = 0;
230 failed = (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
231
232 f2_game = FOOTCHMP;
233 return failed;
234 }
235
VIDEO_START(taitof2_hthero)236 VIDEO_START( taitof2_hthero )
237 {
238 int failed;
239 f2_tilemap_xoffs = 0x33;
240 f2_tilemap_yoffs = - 0x04;
241 f2_text_xoffs = -1;
242 f2_tilemap_col_base = 0;
243 failed = (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
244
245 f2_game = FOOTCHMP;
246 return failed;
247 }
248
VIDEO_START(taitof2_deadconx)249 VIDEO_START( taitof2_deadconx )
250 {
251 f2_tilemap_xoffs = 0x1e;
252 f2_tilemap_yoffs = 0x08;
253 f2_text_xoffs = -1;
254 f2_tilemap_col_base = 0;
255 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
256 }
257
VIDEO_START(taitof2_deadconj)258 VIDEO_START( taitof2_deadconj )
259 {
260 f2_tilemap_xoffs = 0x34;
261 f2_tilemap_yoffs = - 0x05;
262 f2_text_xoffs = -1;
263 f2_tilemap_col_base = 0;
264 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
265 }
266
VIDEO_START(taitof2_metalb)267 VIDEO_START( taitof2_metalb )
268 {
269 f2_tilemap_xoffs = 0x32;
270 f2_tilemap_yoffs = - 0x04;
271 f2_text_xoffs = 1; /* not the usual -1 */
272 f2_tilemap_col_base = 256; /* separate palette area for tilemaps */
273 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
274 }
275
VIDEO_START(taitof2_yuyugogo)276 VIDEO_START( taitof2_yuyugogo )
277 {
278 return (taitof2_core_vh_start(1,3,3,0,0,0,0,0,0));
279 }
280
VIDEO_START(taitof2_yesnoj)281 VIDEO_START( taitof2_yesnoj )
282 {
283 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
284 }
285
VIDEO_START(taitof2_dinorex)286 VIDEO_START( taitof2_dinorex )
287 {
288 return (taitof2_core_vh_start(3,3,3,0,0,0,0,0,0));
289 }
290
VIDEO_START(taitof2_dondokod)291 VIDEO_START( taitof2_dondokod ) /* dondokod, cameltry */
292 {
293 f2_pivot_xdisp = -16;
294 f2_pivot_ydisp = 0;
295 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
296 }
297
VIDEO_START(taitof2_pulirula)298 VIDEO_START( taitof2_pulirula )
299 {
300 f2_pivot_xdisp = -10; /* alignment seems correct (see level 2, falling */
301 f2_pivot_ydisp = 16; /* block of ice after armour man) */
302 return (taitof2_core_vh_start(2,3,3,0,0,0,0,0,0));
303 }
304
VIDEO_START(taitof2_driftout)305 VIDEO_START( taitof2_driftout )
306 {
307 f2_pivot_xdisp = -16;
308 f2_pivot_ydisp = 16;
309 return (taitof2_core_vh_start(0,3,3,0,0,0,0,0,0));
310 }
311
312
313 /********************************************************
314 SPRITE READ AND WRITE HANDLERS
315
316 The spritebank buffering is currently not needed.
317
318 If we wanted to buffer sprites by an extra frame, it
319 might be for Footchmp. That seems to be the only game
320 altering spritebanks of sprites while they're on screen.
321 ********************************************************/
322
WRITE16_HANDLER(taitof2_sprite_extension_w)323 WRITE16_HANDLER( taitof2_sprite_extension_w )
324 {
325 /* areas above 0x1000 cleared in some games, but not used */
326
327 if (offset < 0x800)
328 {
329 COMBINE_DATA(&f2_sprite_extension[offset]);
330 }
331 }
332
333
WRITE16_HANDLER(taitof2_spritebank_w)334 WRITE16_HANDLER( taitof2_spritebank_w )
335 {
336 int i=0;
337 int j=0;
338
339 if (offset < 2) return; /* irrelevant zero writes */
340
341 if (offset < 4) /* special bank pairs */
342 {
343 j = (offset & 1) << 1; /* either set pair 0&1 or 2&3 */
344 i = data << 11;
345 spritebank_buffered[j] = i;
346 spritebank_buffered[j+1] = (i + 0x400);
347
348 //logerror("bank %d, set to: %04x\n", j, i);
349 //logerror("bank %d, paired so: %04x\n", j + 1, i + 0x400);
350
351 }
352 else /* last 4 are individual banks */
353 {
354 i = data << 10;
355 spritebank_buffered[offset] = i;
356
357 //logerror("bank %d, new value: %04x\n", offset, i);
358 }
359
360 }
361
READ16_HANDLER(koshien_spritebank_r)362 READ16_HANDLER( koshien_spritebank_r )
363 {
364 return koshien_spritebank;
365 }
366
WRITE16_HANDLER(koshien_spritebank_w)367 WRITE16_HANDLER( koshien_spritebank_w )
368 {
369 koshien_spritebank = data;
370
371 spritebank_buffered[0]=0x0000; /* never changes */
372 spritebank_buffered[1]=0x0400;
373
374 spritebank_buffered[2] = ((data & 0x00f) + 1) * 0x800;
375 spritebank_buffered[4] = (((data & 0x0f0) >> 4) + 1) * 0x800;
376 spritebank_buffered[6] = (((data & 0xf00) >> 8) + 1) * 0x800;
377 spritebank_buffered[3] = spritebank_buffered[2] + 0x400;
378 spritebank_buffered[5] = spritebank_buffered[4] + 0x400;
379 spritebank_buffered[7] = spritebank_buffered[6] + 0x400;
380 }
381
382
383
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int * primasks)384 static void draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int *primasks)
385 {
386 /*
387 Sprite format:
388 0000: ---xxxxxxxxxxxxx tile code (0x0000 - 0x1fff)
389 0002: xxxxxxxx-------- sprite y-zoom level
390 --------xxxxxxxx sprite x-zoom level
391
392 0x00 - non scaled = 100%
393 0x80 - scaled to 50%
394 0xc0 - scaled to 25%
395 0xe0 - scaled to 12.5%
396 0xff - scaled to zero pixels size (off)
397
398 [this zoom scale may not be 100% correct, see Gunfront flame screen]
399
400 0004: ----xxxxxxxxxxxx x-coordinate (-0x800 to 0x07ff)
401 ---x------------ latch extra scroll
402 --x------------- latch master scroll
403 -x-------------- don't use extra scroll compensation
404 x--------------- absolute screen coordinates (ignore all sprite scrolls)
405 xxxx------------ the typical use of the above is therefore
406 1010 = set master scroll
407 0101 = set extra scroll
408 0006: ----xxxxxxxxxxxx y-coordinate (-0x800 to 0x07ff)
409 x--------------- marks special control commands (used in conjunction with 00a)
410 If the special command flag is set:
411 ---------------x related to sprite ram bank
412 ---x------------ unknown (deadconx, maybe others)
413 --x------------- unknown, some games (growl, gunfront) set it to 1 when
414 screen is flipped
415 0008: --------xxxxxxxx color (0x00 - 0xff)
416 -------x-------- flipx
417 ------x--------- flipy
418 -----x---------- if set, use latched color, else use & latch specified one
419 ----x----------- if set, next sprite entry is part of sequence
420 ---x------------ if clear, use latched y coordinate, else use current y
421 --x------------- if set, y += 16
422 -x-------------- if clear, use latched x coordinate, else use current x
423 x--------------- if set, x += 16
424 000a: only valid when the special command bit in 006 is set
425 ---------------x related to sprite ram bank. I think this is the one causing
426 the bank switch, implementing it this way all games seem
427 to properly bank switch except for footchmp which uses the
428 bit in byte 006 instead.
429 ------------x--- unknown; some games toggle it before updating sprite ram.
430 ------xx-------- unknown (finalb)
431 -----x---------- unknown (mjnquest)
432 ---x------------ disable the following sprites until another marker with
433 this bit clear is found
434 --x------------- flip screen
435
436 000b - 000f : unused
437
438 DG comment: the sprite zoom code grafted on from Jarek's TaitoB
439 may mean I have pointlessly duplicated x,y latches in the zoom &
440 non zoom parts.
441
442 */
443 int i,x,y,off,extoffs;
444 int code,color,spritedata,spritecont,flipx,flipy;
445 int xcurrent,ycurrent,big_sprite=0;
446 int y_no=0, x_no=0, xlatch=0, ylatch=0, last_continuation_tile=0; /* for zooms */
447 unsigned int zoomword, zoomx, zoomy, zx=0, zy=0, zoomxlatch=0, zoomylatch=0; /* for zooms */
448 int scroll1x, scroll1y;
449 int scrollx=0, scrolly=0;
450 int curx,cury;
451 int f2_x_offset;
452
453 /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
454 while processing sprite ram and then draw them all at the end */
455 struct tempsprite *sprite_ptr = spritelist;
456
457 /* must remember enable status from last frame because driftout fails to
458 reactivate them from a certain point onwards. */
459 int disabled = sprites_disabled;
460
461 /* must remember master scroll from previous frame because driftout
462 sometimes doesn't set it. */
463 int master_scrollx = sprites_master_scrollx;
464 int master_scrolly = sprites_master_scrolly;
465
466 /* must also remember the sprite bank from previous frame. */
467 int area = sprites_active_area;
468
469 scroll1x = 0;
470 scroll1y = 0;
471 x = y = 0;
472 xcurrent = ycurrent = 0;
473 color = 0;
474
475 f2_x_offset = f2_hide_pixels; /* Get rid of 0-3 unwanted pixels on edge of screen. */
476 if (sprites_flipscreen) f2_x_offset = -f2_flip_hide_pixels; // was -f2_x_offset
477
478 /* safety check to avoid getting stuck in bank 2 for games using only one bank */
479 if (area == 0x8000 &&
480 spriteram_buffered[(0x8000+6)/2] == 0 &&
481 spriteram_buffered[(0x8000+10)/2] == 0)
482 area = 0;
483
484
485 for (off = 0;off < 0x4000;off += 16)
486 {
487 /* sprites_active_area may change during processing */
488 int offs = off + area;
489
490 if (spriteram_buffered[(offs+6)/2] & 0x8000)
491 {
492 disabled = spriteram_buffered[(offs+10)/2] & 0x1000;
493 sprites_flipscreen = spriteram_buffered[(offs+10)/2] & 0x2000;
494
495 /* Get rid of 0-3 unwanted pixels on edge of screen. */
496 f2_x_offset = f2_hide_pixels;
497 if (sprites_flipscreen) f2_x_offset = -f2_flip_hide_pixels; // was -f2_x_offset
498
499 if (f2_game == FOOTCHMP)
500 area = 0x8000 * (spriteram_buffered[(offs+6)/2] & 0x0001);
501 else
502 area = 0x8000 * (spriteram_buffered[(offs+10)/2] & 0x0001);
503 continue;
504 }
505
506 //usrintf_showmessage("%04x",area);
507
508 /* check for extra scroll offset */
509 if ((spriteram_buffered[(offs+4)/2] & 0xf000) == 0xa000)
510 {
511 master_scrollx = spriteram_buffered[(offs+4)/2] & 0xfff;
512 if (master_scrollx >= 0x800) master_scrollx -= 0x1000; /* signed value */
513 master_scrolly = spriteram_buffered[(offs+6)/2] & 0xfff;
514 if (master_scrolly >= 0x800) master_scrolly -= 0x1000; /* signed value */
515 }
516
517 if ((spriteram_buffered[(offs+4)/2] & 0xf000) == 0x5000)
518 {
519 scroll1x = spriteram_buffered[(offs+4)/2] & 0xfff;
520 if (scroll1x >= 0x800) scroll1x -= 0x1000; /* signed value */
521
522 scroll1y = spriteram_buffered[(offs+6)/2] & 0xfff;
523 if (scroll1y >= 0x800) scroll1y -= 0x1000; /* signed value */
524 }
525
526 if (disabled)
527 continue;
528
529 spritedata = spriteram_buffered[(offs+8)/2];
530
531 spritecont = (spritedata & 0xff00) >> 8;
532
533 if ((spritecont & 0x08) != 0) /* sprite continuation flag set */
534 {
535 if (big_sprite == 0) /* are we starting a big sprite ? */
536 {
537 xlatch = spriteram_buffered[(offs+4)/2] & 0xfff;
538 ylatch = spriteram_buffered[(offs+6)/2] & 0xfff;
539 x_no = 0;
540 y_no = 0;
541 zoomword = spriteram_buffered[(offs+2)/2];
542 zoomylatch = (zoomword>>8) & 0xff;
543 zoomxlatch = (zoomword) & 0xff;
544 big_sprite = 1; /* we have started a new big sprite */
545 }
546 }
547 else if (big_sprite)
548 {
549 last_continuation_tile = 1; /* don't clear big_sprite until last tile done */
550 }
551
552
553 if ((spritecont & 0x04) == 0)
554 color = spritedata & 0xff;
555
556
557 // The bigsprite == 0 check fixes "tied-up" little sprites in Thunderfox
558 // which (mostly?) have spritecont = 0x20 when they are not continuations
559 // of anything.
560 if (big_sprite == 0 || (spritecont & 0xf0) == 0)
561 {
562 x = spriteram_buffered[(offs+4)/2];
563
564 // Some absolute x values deduced here are 1 too high (scenes when you get
565 // home run in Koshien, and may also relate to BG layer woods and stuff as you
566 // journey in MjnQuest). You will see they are 1 pixel too far to the right.
567 // Where is this extra pixel offset coming from??
568
569 if (x & 0x8000) /* absolute (koshien) */
570 {
571 scrollx = - f2_x_offset - 0x60;
572 scrolly = 0;
573 }
574 else if (x & 0x4000) /* ignore extra scroll */
575 {
576 scrollx = master_scrollx - f2_x_offset - 0x60;
577 scrolly = master_scrolly;
578 }
579 else /* all scrolls applied */
580 {
581 scrollx = scroll1x + master_scrollx - f2_x_offset - 0x60;
582 scrolly = scroll1y + master_scrolly;
583 }
584 x &= 0xfff;
585 y = spriteram_buffered[(offs+6)/2] & 0xfff;
586
587 xcurrent = x;
588 ycurrent = y;
589 }
590 else
591 {
592 if ((spritecont & 0x10) == 0)
593 y = ycurrent;
594 else if ((spritecont & 0x20) != 0)
595 {
596 y += 16;
597 y_no++; /* keep track of y tile for zooms */
598 }
599 if ((spritecont & 0x40) == 0)
600 x = xcurrent;
601 else if ((spritecont & 0x80) != 0)
602 {
603 x += 16;
604 y_no=0;
605 x_no++; /* keep track of x tile for zooms */
606 }
607 }
608
609 if (big_sprite)
610 {
611 zoomx = zoomxlatch;
612 zoomy = zoomylatch;
613 zx = 0x10; /* default, no zoom: 16 pixels across */
614 zy = 0x10; /* default, no zoom: 16 pixels vertical */
615
616 if (zoomx || zoomy)
617 {
618 /* "Zoom" zx&y is pixel size horizontally and vertically
619 of our sprite chunk. So it is difference in x and y
620 coords of our chunk and diagonally adjoining one. */
621
622 // These calcs caused black lines between flames in Gunfront attract...
623 // x = xlatch + x_no * (0x100 - zoomx) / 16;
624 // y = ylatch + y_no * (0x100 - zoomy) / 16;
625 // zx = xlatch + (x_no+1) * (0x100 - zoomx) / 16 - x;
626 // zy = ylatch + (y_no+1) * (0x100 - zoomy) / 16 - y;
627
628 x = xlatch + (x_no * (0x100 - zoomx)+12) / 16; //ks
629 y = ylatch + (y_no * (0x100 - zoomy)+12) / 16; //ks
630 zx = xlatch + ((x_no+1) * (0x100 - zoomx)+12) / 16 - x; //ks
631 zy = ylatch + ((y_no+1) * (0x100 - zoomy)+12) / 16 - y; //ks
632 }
633 }
634 else
635 {
636 zoomword = spriteram_buffered[(offs+2)/2];
637 zoomy = (zoomword>>8) & 0xff;
638 zoomx = (zoomword) & 0xff;
639 zx = (0x100 - zoomx) / 16;
640 zy = (0x100 - zoomy) / 16;
641 }
642
643 if (last_continuation_tile)
644 {
645 big_sprite=0;
646 last_continuation_tile=0;
647 }
648
649 code = 0;
650 extoffs = offs;
651 /* spriteram[0x4000-7fff] has no corresponding extension area */
652 if (extoffs >= 0x8000) extoffs -= 0x4000;
653
654 if (f2_sprite_type == 0)
655 {
656 code = spriteram_buffered[(offs)/2] & 0x1fff;
657 i = (code & 0x1c00) >> 10;
658 code = spritebank[i] + (code & 0x3ff);
659 }
660
661 if (f2_sprite_type == 1) /* Yuyugogo */
662 {
663 code = spriteram_buffered[(offs)/2] & 0x3ff;
664 i = (f2_sprite_extension[(extoffs >> 4)] & 0x3f ) << 10;
665 code = (i | code);
666 }
667
668 if (f2_sprite_type == 2) /* Pulirula */
669 {
670 code = spriteram_buffered[(offs)/2] & 0xff;
671 i = (f2_sprite_extension[(extoffs >> 4)] & 0xff00 );
672 code = (i | code);
673 }
674
675 if (f2_sprite_type == 3) /* Dinorex and a few quizzes */
676 {
677 code = spriteram_buffered[(offs)/2] & 0xff;
678 i = (f2_sprite_extension[(extoffs >> 4)] & 0xff ) << 8;
679 code = (i | code);
680 }
681
682 if (code == 0) continue;
683
684 flipx = spritecont & 0x01;
685 flipy = spritecont & 0x02;
686
687 curx = (x + scrollx) & 0xfff;
688 if (curx >= 0x800) curx -= 0x1000; /* treat it as signed */
689
690 cury = (y + scrolly) & 0xfff;
691 if (cury >= 0x800) cury -= 0x1000; /* treat it as signed */
692
693 if (sprites_flipscreen)
694 {
695 /* -zx/y is there to fix zoomed sprite coords in screenflip.
696 drawgfxzoom does not know to draw from flip-side of sprites when
697 screen is flipped; so we must correct the coords ourselves. */
698
699 curx = 320 - curx - zx;
700 cury = 256 - cury - zy;
701 flipx = !flipx;
702 flipy = !flipy;
703 }
704
705 {
706 sprite_ptr->code = code;
707 sprite_ptr->color = color;
708 if (Machine->gfx[0]->color_granularity == 64) /* Final Blow is 6-bit deep */
709 sprite_ptr->color /= 4;
710 sprite_ptr->flipx = flipx;
711 sprite_ptr->flipy = flipy;
712 sprite_ptr->x = curx;
713 sprite_ptr->y = cury;
714 sprite_ptr->zoomx = zx << 12;
715 sprite_ptr->zoomy = zy << 12;
716
717 if (primasks)
718 {
719 sprite_ptr->primask = primasks[(color & 0xc0) >> 6];
720
721 sprite_ptr++;
722 }
723 else
724 {
725 drawgfxzoom(bitmap,Machine->gfx[0],
726 sprite_ptr->code,
727 sprite_ptr->color,
728 sprite_ptr->flipx,sprite_ptr->flipy,
729 sprite_ptr->x,sprite_ptr->y,
730 cliprect,TRANSPARENCY_PEN,0,
731 sprite_ptr->zoomx,sprite_ptr->zoomy);
732 }
733 }
734 }
735
736
737 /* this happens only if primsks != NULL */
738 while (sprite_ptr != spritelist)
739 {
740 sprite_ptr--;
741
742 pdrawgfxzoom(bitmap,Machine->gfx[0],
743 sprite_ptr->code,
744 sprite_ptr->color,
745 sprite_ptr->flipx,sprite_ptr->flipy,
746 sprite_ptr->x,sprite_ptr->y,
747 cliprect,TRANSPARENCY_PEN,0,
748 sprite_ptr->zoomx,sprite_ptr->zoomy,
749 sprite_ptr->primask);
750 }
751 }
752
753
754
755
756 static int prepare_sprites;
757
update_spritebanks(void)758 static void update_spritebanks(void)
759 {
760 int i;
761 #if 1
762 for (i = 0; i < 8; i ++)
763 {
764 spritebank[i] = spritebank_buffered[i];
765 }
766 #else
767 /* this makes footchmp blobbing worse! */
768 for (i = 0; i < 8; i ++)
769 {
770 spritebank[i] = spritebank_eof[i];
771 spritebank_eof[i] = spritebank_buffered[i];
772 }
773 #endif
774 }
775
taitof2_handle_sprite_buffering(void)776 static void taitof2_handle_sprite_buffering(void)
777 {
778 if (prepare_sprites) /* no buffering */
779 {
780 memcpy(spriteram_buffered,spriteram16,spriteram_size);
781 prepare_sprites = 0;
782 }
783 }
784
taitof2_update_sprites_active_area(void)785 static void taitof2_update_sprites_active_area(void)
786 {
787 int off;
788
789 update_spritebanks();
790
791 /* if the frame was skipped, we'll have to do the buffering now */
792 taitof2_handle_sprite_buffering();
793
794 /* safety check to avoid getting stuck in bank 2 for games using only one bank */
795 if (sprites_active_area == 0x8000 &&
796 spriteram_buffered[(0x8000+6)/2] == 0 &&
797 spriteram_buffered[(0x8000+10)/2] == 0)
798 sprites_active_area = 0;
799
800 for (off = 0;off < 0x4000;off += 16)
801 {
802 /* sprites_active_area may change during processing */
803 int offs = off + sprites_active_area;
804
805 if (spriteram_buffered[(offs+6)/2] & 0x8000)
806 {
807 sprites_disabled = spriteram_buffered[(offs+10)/2] & 0x1000;
808 if (f2_game == FOOTCHMP)
809 sprites_active_area = 0x8000 * (spriteram_buffered[(offs+6)/2] & 0x0001);
810 else
811 sprites_active_area = 0x8000 * (spriteram_buffered[(offs+10)/2] & 0x0001);
812 continue;
813 }
814
815 /* check for extra scroll offset */
816 if ((spriteram_buffered[(offs+4)/2] & 0xf000) == 0xa000)
817 {
818 sprites_master_scrollx = spriteram_buffered[(offs+4)/2] & 0xfff;
819 if (sprites_master_scrollx >= 0x800)
820 sprites_master_scrollx -= 0x1000; /* signed value */
821
822 sprites_master_scrolly = spriteram_buffered[(offs+6)/2] & 0xfff;
823 if (sprites_master_scrolly >= 0x800)
824 sprites_master_scrolly -= 0x1000; /* signed value */
825 }
826 }
827 }
828
VIDEO_EOF(taitof2_no_buffer)829 VIDEO_EOF( taitof2_no_buffer )
830 {
831 taitof2_update_sprites_active_area();
832
833 prepare_sprites = 1;
834 }
835
VIDEO_EOF(taitof2_full_buffer_delayed)836 VIDEO_EOF( taitof2_full_buffer_delayed )
837 {
838 int i;
839
840 taitof2_update_sprites_active_area();
841
842 prepare_sprites = 0;
843 memcpy(spriteram_buffered,spriteram_delayed,spriteram_size);
844 for (i = 0;i < spriteram_size/2;i++)
845 spriteram_buffered[i] = spriteram16[i];
846 memcpy(spriteram_delayed,spriteram16,spriteram_size);
847 }
848
VIDEO_EOF(taitof2_partial_buffer_delayed)849 VIDEO_EOF( taitof2_partial_buffer_delayed )
850 {
851 int i;
852
853 taitof2_update_sprites_active_area();
854
855 prepare_sprites = 0;
856 memcpy(spriteram_buffered,spriteram_delayed,spriteram_size);
857 for (i = 0;i < spriteram_size/2;i += 4)
858 spriteram_buffered[i] = spriteram16[i];
859 memcpy(spriteram_delayed,spriteram16,spriteram_size);
860 }
861
VIDEO_EOF(taitof2_partial_buffer_delayed_thundfox)862 VIDEO_EOF( taitof2_partial_buffer_delayed_thundfox )
863 {
864 int i;
865
866 taitof2_update_sprites_active_area();
867
868 prepare_sprites = 0;
869 memcpy(spriteram_buffered,spriteram_delayed,spriteram_size);
870 for (i = 0;i < spriteram_size/2;i += 8)
871 {
872 spriteram_buffered[i] = spriteram16[i];
873 spriteram_buffered[i+1] = spriteram16[i+1];
874 spriteram_buffered[i+4] = spriteram16[i+4];
875 }
876 memcpy(spriteram_delayed,spriteram16,spriteram_size);
877 }
878
VIDEO_EOF(taitof2_partial_buffer_delayed_qzchikyu)879 VIDEO_EOF( taitof2_partial_buffer_delayed_qzchikyu )
880 {
881 /* spriteram[2] and [3] are 1 frame behind...
882 probably thundfox_eof_callback would work fine */
883
884 int i;
885
886 taitof2_update_sprites_active_area();
887
888 prepare_sprites = 0;
889 memcpy(spriteram_buffered,spriteram_delayed,spriteram_size);
890 for (i = 0;i < spriteram_size/2;i += 8)
891 {
892 spriteram_buffered[i] = spriteram16[i];
893 spriteram_buffered[i+1] = spriteram16[i+1];
894 spriteram_buffered[i+4] = spriteram16[i+4];
895 spriteram_buffered[i+5] = spriteram16[i+5]; // not needed?
896 spriteram_buffered[i+6] = spriteram16[i+6]; // not needed?
897 spriteram_buffered[i+7] = spriteram16[i+7]; // not needed?
898 }
899 memcpy(spriteram_delayed,spriteram16,spriteram_size);
900 }
901
902
903 /* SSI */
VIDEO_UPDATE(ssi)904 VIDEO_UPDATE( ssi )
905 {
906 taitof2_handle_sprite_buffering();
907
908 /* SSI only uses sprites, the tilemap registers are not even initialized.
909 (they are in Majestic 12, but the tilemaps are not used anyway) */
910 fillbitmap(priority_bitmap,0,cliprect);
911 fillbitmap(bitmap,Machine->pens[0],cliprect);
912 draw_sprites(bitmap,cliprect,NULL);
913 }
914
915
VIDEO_UPDATE(yesnoj)916 VIDEO_UPDATE( yesnoj )
917 {
918 taitof2_handle_sprite_buffering();
919
920 TC0100SCN_tilemap_update();
921
922 fillbitmap(priority_bitmap,0,cliprect);
923 fillbitmap(bitmap,Machine->pens[0],cliprect); /* wrong color? */
924 draw_sprites(bitmap,cliprect,NULL);
925 TC0100SCN_tilemap_draw(bitmap,cliprect,0,TC0100SCN_bottomlayer(0),0,0);
926 TC0100SCN_tilemap_draw(bitmap,cliprect,0,TC0100SCN_bottomlayer(0)^1,0,0);
927 TC0100SCN_tilemap_draw(bitmap,cliprect,0,2,0,0);
928 }
929
930
VIDEO_UPDATE(taitof2)931 VIDEO_UPDATE( taitof2 )
932 {
933 taitof2_handle_sprite_buffering();
934
935 TC0100SCN_tilemap_update();
936
937 fillbitmap(priority_bitmap,0,cliprect);
938 fillbitmap(bitmap,Machine->pens[0],cliprect); /* wrong color? */
939 TC0100SCN_tilemap_draw(bitmap,cliprect,0,TC0100SCN_bottomlayer(0),0,0);
940 TC0100SCN_tilemap_draw(bitmap,cliprect,0,TC0100SCN_bottomlayer(0)^1,0,0);
941 draw_sprites(bitmap,cliprect,NULL);
942 TC0100SCN_tilemap_draw(bitmap,cliprect,0,2,0,0);
943 }
944
945
VIDEO_UPDATE(taitof2_pri)946 VIDEO_UPDATE( taitof2_pri )
947 {
948 int tilepri[3];
949 int spritepri[4];
950 int layer[3];
951
952
953 taitof2_handle_sprite_buffering();
954
955 TC0100SCN_tilemap_update();
956
957 layer[0] = TC0100SCN_bottomlayer(0);
958 layer[1] = layer[0]^1;
959 layer[2] = 2;
960 tilepri[layer[0]] = TC0360PRI_regs[5] & 0x0f;
961 tilepri[layer[1]] = TC0360PRI_regs[5] >> 4;
962 tilepri[layer[2]] = TC0360PRI_regs[4] >> 4;
963
964 spritepri[0] = TC0360PRI_regs[6] & 0x0f;
965 spritepri[1] = TC0360PRI_regs[6] >> 4;
966 spritepri[2] = TC0360PRI_regs[7] & 0x0f;
967 spritepri[3] = TC0360PRI_regs[7] >> 4;
968
969 fillbitmap(priority_bitmap,0,cliprect);
970 fillbitmap(bitmap,Machine->pens[0],cliprect); /* wrong color? */
971
972 TC0100SCN_tilemap_draw(bitmap,cliprect,0,layer[0],0,1);
973 TC0100SCN_tilemap_draw(bitmap,cliprect,0,layer[1],0,2);
974 TC0100SCN_tilemap_draw(bitmap,cliprect,0,layer[2],0,4);
975
976 {
977 int primasks[4] = {0,0,0,0};
978 int i;
979
980 for (i = 0;i < 4;i++)
981 {
982 if (spritepri[i] < tilepri[0]) primasks[i] |= 0xaa;
983 if (spritepri[i] < tilepri[1]) primasks[i] |= 0xcc;
984 if (spritepri[i] < tilepri[2]) primasks[i] |= 0xf0;
985 }
986
987 draw_sprites(bitmap,cliprect,primasks);
988 }
989
990 #if 0
991 {
992 char buf[100];
993 sprintf(buf,"spritebanks: %04x %04x %04x %04x %04x %04x",spritebank[2],
994 spritebank[3],spritebank[4],spritebank[5],spritebank[6],spritebank[7]);
995 usrintf_showmessage(buf);
996 }
997 #endif
998 }
999
1000
1001
draw_roz_layer(struct mame_bitmap * bitmap,const struct rectangle * cliprect)1002 static void draw_roz_layer(struct mame_bitmap *bitmap,const struct rectangle *cliprect)
1003 {
1004 if (has_TC0280GRD())
1005 TC0280GRD_zoom_draw(bitmap,cliprect,f2_pivot_xdisp,f2_pivot_ydisp,8);
1006
1007 if (has_TC0430GRW())
1008 TC0430GRW_zoom_draw(bitmap,cliprect,f2_pivot_xdisp,f2_pivot_ydisp,8);
1009 }
1010
1011
VIDEO_UPDATE(taitof2_pri_roz)1012 VIDEO_UPDATE( taitof2_pri_roz )
1013 {
1014 int tilepri[3];
1015 int spritepri[4];
1016 int rozpri;
1017 int layer[3];
1018 int drawn;
1019 int lastpri;
1020 int roz_base_color = (TC0360PRI_regs[1] & 0x3f) << 2;
1021
1022
1023 taitof2_handle_sprite_buffering();
1024
1025 if (has_TC0280GRD())
1026 TC0280GRD_tilemap_update(roz_base_color);
1027
1028 if (has_TC0430GRW())
1029 TC0430GRW_tilemap_update(roz_base_color);
1030
1031 TC0100SCN_tilemap_update();
1032
1033 layer[0] = TC0100SCN_bottomlayer(0);
1034 layer[1] = layer[0]^1;
1035 layer[2] = 2;
1036 tilepri[layer[0]] = TC0360PRI_regs[5] & 0x0f;
1037 tilepri[layer[1]] = TC0360PRI_regs[5] >> 4;
1038 tilepri[layer[2]] = TC0360PRI_regs[4] >> 4;
1039
1040 spritepri[0] = TC0360PRI_regs[6] & 0x0f;
1041 spritepri[1] = TC0360PRI_regs[6] >> 4;
1042 spritepri[2] = TC0360PRI_regs[7] & 0x0f;
1043 spritepri[3] = TC0360PRI_regs[7] >> 4;
1044
1045 rozpri = (TC0360PRI_regs[1] & 0xc0) >> 6;
1046 rozpri = (TC0360PRI_regs[8 + rozpri/2] >> 4*(rozpri & 1)) & 0x0f;
1047
1048 fillbitmap(priority_bitmap,0,cliprect);
1049 fillbitmap(bitmap,Machine->pens[0],cliprect); /* wrong color? */
1050
1051 drawn = 0;
1052 lastpri = 0;
1053 while (drawn < 3)
1054 {
1055 if (rozpri > lastpri && rozpri <= tilepri[drawn])
1056 {
1057 draw_roz_layer(bitmap,cliprect);
1058 lastpri = rozpri;
1059 }
1060 TC0100SCN_tilemap_draw(bitmap,cliprect,0,layer[drawn],0,1<<drawn);
1061 lastpri = tilepri[drawn];
1062 drawn++;
1063 }
1064 if (rozpri > lastpri)
1065 draw_roz_layer(bitmap,cliprect);
1066
1067 {
1068 int primasks[4] = {0,0,0,0};
1069 int i;
1070
1071 for (i = 0;i < 4;i++)
1072 {
1073 if (spritepri[i] < tilepri[0]) primasks[i] |= 0xaaaa;
1074 if (spritepri[i] < tilepri[1]) primasks[i] |= 0xcccc;
1075 if (spritepri[i] < tilepri[2]) primasks[i] |= 0xf0f0;
1076 if (spritepri[i] < rozpri) primasks[i] |= 0xff00;
1077 }
1078
1079 draw_sprites(bitmap,cliprect,primasks);
1080 }
1081 }
1082
1083
1084
1085 /* Thunderfox */
VIDEO_UPDATE(thundfox)1086 VIDEO_UPDATE( thundfox )
1087 {
1088 int tilepri[2][3];
1089 int spritepri[4];
1090 int layer[2][3];
1091 int drawn[2];
1092
1093
1094 taitof2_handle_sprite_buffering();
1095
1096 TC0100SCN_tilemap_update();
1097
1098 layer[0][0] = TC0100SCN_bottomlayer(0);
1099 layer[0][1] = layer[0][0]^1;
1100 layer[0][2] = 2;
1101 tilepri[0][layer[0][0]] = TC0360PRI_regs[5] & 0x0f;
1102 tilepri[0][layer[0][1]] = TC0360PRI_regs[5] >> 4;
1103 tilepri[0][layer[0][2]] = TC0360PRI_regs[4] >> 4;
1104
1105 layer[1][0] = TC0100SCN_bottomlayer(1);
1106 layer[1][1] = layer[1][0]^1;
1107 layer[1][2] = 2;
1108 tilepri[1][layer[1][0]] = TC0360PRI_regs[9] & 0x0f;
1109 tilepri[1][layer[1][1]] = TC0360PRI_regs[9] >> 4;
1110 tilepri[1][layer[1][2]] = TC0360PRI_regs[8] >> 4;
1111
1112 spritepri[0] = TC0360PRI_regs[6] & 0x0f;
1113 spritepri[1] = TC0360PRI_regs[6] >> 4;
1114 spritepri[2] = TC0360PRI_regs[7] & 0x0f;
1115 spritepri[3] = TC0360PRI_regs[7] >> 4;
1116
1117
1118 fillbitmap(priority_bitmap,0,cliprect);
1119 fillbitmap(bitmap,Machine->pens[0],cliprect); /* wrong color? */
1120
1121
1122 /*
1123 TODO: This isn't the correct way to handle the priority. At the moment of
1124 writing, pdrawgfx() doesn't support 6 layers, so I have to cheat, assuming
1125 that the two FG layers are always on top of sprites.
1126 */
1127
1128 drawn[0] = drawn[1] = 0;
1129 while (drawn[0] < 2 && drawn[1] < 2)
1130 {
1131 int pick;
1132
1133 if (tilepri[0][drawn[0]] < tilepri[1][drawn[1]])
1134 pick = 0;
1135 else pick = 1;
1136
1137 TC0100SCN_tilemap_draw(bitmap,cliprect,pick,layer[pick][drawn[pick]],0,1<<(drawn[pick]+2*pick));
1138 drawn[pick]++;
1139 }
1140 while (drawn[0] < 2)
1141 {
1142 TC0100SCN_tilemap_draw(bitmap,cliprect,0,layer[0][drawn[0]],0,1<<drawn[0]);
1143 drawn[0]++;
1144 }
1145 while (drawn[1] < 2)
1146 {
1147 TC0100SCN_tilemap_draw(bitmap,cliprect,1,layer[1][drawn[1]],0,1<<(drawn[1]+2));
1148 drawn[1]++;
1149 }
1150
1151 {
1152 int primasks[4] = {0,0,0,0};
1153 int i;
1154
1155 for (i = 0;i < 4;i++)
1156 {
1157 if (spritepri[i] < tilepri[0][0]) primasks[i] |= 0xaaaa;
1158 if (spritepri[i] < tilepri[0][1]) primasks[i] |= 0xcccc;
1159 if (spritepri[i] < tilepri[1][0]) primasks[i] |= 0xf0f0;
1160 if (spritepri[i] < tilepri[1][1]) primasks[i] |= 0xff00;
1161 }
1162
1163 draw_sprites(bitmap,cliprect,primasks);
1164 }
1165
1166
1167 /*
1168 TODO: This isn't the correct way to handle the priority. At the moment of
1169 writing, pdrawgfx() doesn't support 6 layers, so I have to cheat, assuming
1170 that the two FG layers are always on top of sprites.
1171 */
1172
1173 if (tilepri[0][2] < tilepri[1][2])
1174 {
1175 TC0100SCN_tilemap_draw(bitmap,cliprect,0,layer[0][2],0,0);
1176 TC0100SCN_tilemap_draw(bitmap,cliprect,1,layer[1][2],0,0);
1177 }
1178 else
1179 {
1180 TC0100SCN_tilemap_draw(bitmap,cliprect,1,layer[1][2],0,0);
1181 TC0100SCN_tilemap_draw(bitmap,cliprect,0,layer[0][2],0,0);
1182 }
1183 }
1184
1185
1186
1187 /*********************************************************************
1188
1189 Deadconx and Footchmp use in the PRI chip
1190 -----------------------------------------
1191
1192 +4 xxxx0000 BG0
1193 0000xxxx BG3
1194 +6 xxxx0000 BG2
1195 0000xxxx BG1
1196
1197 Deadconx = 0x7db9 (bg0-3) 0x8eca (sprites)
1198 So it has bg0 [back] / s / bg1 / s / bg2 / s / bg3 / s
1199
1200 Footchmp = 0x8db9 (bg0-3) 0xe5ac (sprites)
1201 So it has s / bg0 [grass] / bg1 [crowd] / s / bg2 [goal] / s / bg3 [messages] / s [scan dots]
1202
1203 Metalb uses in the PRI chip
1204 ---------------------------
1205
1206 +4 xxxx0000 BG1
1207 0000xxxx BG0
1208 +6 xxxx0000 BG3
1209 0000xxxx BG2
1210
1211 and it changes these (and the sprite pri settings) a lot.
1212
1213 ********************************************************************/
1214
VIDEO_UPDATE(metalb)1215 VIDEO_UPDATE( metalb )
1216 {
1217 UINT8 layer[5];
1218 UINT8 tilepri[5];
1219 UINT8 spritepri[4];
1220 UINT16 priority;
1221
1222 taitof2_handle_sprite_buffering();
1223
1224 TC0480SCP_tilemap_update();
1225
1226 priority = TC0480SCP_get_bg_priority();
1227
1228 layer[0] = (priority &0xf000) >> 12; /* tells us which bg layer is bottom */
1229 layer[1] = (priority &0x0f00) >> 8;
1230 layer[2] = (priority &0x00f0) >> 4;
1231 layer[3] = (priority &0x000f) >> 0; /* tells us which is top */
1232 layer[4] = 4; /* text layer always over bg layers */
1233
1234 tilepri[0] = TC0360PRI_regs[4] & 0x0f; /* bg0 */
1235 tilepri[1] = TC0360PRI_regs[4] >> 4; /* bg1 */
1236 tilepri[2] = TC0360PRI_regs[5] & 0x0f; /* bg2 */
1237 tilepri[3] = TC0360PRI_regs[5] >> 4; /* bg3 */
1238
1239 /* we actually assume text layer is on top of everything anyway, but FWIW... */
1240 tilepri[layer[4]] = TC0360PRI_regs[7] & 0x0f; /* fg (text layer) */
1241
1242 spritepri[0] = TC0360PRI_regs[6] & 0x0f;
1243 spritepri[1] = TC0360PRI_regs[6] >> 4;
1244 spritepri[2] = TC0360PRI_regs[7] & 0x0f;
1245 spritepri[3] = TC0360PRI_regs[7] >> 4;
1246
1247 fillbitmap(priority_bitmap,0,cliprect);
1248 fillbitmap(bitmap,Machine->pens[0],cliprect);
1249
1250 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[0],0,1);
1251 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[1],0,2);
1252 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[2],0,4);
1253 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[3],0,8);
1254
1255 {
1256 int primasks[4] = {0,0,0,0};
1257 int i;
1258
1259 for (i = 0;i < 4;i++)
1260 {
1261 if (spritepri[i] < tilepri[(layer[0])]) primasks[i] |= 0xaaaa;
1262 if (spritepri[i] < tilepri[(layer[1])]) primasks[i] |= 0xcccc;
1263 if (spritepri[i] < tilepri[(layer[2])]) primasks[i] |= 0xf0f0;
1264 if (spritepri[i] < tilepri[(layer[3])]) primasks[i] |= 0xff00;
1265 }
1266
1267 draw_sprites(bitmap,cliprect,primasks);
1268 }
1269
1270 /*
1271 TODO: This isn't the correct way to handle the priority. At the moment of
1272 writing, pdrawgfx() doesn't support 5 layers, so I have to cheat, assuming
1273 that the FG layer is always on top of sprites.
1274 */
1275
1276 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[4],0,0);
1277 }
1278
1279
1280 /* Deadconx, Footchmp */
VIDEO_UPDATE(deadconx)1281 VIDEO_UPDATE( deadconx )
1282 {
1283 UINT8 layer[5];
1284 UINT8 tilepri[5];
1285 UINT8 spritepri[4];
1286 UINT16 priority;
1287
1288 taitof2_handle_sprite_buffering();
1289
1290 TC0480SCP_tilemap_update();
1291
1292 priority = TC0480SCP_get_bg_priority();
1293
1294 layer[0] = (priority &0xf000) >> 12; /* tells us which bg layer is bottom */
1295 layer[1] = (priority &0x0f00) >> 8;
1296 layer[2] = (priority &0x00f0) >> 4;
1297 layer[3] = (priority &0x000f) >> 0; /* tells us which is top */
1298 layer[4] = 4; /* text layer always over bg layers */
1299
1300 tilepri[0] = TC0360PRI_regs[4] >> 4; /* bg0 */
1301 tilepri[1] = TC0360PRI_regs[5] & 0x0f; /* bg1 */
1302 tilepri[2] = TC0360PRI_regs[5] >> 4; /* bg2 */
1303 tilepri[3] = TC0360PRI_regs[4] & 0x0f; /* bg3 */
1304
1305 /* we actually assume text layer is on top of everything anyway, but FWIW... */
1306 tilepri[layer[4]] = TC0360PRI_regs[7] >> 4; /* fg (text layer) */
1307
1308 spritepri[0] = TC0360PRI_regs[6] & 0x0f;
1309 spritepri[1] = TC0360PRI_regs[6] >> 4;
1310 spritepri[2] = TC0360PRI_regs[7] & 0x0f;
1311 spritepri[3] = TC0360PRI_regs[7] >> 4;
1312
1313 fillbitmap(priority_bitmap,0,cliprect);
1314 fillbitmap(bitmap,Machine->pens[0],cliprect);
1315
1316 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[0],0,1);
1317 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[1],0,2);
1318 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[2],0,4);
1319 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[3],0,8);
1320
1321 {
1322 int primasks[4] = {0,0,0,0};
1323 int i;
1324
1325 for (i = 0;i < 4;i++)
1326 {
1327 if (spritepri[i] < tilepri[(layer[0])]) primasks[i] |= 0xaaaa;
1328 if (spritepri[i] < tilepri[(layer[1])]) primasks[i] |= 0xcccc;
1329 if (spritepri[i] < tilepri[(layer[2])]) primasks[i] |= 0xf0f0;
1330 if (spritepri[i] < tilepri[(layer[3])]) primasks[i] |= 0xff00;
1331 }
1332
1333 draw_sprites(bitmap,cliprect,primasks);
1334 }
1335
1336 /*
1337 TODO: This isn't the correct way to handle the priority. At the moment of
1338 writing, pdrawgfx() doesn't support 5 layers, so I have to cheat, assuming
1339 that the FG layer is always on top of sprites.
1340 */
1341
1342 TC0480SCP_tilemap_draw(bitmap,cliprect,layer[4],0,0);
1343 }
1344