diff options
author | 2017-07-29 00:11:51 -0400 | |
---|---|---|
committer | 2017-07-29 00:19:11 -0400 | |
commit | 9cea5e1518bcd59181cd3428d67b3d4cfa06fa98 (patch) | |
tree | 0e468bc50a5ae8c6049b7325c95fe7a14eee34c1 | |
parent | 7d3e01bc576580df6e95b9e6d08979aa57985eda (diff) |
decocass.cpp: Major improvements to colors and graphics layer priorities
- Implement the PRI2 pen modification effect. This makes the tunnels and headlight in Highway Chase look much more accurate, and makes some color changes work in Astro Fantasia.
- Shadow color in Skater is now properly black (not a pen modification effect).
- Correct background fill color, making high score screen in Super Doubles Tennis properly blue.
-rw-r--r-- | src/mame/drivers/decocass.cpp | 28 | ||||
-rw-r--r-- | src/mame/includes/decocass.h | 6 | ||||
-rw-r--r-- | src/mame/video/decocass.cpp | 120 |
3 files changed, 92 insertions, 62 deletions
diff --git a/src/mame/drivers/decocass.cpp b/src/mame/drivers/decocass.cpp index d45bc293a3b..1559ab810f4 100644 --- a/src/mame/drivers/decocass.cpp +++ b/src/mame/drivers/decocass.cpp @@ -933,34 +933,20 @@ static const gfx_layout objlayout = static GFXDECODE_START( decocass ) GFXDECODE_ENTRY( nullptr, 0x6000, charlayout, 0, 4 ) /* char set #1 */ GFXDECODE_ENTRY( nullptr, 0x6000, spritelayout, 0, 4 ) /* sprites */ - GFXDECODE_ENTRY( nullptr, 0xd000, tilelayout, 32, 2 ) /* background tiles */ - GFXDECODE_ENTRY( nullptr, 0xd800, objlayout, 48, 4 ) /* object */ + GFXDECODE_ENTRY( nullptr, 0xd000, tilelayout, 0, 8 ) /* background tiles */ + GFXDECODE_ENTRY( nullptr, 0xd800, objlayout, 0, 64 ) /* object */ GFXDECODE_END PALETTE_INIT_MEMBER(decocass_state, decocass) { int i; - /* set up 32 colors 1:1 pens */ + // set up 32 colors 1:1 pens and flipped colors for background tiles (D7 of color_center_bot) for (i = 0; i < 32; i++) - palette.set_pen_indirect(i, i); - - /* setup straight/flipped colors for background tiles (D7 of color_center_bot ?) */ - for (i = 0; i < 8; i++) { - palette.set_pen_indirect(32+i, 3*8+i); - palette.set_pen_indirect(40+i, 3*8+((i << 1) & 0x04) + ((i >> 1) & 0x02) + (i & 0x01)); + palette.set_pen_indirect(i, i); + palette.set_pen_indirect(32+i, BITSWAP8(i, 7, 6, 5, 4, 3, 1, 2, 0)); } - - /* setup 4 colors for 1bpp object */ - palette.set_pen_indirect(48+0*2+0, 0); - palette.set_pen_indirect(48+0*2+1, 25); /* testtape red from 4th palette section? */ - palette.set_pen_indirect(48+1*2+0, 0); - palette.set_pen_indirect(48+1*2+1, 28); /* testtape blue from 4th palette section? */ - palette.set_pen_indirect(48+2*2+0, 0); - palette.set_pen_indirect(48+2*2+1, 26); /* testtape green from 4th palette section? */ - palette.set_pen_indirect(48+3*2+0, 0); - palette.set_pen_indirect(48+3*2+1, 23); /* ???? */ } @@ -993,7 +979,7 @@ static MACHINE_CONFIG_START( decocass ) MCFG_SCREEN_PALETTE("palette") MCFG_GFXDECODE_ADD("gfxdecode", "palette", decocass) - MCFG_PALETTE_ADD("palette", 32+2*8+2*4) + MCFG_PALETTE_ADD("palette", 64) MCFG_PALETTE_INDIRECT_ENTRIES(32) MCFG_PALETTE_INIT_OWNER(decocass_state, decocass) @@ -2117,7 +2103,7 @@ DRIVER_INIT_MEMBER(decocass_state,cdsteljn) /* */ GAME( 1983, cnightst2, cnightst, cnightst, cnightst, decocass_type3_state, decocass, ROT270, "Data East Corporation", "Night Star (DECO Cassette) (US) (set 2)", 0 ) /* 33 */ GAME( 1983, cpsoccer, decocass, cpsoccer, cpsoccer, decocass_type3_state, decocass, ROT270, "Data East Corporation", "Pro Soccer (DECO Cassette) (US)", 0 ) /* */ GAME( 1983, cpsoccerj, cpsoccer, cpsoccer, cpsoccer, decocass_type3_state, decocass, ROT270, "Data East Corporation", "Pro Soccer (DECO Cassette) (Japan)", 0 ) -/* 34 */ GAME( 1983, csdtenis, decocass, csdtenis, csdtenis, decocass_type3_state, decocass, ROT270, "Data East Corporation", "Super Doubles Tennis (DECO Cassette) (Japan)", MACHINE_WRONG_COLORS ) +/* 34 */ GAME( 1983, csdtenis, decocass, csdtenis, csdtenis, decocass_type3_state, decocass, ROT270, "Data East Corporation", "Super Doubles Tennis (DECO Cassette) (Japan)", 0 ) /* 35 */ GAME( 1985, cflyball, decocass, decocass, cflyball, decocass_nodong_state,decocass, ROT270, "Data East Corporation", "Flying Ball (DECO Cassette) (US)", 0 ) /* 36 */ // 1984.04 Genesis/Boomer Rang'r /* 37 */ GAME( 1983, czeroize, decocass, czeroize, czeroize, decocass_type3_state, decocass, ROT270, "Data East Corporation", "Zeroize (DECO Cassette) (US)", 0 ) diff --git a/src/mame/includes/decocass.h b/src/mame/includes/decocass.h index 25120f9877f..fc8ccd34882 100644 --- a/src/mame/includes/decocass.h +++ b/src/mame/includes/decocass.h @@ -192,14 +192,14 @@ public: TIMER_DEVICE_CALLBACK_MEMBER(decocass_audio_nmi_gen); private: void draw_edge(bitmap_ind16 &bitmap, const rectangle &cliprect, int which, bool opaque); - void draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_special_priority(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect); void draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect); void mark_bg_tile_dirty(offs_t offset); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int color, + void draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect, int color, int sprite_y_adjust, int sprite_y_adjust_flip_screen, uint8_t *sprite_ram, int interleave); - void draw_missiles(bitmap_ind16 &bitmap, const rectangle &cliprect, + void draw_missiles(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect, int missile_y_adjust, int missile_y_adjust_flip_screen, uint8_t *missile_ram, int interleave); protected: diff --git a/src/mame/video/decocass.cpp b/src/mame/video/decocass.cpp index 8fca6755838..7c4708ad6bd 100644 --- a/src/mame/video/decocass.cpp +++ b/src/mame/video/decocass.cpp @@ -13,8 +13,8 @@ Additionally it supports the headlight and tunnel effects also needed for a Highway Chase style game. These both produce a pen - modification effect which is not emulated properly now. The lack - of tunnel . + modification effect mapped to bit 4 of the palette, unless bit + 5 of the mode register is set. --- @@ -39,14 +39,14 @@ reverts to red when player explodes mamedev.emulab.it/haze/reference/sm18975592-HWY_CHASE.mp4 - - road / bg colour should be darkish blue outside of tunnels - - road / bg colour should be black in tunnels + - road / bg colour should be darkish blue outside of tunnels (OK) + - road / bg colour should be black in tunnels (OK) - headlight should be the same darkish blue as the road - at all times, so only visible in tunnels + at all times, so only visible in tunnels (OK) - center line of road does not exist on hw! - - enemies are hidden in tunnels (like madalien) + - enemies are hidden in tunnels (like madalien) (OK) - road / bg flashs regular blue when enemy is hit revealing - them + them (OK) - some glitchy enemies visible even over tunnel bg for some frames - colours of BG tilemap are glitchy even on hardware eg. @@ -77,7 +77,7 @@ mamedev.emulab.it/haze/reference/sm17202585-SUPER_DOUBLE_TENNIS.mp4 - background colours during high-score / title ar shades of - blue, they appear green in our emulation + blue, not green as in previous emulation (OK now) mamedev.emulab.it/haze/reference/sm17202201-SKATER.mp4 - the game turns on the 'cross' bit, why? @@ -202,7 +202,7 @@ TILE_GET_INFO_MEMBER(decocass_state::get_bg_l_tile_info) int color = (m_color_center_bot >> 7) & 1; SET_TILE_INFO_MEMBER(2, m_bgvideoram[tile_index] >> 4, - color, + color * 4 + 1, 0); if (tile_index & 0x80) tileinfo.pen_data = m_empty_tile; @@ -213,7 +213,7 @@ TILE_GET_INFO_MEMBER(decocass_state::get_bg_r_tile_info ) int color = (m_color_center_bot >> 7) & 1; SET_TILE_INFO_MEMBER(2, m_bgvideoram[tile_index] >> 4, - color, + color * 4 + 1, TILE_FLIPY); if (!(tile_index & 0x80)) tileinfo.pen_data = m_empty_tile; @@ -225,7 +225,7 @@ TILE_GET_INFO_MEMBER(decocass_state::get_fg_tile_info ) uint8_t attr = m_colorram[tile_index]; SET_TILE_INFO_MEMBER(0, 256 * (attr & 3) + code, - m_color_center_bot & 1, + BIT(m_color_center_bot, 0), 0); } @@ -233,24 +233,61 @@ TILE_GET_INFO_MEMBER(decocass_state::get_fg_tile_info ) big object ********************************************/ -void decocass_state::draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect) +void decocass_state::draw_special_priority(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect) { - int sx, sy, color; + int crossing = m_mode_set & 3; - if (0 == (m_mode_set & 0x80)) /* part_h_enable off? */ + // in daylight or during explosion + if ((crossing == 0 || BIT(m_mode_set, 6)) && !BIT(m_mode_set, 5)) return; - color = (m_color_center_bot >> 4) & 15; + int color = (BITSWAP8(m_color_center_bot, 0, 1, 7, 2, 3, 4, 5, 6) & 0x27) | 0x08; - sy = 64 - m_part_v_shift + 1; + int sy = 64 - m_part_v_shift + 1; if (sy < 0) sy += 256; - sx = m_part_h_shift - 128; + int sx = m_part_h_shift - 128; - m_gfxdecode->gfx(3)->transpen(bitmap,cliprect, 0, color, 0, 0, sx + 64, sy, 0); - m_gfxdecode->gfx(3)->transpen(bitmap,cliprect, 1, color, 0, 0, sx, sy, 0); - m_gfxdecode->gfx(3)->transpen(bitmap,cliprect, 0, color, 0, 1, sx + 64, sy - 64, 0); - m_gfxdecode->gfx(3)->transpen(bitmap,cliprect, 1, color, 0, 1, sx, sy - 64, 0); + const uint8_t *objdata0 = m_gfxdecode->gfx(3)->get_data(0); + const uint8_t *objdata1 = m_gfxdecode->gfx(3)->get_data(1); + assert(m_gfxdecode->gfx(3)->rowbytes() == 64); + + for (int y = cliprect.min_y; y <= cliprect.max_y; y++) + { + const int dy = y - sy; + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + { + const int dx = x - sx; + + bool pri2 = false; + int scroll = m_back_h_shift; + + switch (crossing) + { + case 0: pri2 = true; break; // outside tunnel (for reference; not usually handled in this loop) + case 1: pri2 = (x >= scroll); break; // exiting tunnel + case 2: break; // inside tunnel + case 3: pri2 = (x < scroll); break; // entering tunnel + } + + if (BIT(m_mode_set, 7)) + { + // check coordinates against object data + if ((dy >= -64 && dy < 0 && dx >= 64 && dx < 128 && objdata0[(-1 - dy) * 64 + dx - 64] != 0) || + (dy >= 0 && dy < 64 && dx >= 64 && dx < 128 && objdata0[dy * 64 + dx - 64] != 0) || + (dy >= -64 && dy < 0 && dx >= 0 && dx < 64 && objdata1[(-1 - dy) * 64 + dx] != 0) || + (dy >= 0 && dy < 64 && dx >= 0 && dx < 64 && objdata1[dy * 64 + dx] != 0)) + { + pri2 = true; + if (BIT(m_mode_set, 5) && priority.pix8(y, x) == 0) // least priority? + bitmap.pix16(y, x) = color; + } + } + + if (!pri2) + bitmap.pix16(y, x) |= 0x10; + } + } } void decocass_state::draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -483,7 +520,7 @@ WRITE8_MEMBER(decocass_state::decocass_center_v_shift_w ) memory handlers ********************************************/ -void decocass_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int color, +void decocass_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect, int color, int sprite_y_adjust, int sprite_y_adjust_flip_screen, uint8_t *sprite_ram, int interleave) { @@ -514,25 +551,25 @@ void decocass_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprec sy -= sprite_y_adjust; - m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, + m_gfxdecode->gfx(1)->prio_transpen(bitmap,cliprect, sprite_ram[offs + interleave], color, flipx,flipy, - sx,sy, 0); + sx,sy, priority, 1 << 1, 0); sy += (flip_screen() ? -256 : 256); // Wrap around - m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, + m_gfxdecode->gfx(1)->prio_transpen(bitmap,cliprect, sprite_ram[offs + interleave], color, flipx,flipy, - sx,sy, 0); + sx,sy, priority, 1 << 1, 0); } } -void decocass_state::draw_missiles(bitmap_ind16 &bitmap, const rectangle &cliprect, +void decocass_state::draw_missiles(bitmap_ind16 &bitmap, bitmap_ind8 &priority, const rectangle &cliprect, int missile_y_adjust, int missile_y_adjust_flip_screen, uint8_t *missile_ram, int interleave) { @@ -556,7 +593,10 @@ void decocass_state::draw_missiles(bitmap_ind16 &bitmap, const rectangle &clipre for (x = 0; x < 4; x++) { if (sx >= cliprect.min_x && sx <= cliprect.max_x) + { bitmap.pix16(sy, sx) = (m_color_missiles & 7) | 8; + priority.pix8(sy, sx) |= 1 << 2; + } sx++; } @@ -572,7 +612,10 @@ void decocass_state::draw_missiles(bitmap_ind16 &bitmap, const rectangle &clipre for (x = 0; x < 4; x++) { if (sx >= cliprect.min_x && sx <= cliprect.max_x) + { bitmap.pix16(sy, sx) = ((m_color_missiles >> 4) & 7) | 8; + priority.pix8(sy, sx) |= 1 << 3; + } sx++; } } @@ -644,9 +687,7 @@ void decocass_state::draw_edge(bitmap_ind16 &bitmap, const rectangle &cliprect, uint16_t pix = src[srccol]; if ((pix & 0x3) || opaque) - { dst[x] = pix; - } } } @@ -716,27 +757,27 @@ uint32_t decocass_state::screen_update_decocass(screen_device &screen, bitmap_in } #endif - bitmap.fill(0, cliprect); + bitmap_ind8 &priority = screen.priority(); + bitmap.fill(8, cliprect); + priority.fill(0, cliprect); if (m_mode_set & 0x08) /* bkg_ena on ? */ { - draw_edge(bitmap,cliprect,0,true); - draw_edge(bitmap,cliprect,1,true); + draw_edge(bitmap, cliprect, 0, true); + draw_edge(bitmap, cliprect, 1, true); } if (m_mode_set & 0x20) { - draw_object(bitmap, cliprect); draw_center(bitmap, cliprect); } else { - draw_object(bitmap, cliprect); draw_center(bitmap, cliprect); if (m_mode_set & 0x08) /* bkg_ena on ? */ { - draw_edge(bitmap,cliprect,0,false); - draw_edge(bitmap,cliprect,1,false); + draw_edge(bitmap, cliprect, 0, false); + draw_edge(bitmap, cliprect, 1, false); } } @@ -747,10 +788,13 @@ uint32_t decocass_state::screen_update_decocass(screen_device &screen, bitmap_in m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); // priority 1: sprites - draw_sprites(bitmap, cliprect, (m_color_center_bot >> 1) & 1, 0, 0, m_fgvideoram, 0x20); + draw_sprites(bitmap, priority, cliprect, (m_color_center_bot >> 1) & 1, 0, 0, m_fgvideoram, 0x20); // priority 2 & 3: missiles - draw_missiles(bitmap, cliprect, 1, 0, m_colorram, 0x20); + draw_missiles(bitmap, priority, cliprect, 1, 0, m_colorram, 0x20); + + // PRI1 & PRI2: special handling for 1bpp object and tunnel sections + draw_special_priority(bitmap, priority, cliprect); return 0; } |