1 // license:BSD-3-Clause
2 // copyright-holders:David Graves
3 #include "emu.h"
4 #include "includes/wgp.h"
5 #include "screen.h"
6 
7 
8 // reference : https://www.youtube.com/watch?v=Sb3I3eQQvcU
9 /*******************************************************************/
10 
11 template<unsigned Offset>
TILE_GET_INFO_MEMBER(wgp_state::get_piv_tile_info)12 TILE_GET_INFO_MEMBER(wgp_state::get_piv_tile_info)
13 {
14 	const u16 tilenum = m_pivram[tile_index + Offset];    /* 3 blocks of $2000 */
15 	const u16 attr = m_pivram[tile_index + Offset + 0x8000];  /* 3 blocks of $2000 */
16 
17 	tileinfo.set(1,
18 			tilenum & 0x3fff,
19 			(attr & 0x3f),  /* attr & 0x1 ?? */
20 			TILE_FLIPYX((attr & 0xc0) >> 6));
21 }
22 
23 
core_vh_start(int piv_xoffs,int piv_yoffs)24 void wgp_state::core_vh_start(int piv_xoffs, int piv_yoffs)
25 {
26 	m_piv_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wgp_state::get_piv_tile_info<0x0000>)), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
27 	m_piv_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wgp_state::get_piv_tile_info<0x1000>)), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
28 	m_piv_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wgp_state::get_piv_tile_info<0x2000>)), TILEMAP_SCAN_ROWS, 16, 16, 64, 64);
29 
30 	m_piv_xoffs = piv_xoffs;
31 	m_piv_yoffs = piv_yoffs;
32 
33 	m_piv_tilemap[0]->set_transparent_pen(0);
34 	m_piv_tilemap[1]->set_transparent_pen(0);
35 	m_piv_tilemap[2]->set_transparent_pen(0);
36 
37 	/* flipscreen n/a */
38 	m_piv_tilemap[0]->set_scrolldx(-piv_xoffs, 0);
39 	m_piv_tilemap[1]->set_scrolldx(-piv_xoffs, 0);
40 	m_piv_tilemap[2]->set_scrolldx(-piv_xoffs, 0);
41 	m_piv_tilemap[0]->set_scrolldy(-piv_yoffs, 0);
42 	m_piv_tilemap[1]->set_scrolldy(-piv_yoffs, 0);
43 	m_piv_tilemap[2]->set_scrolldy(-piv_yoffs, 0);
44 
45 	/* We don't need tilemap_set_scroll_rows, as the custom draw routine applies rowscroll manually */
46 	m_tc0100scn->set_colbanks(0x80, 0xc0, 0x40);
47 
48 	save_item(NAME(m_piv_ctrl_reg));
49 	save_item(NAME(m_rotate_ctrl));
50 	save_item(NAME(m_piv_zoom));
51 	save_item(NAME(m_piv_scrollx));
52 	save_item(NAME(m_piv_scrolly));
53 }
54 
video_start()55 void wgp_state::video_start()
56 {
57 	core_vh_start(32, 16);
58 }
59 
VIDEO_START_MEMBER(wgp_state,wgp2)60 VIDEO_START_MEMBER(wgp_state,wgp2)
61 {
62 	core_vh_start(32, 16);
63 }
64 
65 
66 /******************************************************************
67                  PIV TILEMAP READ AND WRITE HANDLERS
68 
69 Piv Tilemaps
70 ------------
71 
72 (The unused gaps look as though Taito considered making their
73 custom chip capable of four rather than three tilemaps.)
74 
75 500000 - 501fff : unknown/unused
76 502000 - 507fff : piv tilemaps 0-2 [tile numbers only]
77 
78 508000 - 50ffff : this area relates to pixel rows in each piv tilemap.
79     Includes rowscroll for the piv tilemaps, 1-2 of which act as a
80     simple road. To curve, it has rowscroll applied to each row.
81 
82 508000 - 5087ff unknown/unused
83 
84 508800  piv0 row color bank (low byte = row horizontal zoom)
85 509000  piv1 row color bank (low byte = row horizontal zoom)
86 509800  piv2 row color bank (low byte = row horizontal zoom)
87 
88     Usual low byte is 0x7f, the default row horizontal zoom.
89 
90     The high byte is the color offset per pixel row. Controlling
91     color bank per scanline is rare in Taito games. Top Speed may
92     have a similar system to make its road 'move'.
93 
94     In-game the high bytes are set to various values (seen 0 - 0x2b).
95 
96 50a000  piv0 rowscroll [sky]  (not used, but the code supports this)
97 50c000  piv1 rowscroll [road] (values 0xfd00 - 0x400)
98 50e000  piv2 rowscroll [road or scenery] (values 0xfd00 - 0x403)
99 
100     [It seems strange that unnecessarily large space allocations were
101     made for rowscroll. Perhaps the raster color/zoom effects were an
102     afterthought, and 508000-9fff was originally slated as rowscroll
103     for 'missing' 4th piv layer. Certainly the layout is illogical.]
104 
105 510000 - 511fff : unknown/unused
106 512000 - 517fff : piv tilemaps 0-2 [just tile colors ??]
107 
108 *******************************************************************/
109 
pivram_word_w(offs_t offset,u16 data,u16 mem_mask)110 void wgp_state::pivram_word_w(offs_t offset, u16 data, u16 mem_mask)
111 {
112 	COMBINE_DATA(&m_pivram[offset]);
113 
114 	if (offset < 0x3000)
115 	{
116 		m_piv_tilemap[(offset / 0x1000)]->mark_tile_dirty((offset % 0x1000));
117 	}
118 	else if ((offset >= 0x3400) && (offset < 0x4000))
119 	{
120 		/* do nothing, custom draw routine takes care of raster effects */
121 	}
122 	else if ((offset >= 0x8000) && (offset < 0xb000))
123 	{
124 		m_piv_tilemap[((offset - 0x8000)/ 0x1000)]->mark_tile_dirty((offset % 0x1000));
125 	}
126 }
127 
piv_ctrl_word_w(offs_t offset,u16 data,u16 mem_mask)128 void wgp_state::piv_ctrl_word_w(offs_t offset, u16 data, u16 mem_mask)
129 {
130 	u16 a, b;
131 
132 	COMBINE_DATA(&m_piv_ctrlram[offset]);
133 	data = m_piv_ctrlram[offset];
134 
135 	switch (offset)
136 	{
137 		case 0x00:
138 			a = -data;
139 			b = (a & 0xffe0) >> 1;  /* kill bit 4 */
140 			m_piv_scrollx[0] = (a & 0xf) | b;
141 			break;
142 
143 		case 0x01:
144 			a = -data;
145 			b = (a & 0xffe0) >> 1;
146 			m_piv_scrollx[1] = (a & 0xf) | b;
147 			break;
148 
149 		case 0x02:
150 			a = -data;
151 			b = (a & 0xffe0) >> 1;
152 			m_piv_scrollx[2] = (a & 0xf) | b;
153 			break;
154 
155 		case 0x03:
156 			m_piv_scrolly[0] = data;
157 			break;
158 
159 		case 0x04:
160 			m_piv_scrolly[1] = data;
161 			break;
162 
163 		case 0x05:
164 			m_piv_scrolly[2] = data;
165 			break;
166 
167 		case 0x06:
168 			/* Overall control reg (?)
169 			   0x39  %00111001   normal
170 			   0x2d  %00101101   piv2 layer goes under piv1
171 			         seen on Wgp stages 4,5,7 in which piv 2 used
172 			         for cloud or scenery wandering up screen */
173 
174 			m_piv_ctrl_reg = data;
175 			break;
176 
177 		case 0x08:
178 			/* piv 0 y zoom (0x7f = normal, not seen others) */
179 			m_piv_zoom[0] = data;
180 			break;
181 
182 		case 0x09:
183 			/* piv 1 y zoom (0x7f = normal, values 0 &
184 			      0xff7f-ffbc in Wgp2) */
185 			m_piv_zoom[1] = data;
186 			break;
187 
188 		case 0x0a:
189 			/* piv 2 y zoom (0x7f = normal, values 0 &
190 			      0xff7f-ffbc in Wgp2, 0-0x98 in Wgp round 4/5) */
191 			m_piv_zoom[2] = data;
192 			break;
193 	}
194 }
195 
196 
197 
198 
199 /****************************************************************
200                      SPRITE DRAW ROUTINES
201 
202 TODO
203 ====
204 
205 Implement rotation/zoom properly.
206 
207 Sprite/piv priority: sprites always over?
208 
209 Wgp round 1 had some junky brown mud bank sprites in-game.
210 They are indexed 0xe720-e790. 0x2720*4 => +0x9c80-9e80 in
211 the spritemap area. They should be 2x2 not 4x4 tiles. We
212 kludge this. Round 2 +0x9d40-9f40 contains the 2x2 sprites.
213 What REALLY controls number of tiles in a sprite?
214 
215 Sprite colors: dust after crash in Wgp2 is odd; some
216 black/grey barrels on late Wgp circuit also look strange -
217 possibly the same wrong color.
218 
219 
220 Memory Map
221 ----------
222 
223 400000 - 40bfff : Sprite tile mapping area
224 
225     Tile numbers (0-0x3fff) alternate with word containing tile
226     color/unknown bits. I'm _not_ 100% sure that only Wgp2 uses
227     the unknown bits.
228 
229     xxxxxxxx x.......  unused ??
230     ........ .x......  unknown (Wgp2 only: Taito tyre bridge on default course)
231     ........ ..x.....  unknown (Wgp2 only)
232     ........ ...x....  unknown (Wgp2 only: Direction signs just before hill # 1)
233     ........ ....cccc  color (0-15)
234 
235     Tile map for each standard big sprite is 64 bytes (16 tiles).
236     (standard big sprite comprises 4x4 16x16 tiles)
237 
238     Tile map for each small sprite only uses 16 of the 64 bytes.
239       The remaining 48 bytes are garbage and should be ignored.
240     (small sprite comprises 2x2 16x16 tiles)
241 
242 40c000 - 40dbff : Sprite Table
243 
244     Every 16 bytes contains one sprite entry. First entry is
245     ignored [as 0 in active sprites list means no sprite].
246 
247     (0x1c0 [no.of entries] * 0x40 [bytes for big sprite] = 0x6fff
248     of sprite tile mapping area can be addressed at any one time.)
249 
250     Sprite entry     (preliminary)
251     ------------
252 
253     +0x00  x pos (signed)
254     +0x02  y pos (signed)
255     +0x04  index to tile mapping area [2 msbs always set]
256 
257            (400000 + (index & 0x3fff) << 2) points to relevant part of
258            sprite tile mapping area. Index >0x2fff would be invalid.
259 
260     +0x06  zoom size (pixels) [typical range 0x1-5f, 0x3f = standard]
261            Looked up from a logarithm table in the data rom indexed
262            by the z coordinate. Max size prog allows before it blanks
263            the sprite is 0x140.
264 
265     +0x08  incxx ?? (usually stuck at 0xf800)
266     +0x0a  incyy ?? (usually stuck at 0xf800)
267 
268     +0x0c  z coordinate i.e. how far away the sprite is from you
269            going into the screen. Max distance prog allows before it
270            blanks the sprite is 0x3fff. 0x1400 is about the farthest
271            away that the code creates sprites. 0x400 = standard
272            distance corresponding to 0x3f zoom.  <0x400 = close to
273 
274     +0x0e  non-zero only during rotation.
275 
276     NB: +0x0c and +0x0e are paired. Equivalent of incyx and incxy ??
277 
278     (No longer used entries typically have 0xfff6 in +0x06 and +0x08.)
279 
280     Only 2 rotation examples (i) at 0x40c000 when Taito
281     logo displayed (Wgp only). (ii) stage 5 (rain).
282     Other in-game sprites are simply using +0x06 and +0x0c,
283 
284     So the sprite rotation in Wgp screenshots must be a *blanket*
285     rotate effect, identical to the one applied to piv layers.
286     This explains why sprite/piv positions are basically okay
287     despite failure to implement rotation.
288 
289 40dc00 - 40dfff: Active Sprites list
290 
291     Each word is a sprite number, 0x0 through 0x1bf. If !=0
292     a word makes active the 0x10 bytes of sprite data at
293     (40c000 + sprite_num * 0x10). (Wgp2 fills this in reverse).
294 
295 40fff0: Unknown (sprite control word?)
296 
297     Wgp alternates 0x8000 and 0. Wgp2 only pokes 0.
298     Could this be some frame buffer control that would help to
299     reduce the sprite timing glitches in Wgp?
300 
301 ****************************************************************/
302 
303 /* Sprite tilemapping area doesn't have a straightforward
304    structure for each big sprite: the hardware is probably
305    constructing each 4x4 sprite from 4 2x2 sprites... */
306 
307 static const u8 xlookup[16] =
308 	{ 0, 1, 0, 1,
309 		2, 3, 2, 3,
310 		0, 1, 0, 1,
311 		2, 3, 2, 3 };
312 
313 static const u8 ylookup[16] =
314 	{ 0, 0, 1, 1,
315 		0, 0, 1, 1,
316 		2, 2, 3, 3,
317 		2, 2, 3, 3 };
318 
draw_sprites(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,int y_offs)319 void wgp_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int y_offs)
320 {
321 	int i, j, k;
322 //  u16 rotate = 0;
323 	const u32 tile_mask = (m_gfxdecode->gfx(0)->elements()) - 1;
324 	static const u32 primasks[2] = {0x0, 0xfffc};   /* fff0 => under rhs of road only */
325 
326 	for (int offs = 0x1ff; offs >= 0; offs--)
327 	{
328 		const int code = (m_spriteram[0xe00 + offs]);
329 
330 		if (code)   /* do we have an active sprite ? */
331 		{
332 			i = (code << 3) & 0xfff;    /* yes, so we look up its sprite entry */
333 
334 			int x = m_spriteram[i];
335 			int y = m_spriteram[i + 1];
336 			const int bigsprite = m_spriteram[i + 2] & 0x3fff;
337 
338 			/* The last five words [i + 3 through 7] must be zoom/rotation
339 			   control: for time being we kludge zoom using 1 word.
340 			   Timing problems are causing many glitches. */
341 
342 			if ((m_spriteram[i + 4] == 0xfff6) && (m_spriteram[i + 5] == 0))
343 				continue;
344 
345 //          if (((m_spriteram[i + 4] != 0xf800) && (m_spriteram[i + 4] != 0xfff6))
346 //              || ((m_spriteram[i + 5] != 0xf800) && (m_spriteram[i + 5] != 0))
347 //              || m_spriteram[i + 7] != 0)
348 //              rotate = i << 1;
349 
350 			/***** Begin zoom kludge ******/
351 
352 			const int zoomx = (m_spriteram[i + 3] & 0x1ff) + 1;
353 			const int zoomy = (m_spriteram[i + 3] & 0x1ff) + 1;
354 
355 			y -= 4;
356 			// distant sprites were some 16 pixels too far down //
357 			y -= ((0x40 - zoomy)/4);
358 
359 			/****** end zoom kludge *******/
360 
361 			/* Treat coords as signed */
362 			if (x & 0x8000)  x -= 0x10000;
363 			if (y & 0x8000)  y -= 0x10000;
364 
365 			const int map_index = bigsprite << 1; /* now we access sprite tilemap */
366 
367 			/* don't know what selects 2x2 sprites: we use a nasty kludge which seems to work */
368 
369 			i = m_spritemap[map_index + 0xa];
370 			j = m_spritemap[map_index + 0xc];
371 			const bool small_sprite = ((i > 0) & (i <= 8) & (j > 0) & (j <= 8));
372 
373 			if (small_sprite)
374 			{
375 				for (i = 0; i < 4; i++)
376 				{
377 					const u32 tile = m_spritemap[(map_index + (i << 1))] & tile_mask;
378 					const u32 col  = m_spritemap[(map_index + (i << 1) + 1)] & 0xf;
379 
380 					/* not known what controls priority */
381 					const int priority = (m_spritemap[(map_index + (i << 1) + 1)] & 0x70) >> 4;
382 
383 					int flipx = 0;  // no flip xy?
384 					int flipy = 0;
385 
386 					k = xlookup[i]; // assumes no xflip
387 					j = ylookup[i]; // assumes no yflip
388 
389 					const int curx = x + ((k * zoomx) / 2);
390 					const int cury = y + ((j * zoomy) / 2);
391 
392 					const int zx = x + (((k + 1) * zoomx) / 2) - curx;
393 					const int zy = y + (((j + 1) * zoomy) / 2) - cury;
394 
395 					m_gfxdecode->gfx(0)->prio_zoom_transpen(bitmap,cliprect,
396 							tile,
397 							col,
398 							flipx, flipy,
399 							curx,cury,
400 							zx << 12, zy << 12,
401 							screen.priority(),primasks[((priority >> 1) &1)],0);  /* maybe >> 2 or 0...? */
402 				}
403 			}
404 			else
405 			{
406 				for (i = 0; i < 16; i++)
407 				{
408 					const u32 tile = m_spritemap[(map_index + (i << 1))] & tile_mask;
409 					const u32 col  = m_spritemap[(map_index + (i << 1) + 1)] & 0xf;
410 
411 					/* not known what controls priority */
412 					const int priority = (m_spritemap[(map_index + (i << 1) + 1)] & 0x70) >> 4;
413 
414 					int flipx = 0;  // no flip xy?
415 					int flipy = 0;
416 
417 					k = xlookup[i]; // assumes no xflip
418 					j = ylookup[i]; // assumes no yflip
419 
420 					const int curx = x + ((k * zoomx) / 4);
421 					const int cury = y + ((j * zoomy) / 4);
422 
423 					const int zx = x + (((k + 1) * zoomx) / 4) - curx;
424 					const int zy = y + (((j + 1) * zoomy) / 4) - cury;
425 
426 					m_gfxdecode->gfx(0)->prio_zoom_transpen(bitmap,cliprect,
427 							tile,
428 							col,
429 							flipx, flipy,
430 							curx,cury,
431 							zx << 12, zy << 12,
432 							screen.priority(),primasks[((priority >> 1) &1)],0);  /* maybe >> 2 or 0...? */
433 				}
434 			}
435 		}
436 
437 	}
438 #if 0
439 	if (rotate)
440 	{
441 		char buf[80];
442 		sprintf(buf, "sprite rotate offs %04x ?", rotate);
443 		popmessage(buf);
444 	}
445 #endif
446 }
447 
448 
449 /*********************************************************
450                        CUSTOM DRAW
451 *********************************************************/
452 
bryan2_drawscanline(bitmap_ind16 & bitmap,int x,int y,int length,const u16 * src,bool transparent,u32 orient,bitmap_ind8 & priority,u8 pri,u8 primask=0xff)453 static inline void bryan2_drawscanline(bitmap_ind16 &bitmap, int x, int y, int length,
454 		const u16 *src, bool transparent, u32 orient, bitmap_ind8 &priority, u8 pri, u8 primask = 0xff)
455 {
456 	u16 *dsti = &bitmap.pix(y, x);
457 	u8 *dstp = &priority.pix(y, x);
458 
459 	if (transparent)
460 	{
461 		while (length--)
462 		{
463 			const u32 spixel = *src++;
464 			if (spixel < 0x7fff)
465 			{
466 				*dsti = spixel;
467 				*dstp = (*dstp & primask) | pri;
468 			}
469 			dsti++;
470 			dstp++;
471 		}
472 	}
473 	else  /* Not transparent case */
474 	{
475 		while (length--)
476 		{
477 			*dsti++ = *src++;
478 			*dstp = (*dstp & primask) | pri;
479 			dstp++;
480 		}
481 	}
482 }
483 
484 
485 
piv_layer_draw(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect,int layer,int flags,u32 priority)486 void wgp_state::piv_layer_draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, u32 priority)
487 {
488 	bitmap_ind16 &srcbitmap = m_piv_tilemap[layer]->pixmap();
489 	bitmap_ind8 &flagsbitmap = m_piv_tilemap[layer]->flagsmap();
490 
491 	int y_index;
492 
493 	/* I have a fairly strong feeling these should be u32's, x_index is
494 	   falling through from max +ve to max -ve quite a lot in this routine */
495 	int sx;
496 
497 	u16 scanline[512];
498 	int flipscreen = 0; /* n/a */
499 
500 	const int screen_width = cliprect.width();
501 	const int min_y = cliprect.min_y;
502 	const int max_y = cliprect.max_y;
503 
504 	const int width_mask = 0x3ff;
505 
506 	const u32 zoomx = 0x10000;    /* No overall X zoom, unlike TC0480SCP */
507 
508 	/* Y-axis zoom offers expansion/compression: 0x7f = no zoom, 0xff = max ???
509 	   In WGP see:  stage 4 (big spectator stand)
510 	                stage 5 (cloud layer)
511 	                stage 7 (two bits of background scenery)
512 	                stage 8 (unknown - surely something should be appearing here...)
513 	   In WGP2 see: road at big hill (default course) */
514 
515 	/* This calculation may be wrong, the y_index one too */
516 	const u32 zoomy = 0x10000 - (((m_piv_ctrlram[0x08 + layer] & 0xff) - 0x7f) * 512);
517 
518 	if (!flipscreen)
519 	{
520 		sx = ((m_piv_scrollx[layer]) << 16);
521 		sx += (m_piv_xoffs) * zoomx;     /* may be imperfect */
522 
523 		y_index = (m_piv_scrolly[layer] << 16);
524 		y_index += (m_piv_yoffs + min_y) * zoomy;        /* may be imperfect */
525 	}
526 	else    /* piv tiles flipscreen n/a */
527 	{
528 		sx = 0;
529 		y_index = 0;
530 	}
531 
532 	for (int y = min_y; y <= max_y; y++)
533 	{
534 		int a;
535 
536 		const int src_y_index = (y_index >> 16) & 0x3ff;
537 		const int row_index = src_y_index;
538 
539 		const int row_zoom = m_pivram[row_index + layer * 0x400 + 0x3400] & 0xff;
540 
541 		u16 row_colbank = m_pivram[row_index + layer * 0x400 + 0x3400] >> 8;
542 		a = (row_colbank & 0xe0);   /* kill bit 4 */
543 		row_colbank = (((row_colbank & 0xf) << 1) | a) << 4;
544 
545 		u16 row_scroll = m_pivram[row_index + layer * 0x1000 + 0x4000];
546 		a = (row_scroll & 0xffe0) >> 1; /* kill bit 4 */
547 		row_scroll = ((row_scroll & 0xf) | a) & width_mask;
548 
549 		int x_index = sx - (row_scroll << 16);
550 
551 		int x_step = zoomx;
552 		if (row_zoom > 0x7f)    /* zoom in: reduce x_step */
553 		{
554 			x_step -= (((row_zoom - 0x7f) << 8) & 0xffff);
555 		}
556 		else if (row_zoom < 0x7f)   /* zoom out: increase x_step */
557 		{
558 			x_step += (((0x7f - row_zoom) << 8) & 0xffff);
559 		}
560 
561 		const u16 *const src16 = &srcbitmap.pix(src_y_index);
562 		const u8 *const  tsrc  = &flagsbitmap.pix(src_y_index);
563 		u16 *dst16 = scanline;
564 
565 		if (flags & TILEMAP_DRAW_OPAQUE)
566 		{
567 			for (int i = 0; i < screen_width; i++)
568 			{
569 				*dst16++ = src16[(x_index >> 16) & width_mask] + row_colbank;
570 				x_index += x_step;
571 			}
572 		}
573 		else
574 		{
575 			for (int i = 0; i < screen_width; i++)
576 			{
577 				if (tsrc[(x_index >> 16) & width_mask])
578 					*dst16++ = src16[(x_index >> 16) & width_mask] + row_colbank;
579 				else
580 					*dst16++ = 0x8000;
581 				x_index += x_step;
582 			}
583 		}
584 
585 		bryan2_drawscanline(bitmap, 0, y, screen_width, scanline, (flags & TILEMAP_DRAW_OPAQUE) ? false : true, ROT0, screen.priority(), priority);
586 
587 		y_index += zoomy;
588 	}
589 }
590 
591 
592 
593 /**************************************************************
594                         SCREEN REFRESH
595 **************************************************************/
596 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)597 u32 wgp_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
598 {
599 	u8 layer[3];
600 
601 #ifdef MAME_DEBUG
602 	if (machine().input().code_pressed_once (KEYCODE_V))
603 	{
604 		m_dislayer[0] ^= 1;
605 		popmessage("piv0: %01x",m_dislayer[0]);
606 	}
607 
608 	if (machine().input().code_pressed_once (KEYCODE_B))
609 	{
610 		m_dislayer[1] ^= 1;
611 		popmessage("piv1: %01x",m_dislayer[1]);
612 	}
613 
614 	if (machine().input().code_pressed_once (KEYCODE_N))
615 	{
616 		m_dislayer[2] ^= 1;
617 		popmessage("piv2: %01x",m_dislayer[2]);
618 	}
619 
620 	if (machine().input().code_pressed_once (KEYCODE_M))
621 	{
622 		m_dislayer[3] ^= 1;
623 		popmessage("TC0100SCN top bg layer: %01x",m_dislayer[3]);
624 	}
625 #endif
626 
627 	for (int i = 0; i < 3; i++)
628 	{
629 		m_piv_tilemap[i]->set_scrollx(0, m_piv_scrollx[i]);
630 		m_piv_tilemap[i]->set_scrolly(0, m_piv_scrolly[i]);
631 	}
632 
633 	m_tc0100scn->tilemap_update();
634 
635 	screen.priority().fill(0, cliprect);
636 	bitmap.fill(0, cliprect);
637 
638 	layer[0] = 0;
639 	layer[1] = 1;
640 	layer[2] = 2;
641 
642 	if (m_piv_ctrl_reg == 0x2d)
643 	{
644 		layer[1] = 2;
645 		layer[2] = 1;
646 	}
647 
648 /* We should draw the following on a 1024x1024 bitmap... */
649 
650 #ifdef MAME_DEBUG
651 	if (m_dislayer[layer[0]] == 0)
652 #endif
653 	piv_layer_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 1);
654 
655 #ifdef MAME_DEBUG
656 	if (m_dislayer[layer[1]] == 0)
657 #endif
658 	piv_layer_draw(screen, bitmap, cliprect, layer[1], 0, 2);
659 
660 #ifdef MAME_DEBUG
661 	if (m_dislayer[layer[2]] == 0)
662 #endif
663 	piv_layer_draw(screen, bitmap, cliprect, layer[2], 0, 4);
664 
665 	draw_sprites(screen, bitmap, cliprect, 16);
666 
667 /* ... then here we should apply rotation from m_rotate_ctrl[] to the bitmap before we draw the TC0100SCN layers on it */
668 	layer[0] = m_tc0100scn->bottomlayer();
669 	layer[1] = layer[0] ^ 1;
670 	layer[2] = 2;
671 
672 	m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[0], 0, 0);
673 
674 #ifdef MAME_DEBUG
675 	if (m_dislayer[3] == 0)
676 #endif
677 	m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 0);
678 	m_tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 0);
679 
680 #if 0
681 	{
682 		char buf[80];
683 		sprintf(buf,"piv_ctrl_reg: %04x y zoom: %04x %04x %04x",m_piv_ctrl_reg,
684 						m_piv_zoom[0],m_piv_zoom[1],m_piv_zoom[2]);
685 		popmessage(buf);
686 	}
687 #endif
688 
689 /* Enable this to watch the rotation control words */
690 #if 0
691 	{
692 		char buf[80];
693 		int i;
694 
695 		for (int i = 0; i < 8; i += 1)
696 		{
697 			sprintf (buf, "%02x: %04x", i, rotate_ctrl[i]);
698 			ui_draw_text (buf, 0, i*8);
699 		}
700 	}
701 #endif
702 	return 0;
703 }
704