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