summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/tc0100scn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/tc0100scn.cpp')
-rw-r--r--src/mame/video/tc0100scn.cpp187
1 files changed, 82 insertions, 105 deletions
diff --git a/src/mame/video/tc0100scn.cpp b/src/mame/video/tc0100scn.cpp
index 6c8d8000def..d40cef83a33 100644
--- a/src/mame/video/tc0100scn.cpp
+++ b/src/mame/video/tc0100scn.cpp
@@ -144,43 +144,39 @@ the wide tilemap mode)
#include "tc0100scn.h"
#include "screen.h"
+#include <algorithm>
+
#define TC0100SCN_RAM_SIZE 0x14000 /* enough for double-width tilemaps */
#define TC0100SCN_TOTAL_CHARS 256
DEFINE_DEVICE_TYPE(TC0100SCN, tc0100scn_device, "tc0100scn", "Taito TC0100SCN")
tc0100scn_device::tc0100scn_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, TC0100SCN, tag, owner, clock),
- m_ram(nullptr),
- m_bg_ram(nullptr),
- m_fg_ram(nullptr),
- m_tx_ram(nullptr),
- m_char_ram(nullptr),
- m_bgscroll_ram(nullptr),
- m_fgscroll_ram(nullptr),
- m_colscroll_ram(nullptr),
- m_bgscrollx(0),
- m_bgscrolly(0),
- m_fgscrollx(0),
- m_fgscrolly(0),
- m_bg0_colbank(0),
- m_bg1_colbank(0),
- m_tx_colbank(0),
- m_dblwidth(0),
- m_dirty(false),
- m_gfxnum(0),
- m_txnum(0),
- m_x_offset(0),
- m_y_offset(0),
- m_flip_xoffs(0),
- m_flip_yoffs(0),
- m_flip_text_xoffs(0),
- m_flip_text_yoffs(0),
- m_multiscrn_xoffs(0),
- m_multiscrn_hack(0),
- m_gfxdecode(*this, finder_base::DUMMY_TAG),
- m_palette(*this, finder_base::DUMMY_TAG)
+ : device_t(mconfig, TC0100SCN, tag, owner, clock)
+ , device_gfx_interface(mconfig, *this)
+ , m_ram(nullptr)
+ , m_bgscroll_ram(nullptr)
+ , m_fgscroll_ram(nullptr)
+ , m_colscroll_ram(nullptr)
+ , m_bgscrollx(0)
+ , m_bgscrolly(0)
+ , m_fgscrollx(0)
+ , m_fgscrolly(0)
+ , m_tx_colbank(0)
+ , m_dblwidth(0)
+ , m_dirty(false)
+ , m_gfxnum(0)
+ , m_x_offset(0)
+ , m_y_offset(0)
+ , m_flip_xoffs(0)
+ , m_flip_yoffs(0)
+ , m_flip_text_xoffs(0)
+ , m_flip_text_yoffs(0)
+ , m_multiscrn_xoffs(0)
+ , m_multiscrn_hack(0)
+ , m_gfxdecode(*this, finder_base::DUMMY_TAG)
{
+ std::fill(std::begin(m_bg_colbank), std::end(m_bg_colbank), 0);
}
//-------------------------------------------------
@@ -192,7 +188,7 @@ void tc0100scn_device::device_start()
// bind callbacks
m_tc0100scn_cb.bind_relative_to(*owner());
- static const gfx_layout tc0100scn_charlayout =
+ static const gfx_layout charlayout =
{
8,8, /* 8*8 characters */
256, /* 256 characters */
@@ -214,14 +210,14 @@ void tc0100scn_device::device_start()
we're safe as it uses single width tilemaps. */
/* Single width versions */
- m_tilemap[0][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
- m_tilemap[1][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
- m_tilemap[2][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_tx_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
+ m_tilemap[0][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(&tc0100scn_device::get_bg_tile_info<0x00000, 0>, "bg0_std", this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
+ m_tilemap[1][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(&tc0100scn_device::get_bg_tile_info<0x04000, 1>, "bg1_std", this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
+ m_tilemap[2][0] = &machine().tilemap().create(*this, tilemap_get_info_delegate(&tc0100scn_device::get_tx_tile_info<0x02000, 0>, "txt_std", this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
/* Double width versions */
- m_tilemap[0][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
- m_tilemap[1][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
- m_tilemap[2][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tc0100scn_device::get_tx_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 32);
+ m_tilemap[0][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(&tc0100scn_device::get_bg_tile_info<0x00000, 0>, "bg0_wide", this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
+ m_tilemap[1][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(&tc0100scn_device::get_bg_tile_info<0x04000, 1>, "bg1_wide", this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
+ m_tilemap[2][1] = &machine().tilemap().create(*this, tilemap_get_info_delegate(&tc0100scn_device::get_tx_tile_info<0x09000, 1>, "txt_wide", this), TILEMAP_SCAN_ROWS, 8, 8, 128, 32);
m_tilemap[0][0]->set_transparent_pen(0);
m_tilemap[1][0]->set_transparent_pen(0);
@@ -270,15 +266,18 @@ void tc0100scn_device::device_start()
set_layer_ptrs();
/* create the char set (gfx will then be updated dynamically from RAM) */
- m_gfxdecode->set_gfx(m_txnum, std::make_unique<gfx_element>(m_palette, tc0100scn_charlayout, (u8 *)m_char_ram, NATIVE_ENDIAN_VALUE_LE_BE(8,0), 256, 0));
+ set_gfx(0, std::make_unique<gfx_element>(&palette(), charlayout, (u8 *)&m_ram[0x6000 / 2], NATIVE_ENDIAN_VALUE_LE_BE(8,0), 256, 0));
+ set_gfx(1, std::make_unique<gfx_element>(&palette(), charlayout, (u8 *)&m_ram[0x11000 / 2], NATIVE_ENDIAN_VALUE_LE_BE(8,0), 256, 0));
- gfx_element *gfx = m_gfxdecode->gfx(m_gfxnum);
- gfx_element *txt = m_gfxdecode->gfx(m_txnum);
+ gfx_element *bg_gfx = m_gfxdecode->gfx(m_gfxnum);
+ gfx_element *txt0 = gfx(0);
+ gfx_element *txt1 = gfx(1);
- if (gfx->granularity() == 2) /* Yuyugogo, Yesnoj */
- gfx->set_granularity(16);
+ if (bg_gfx->granularity() == 2) /* Yuyugogo, Yesnoj */
+ bg_gfx->set_granularity(16);
- txt->set_granularity(gfx->granularity());
+ txt0->set_granularity(bg_gfx->granularity());
+ txt1->set_granularity(bg_gfx->granularity());
set_colbanks(0, 0, 0); /* standard values, only Wgp & multiscreen games change them */
/* we call this here, so that they can be modified at video_start*/
@@ -305,10 +304,11 @@ void tc0100scn_device::device_reset()
DEVICE HANDLERS
*****************************************************************************/
-void tc0100scn_device::common_get_tile_info( tile_data &tileinfo, int tile_index, u16 *ram, int colbank )
+template<unsigned Offset, unsigned Colbank>
+TILE_GET_INFO_MEMBER(tc0100scn_device::get_bg_tile_info)
{
- u32 code = ram[2 * tile_index + 1];
- const u16 attr = ram[2 * tile_index];
+ u32 code = m_ram[(2 * tile_index) + 1 + Offset];
+ const u16 attr = m_ram[(2 * tile_index) + Offset];
u16 color = attr & 0xff;
/* Mahjong Quest (F2 system) inexplicably has a banking feature */
@@ -317,25 +317,16 @@ void tc0100scn_device::common_get_tile_info( tile_data &tileinfo, int tile_index
SET_TILE_INFO_MEMBER(m_gfxnum,
code,
- ((attr + colbank) & 0xff),
+ ((color + m_bg_colbank[Colbank]) & 0xff),
TILE_FLIPYX((attr & 0xc000) >> 14));
}
-TILE_GET_INFO_MEMBER(tc0100scn_device::get_bg_tile_info)
-{
- common_get_tile_info(tileinfo, tile_index, m_bg_ram, m_bg0_colbank);
-}
-
-TILE_GET_INFO_MEMBER(tc0100scn_device::get_fg_tile_info)
-{
- common_get_tile_info(tileinfo, tile_index, m_fg_ram, m_bg1_colbank);
-}
-
+template<unsigned Offset, unsigned Gfx>
TILE_GET_INFO_MEMBER(tc0100scn_device::get_tx_tile_info)
{
- int attr = m_tx_ram[tile_index];
+ int attr = m_ram[Offset + tile_index];
- SET_TILE_INFO_MEMBER(m_txnum,
+ SET_TILE_INFO_MEMBER(Gfx,
attr & 0x00ff,
((attr & 0x3f00) >> 8) + m_tx_colbank,
TILE_FLIPYX((attr & 0xc000) >> 14));
@@ -343,8 +334,8 @@ TILE_GET_INFO_MEMBER(tc0100scn_device::get_tx_tile_info)
void tc0100scn_device::set_colbanks( int bg0, int bg1, int tx )
{
- m_bg0_colbank = bg0;
- m_bg1_colbank = bg1;
+ m_bg_colbank[0] = bg0;
+ m_bg_colbank[1] = bg1;
m_tx_colbank = tx;
}
@@ -358,33 +349,18 @@ void tc0100scn_device::set_layer_ptrs()
{
if (!m_dblwidth)
{
- m_bg_ram = m_ram.get() + 0x0;
- m_tx_ram = m_ram.get() + 0x4000 /2;
- m_char_ram = m_ram.get() + 0x6000 /2;
- m_fg_ram = m_ram.get() + 0x8000 /2;
m_bgscroll_ram = m_ram.get() + 0xc000 /2;
m_fgscroll_ram = m_ram.get() + 0xc400 /2;
m_colscroll_ram = m_ram.get() + 0xe000 /2;
}
else
{
- m_bg_ram = m_ram.get() + 0x0;
- m_fg_ram = m_ram.get() + 0x08000 /2;
m_bgscroll_ram = m_ram.get() + 0x10000 /2;
m_fgscroll_ram = m_ram.get() + 0x10400 /2;
m_colscroll_ram = m_ram.get() + 0x10800 /2;
- m_char_ram = m_ram.get() + 0x11000 /2;
- m_tx_ram = m_ram.get() + 0x12000 /2;
}
}
-void tc0100scn_device::dirty_tilemaps()
-{
- m_tilemap[0][m_dblwidth]->mark_all_dirty();
- m_tilemap[1][m_dblwidth]->mark_all_dirty();
- m_tilemap[2][m_dblwidth]->mark_all_dirty();
-}
-
void tc0100scn_device::restore_scroll()
{
int flip;
@@ -417,8 +393,6 @@ void tc0100scn_device::device_post_load()
set_layer_ptrs();
restore_scroll();
- m_gfxdecode->gfx(m_txnum)->set_source((u8 *)m_char_ram);
-
m_tilemap[0][0]->mark_all_dirty();
m_tilemap[1][0]->mark_all_dirty();
m_tilemap[2][0]->mark_all_dirty();
@@ -435,28 +409,36 @@ u16 tc0100scn_device::ram_r(offs_t offset)
void tc0100scn_device::ram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_ram[offset]);
- if (!m_dblwidth)
+ /* Double-width tilemaps have a different memory map */
+ if (offset < 0x2000)
+ {
+ m_tilemap[0][0]->mark_tile_dirty(offset / 2);
+ m_tilemap[0][1]->mark_tile_dirty(offset / 2);
+ }
+ else if (offset < 0x3000)
{
- if (offset < 0x2000)
- m_tilemap[0][0]->mark_tile_dirty(offset / 2);
- else if (offset < 0x3000)
- m_tilemap[2][0]->mark_tile_dirty((offset & 0x0fff));
- else if (offset < 0x3800)
- m_gfxdecode->gfx(m_txnum)->mark_dirty((offset - 0x3000) / 8);
- else if (offset >= 0x4000 && offset < 0x6000)
- m_tilemap[1][0]->mark_tile_dirty((offset & 0x1fff) / 2);
+ m_tilemap[2][0]->mark_tile_dirty((offset & 0x0fff));
+ m_tilemap[0][1]->mark_tile_dirty(offset / 2);
}
- else /* Double-width tilemaps have a different memory map */
+ else if (offset < 0x3800)
{
- if (offset < 0x4000)
- m_tilemap[0][1]->mark_tile_dirty(offset / 2);
- else if (offset >= 0x4000 && offset < 0x8000)
- m_tilemap[1][1]->mark_tile_dirty((offset & 0x3fff) / 2);
- else if (offset >= 0x8800 && offset < 0x9000)
- m_gfxdecode->gfx(m_txnum)->mark_dirty((offset - 0x8800) / 8);
- else if (offset >= 0x9000)
- m_tilemap[2][1]->mark_tile_dirty((offset & 0x0fff));
+ gfx(0)->mark_dirty((offset - 0x3000) / 8);
+ m_tilemap[0][1]->mark_tile_dirty(offset / 2);
}
+ else if (offset < 0x4000)
+ m_tilemap[0][1]->mark_tile_dirty(offset / 2);
+ else if (offset < 0x6000)
+ {
+ m_tilemap[1][0]->mark_tile_dirty((offset & 0x1fff) / 2);
+ m_tilemap[1][1]->mark_tile_dirty((offset & 0x3fff) / 2);
+ }
+ else if (offset < 0x8000)
+ m_tilemap[1][1]->mark_tile_dirty((offset & 0x3fff) / 2);
+ else if (offset >= 0x8800 && offset < 0x9000)
+ gfx(1)->mark_dirty((offset - 0x8800) / 8);
+ else if (offset >= 0x9000)
+ m_tilemap[2][1]->mark_tile_dirty((offset & 0x0fff));
+
}
u16 tc0100scn_device::ctrl_r(offs_t offset)
@@ -507,12 +489,6 @@ void tc0100scn_device::ctrl_w(offs_t offset, u16 data, u16 mem_mask)
{
/* Reinitialise layer pointers */
set_layer_ptrs();
-
- /* and ensure full redraw of the tilemaps */
- dirty_tilemaps();
-
- /* reset the pointer to the text characters (and dirty them all) */
- m_gfxdecode->gfx(m_txnum)->set_source((u8 *)m_char_ram);
}
break;
@@ -560,7 +536,7 @@ void tc0100scn_device::tilemap_update()
m_tilemap[1][m_dblwidth]->set_scrollx((j + m_fgscrolly) & 0x1ff, m_fgscrollx - m_fgscroll_ram[j]);
}
-void tc0100scn_device::tilemap_draw_fg( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, tilemap_t* tmap, int flags, u32 priority, u8 pmask )
+void tc0100scn_device::tilemap_draw_fg( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, tilemap_t* tmap, int flags, u8 priority, u8 pmask )
{
const bitmap_ind16 &src_bitmap = tmap->pixmap();
int width_mask, height_mask, x, y, p;
@@ -577,8 +553,9 @@ void tc0100scn_device::tilemap_draw_fg( screen_device &screen, bitmap_ind16 &bit
//We use cliprect.max_y and cliprect.max_x to support games which use more than 1 screen
+ src_y += cliprect.top();
// Row offsets are 'screen space' 0-255 regardless of Y scroll
- for (y = 0; y <= cliprect.max_y; y++)
+ for (y = cliprect.top(); y <= cliprect.bottom(); y++)
{
src_x = (m_fgscrollx - m_fgscroll_ram[(y + scrolly_delta) & 0x1ff] + scrollx_delta + cliprect.min_x) & width_mask;
if (m_ctrl[0x7] & 1) // Flipscreen
@@ -605,7 +582,7 @@ void tc0100scn_device::tilemap_draw_fg( screen_device &screen, bitmap_ind16 &bit
}
}
-int tc0100scn_device::tilemap_draw( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, u32 priority, u8 pmask )
+int tc0100scn_device::tilemap_draw( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, u8 priority, u8 pmask )
{
int disable = m_ctrl[6] & 0xf7;
rectangle clip = cliprect;