// license:BSD-3-Clause // copyright-holders:Olivier Galibert #include "emu.h" #include "includes/sf.h" /*************************************************************************** Callbacks for the TileMap code ***************************************************************************/ TILE_GET_INFO_MEMBER(sf_state::get_bg_tile_info) { uint8_t *base = &m_tilerom[2 * tile_index]; int attr = base[0x10000]; int color = base[0]; int code = (base[0x10000 + 1] << 8) | base[1]; SET_TILE_INFO_MEMBER(0, code, color, TILE_FLIPYX(attr & 3)); } TILE_GET_INFO_MEMBER(sf_state::get_fg_tile_info) { uint8_t *base = &m_tilerom[0x20000 + 2 * tile_index]; int attr = base[0x10000]; int color = base[0]; int code = (base[0x10000 + 1] << 8) | base[1]; SET_TILE_INFO_MEMBER(1, code, color, TILE_FLIPYX(attr & 3)); } TILE_GET_INFO_MEMBER(sf_state::get_tx_tile_info) { int code = m_videoram[tile_index]; SET_TILE_INFO_MEMBER(3, code & 0x3ff, code>>12, TILE_FLIPYX((code & 0xc00)>>10)); } /*************************************************************************** Start the video hardware emulation. ***************************************************************************/ void sf_state::video_start() { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sf_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 2048, 16); m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sf_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 2048, 16); m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sf_state::get_tx_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32); m_fg_tilemap->set_transparent_pen(15); m_tx_tilemap->set_transparent_pen(3); } /*************************************************************************** Memory handlers ***************************************************************************/ WRITE16_MEMBER(sf_state::videoram_w) { COMBINE_DATA(&m_videoram[offset]); m_tx_tilemap->mark_tile_dirty(offset); } WRITE16_MEMBER(sf_state::bg_scroll_w) { COMBINE_DATA(&m_bgscroll); m_bg_tilemap->set_scrollx(0, m_bgscroll); } WRITE16_MEMBER(sf_state::fg_scroll_w) { COMBINE_DATA(&m_fgscroll); m_fg_tilemap->set_scrollx(0, m_fgscroll); } WRITE16_MEMBER(sf_state::gfxctrl_w) { /* b0 = reset, or maybe "set anyway" */ /* b1 = pulsed when control6.b6==0 until it's 1 */ /* b2 = active when dip 8 (flip) on */ /* b3 = active character plane */ /* b4 = unused */ /* b5 = active background plane */ /* b6 = active middle plane */ /* b7 = active sprites */ if (ACCESSING_BITS_0_7) { m_active = data & 0xff; flip_screen_set(data & 0x04); m_tx_tilemap->enable(data & 0x08); m_bg_tilemap->enable(data & 0x20); m_fg_tilemap->enable(data & 0x40); } } /*************************************************************************** Display refresh ***************************************************************************/ inline int sf_state::invert( int nb ) { static const int delta[4] = {0x00, 0x18, 0x18, 0x00}; return nb ^ delta[(nb >> 3) & 3]; } void sf_state::draw_sprites( bitmap_ind16 &bitmap,const rectangle &cliprect ) { int offs; for (offs = 0x1000 - 0x20; offs >= 0; offs -= 0x20) { int c = m_objectram[offs]; int attr = m_objectram[offs + 1]; int sy = m_objectram[offs + 2]; int sx = m_objectram[offs + 3]; int color = attr & 0x000f; int flipx = attr & 0x0100; int flipy = attr & 0x0200; if (attr & 0x400) /* large sprite */ { int c1, c2, c3, c4, t; if (flip_screen()) { sx = 480 - sx; sy = 224 - sy; flipx = !flipx; flipy = !flipy; } c1 = c; c2 = c + 1; c3 = c + 16; c4 = c + 17; if (flipx) { t = c1; c1 = c2; c2 = t; t = c3; c3 = c4; c4 = t; } if (flipy) { t = c1; c1 = c3; c3 = t; t = c2; c2 = c4; c4 = t; } m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, invert(c1), color, flipx,flipy, sx,sy, 15); m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, invert(c2), color, flipx,flipy, sx+16,sy, 15); m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, invert(c3), color, flipx,flipy, sx,sy+16, 15); m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, invert(c4), color, flipx,flipy, sx+16,sy+16, 15); } else { if (flip_screen()) { sx = 496 - sx; sy = 240 - sy; flipx = !flipx; flipy = !flipy; } m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, invert(c), color, flipx,flipy, sx,sy, 15); } } } uint32_t sf_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { if (m_active & 0x20) m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); else bitmap.fill(0, cliprect); m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); if (m_active & 0x80) draw_sprites(bitmap, cliprect); m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0); return 0; }