// license:BSD-3-Clause // copyright-holders:Nicola Salmoria #include "emu.h" #include "includes/dogfgt.h" /*************************************************************************** Convert the color PROMs into a more useable format. Dog-Fight has both palette RAM and PROMs. The PROMs are used for tiles & pixmap, RAM for sprites. ***************************************************************************/ void dogfgt_state::dogfgt_palette(palette_device &palette) const { uint8_t const *const color_prom = memregion("proms")->base(); // first 16 colors are RAM for (int i = 0; i < 64; i++) { int bit0, bit1, bit2; // red component bit0 = BIT(color_prom[i], 0); bit1 = BIT(color_prom[i], 1); bit2 = BIT(color_prom[i], 2); int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; // green component bit0 = BIT(color_prom[i], 3); bit1 = BIT(color_prom[i], 4); bit2 = BIT(color_prom[i], 5); int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; // blue component bit0 = 0; bit1 = BIT(color_prom[i], 6); bit2 = BIT(color_prom[i], 7); int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; palette.set_pen_color(i + 16, rgb_t(r, g, b)); } } /*************************************************************************** Callbacks for the TileMap code ***************************************************************************/ TILE_GET_INFO_MEMBER(dogfgt_state::get_tile_info) { SET_TILE_INFO_MEMBER(0, m_bgvideoram[tile_index], m_bgvideoram[tile_index + 0x400] & 0x03, 0); } /*************************************************************************** Start the video hardware emulation. ***************************************************************************/ void dogfgt_state::video_start() { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(dogfgt_state::get_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32); m_bitmapram = std::make_unique(BITMAPRAM_SIZE); save_pointer(NAME(m_bitmapram), BITMAPRAM_SIZE); m_screen->register_screen_bitmap(m_pixbitmap); save_item(NAME(m_pixbitmap)); } /*************************************************************************** Memory handlers ***************************************************************************/ WRITE8_MEMBER(dogfgt_state::plane_select_w) { m_bm_plane = data; } READ8_MEMBER(dogfgt_state::bitmapram_r) { if (m_bm_plane > 2) { popmessage("bitmapram_r offs %04x plane %d\n", offset, m_bm_plane); return 0; } return m_bitmapram[offset + BITMAPRAM_SIZE / 3 * m_bm_plane]; } WRITE8_MEMBER(dogfgt_state::internal_bitmapram_w) { m_bitmapram[offset] = data; offset &= (BITMAPRAM_SIZE / 3 - 1); int x = 8 * (offset / 256); int y = offset % 256; for (int subx = 0; subx < 8; subx++) { int color = 0; for (int i = 0; i < 3; i++) color |= ((m_bitmapram[offset + BITMAPRAM_SIZE / 3 * i] >> subx) & 1) << i; if (flip_screen()) m_pixbitmap.pix16(y ^ 0xff, (x + subx) ^ 0xff) = PIXMAP_COLOR_BASE + 8 * m_pixcolor + color; else m_pixbitmap.pix16(y, x + subx) = PIXMAP_COLOR_BASE + 8 * m_pixcolor + color; } } WRITE8_MEMBER(dogfgt_state::bitmapram_w) { if (m_bm_plane > 2) { popmessage("bitmapram_w offs %04x plane %d\n", offset, m_bm_plane); return; } internal_bitmapram_w(space, offset + BITMAPRAM_SIZE / 3 * m_bm_plane, data); } WRITE8_MEMBER(dogfgt_state::bgvideoram_w) { m_bgvideoram[offset] = data; m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); } WRITE8_MEMBER(dogfgt_state::scroll_w) { m_scroll[offset] = data; m_bg_tilemap->set_scrollx(0, m_scroll[0] + 256 * m_scroll[1] + 256); m_bg_tilemap->set_scrolly(0, m_scroll[2] + 256 * m_scroll[3]); } WRITE8_MEMBER(dogfgt_state::_1800_w) { /* bits 0 and 1 are probably text color (not verified because PROM is missing) */ m_pixcolor = ((data & 0x01) << 1) | ((data & 0x02) >> 1); /* bits 4 and 5 are coin counters */ machine().bookkeeping().coin_counter_w(0, data & 0x10); machine().bookkeeping().coin_counter_w(1, data & 0x20); /* bit 7 is screen flip */ flip_screen_set(data & 0x80); /* other bits unused? */ logerror("PC %04x: 1800 = %02x\n", m_maincpu->pc(), data); } /*************************************************************************** Display refresh ***************************************************************************/ void dogfgt_state::draw_sprites( bitmap_ind16 &bitmap,const rectangle &cliprect ) { for (int offs = 0; offs < m_spriteram.bytes(); offs += 4) { if (m_spriteram[offs] & 0x01) { int sx = m_spriteram[offs + 3]; int sy = (240 - m_spriteram[offs + 2]) & 0xff; int flipx = m_spriteram[offs] & 0x04; int flipy = m_spriteram[offs] & 0x02; if (flip_screen()) { sx = 240 - sx; sy = 240 - sy; flipx = !flipx; flipy = !flipy; } m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, m_spriteram[offs + 1] + ((m_spriteram[offs] & 0x30) << 4), (m_spriteram[offs] & 0x08) >> 3, flipx,flipy, sx,sy,0); } } } uint32_t dogfgt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { if (m_lastflip != flip_screen() || m_lastpixcolor != m_pixcolor) { address_space &space = m_maincpu->space(AS_PROGRAM); m_lastflip = flip_screen(); m_lastpixcolor = m_pixcolor; for (int offs = 0; offs < BITMAPRAM_SIZE; offs++) internal_bitmapram_w(space, offs, m_bitmapram[offs]); } m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); draw_sprites(bitmap, cliprect); copybitmap_trans(bitmap, m_pixbitmap, 0, 0, 0, 0, cliprect, PIXMAP_COLOR_BASE + 8 * m_pixcolor); return 0; }