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