diff options
Diffstat (limited to 'src/mame/upl/nova2001_v.cpp')
-rw-r--r-- | src/mame/upl/nova2001_v.cpp | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/src/mame/upl/nova2001_v.cpp b/src/mame/upl/nova2001_v.cpp new file mode 100644 index 00000000000..7812e9a27eb --- /dev/null +++ b/src/mame/upl/nova2001_v.cpp @@ -0,0 +1,378 @@ +// license:BSD-3-Clause +// copyright-holders:Howie Cohen, Frank Palazzolo, Alex Pasadyn, David Haywood, Phil Stroffolino, Uki +#include "emu.h" +#include "nova2001.h" + + +/************************************* + * + * Palette handling + * + *************************************/ + +void nova2001_state::nova2001_palette(palette_device &palette) const +{ + u8 const *const color_prom = memregion("proms")->base(); + + /* + Color #1 is used for palette animation. + To handle this, color entries 0-15 are based on + the primary 16 colors, while color entries 16-31 + are based on the secondary set. + + The only difference between 0-15 and 16-31 is that + color #1 changes each time + */ + for (int i = 0; i < 0x200; ++i) + { + int entry; + if ((i & 0xf) == 1) + entry = ((i & 0xf0) >> 4) | ((i & 0x100) >> 4); + else + entry = ((i & 0x0f) >> 0) | ((i & 0x100) >> 4); + + palette.set_pen_color(i, BBGGRRII(color_prom[entry])); + } +} + +rgb_t nova2001_state::BBGGRRII(u32 raw) +{ + u8 const i = raw & 3; + u8 const r = ((raw >> 0) & 0x0c) | i; + u8 const g = ((raw >> 2) & 0x0c) | i; + u8 const b = ((raw >> 4) & 0x0c) | i; + + return rgb_t(r | (r << 4), g | (g << 4), b | (b << 4)); +} + +void nova2001_state::paletteram_w(offs_t offset, u8 data) +{ + m_palette->write8(offset, data); + + // expand the sprite palette to full length + if (offset < 16) + { + m_palette->write8(0x200 + offset * 16 + 1, data); + + if (offset != 1) + { + for (int i = 0; i < 16; i++) + { + m_palette->write8(0x200 + offset + i * 16, data); + } + } + } +} + +u8 nova2001_state::paletteram_r(offs_t offset) +{ + return m_paletteram[offset]; +} + + +/************************************* + * + * Callbacks for the TileMap code + * + *************************************/ + +TILE_GET_INFO_MEMBER(nova2001_state::nova2001_get_bg_tile_info) +{ + int const code = m_bg_videoram[tile_index]; + int const color = m_bg_videoram[tile_index + 0x400] & 0x0f; + + tileinfo.set(2, code, color, 0); +} + +TILE_GET_INFO_MEMBER(nova2001_state::nova2001_get_fg_tile_info) +{ + int const attr = m_fg_videoram[tile_index + 0x400]; + int const code = m_fg_videoram[tile_index]; + int const color = attr & 0x0f; + + tileinfo.set(1, code, color, 0); + + tileinfo.category = (attr & 0x10) >> 4; +} + +TILE_GET_INFO_MEMBER(nova2001_state::ninjakun_get_bg_tile_info) +{ + int const attr = m_bg_videoram[tile_index + 0x400]; + int const code = m_bg_videoram[tile_index] + ((attr & 0xc0) << 2); + int const color = attr & 0x0f; + + tileinfo.set(2, code, color, 0); +} + +TILE_GET_INFO_MEMBER(nova2001_state::ninjakun_get_fg_tile_info) +{ + int const attr = m_fg_videoram[tile_index + 0x400]; + int const code = m_fg_videoram[tile_index] + ((attr & 0x20) << 3); + int const color = attr & 0x0f; + + tileinfo.set(1, code, color, 0); + + tileinfo.category = (attr & 0x10) >> 4; +} + +TILE_GET_INFO_MEMBER(nova2001_state::pkunwar_get_bg_tile_info) +{ + int const attr = m_bg_videoram[tile_index + 0x400]; + int const code = m_bg_videoram[tile_index] + ((attr & 0x07) << 8); + int const color = (attr & 0xf0) >> 4; + + tileinfo.set(1, code, color, 0); + + tileinfo.category = (attr & 0x08) >> 3; +} + +TILE_GET_INFO_MEMBER(nova2001_state::raiders5_get_bg_tile_info) +{ + int const attr = m_bg_videoram[tile_index + 0x400]; + int const code = m_bg_videoram[tile_index] + ((attr & 0x01) << 8); + int const color = (attr & 0xf0) >> 4; + + tileinfo.set(2, code, color, 0); +} + +TILE_GET_INFO_MEMBER(nova2001_state::raiders5_get_fg_tile_info) +{ + int const code = m_fg_videoram[tile_index]; + int const color = (m_fg_videoram[tile_index + 0x400] & 0xf0) >> 4; + + tileinfo.set(1, code, color, 0); +} + + + +/************************************* + * + * Video system start + * + *************************************/ + +VIDEO_START_MEMBER(nova2001_state,nova2001) +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(nova2001_state::nova2001_get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(nova2001_state::nova2001_get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap->set_transparent_pen(0); + m_bg_tilemap->set_scrolldx(0, -7); +} + +VIDEO_START_MEMBER(nova2001_state,pkunwar) +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(nova2001_state::pkunwar_get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_bg_tilemap->set_transparent_pen(0); +} + +VIDEO_START_MEMBER(nova2001_state,ninjakun) +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(nova2001_state::ninjakun_get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(nova2001_state::ninjakun_get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap->set_transparent_pen(0); + m_bg_tilemap->set_scrolldx(7, 0); +} + +VIDEO_START_MEMBER(nova2001_state,raiders5) +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(nova2001_state::raiders5_get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(nova2001_state::raiders5_get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + m_fg_tilemap->set_transparent_pen(0); + m_bg_tilemap->set_scrolldx(7, 0); +} + + + +/************************************* + * + * Memory handlers + * + *************************************/ + +void nova2001_state::fg_videoram_w(offs_t offset, u8 data) +{ + m_fg_videoram[offset] = data; + m_fg_tilemap->mark_tile_dirty(offset & 0x3ff); +} + +void nova2001_state::nova2001_bg_videoram_w(offs_t offset, u8 data) +{ + m_bg_videoram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); +} + +void nova2001_state::ninjakun_bg_videoram_w(offs_t offset, u8 data) +{ + int const x = m_bg_tilemap->scrollx(0) >> 3; + int const y = m_bg_tilemap->scrolly(0) >> 3; + + // add scroll registers to address + offset = ((offset + x + (y << 5)) & 0x3ff) + (offset & 0x400); + + m_bg_videoram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); +} + +u8 nova2001_state::ninjakun_bg_videoram_r(offs_t offset) +{ + int const x = m_bg_tilemap->scrollx(0) >> 3; + int const y = m_bg_tilemap->scrolly(0) >> 3; + + // add scroll registers to address + offset = ((offset + x + (y << 5)) & 0x3ff) + (offset & 0x400); + + return m_bg_videoram[offset]; +} + +void nova2001_state::scroll_x_w(u8 data) +{ + m_bg_tilemap->set_scrollx(0, data); +} + +void nova2001_state::scroll_y_w(u8 data) +{ + m_bg_tilemap->set_scrolly(0, data); +} + +void nova2001_state::nova2001_flipscreen_w(u8 data) +{ + // inverted + flip_screen_set(~data & 1); +} + +void nova2001_state::pkunwar_flipscreen_w(u8 data) +{ + flip_screen_set(data & 1); +} + + + +/************************************* + * + * Video update + * + *************************************/ + +void nova2001_state::nova2001_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ) +{ + for (int offs = 0; offs < 0x800; offs += 32) + { + int const attr = m_spriteram[offs+3]; + int flipx = attr & 0x10; + int flipy = attr & 0x20; + int sx = m_spriteram[offs+1] - ((attr & 0x40) << 2); // high bit shown in schematics, not used by game + int sy = m_spriteram[offs+2]; + int const tile = m_spriteram[offs+0]; + int const color = attr & 0x0f; + + if (attr & 0x80) // disable bit shown in schematics, not used by game + { + continue; + } + + if (flip_screen()) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, + tile, + color, + flipx, flipy, + sx, sy, 0); + } +} + +void nova2001_state::pkunwar_draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ) +{ + for (int offs = 0; offs < 0x800; offs += 32) + { + int const attr = m_spriteram[offs+3]; + int flipx = m_spriteram[offs+0] & 0x01; + int flipy = m_spriteram[offs+0] & 0x02; + int sx = m_spriteram[offs+1]; + int sy = m_spriteram[offs+2]; + int const tile = ((m_spriteram[offs+0] & 0xfc) >> 2) + ((attr & 0x07) << 6); + int const color = (attr & 0xf0) >> 4; + + if (attr & 0x08) // deducted by comparison, not used by game + { + continue; + } + + if (flip_screen()) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, + tile, + color, + flipx, flipy, + sx, sy, 0); + + // there's no X MSB, so draw with wraparound (fixes title screen) + m_gfxdecode->gfx(0)->transpen(bitmap,cliprect, + tile, + color, + flipx, flipy, + sx - 256, sy, 0); + } +} + + + +u32 nova2001_state::screen_update_nova2001(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + nova2001_draw_sprites(bitmap, cliprect); + + // according to the schematics, fg category 0 should be drawn behind sprites, + // but it doesn't look right that way + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + m_fg_tilemap->draw(screen, bitmap, cliprect, 1, 0); + + return 0; +} + +u32 nova2001_state::screen_update_pkunwar(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0); + + pkunwar_draw_sprites(bitmap, cliprect); + + m_bg_tilemap->draw(screen, bitmap, cliprect, 1, 0); + + return 0; +} + +u32 nova2001_state::screen_update_ninjakun(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + m_fg_tilemap->draw(screen, bitmap, cliprect, 1, 0); + + nova2001_draw_sprites(bitmap, cliprect); + + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + return 0; +} + +u32 nova2001_state::screen_update_raiders5(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + pkunwar_draw_sprites(bitmap, cliprect); + + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + return 0; +} |