summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/technos/ddragon3_v.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/technos/ddragon3_v.cpp')
-rw-r--r--src/mame/technos/ddragon3_v.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/src/mame/technos/ddragon3_v.cpp b/src/mame/technos/ddragon3_v.cpp
new file mode 100644
index 00000000000..2bd0dfcae8e
--- /dev/null
+++ b/src/mame/technos/ddragon3_v.cpp
@@ -0,0 +1,315 @@
+// license:BSD-3-Clause
+// copyright-holders:Bryan McPhail, David Haywood
+/***************************************************************************
+
+ Video Hardware for Double Dragon 3
+
+***************************************************************************/
+
+#include "emu.h"
+#include "ddragon3.h"
+
+void ddragon3_state::ddragon3_scroll_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ switch (offset)
+ {
+ case 0: COMBINE_DATA(&m_fg_scrollx); break; // Scroll X, BG1
+ case 1: COMBINE_DATA(&m_fg_scrolly); break; // Scroll Y, BG1
+ case 2: COMBINE_DATA(&m_bg_scrollx); break; // Scroll X, BG0
+ case 3: COMBINE_DATA(&m_bg_scrolly); break; // Scroll Y, BG0
+ case 4: break; // Unknown write
+ case 5: flip_screen_set(data & 0x01); break; // Flip Screen
+ case 6:
+ COMBINE_DATA(&m_bg_tilebase); // BG Tile Base
+ m_bg_tilebase &= 0x1ff;
+ m_bg_tilemap->mark_all_dirty();
+ break;
+ }
+}
+
+uint16_t ddragon3_state::ddragon3_scroll_r(offs_t offset)
+{
+ switch (offset)
+ {
+ case 0: return m_fg_scrollx;
+ case 1: return m_fg_scrolly;
+ case 2: return m_bg_scrollx;
+ case 3: return m_bg_scrolly;
+ case 5: return flip_screen();
+ case 6: return m_bg_tilebase;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************************************************************************************/
+
+TILE_GET_INFO_MEMBER(ddragon3_state::get_bg_tile_info)
+{
+ uint16_t attr = m_bg_videoram[tile_index];
+ int code = (attr & 0x0fff) | ((m_bg_tilebase & 0x01) << 12);
+ int color = ((attr & 0xf000) >> 12);
+
+ tileinfo.set(0, code, color, 0);
+}
+
+
+
+void ddragon3_state::ddragon3_bg_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ COMBINE_DATA(&m_bg_videoram[offset]);
+ m_bg_tilemap->mark_tile_dirty(offset);
+}
+
+
+
+/*****************************************************************************************************************************************************/
+
+TILE_GET_INFO_MEMBER(ddragon3_state::get_fg_tile_info)
+{
+ uint16_t *tilebase = &m_fg_videoram[tile_index * 2];
+ int tileno = (tilebase[1] & 0x1fff);
+ int colbank = (tilebase[0] & 0x000f);
+
+ tileinfo.set(1, tileno, colbank, TILE_FLIPYX((tilebase[0] & 0x00c0) >> 6));
+}
+
+
+
+void ddragon3_state::ddragon3_fg_videoram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ COMBINE_DATA(&m_fg_videoram[offset]);
+ m_fg_tilemap->mark_tile_dirty(offset / 2);
+}
+
+
+
+/*****************************************************************************************************************************************************/
+/* 8x8 text layer - wwfwfest only */
+
+TILE_GET_INFO_MEMBER(wwfwfest_state::get_fg0_tile_info)
+{
+ uint16_t *tilebase = &m_fg0_videoram[tile_index * 2];
+ int tileno = (tilebase[0] & 0x00ff) | ((tilebase[1] & 0x000f) << 8);
+ int colbank = (tilebase[1] & 0x00f0) >> 4;
+
+ tileinfo.set(3, tileno, colbank, 0);
+}
+
+void wwfwfest_state::wwfwfest_fg0_videoram_w(offs_t offset, uint16_t data)
+{
+ // Videoram is 8 bit, upper & lower byte writes end up in the same place due to m68k byte smearing
+ m_fg0_videoram[offset] = data & 0xff;
+ m_fg0_tilemap->mark_tile_dirty(offset / 2);
+}
+
+/*****************************************************************************************************************************************************/
+
+void ddragon3_state::video_start()
+{
+ save_item(NAME(m_pri));
+
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ddragon3_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
+ m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ddragon3_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
+
+ m_bg_tilemap->set_transparent_pen(0);
+ m_fg_tilemap->set_transparent_pen(0);
+
+ m_sprite_xoff = m_bg0_dx = m_bg1_dx[0] = m_bg1_dx[1] = 0;
+ m_bg_tilebase = 0;
+}
+
+void wwfwfest_state::video_start()
+{
+ ddragon3_state::video_start();
+
+ m_fg0_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(wwfwfest_state::get_fg0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
+ m_fg0_tilemap->set_transparent_pen(0);
+
+}
+
+VIDEO_START_MEMBER(wwfwfest_state,wwfwfstb)
+{
+ wwfwfest_state::video_start();
+
+ m_sprite_xoff = 2;
+ m_bg0_dx = m_bg1_dx[0] = -4;
+ m_bg1_dx[1] = -2;
+}
+
+/*****************************************************************************************************************************************************/
+
+void ddragon3_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect )
+{
+ /*- SPR RAM Format -**
+
+ 16 bytes per sprite (8-bit RAM? only every other byte is used)
+
+ ---- ---- yyyy yyyy ---- ---- lllF fXYE ---- ---- nnnn nnnn ---- ---- NNNN NNNN
+ ---- ---- ---- CCCC ---- ---- xxxx xxxx ---- ---- ---- ---- ---- ---- ---- ----
+
+ Yy = sprite Y Position
+ Xx = sprite X Position
+ C = colour bank
+ f = flip Y
+ F = flip X
+ l = chain sprite
+ E = sprite enable
+ Nn = Sprite Number
+
+ other bits unused
+ */
+
+ uint16_t *buffered_spriteram16 = m_spriteram->buffer();
+ int length = m_spriteram->bytes();
+ gfx_element *gfx = m_gfxdecode->gfx(2);
+ uint16_t *source = buffered_spriteram16;
+ uint16_t *finish = source + length / 2;
+
+ while (source < finish)
+ {
+ if (source[1] & 0x0001)
+ {
+ int xpos = (source[5] & 0x00ff) | (source[1] & 0x0004) << 6;
+ if (xpos > 512 - 16) xpos -= 512;
+ xpos += m_sprite_xoff;
+
+ int ypos = (source[0] & 0x00ff) | (source[1] & 0x0002) << 7;
+ ypos = (256 - ypos) & 0x1ff;
+ ypos -= 16;
+
+ int flipx = (source[1] & 0x0010) >> 4;
+ int flipy = (source[1] & 0x0008) >> 3;
+ int chain = (source[1] & 0x00e0) >> 5;
+ int number = (source[2] & 0x00ff) | (source[3] & 0x00ff) << 8;
+ int colourbank = (source[4] & 0x000f);
+
+ if (flip_screen())
+ {
+ flipy = !flipy;
+ flipx = !flipx;
+ ypos = 240 - ypos - m_sprite_xoff;
+ xpos = 304 - xpos;
+ }
+
+ for (int count = 0; count <= chain; count++)
+ {
+ if (flip_screen())
+ {
+ if (!flipy)
+ gfx->transpen(bitmap, cliprect, number + count, colourbank, flipx, flipy, xpos, ypos + (16 * chain) - (16 * count), 0);
+ else
+ gfx->transpen(bitmap, cliprect, number + count, colourbank, flipx, flipy, xpos, ypos + 16 * count, 0);
+ }
+ else
+ {
+ if (flipy)
+ gfx->transpen(bitmap, cliprect, number + count, colourbank, flipx, flipy, xpos, ypos - (16 * chain) + (16 * count), 0);
+ else
+ gfx->transpen(bitmap, cliprect, number + count, colourbank, flipx, flipy, xpos, ypos - 16 * count, 0);
+ }
+ }
+ }
+
+ source += 8;
+ }
+}
+
+
+
+/*****************************************************************************************************************************************************/
+
+uint32_t ddragon3_state::screen_update_ddragon3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
+ m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
+ m_fg_tilemap->set_scrollx(0, m_fg_scrollx);
+ m_fg_tilemap->set_scrolly(0, m_fg_scrolly);
+
+ if ((m_vreg & 0x60) == 0x40)
+ {
+ m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+ }
+ else if ((m_vreg & 0x60) == 0x60)
+ {
+ m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+ }
+ else
+ {
+ m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ draw_sprites(bitmap, cliprect);
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ }
+ return 0;
+}
+
+uint32_t ddragon3_state::screen_update_ctribe(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
+ m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
+ m_fg_tilemap->set_scrollx(0, m_fg_scrollx);
+ m_fg_tilemap->set_scrolly(0, m_fg_scrolly);
+
+ if (m_vreg & 8)
+ {
+ m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ draw_sprites(bitmap, cliprect);
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ }
+ else
+ {
+ m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+ }
+ return 0;
+}
+
+
+uint32_t wwfwfest_state::screen_update_wwfwfest(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ if (m_pri == 0x78)
+ {
+ m_fg_tilemap->set_scrolly(0, m_fg_scrolly);
+ m_fg_tilemap->set_scrollx(0, m_fg_scrollx + m_bg0_dx);
+ m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
+ m_bg_tilemap->set_scrollx(0, m_bg_scrollx + m_bg1_dx[0]);
+ }
+ else
+ {
+ m_bg_tilemap->set_scrolly(0, m_fg_scrolly);
+ m_bg_tilemap->set_scrollx(0, m_fg_scrollx + m_bg1_dx[1]);
+ m_fg_tilemap->set_scrolly(0, m_bg_scrolly);
+ m_fg_tilemap->set_scrollx(0, m_bg_scrollx + m_bg0_dx);
+ }
+
+ // TODO: which bits of pri are significant to the order
+ if (m_pri == 0x7b)
+ {
+ m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+ }
+
+ if (m_pri == 0x7c)
+ {
+ m_fg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ draw_sprites(bitmap, cliprect);
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ }
+
+ if (m_pri == 0x78)
+ {
+ m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ draw_sprites(bitmap, cliprect);
+ }
+
+ m_fg0_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+
+ return 0;
+}