Previous 199869 Revisions Next

r33105 Saturday 1st November, 2014 at 09:33:54 UTC by Alex W. Jackson
twin16.c: Rewrite video mixing based on PAL equations [Alex Jackson]
[src/mame/video]twin16.c

trunk/src/mame/video/twin16.c
r241616r241617
1919
2020enum
2121{
22   TWIN16_SCREEN_FLIPY     = 0x01,
23   TWIN16_SCREEN_FLIPX     = 0x02, // confirmed: Hard Puncher Intro
24   TWIN16_UNKNOWN_PRI0     = 0x04, // ? Hard Puncher uses this
25   TWIN16_PLANE_ORDER      = 0x08, // confirmed: Devil Worlds
26   TWIN16_UNKNOWN_PRI2     = 0x10, // unused?
27   TWIN16_TILE_FLIPY       = 0x20  // confirmed: Vulcan Venture
22   TWIN16_SCREEN_FLIPY = 0x01,
23   TWIN16_SCREEN_FLIPX = 0x02, // confirmed: Hard Puncher Intro
24   TWIN16_PRI0         = 0x04, // PRI0 input into 007789 PAL
25   TWIN16_PRI1         = 0x08, // PRI1 input into 007789 PAL
26   TWIN16_PRI2_UNUSED  = 0x10, // schematic shows as PRI2 input, but unused
27   TWIN16_TILE_FLIPY   = 0x20  // confirmed: Vulcan Venture
2828};
2929
3030enum
3131{
3232   // user-defined priorities
33   TWIN16_BG_LAYER1            = 0x01,
34   TWIN16_SPRITE_PRI_L1        = 0x02,
35   TWIN16_BG_LAYER2            = 0x04,
36   TWIN16_SPRITE_PRI_L2        = 0x08,
37   TWIN16_SPRITE_OCCUPIED      = 0x10, // sprite on screen pixel
38   TWIN16_SPRITE_CAST_SHADOW   = 0x20
33   TWIN16_BG_OVER_SPRITES = 0x01, // BG pixel has priority over opaque sprite pixels
34   TWIN16_BG_NO_SHADOW    = 0x02, // BG pixel has priority over shadow sprite pixels
35   TWIN16_SPRITE_OCCUPIED = 0x04
3936};
4037
4138
r241616r241617
177174 *   2  | -------xxxxxxxxx | xpos
178175 * -----+------------------+
179176 *   3  | x--------------- | enable
180 *   3  | -x-------------- | priority   ?
181 *   3  | -----x---------- | no shadow  ?
177 *   3  | -xxxxx---------- | ?
182178 *   3  | ------x--------- | yflip  ?
183179 *   3  | -------x-------- | xflip
184180 *   3  | --------xx------ | height
r241616r241617
230226         UINT32 xpos = (0x10000*source[4])|source[5];
231227         UINT32 ypos = (0x10000*source[6])|source[7];
232228
233         /* notes on uncertain attributes:
234         shadows: pen $F only (like other Konami hw), used in devilw, fround,
235          miaj? (shadows are solid in tmnt hw version),
236          gradius2? (ship exhaust)
229         /* notes on sprite attributes:
237230
238         sprite-background priority: in devilw, most sprites look best at high priority,
239         in gradius2, most sprites look best at low priority. exceptions:
240         - devilw prologue: sprites behind crowd (maybe more, haven't completed the game)
241         - gradius2 intro showing earlier games: sprites above layers
231         The only inputs from the sprite hardware into the mixer PAL are four bits of
232         pixel data, with 0000 being transparent, 1111 being shadow, and anything else
233         opaque. Sprite to background priority, and whether shadows are visible, depends
234         entirely on the priority mode bits in m_video_register and on the underlying
235         background pixel, and not on any of the sprite attribute bits.
242236
243         currently using (priority&0x200), broken:
244         - devilw prologue: sprites should be behind crowd
245         - gradius2 level 7: bosses should be behind portal (ok except brain boss and mouth boss)
246         - gradius2 ending: sun should be behind planet
237         Shadows in the devilw lava stages look a bit strange; the shadows "punch holes"
238         in the platforms and reveal the lava underneath. As far as I can tell from the
239         schematics this has to be correct; unlike later Konami hardware there seems to
240         be no way for a sprite to cast a shadow onto another sprite.
247241
248         does TWIN16_PLANE_ORDER affect it?
249
250         more?
251         devilw monster dens exploding monochrome, players fading to white in prologue, and trees in
252         the 1st level shrinking with a solid green color look odd, maybe alpha blended?
253
254         fround, hpuncher, miaj, cuebrickj, don't use the preprocessor. all sprites are expected
255         to be high priority, and shadows are enabled
242         fround, hpuncher, miaj, cuebrickj, don't use the preprocessor.
256243         */
257         UINT16 attributes = 0x8000| // enabled
258            (source[2]&0x03ff)| // scale,size,color
259            (source[2]&0x4000)>>4|  // no-shadow? (gradius2 level 7 boss sets this bit and appears to expect pen $F to be solid)
260            (priority&0x200)<<5;    // sprite-background priority?
244         UINT16 attributes = 0x8000 | (source[2]&0x03ff); // scale,size,color
261245
262246         dest[0] = source[3]; /* gfx data */
263247         dest[1] = ((xpos>>8) - dx)&0xffff;
r241616r241617
291275         const UINT16 *pen_data = 0;
292276         int flipy = attributes&0x0200;
293277         int flipx = attributes&0x0100;
294         int priority = (attributes&0x4000)?TWIN16_SPRITE_PRI_L1:TWIN16_SPRITE_PRI_L2;
295278
296279         if( m_is_fround ) {
297280            /* fround board */
r241616r241617
360343                  {
361344                     UINT16 pen = pen_data[x>>2]>>((~x&3)<<2)&0xf;
362345
363                     if( pen )
346                     if( pen && !(pdest[sx] & TWIN16_SPRITE_OCCUPIED))
364347                     {
365                        int shadow = (pen==0xf) & ((attributes&0x400)==0);
348                        pdest[sx] |= TWIN16_SPRITE_OCCUPIED;
366349
367                        if (pdest[sx]<priority) {
368                           if (shadow) {
350                        if (pen==0xf) // shadow
351                        {
352                           if (!(pdest[sx] & TWIN16_BG_NO_SHADOW))
369353                              dest[sx] = m_palette->shadow_table()[dest[sx]];
370                              pdest[sx]|=TWIN16_SPRITE_CAST_SHADOW;
371                           }
372                           else {
354                        }
355                        else // opaque pixel
356                        {
357                           if (!(pdest[sx] & TWIN16_BG_OVER_SPRITES))
373358                              dest[sx] = pal_base + pen;
374                           }
375359                        }
376                        else if (!shadow && pdest[sx]&TWIN16_SPRITE_CAST_SHADOW && (pdest[sx]&0xf)<priority) {
377                           // shadow cast onto sprite below, evident in devilw lava level
378                           dest[sx] = m_palette->shadow_table()[pal_base + pen];
379                           pdest[sx]^=TWIN16_SPRITE_CAST_SHADOW;
380                        }
381
382                        pdest[sx]|=TWIN16_SPRITE_OCCUPIED;
383360                     }
384361                  }
385362               }
r241616r241617
412389void twin16_state::tile_get_info(tile_data &tileinfo, UINT16 data, int color_base)
413390{
414391   /* fedcba9876543210
415      xxx------------- color
392      xxx------------- color; high bit is also priority over sprites
416393      ---xxxxxxxxxxxxx tile number
417394   */
418395   int code = (data & 0x1fff);
r241616r241617
420397   int flags = 0;
421398   if (m_video_register & TWIN16_TILE_FLIPY) flags |= TILE_FLIPY;
422399   SET_TILE_INFO_MEMBER(1, code, color, flags);
400   tileinfo.category = BIT(data, 15);
423401}
424402
425403void fround_state::tile_get_info(tile_data &tileinfo, UINT16 data, int color_base)
426404{
427405   /* fedcba9876543210
428      xxx------------- color
406      xxx------------- color; high bit is also priority over sprites
429407      ---xx----------- tile bank
430408      -----xxxxxxxxxxx tile number
431409   */
r241616r241617
435413   int flags = 0;
436414   if (m_video_register & TWIN16_TILE_FLIPY) flags |= TILE_FLIPY;
437415   SET_TILE_INFO_MEMBER(1, code, color, flags);
416   tileinfo.category = BIT(data, 15);
438417}
439418
440419TILE_GET_INFO_MEMBER(twin16_state::layer0_tile_info)
r241616r241617
483462
484463UINT32 twin16_state::screen_update_twin16(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
485464{
486   int layer = m_video_register & TWIN16_PLANE_ORDER ? 0 : 1;
465/*
466    PAL equations (007789 @ 11J):
487467
488   m_scroll_tmap[layer]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, TWIN16_BG_LAYER1, 0);
489   m_scroll_tmap[layer^1]->draw(screen, bitmap, cliprect, 0, TWIN16_BG_LAYER2);
468    /SHAD = /FIX * /PRI1 * OCO0 * OCO1 * OCO2 * OCO3
469          + /FIX * /PRI0 * OCO0 * OCO1 * OCO2 * OCO3 * /V1C0
470          + /FIX * PRI0 * OCO0 * OCO1 * OCO2 * OCO3 * /V2C6
471          + /FIX * PRI0 * /V2C0 * /V2C3 * OCO0 * /V2C2 * OCO1 * /V2C1 * OCO2 * OCO3
490472
473    /SELB = /FIX * OCO0 * OCO1 * OCO2 * OCO3
474          + /FIX * /OCO0 * /OCO1 * /OCO2 * /OCO3
475          + /FIX * PRI0 * /PRI1 * V1C0
476          + /FIX * PRI0 * PRI1 * V2C0 * V2C6
477          + /FIX * PRI0 * PRI1 * V2C1 * V2C6
478          + /FIX * PRI0 * PRI1 * V2C2 * V2C6
479          + /FIX * PRI0 * PRI1 * V2C3 * V2C6
480
481     SELA = FIX
482          + PRI0 * /PRI1 * V1C0
483          + /PRI1 * OCO0 * OCO1 * OCO2 * OCO3 * V1C0
484          + /PRI1 * /OCO0 * /OCO1 * /OCO2 * /OCO3 * V1C0
485          + PRI1 * /V2C0 * /V2C3 * OCO0 * /V2C2 * OCO1 * /V2C1 * OCO2 * OCO3
486          + PRI1 * /V2C0 * /V2C3 * /OCO0 * /V2C2 * /OCO1 * /V2C1 * /OCO2 * /OCO3
487
488     SELB  SELA  Visible layer
489      0     0    VRAM2
490      0     1    VRAM1
491      1     0    Object
492      1     1    Fix
493*/
494   screen.priority().fill(0, cliprect);
495
496   switch ((m_video_register >> 2) & 0x3)
497   {
498      case 0: // PRI1 = 0, PRI0 = 0
499         m_scroll_tmap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES | TILEMAP_DRAW_OPAQUE);
500         m_scroll_tmap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES);
501         break;
502      case 1: // PRI1 = 0, PRI0 = 1
503         m_scroll_tmap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES | TILEMAP_DRAW_OPAQUE);
504         m_scroll_tmap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES, TWIN16_BG_OVER_SPRITES);
505         break;
506      case 2: // PRI1 = 1, PRI0 = 0
507         m_scroll_tmap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES | TILEMAP_DRAW_OPAQUE);
508         m_scroll_tmap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES, TWIN16_BG_NO_SHADOW);
509         m_scroll_tmap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES);
510         break;
511      case 3: // PRI1 = 1, PRI0 = 1
512         m_scroll_tmap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALL_CATEGORIES | TILEMAP_DRAW_OPAQUE);
513         m_scroll_tmap[1]->draw(screen, bitmap, cliprect, 0);
514         m_scroll_tmap[1]->draw(screen, bitmap, cliprect, 1, TWIN16_BG_OVER_SPRITES | TWIN16_BG_NO_SHADOW);
515         break;
516   }
517
491518   draw_sprites( screen, bitmap );
492519
493520   m_fixed_tmap->draw(screen, bitmap, cliprect, 0);


Previous 199869 Revisions Next


© 1997-2024 The MAME Team