mame/video/tmap038.cpp : Device-fied 038 Tilemap generator (#5704)

* mame/video/tmap038.cpp : Device-fied 038 Tilemap generator
Used on cave.cpp, mcatadv.cpp
cave.cpp, mcatadv.cpp : Convert tilemap draw routine into tmap038.cpp
cave.cpp : Add notes, Fix spacing, Reduce duplicates
mcatadv.cpp : Simplify handlers, Reduce unnecessary line, Fix tilemap flicker with debug function enabled, Use shorter/correct type values

* tmap038.cpp : Add notes for manufacturer

Date marking (ex: 9341EX702) seems like NEC style.

* mcatadv.cpp : Minor revert

* tmap038.h : Add notes, const'd getters
This commit is contained in:
cam900 2019-10-18 23:32:00 +09:00 committed by R. Belmont
parent 0001989dea
commit 866b52fda9
9 changed files with 810 additions and 707 deletions

View File

@ -961,6 +961,8 @@ files {
MAME_DIR .. "src/mame/video/avgdvg.h",
MAME_DIR .. "src/mame/video/awpvid.cpp",
MAME_DIR .. "src/mame/video/awpvid.h",
MAME_DIR .. "src/mame/video/tmap038.cpp",
MAME_DIR .. "src/mame/video/tmap038.h",
MAME_DIR .. "src/mame/audio/dcs.cpp",
MAME_DIR .. "src/mame/audio/dcs.h",
MAME_DIR .. "src/mame/audio/decobsmt.cpp",

File diff suppressed because it is too large Load Diff

View File

@ -148,34 +148,32 @@ Stephh's notes (based on the games M68000 code and some tests) :
#include "speaker.h"
template<int Chip>
void mcatadv_state::get_banked_color(bool tiledim, u32 &color, u32 &pri, u32 &code)
{
pri |= 0x8;
color += m_palette_bank[Chip] * 0x40;
}
/*** Main CPU ***/
#if 0 // mcat only.. install read handler?
WRITE16_MEMBER(mcatadv_state::mcat_coin_w)
void mcatadv_state::mcat_coin_w(u8 data)
{
if(ACCESSING_BITS_8_15)
{
machine().bookkeeping().coin_counter_w(0, data & 0x1000);
machine().bookkeeping().coin_counter_w(1, data & 0x2000);
machine().bookkeeping().coin_lockout_w(0, ~data & 0x4000);
machine().bookkeeping().coin_lockout_w(1, ~data & 0x8000);
}
machine().bookkeeping().coin_counter_w(0, data & 0x10);
machine().bookkeeping().coin_counter_w(1, data & 0x20);
machine().bookkeeping().coin_lockout_w(0, ~data & 0x40);
machine().bookkeeping().coin_lockout_w(1, ~data & 0x80);
}
#endif
READ16_MEMBER(mcatadv_state::mcat_wd_r)
u16 mcatadv_state::mcat_wd_r()
{
m_watchdog->watchdog_reset();
if (!machine().side_effects_disabled())
m_watchdog->watchdog_reset();
return 0xc00;
}
template<int Chip>
WRITE16_MEMBER(mcatadv_state::vram_w)
{
COMBINE_DATA(&m_vram[Chip][offset]);
m_tilemap[Chip]->mark_tile_dirty(offset / 2);
}
void mcatadv_state::mcatadv_map(address_map &map)
{
@ -184,11 +182,11 @@ void mcatadv_state::mcatadv_map(address_map &map)
// map(0x180018, 0x18001f).nopr(); // ?
map(0x200000, 0x200005).ram().share("scroll1");
map(0x300000, 0x300005).ram().share("scroll2");
map(0x200000, 0x200005).rw(m_tilemap[0], FUNC(tilemap038_device::vregs_r), FUNC(tilemap038_device::vregs_w));
map(0x300000, 0x300005).rw(m_tilemap[1], FUNC(tilemap038_device::vregs_r), FUNC(tilemap038_device::vregs_w));
map(0x400000, 0x401fff).ram().w(FUNC(mcatadv_state::vram_w<0>)).share("vram_1"); // Tilemap 0
map(0x500000, 0x501fff).ram().w(FUNC(mcatadv_state::vram_w<1>)).share("vram_2"); // Tilemap 1
map(0x400000, 0x401fff).m(m_tilemap[0], FUNC(tilemap038_device::vram_16x16_map)); // Tilemap 0
map(0x500000, 0x501fff).m(m_tilemap[1], FUNC(tilemap038_device::vram_16x16_map)); // Tilemap 1
map(0x600000, 0x601fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x602000, 0x602fff).ram(); // Bigger than needs to be?
@ -198,7 +196,7 @@ void mcatadv_state::mcatadv_map(address_map &map)
map(0x800000, 0x800001).portr("P1");
map(0x800002, 0x800003).portr("P2");
// map(0x900000, 0x900001).w(FUNC(mcatadv_state::mcat_coin_w)); // Lockout / Counter MCAT Only
// map(0x900000, 0x900000).w(FUNC(mcatadv_state::mcat_coin_w)); // Lockout / Counter MCAT Only
map(0xa00000, 0xa00001).portr("DSW1");
map(0xa00002, 0xa00003).portr("DSW2");
@ -212,7 +210,7 @@ void mcatadv_state::mcatadv_map(address_map &map)
/*** Sound ***/
WRITE8_MEMBER(mcatadv_state::mcatadv_sound_bw_w)
void mcatadv_state::mcatadv_sound_bw_w(u8 data)
{
m_soundbank->set_entry(data);
}
@ -408,14 +406,14 @@ INPUT_PORTS_END
/*** GFX Decode ***/
static GFXDECODE_START( gfx_mcatadv )
GFXDECODE_ENTRY( "bg0", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0, 0x200 )
GFXDECODE_ENTRY( "bg1", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0, 0x200 )
GFXDECODE_ENTRY( "bg0", 0, gfx_8x8x4_packed_msb, 0, 0x200 )
GFXDECODE_ENTRY( "bg1", 0, gfx_8x8x4_packed_msb, 0, 0x200 )
GFXDECODE_END
void mcatadv_state::machine_start()
{
uint32_t max = memregion("soundcpu")->bytes()/0x4000;
const u32 max = memregion("soundcpu")->bytes()/0x4000;
m_soundbank->configure_entries(0, max, memregion("soundcpu")->base(), 0x4000);
m_soundbank->set_entry(1);
@ -447,6 +445,16 @@ void mcatadv_state::mcatadv(machine_config &config)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_mcatadv);
PALETTE(config, m_palette).set_format(palette_device::xGRB_555, 0x2000/2);
TMAP038(config, m_tilemap[0]);
m_tilemap[0]->set_gfxdecode_tag(m_gfxdecode);
m_tilemap[0]->set_gfx(0);
m_tilemap[0]->set_tile_callback(tilemap038_device::tmap038_cb_delegate(FUNC(mcatadv_state::get_banked_color<0>), this));
TMAP038(config, m_tilemap[1]);
m_tilemap[1]->set_gfxdecode_tag(m_gfxdecode);
m_tilemap[1]->set_gfx(1);
m_tilemap[1]->set_tile_callback(tilemap038_device::tmap038_cb_delegate(FUNC(mcatadv_state::get_banked_color<1>), this));
WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_seconds(3)); /* a guess, and certainly wrong */
/* sound hardware */

View File

@ -15,6 +15,7 @@
#include "machine/gen_latch.h"
#include "machine/timer.h"
#include "sound/okim6295.h"
#include "video/tmap038.h"
#include "emupal.h"
#include "screen.h"
#include "tilemap.h"
@ -25,8 +26,6 @@ public:
cave_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_videoregs(*this, "videoregs.%u", 0)
, m_vram(*this, "vram.%u", 0)
, m_vctrl(*this, "vctrl.%u", 0)
, m_spriteram(*this, "spriteram.%u", 0)
, m_io_in0(*this, "IN0")
, m_touch_x(*this, "TOUCH%u_X", 1U)
@ -48,6 +47,7 @@ public:
, m_gfxdecode(*this, "gfxdecode.%u", 0U)
, m_screen(*this, "screen.%u", 0U)
, m_palette(*this, "palette.%u", 0U)
, m_tilemap(*this, "tilemap.%u", 0U)
, m_soundlatch(*this, "soundlatch")
, m_startup(*this, "startup")
, m_led_outputs(*this, "led%u", 0U)
@ -103,7 +103,7 @@ private:
void (cave_state::*m_get_sprite_info)(int chip);
void (cave_state::*m_sprite_draw)(int chip, int priority);
void add_base_config(machine_config &config);
void add_base_config(machine_config &config, int layer);
void add_ymz(machine_config &config);
u16 irq_cause_r(offs_t offset);
@ -124,8 +124,6 @@ private:
template<int Mask> void z80_rombank_w(u8 data);
template<int Mask> void oki1_bank_w(u8 data);
template<int Mask> void oki2_bank_w(u8 data);
template<int Chip> void vram_w(offs_t offset, u16 data, u16 mem_mask);
template<int Chip> void vram_8x8_w(offs_t offset, u16 data, u16 mem_mask);
void eeprom_w(u8 data);
void sailormn_eeprom_w(u8 data);
void hotdogst_eeprom_w(u8 data);
@ -138,17 +136,12 @@ private:
void ppsatan_io_mux_w(offs_t offset, u16 data, u16 mem_mask);
template<int Player> u16 ppsatan_touch_r();
void ppsatan_out_w(offs_t offset, u16 data, u16 mem_mask);
TILE_GET_INFO_MEMBER(sailormn_get_tile_info_2);
template<int Chip, int Gfx> TILE_GET_INFO_MEMBER(get_tile_info);
void sailormn_get_banked_code(bool tiledim, u32 &color, u32 &pri, u32 &code);
DECLARE_MACHINE_RESET(sailormn);
DECLARE_VIDEO_START(ddonpach);
DECLARE_VIDEO_START(dfeveron);
DECLARE_VIDEO_START(donpachi);
DECLARE_VIDEO_START(spr_4bpp);
DECLARE_VIDEO_START(spr_8bpp);
DECLARE_VIDEO_START(korokoro);
DECLARE_VIDEO_START(ppsatan);
DECLARE_VIDEO_START(pwrinst2);
DECLARE_VIDEO_START(sailormn);
DECLARE_VIDEO_START(uopoko);
void cave_palette(palette_device &palette);
void dfeveron_palette(palette_device &palette);
void korokoro_palette(palette_device &palette);
@ -183,8 +176,6 @@ private:
/* memory pointers */
optional_shared_ptr_array<u16, 4> m_videoregs;
optional_shared_ptr_array<u16, 4> m_vram;
optional_shared_ptr_array<u16, 4> m_vctrl;
optional_shared_ptr_array<u16, 4> m_spriteram;
optional_ioport m_io_in0;
@ -235,10 +226,6 @@ private:
std::unique_ptr<sprite_cave []> m_sprite[4];
sprite_cave *m_sprite_table[4][MAX_PRIORITY][MAX_SPRITE_NUM + 1];
tilemap_t *m_tilemap[4];
bool m_tiledim[4];
bool m_old_tiledim[4];
bitmap_ind16 m_sprite_zbuf[4];
u16 m_sprite_zbuf_baseval;
@ -295,6 +282,7 @@ private:
optional_device_array<gfxdecode_device, 4> m_gfxdecode;
optional_device_array<screen_device, 4> m_screen;
optional_device_array<palette_device, 4> m_palette;
optional_device_array<tilemap038_device, 4> m_tilemap;
optional_device<generic_latch_16_device> m_soundlatch;
optional_device<timer_device> m_startup;
output_finder<9> m_led_outputs;
@ -304,7 +292,7 @@ private:
inline void tilemap_draw(int chip, screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 flags, u32 priority, u32 priority2, int GFX);
void set_pens(int chip);
void vh_start(int num, u16 sprcol_base, u16 sprcol_granularity);
void vh_start(u16 sprcol_base, u16 sprcol_granularity);
void get_sprite_info_cave(int chip);
void get_sprite_info_donpachi(int chip);
void sprite_init();

View File

@ -6,6 +6,7 @@
#pragma once
#include "machine/watchdog.h"
#include "video/tmap038.h"
#include "emupal.h"
#include "tilemap.h"
@ -14,8 +15,6 @@ class mcatadv_state : public driver_device
public:
mcatadv_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_vram(*this, "vram_%u", 1)
, m_scroll(*this, "scroll%u", 1)
, m_spriteram(*this, "spriteram")
, m_vidregs(*this, "vidregs")
, m_sprdata(*this, "sprdata")
@ -25,6 +24,7 @@ public:
, m_watchdog(*this, "watchdog")
, m_gfxdecode(*this, "gfxdecode")
, m_palette(*this, "palette")
, m_tilemap(*this, "tilemap_%u", 0U)
{ }
void nost(machine_config &config);
@ -32,18 +32,15 @@ public:
private:
/* memory pointers */
required_shared_ptr_array<uint16_t, 2> m_vram;
required_shared_ptr_array<uint16_t, 2> m_scroll;
required_shared_ptr<uint16_t> m_spriteram;
std::unique_ptr<uint16_t[]> m_spriteram_old;
required_shared_ptr<uint16_t> m_vidregs;
std::unique_ptr<uint16_t[]> m_vidregs_old;
required_shared_ptr<u16> m_spriteram;
std::unique_ptr<u16[]> m_spriteram_old;
required_shared_ptr<u16> m_vidregs;
std::unique_ptr<u16[]> m_vidregs_old;
required_region_ptr<uint8_t> m_sprdata;
required_region_ptr<u8> m_sprdata;
required_memory_bank m_soundbank;
/* video-related */
tilemap_t *m_tilemap[2];
int m_palette_bank[2];
/* devices */
@ -52,14 +49,14 @@ private:
required_device<watchdog_timer_device> m_watchdog;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
optional_device_array<tilemap038_device, 2> m_tilemap;
DECLARE_READ16_MEMBER(mcat_wd_r);
DECLARE_WRITE8_MEMBER(mcatadv_sound_bw_w);
template<int Chip> DECLARE_WRITE16_MEMBER(vram_w);
template<int Chip> TILE_GET_INFO_MEMBER(get_mcatadv_tile_info);
u16 mcat_wd_r();
void mcatadv_sound_bw_w(u8 data);
template<int Chip> void get_banked_color(bool tiledim, u32 &color, u32 &pri, u32 &code);
virtual void machine_start() override;
virtual void video_start() override;
uint32_t screen_update_mcatadv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_mcatadv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank_mcatadv);
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
void mcatadv_draw_tilemap_part( screen_device &screen, int layer, int i, bitmap_ind16 &bitmap, const rectangle &cliprect );

View File

@ -59,62 +59,6 @@ Note: if MAME_DEBUG is defined, pressing:
#define SPRITE_VISIBLE_CAVE 0x04
/***************************************************************************
Tiles Format
Offset: Bits: Value:
0.w fe-- ---- ---- --- Priority
--dc ba98 ---- ---- Color
---- ---- 7654 3210
2.w Code
When a row-scroll / row-select effect is enabled, the scroll values are
fetched starting from tile RAM + $1000, 4 bytes per scan line:
Offset: Value:
0.w Tilemap line to display
2.w X Scroll value
***************************************************************************/
template<int Chip, int Gfx>
TILE_GET_INFO_MEMBER(cave_state::get_tile_info)
{
u16 *VRAM = m_vram[Chip];
const bool TDIM = m_tiledim[Chip];
u32 code, color, pri, tile;
if (TDIM)
{
tile = (tile_index % (512 / 8)) / 2 + ((tile_index / (512 / 8)) / 2) * (512 / 16);
code = (VRAM[tile * 2 + 0x0000 / 2] << 16) + VRAM[tile * 2 + 0x0002 / 2];
color = (code & 0x3f000000) >> (32-8);
pri = (code & 0xc0000000) >> (32-2);
code = (code & 0x00ffffff) * 4;
code += tile_index & 1;
code += ((tile_index / (512 / 8)) & 1) * 2;
}
else
{
code = (VRAM[tile_index * 2 + 0x4000 / 2] << 16) + VRAM[tile_index * 2 + 0x4002 / 2];
color = (code & 0x3f000000) >> (32 - 8);
pri = (code & 0xc0000000) >> (32 - 2);
code = (code & 0x00ffffff);
}
SET_TILE_INFO_MEMBER(Gfx, code, color, 0);
tileinfo.category = pri;
}
/* Sailormn: the lower 2 Megabytes of tiles banked */
void cave_state::sailormn_tilebank_w(int bank)
@ -126,36 +70,13 @@ void cave_state::sailormn_tilebank_w(int bank)
}
}
TILE_GET_INFO_MEMBER(cave_state::sailormn_get_tile_info_2)
void cave_state::sailormn_get_banked_code(bool tiledim, u32 &color, u32 &pri, u32 &code)
{
u32 code, color, pri;
if (m_tiledim[2])
if (!tiledim)
{
u32 tile;
tile = (tile_index % (512 / 8)) / 2 + ((tile_index / (512 / 8)) / 2) * (512 / 16);
code = (m_vram[2][tile * 2 + 0x0000 / 2] << 16) + m_vram[2][tile * 2 + 0x0002 / 2];
color = (code & 0x3f000000) >> (32 - 8);
pri = (code & 0xc0000000) >> (32 - 2);
code = (code & 0x00ffffff) * 4;
code += tile_index & 1;
code += ((tile_index / (512 / 8)) & 1) * 2;
}
else
{
code = (m_vram[2][tile_index * 2 + 0x4000 / 2] << 16) + m_vram[2][tile_index * 2 + 0x4002 / 2];
color = (code & 0x3f000000) >> (32 - 8);
pri = (code & 0xc0000000) >> (32 - 2);
code = (code & 0x00ffffff);
if ((code < 0x10000) && (m_sailormn_tilebank))
code += 0x40000;
}
SET_TILE_INFO_MEMBER(2, code, color, 0);
tileinfo.category = pri;
}
@ -168,65 +89,11 @@ TILE_GET_INFO_MEMBER(cave_state::sailormn_get_tile_info_2)
***************************************************************************/
void cave_state::vh_start(int num, u16 sprcol_base, u16 sprcol_granularity)
void cave_state::vh_start(u16 sprcol_base, u16 sprcol_granularity)
{
m_sprite_base_pal = sprcol_base;
m_sprite_granularity = sprcol_granularity;
m_tilemap[0] = nullptr;
m_tilemap[1] = nullptr;
m_tilemap[2] = nullptr;
m_tilemap[3] = nullptr;
m_tiledim[0] = false;
m_tiledim[1] = false;
m_tiledim[2] = false;
m_tiledim[3] = false;
m_old_tiledim[0] = false;
m_old_tiledim[1] = false;
m_old_tiledim[2] = false;
m_old_tiledim[3] = false;
assert((num >= 1) && (num <= 4));
switch (num)
{
case 4:
m_tilemap[3] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(&cave_state::get_tile_info<3, 3>, "screen0_layer3",this), TILEMAP_SCAN_ROWS, 8, 8, 512 / 8, 512 / 8);
m_tilemap[3]->set_transparent_pen(0);
m_tilemap[3]->set_scroll_rows(1);
m_tilemap[3]->set_scroll_cols(1);
save_item(NAME(m_tiledim[3]));
save_item(NAME(m_old_tiledim[3]));
case 3:
m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(&cave_state::get_tile_info<2, 2>, "screen0_layer2",this), TILEMAP_SCAN_ROWS, 8, 8, 512 / 8, 512 / 8);
m_tilemap[2]->set_transparent_pen(0);
m_tilemap[2]->set_scroll_rows(1);
m_tilemap[2]->set_scroll_cols(1);
save_item(NAME(m_tiledim[2]));
save_item(NAME(m_old_tiledim[2]));
case 2:
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(&cave_state::get_tile_info<1, 1>, "screen0_layer1",this), TILEMAP_SCAN_ROWS, 8, 8, 512 / 8, 512 / 8);
m_tilemap[1]->set_transparent_pen(0);
m_tilemap[1]->set_scroll_rows(1);
m_tilemap[1]->set_scroll_cols(1);
save_item(NAME(m_tiledim[1]));
save_item(NAME(m_old_tiledim[1]));
case 1:
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(&cave_state::get_tile_info<0, 0>, "screen0_layer0",this), TILEMAP_SCAN_ROWS, 8, 8, 512 / 8, 512 / 8);
m_tilemap[0]->set_transparent_pen(0);
m_tilemap[0]->set_scroll_rows(1);
m_tilemap[0]->set_scroll_cols(1);
save_item(NAME(m_tiledim[0]));
save_item(NAME(m_old_tiledim[0]));
break;
}
sprite_init();
m_layers_offs_x = 0x13;
@ -255,48 +122,28 @@ void cave_state::vh_start(int num, u16 sprcol_base, u16 sprcol_granularity)
}
}
// ddonpach esprade gaia guwange (8bpp tilemap)
VIDEO_START_MEMBER(cave_state,ddonpach)
// 4 bit sprite granularity
VIDEO_START_MEMBER(cave_state,spr_4bpp)
{
vh_start(3, 0, 256);
vh_start(0, 16);
}
// dfeveron mazinger
VIDEO_START_MEMBER(cave_state,dfeveron)
// 8 bit sprite granularity
VIDEO_START_MEMBER(cave_state,spr_8bpp)
{
vh_start(2, 0, 16);
}
// donpachi hotdogst metmqstr
VIDEO_START_MEMBER(cave_state,donpachi)
{
vh_start(3, 0, 16);
vh_start(0, 256);
}
// korokoro (different sprite base palette)
VIDEO_START_MEMBER(cave_state,korokoro)
{
vh_start(1, 0x3c00, 16);
vh_start(0x3c00, 16);
}
// ppsatan (3 screen)
VIDEO_START_MEMBER(cave_state,ppsatan)
{
vh_start(1, 0x3c00, 16);
m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode[2], tilemap_get_info_delegate(&cave_state::get_tile_info<2, 0>, "screen2_layer0",this), TILEMAP_SCAN_ROWS, 8, 8, 512 / 8, 512 / 8);
m_tilemap[2]->set_transparent_pen(0);
m_tilemap[2]->set_scroll_rows(1);
m_tilemap[2]->set_scroll_cols(1);
save_item(NAME(m_tiledim[2]));
save_item(NAME(m_old_tiledim[2]));
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode[1], tilemap_get_info_delegate(&cave_state::get_tile_info<1, 0>, "screen1_layer0",this), TILEMAP_SCAN_ROWS, 8, 8, 512 / 8, 512 / 8);
m_tilemap[1]->set_transparent_pen(0);
m_tilemap[1]->set_scroll_rows(1);
m_tilemap[1]->set_scroll_cols(1);
save_item(NAME(m_tiledim[1]));
save_item(NAME(m_old_tiledim[1]));
vh_start(0x3c00, 16);
for (int chip = 1; chip < 3; chip++)
{
m_background_pen[chip] = m_gfxdecode[chip]->gfx(0)->colorbase() +
@ -313,33 +160,6 @@ VIDEO_START_MEMBER(cave_state,ppsatan)
}
}
// pwrinst2
VIDEO_START_MEMBER(cave_state,pwrinst2)
{
vh_start(4, 0, 16);
}
// sailormn agallet
VIDEO_START_MEMBER(cave_state,sailormn)
{
vh_start(2, 0, 16);
/* Layer 2 (8x8) needs to be handled differently */
m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(FUNC(cave_state::sailormn_get_tile_info_2),this), TILEMAP_SCAN_ROWS, 8, 8, 512 / 8, 512 / 8);
m_tilemap[2]->set_transparent_pen(0);
m_tilemap[2]->set_scroll_rows(1);
m_tilemap[2]->set_scroll_cols(1);
save_item(NAME(m_tiledim[2]));
save_item(NAME(m_old_tiledim[2]));
}
// uopoko tjumpman (8bpp tilemap, but single tilemap layer)
VIDEO_START_MEMBER(cave_state,uopoko)
{
vh_start(1, 0, 256);
}
/***************************************************************************
Sprites Drawing
@ -1273,19 +1093,19 @@ inline void cave_state::tilemap_draw(int chip,
screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect,
u32 flags, u32 priority, u32 priority2, int GFX)
{
tilemap_t *TILEMAP = m_tilemap[GFX];
const u16 *VRAM = m_vram[GFX];
const u16 *VCTRL = m_vctrl[GFX];
tilemap038_device *TILEMAP = m_tilemap[GFX];
/* Bail out if ... */
if ((!TILEMAP) || /* no tilemap; */
((VCTRL[2] & 0x0003) != priority2) || /* tilemap's global priority not the requested one; */
((VCTRL[2] & 0x0010))) /* tilemap's disabled. */
if (!TILEMAP) /* no tilemap; */
return;
const bool flipx = ~VCTRL[0] & 0x8000;
const bool flipy = ~VCTRL[1] & 0x8000;
if (((TILEMAP->external() & 0x0003) != priority2) || /* tilemap's global priority not the requested one; */
((!TILEMAP->enable()))) /* tilemap's disabled. */
return;
const bool flipx = TILEMAP->flipx();
const bool flipy = TILEMAP->flipy();
TILEMAP->set_flip((flipx ? TILEMAP_FLIPX : 0) | (flipy ? TILEMAP_FLIPY : 0));
int offs_x = m_layers_offs_x;
@ -1296,15 +1116,15 @@ inline void cave_state::tilemap_draw(int chip,
/* An additional 8 pixel offset for layers with 8x8 tiles. Plus
Layer 0 is displaced by 1 pixel wrt Layer 1, so is Layer 2 wrt
Layer 1 */
if (TILEMAP == m_tilemap[0]) offs_x -= (m_tiledim[0] ? 1 : (1 + 8));
else if (TILEMAP == m_tilemap[1]) offs_x -= (m_tiledim[1] ? 2 : (2 + 8));
else if (TILEMAP == m_tilemap[2]) offs_x -= (m_tiledim[2] ? 3 : (3 + 8));
else if (TILEMAP == m_tilemap[3]) offs_x -= (m_tiledim[3] ? 4 : (4 + 8));
if (TILEMAP == m_tilemap[0]) offs_x -= (TILEMAP->tiledim() ? 1 : (1 + 8));
else if (TILEMAP == m_tilemap[1]) offs_x -= (TILEMAP->tiledim() ? 2 : (2 + 8));
else if (TILEMAP == m_tilemap[2]) offs_x -= (TILEMAP->tiledim() ? 3 : (3 + 8));
else if (TILEMAP == m_tilemap[3]) offs_x -= (TILEMAP->tiledim() ? 4 : (4 + 8));
const int sx = VCTRL[0] - m_videoregs[chip][0] + (flipx ? (offs_x + 2) : -offs_x);
const int sy = VCTRL[1] - m_videoregs[chip][1] + (flipy ? (offs_y + 2) : -offs_y);
const int sx = TILEMAP->scrollx() - m_videoregs[chip][0] + (flipx ? (offs_x + 2) : -offs_x);
const int sy = TILEMAP->scrolly() - m_videoregs[chip][1] + (flipy ? (offs_y + 2) : -offs_y);
if (VCTRL[1] & 0x4000) // row-select
if (TILEMAP->rowselect_en()) // row-select
{
rectangle clip;
int endline, vramdata0, vramdata1;
@ -1323,26 +1143,26 @@ inline void cave_state::tilemap_draw(int chip,
for (int startline = cliprect.min_y; startline <= cliprect.max_y;)
{
/* Find the largest slice */
vramdata0 = (vramdata1 = VRAM[(0x1002 + (((sy + offs_row + startline) * 4) & 0x7ff)) / 2]);
vramdata0 = (vramdata1 = TILEMAP->rowselect(sy + offs_row + startline));
for (endline = startline + 1; endline <= cliprect.max_y; endline++)
if ((++vramdata1) != VRAM[(0x1002 + (((sy + offs_row + endline) * 4) & 0x7ff)) / 2]) break;
if ((++vramdata1) != TILEMAP->rowselect(sy + offs_row + endline)) break;
TILEMAP->set_scrolly(0, vramdata0 - startline);
if (VCTRL[0] & 0x4000) // row-scroll, row-select
if (TILEMAP->rowscroll_en()) // row-scroll, row-select
{
/*
Row-scroll:
A different scroll value is specified for each scan line.
This is handled using tilemap_set_scroll_rows and calling
tilemap_draw just once.
This is handled using tilemap->set_scroll_rows and calling
tilemap->draw just once.
*/
TILEMAP->set_scroll_rows(512);
for (int line = startline; line < endline; line++)
TILEMAP->set_scrollx((vramdata0 - startline + line) & 511,
sx + VRAM[(0x1000 + (((sy + offs_row + line) * 4) & 0x7ff)) / 2]);
sx + TILEMAP->rowscroll(sy + offs_row + line));
}
else // no row-scroll, row-select
{
@ -1366,18 +1186,18 @@ inline void cave_state::tilemap_draw(int chip,
startline = endline;
}
}
else if (VCTRL[0] & 0x4000) // row-scroll, no row-select
else if (TILEMAP->rowscroll_en()) // row-scroll, no row-select
{
TILEMAP->set_scroll_rows(512);
for (int line = cliprect.min_y; line <= cliprect.max_y; line++)
TILEMAP->set_scrollx((line + sy) & 511,
sx + VRAM[(0x1000+(((sy + offs_row + line) * 4) & 0x7ff)) / 2]);
sx + TILEMAP->rowscroll(sy + offs_row + line));
TILEMAP->set_scrolly(0, sy);
TILEMAP->draw(screen, bitmap, cliprect, flags, priority);
}
else
{
/* DEF_STR(Normal) scrolling */
/* Normal scrolling */
TILEMAP->set_scroll_rows(1);
TILEMAP->set_scroll_cols(1);
TILEMAP->set_scrollx(0, sx);
@ -1396,16 +1216,10 @@ u32 cave_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
m_blit.baseaddr_zbuf = reinterpret_cast<u8 *>(m_sprite_zbuf[0].raw_pixptr(0));
m_blit.line_offset_zbuf = m_sprite_zbuf[0].rowbytes();
/* Choose the tilemap to display (8x8 tiles or 16x16 tiles) */
for (int GFX = 0; GFX < 4; GFX++)
{
if (m_tilemap[GFX])
{
m_tiledim[GFX] = m_vctrl[GFX][1] & 0x2000;
if (m_tiledim[GFX] != m_old_tiledim[GFX])
m_tilemap[GFX]->mark_all_dirty();
m_old_tiledim[GFX] = m_tiledim[GFX];
}
m_tilemap[GFX]->prepare();
}
#ifdef MAME_DEBUG
@ -1435,10 +1249,10 @@ u32 cave_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
m_videoregs[0][4], m_videoregs[0][5], m_videoregs[0][6], m_videoregs[0][7]);
#endif
/* Show the scroll / flags registers of the selected layer */
if ((m_tilemap[0]) && (msk & 0x000f)) popmessage("x:%04X y:%04X f:%04X", m_vctrl[0][0],m_vctrl[0][1],m_vctrl[0][2]);
if ((m_tilemap[1]) && (msk & 0x00f0)) popmessage("x:%04X y:%04X f:%04X", m_vctrl[1][0],m_vctrl[1][1],m_vctrl[1][2]);
if ((m_tilemap[2]) && (msk & 0x0f00)) popmessage("x:%04X y:%04X f:%04X", m_vctrl[2][0],m_vctrl[2][1],m_vctrl[2][2]);
if ((m_tilemap[3]) && (msk & 0xf000)) popmessage("x:%04X y:%04X f:%04X", m_vctrl[3][0],m_vctrl[3][1],m_vctrl[3][2]);
if ((m_tilemap[0]) && (msk & 0x000f)) popmessage("x:%04X y:%04X f:%04X", m_tilemap[0]->vregs(0),m_tilemap[0]->vregs(1),m_tilemap[0]->vregs(2));
if ((m_tilemap[1]) && (msk & 0x00f0)) popmessage("x:%04X y:%04X f:%04X", m_tilemap[1]->vregs(0),m_tilemap[1]->vregs(1),m_tilemap[1]->vregs(2));
if ((m_tilemap[2]) && (msk & 0x0f00)) popmessage("x:%04X y:%04X f:%04X", m_tilemap[2]->vregs(0),m_tilemap[2]->vregs(1),m_tilemap[2]->vregs(2));
if ((m_tilemap[3]) && (msk & 0xf000)) popmessage("x:%04X y:%04X f:%04X", m_tilemap[3]->vregs(0),m_tilemap[3]->vregs(1),m_tilemap[3]->vregs(2));
}
/* Show the row / "column" scroll enable flags, when they change state */
@ -1447,8 +1261,8 @@ u32 cave_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const
{
if (m_tilemap[GFX])
{
m_rasflag |= (m_vctrl[GFX][0] & 0x4000) ? 0x0001 << (4*GFX) : 0;
m_rasflag |= (m_vctrl[GFX][1] & 0x4000) ? 0x0002 << (4*GFX) : 0;
m_rasflag |= (m_tilemap[GFX]->vregs(0) & 0x4000) ? 0x0001 << (4*GFX) : 0;
m_rasflag |= (m_tilemap[GFX]->vregs(1) & 0x4000) ? 0x0002 << (4*GFX) : 0;
}
}
@ -1540,10 +1354,7 @@ u32 cave_state::screen_update_ppsatan_core(screen_device &screen, bitmap_rgb32 &
m_blit.baseaddr_zbuf = reinterpret_cast<u8 *>(m_sprite_zbuf[chip].raw_pixptr(0));
m_blit.line_offset_zbuf = m_sprite_zbuf[chip].rowbytes();
m_tiledim[chip] = m_vctrl[chip][1] & 0x2000;
if (m_tiledim[chip] != m_old_tiledim[chip])
m_tilemap[chip]->mark_all_dirty();
m_old_tiledim[chip] = m_tiledim[chip];
m_tilemap[chip]->prepare();
sprite_check(chip, chip, screen, cliprect);

View File

@ -16,31 +16,16 @@ ToDo: Fix Sprites & Rowscroll/Select for Cocktail
#include <algorithm>
template<int Chip>
TILE_GET_INFO_MEMBER(mcatadv_state::get_mcatadv_tile_info)
{
int tileno = m_vram[Chip][tile_index * 2 + 1];
int colour = (m_vram[Chip][tile_index * 2] & 0x3f00) >> 8;
int pri = (m_vram[Chip][tile_index * 2] & 0xc000) >> 14;
pri |= 0x8;
SET_TILE_INFO_MEMBER(Chip,tileno,colour + m_palette_bank[Chip] * 0x40, 0);
tileinfo.category = pri;
}
void mcatadv_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
{
uint16_t *source = (m_spriteram_old.get() + (m_spriteram.bytes() / 2) /2);
u16 *source = (m_spriteram_old.get() + (m_spriteram.bytes() / 2) /2);
source -= 4;
uint16_t *finish = m_spriteram_old.get();
int global_x = m_vidregs[0] - 0x184;
int global_y = m_vidregs[1] - 0x1f1;
u16 *finish = m_spriteram_old.get();
int const global_x = m_vidregs[0] - 0x184;
int const global_y = m_vidregs[1] - 0x1f1;
uint16_t *destline;
uint8_t *priline;
int sprmask = m_sprdata.bytes()-1;
u32 const sprmask = m_sprdata.bytes()-1;
int xstart, xend, xinc;
int ystart, yend, yinc;
@ -57,9 +42,9 @@ void mcatadv_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, c
while (source >= finish)
{
int pen = (source[0] & 0x3f00) >> 8;
int tileno = source[1] & 0xffff;
int pri = (source[0] & 0xc000) >> 14;
u32 const pen = (source[0] & 0x3f00) >> 8;
u32 const tileno = source[1] & 0xffff;
u8 pri = (source[0] & 0xc000) >> 14;
pri |= 0x8;
@ -68,13 +53,9 @@ void mcatadv_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, c
int flipy = source[0] & 0x0040;
int flipx = source[0] & 0x0080;
int height = ((source[3] & 0xf000) >> 12) * 16;
int width = ((source[2] & 0xf000) >> 12) * 16;
int offset = tileno * 256;
int drawxpos, drawypos;
int xcnt, ycnt;
int pix;
int const height = ((source[3] & 0xf000) >> 12) * 16;
int const width = ((source[2] & 0xf000) >> 12) * 16;
u32 offset = tileno * 256;
if (x & 0x200) x-=0x400;
if (y & 0x200) y-=0x400;
@ -97,26 +78,26 @@ void mcatadv_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, c
if(!flipy) { ystart = 0; yend = height; yinc = 1; }
else { ystart = height-1; yend = -1; yinc = -1; }
for (ycnt = ystart; ycnt != yend; ycnt += yinc)
for (int ycnt = ystart; ycnt != yend; ycnt += yinc)
{
drawypos = y + ycnt - global_y;
const int drawypos = y + ycnt - global_y;
if ((drawypos >= cliprect.min_y) && (drawypos <= cliprect.max_y))
{
destline = &bitmap.pix16(drawypos);
priline = &screen.priority().pix8(drawypos);
u16 *destline = &bitmap.pix16(drawypos);
u8 *priline = &screen.priority().pix8(drawypos);
for (xcnt = xstart; xcnt != xend; xcnt += xinc)
for (int xcnt = xstart; xcnt != xend; xcnt += xinc)
{
drawxpos = x + xcnt - global_x;
const int drawxpos = x + xcnt - global_x;
if ((drawxpos >= cliprect.min_x) && (drawxpos <= cliprect.max_x))
{
int pridata = priline[drawxpos];
const int pridata = priline[drawxpos];
if (!(pridata & 0x10)) // if we haven't already drawn a sprite pixel here (sprite masking)
{
pix = m_sprdata[(offset / 2)&sprmask];
u8 pix = m_sprdata[(offset / 2)&sprmask];
if (offset & 1)
pix = pix >> 4;
@ -147,39 +128,38 @@ void mcatadv_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, c
void mcatadv_state::mcatadv_draw_tilemap_part( screen_device &screen, int layer, int i, bitmap_ind16 &bitmap, const rectangle &cliprect )
{
int flip;
uint32_t drawline;
if (!m_tilemap[layer]->enable())
return;
rectangle clip;
clip.min_x = cliprect.min_x;
clip.max_x = cliprect.max_x;
for (drawline = cliprect.min_y; drawline <= cliprect.max_y; drawline++)
for (u32 drawline = cliprect.min_y; drawline <= cliprect.max_y; drawline++)
{
int scrollx, scrolly;
clip.min_y = drawline;
clip.max_y = drawline;
scrollx = (m_scroll[layer][0] & 0x1ff) - 0x194;
scrolly = (m_scroll[layer][1] & 0x1ff) - 0x1df;
int scrollx = (m_tilemap[layer]->scrollx() & 0x1ff) - 0x194;
int scrolly = (m_tilemap[layer]->scrolly() & 0x1ff) - 0x1df;
if ((m_scroll[layer][1] & 0x4000) == 0x4000)
if (m_tilemap[layer]->rowselect_en())
{
int rowselect = m_vram[layer][0x1000 / 2 + (((drawline + scrolly) & 0x1ff) * 2) + 1];
const int rowselect = m_tilemap[layer]->rowselect(drawline + scrolly);
scrolly = rowselect - drawline;
}
if ((m_scroll[layer][0] & 0x4000) == 0x4000)
if (m_tilemap[layer]->rowscroll_en())
{
int rowscroll = m_vram[layer][0x1000 / 2 + (((drawline + scrolly) & 0x1ff) * 2) + 0];
const int rowscroll = m_tilemap[layer]->rowscroll(drawline + scrolly);
scrollx += rowscroll;
}
/* Global Flip */
if (!(m_scroll[layer][0] & 0x8000)) scrollx -= 0x19;
if (!(m_scroll[layer][1] & 0x8000)) scrolly -= 0x141;
flip = ((m_scroll[layer][0] & 0x8000) ? 0 : TILEMAP_FLIPX) | ((m_scroll[layer][1] & 0x8000) ? 0 : TILEMAP_FLIPY);
if (m_tilemap[layer]->flipx()) scrollx -= 0x19;
if (m_tilemap[layer]->flipy()) scrolly -= 0x141;
int flip = (m_tilemap[layer]->flipx() ? TILEMAP_FLIPX : 0) | (m_tilemap[layer]->flipy() ? TILEMAP_FLIPY : 0);
m_tilemap[layer]->set_scrollx(0, scrollx);
m_tilemap[layer]->set_scrolly(0, scrolly);
@ -189,45 +169,39 @@ void mcatadv_state::mcatadv_draw_tilemap_part( screen_device &screen, int layer,
}
}
uint32_t mcatadv_state::screen_update_mcatadv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 mcatadv_state::screen_update_mcatadv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int i;
bitmap.fill(0x3f0, cliprect);
screen.priority().fill(0, cliprect);
if (m_scroll[0][2] != m_palette_bank[0])
for (int i = 0; i < 2; i++)
{
m_palette_bank[0] = m_scroll[0][2]&0xf;
m_tilemap[0]->mark_all_dirty();
}
if (m_scroll[1][2] != m_palette_bank[1])
{
m_palette_bank[1] = m_scroll[1][2]&0xf;
m_tilemap[1]->mark_all_dirty();
m_tilemap[i]->prepare();
if (m_tilemap[i]->external() != m_palette_bank[i])
{
m_palette_bank[i] = m_tilemap[i]->external()&0xf;
m_tilemap[i]->mark_all_dirty();
}
}
/*
popmessage("%02x %02x %02x %02x",
(mcatadv_scroll1[0] & 0x4000) >> 8,
(mcatadv_scroll1[1] & 0x4000) >> 8,
(mcatadv_scroll2[0] & 0x4000) >> 8,
(mcatadv_scroll2[1] & 0x4000) >> 8);
m_tilemap[0]->rowscroll_en(),
m_tilemap[0]->rowselect_en(),
m_tilemap[1]->rowscroll_en(),
m_tilemap[1]->rowselect_en());
*/
for (i = 0; i <= 3; i++)
for (int i = 0; i <= 3; i++)
{
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_Q))
#endif
if (!(m_scroll[0][2]&0x10))
mcatadv_draw_tilemap_part(screen, 0, i|0x8, bitmap, cliprect);
#ifdef MAME_DEBUG
if (!machine().input().code_pressed(KEYCODE_W))
#endif
if (!(m_scroll[1][2]&0x10)) // tilemap flicker effect on large shadow, nost level 7
mcatadv_draw_tilemap_part(screen, 1, i|0x8, bitmap, cliprect);
}
@ -242,14 +216,8 @@ uint32_t mcatadv_state::screen_update_mcatadv(screen_device &screen, bitmap_ind1
void mcatadv_state::video_start()
{
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(mcatadv_state::get_mcatadv_tile_info<0>),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_tilemap[0]->set_transparent_pen(0);
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(mcatadv_state::get_mcatadv_tile_info<1>),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_tilemap[1]->set_transparent_pen(0);
m_spriteram_old = make_unique_clear<uint16_t[]>(m_spriteram.bytes() / 2);
m_vidregs_old = std::make_unique<uint16_t[]>(m_vidregs.bytes() / 2);
m_spriteram_old = make_unique_clear<u16[]>(m_spriteram.bytes() / 2);
m_vidregs_old = std::make_unique<u16[]>(m_vidregs.bytes() / 2);
m_palette_bank[0] = m_palette_bank[1] = 0;

266
src/mame/video/tmap038.cpp Normal file
View File

@ -0,0 +1,266 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia, Paul Priest, David Haywood
/* 038 Tilemap generator manufactured by NEC */
/*
[ Scrolling Layers ]
Each 038 chip generates 1 layer. Up to 4 chips are used
(4 layers)
Layer Size: 512 x 512
Tiles: 8 x 8 & 16 x 16.
There are 2 tilemaps in memory, one per tiles dimension.
A bit decides which one gets displayed.
The tiles depth varies with games, from 16 to 256 colors.
A per layer row-scroll / row-select effect can be enabled:
a different scroll value is fetched (from tile RAM) for each
scan line, and a different tilemap line for each scan line
***************************************************************************
Callbacks for the TileMap code
[ Tiles Format ]
Offset: Bits: Value:
0.w fe-- ---- ---- --- Priority
--dc ba98 ---- ---- Color
---- ---- 7654 3210
2.w Code
When a row-scroll / row-select effect is enabled, the scroll values are
fetched starting from tile RAM + $1000, 4 bytes per scan line:
Offset: Value:
0.w Tilemap line to display
2.w X Scroll value
***************************************************************************
***************************************************************************
Layers Registers
Offset: Bits: Value:
0.w f--- ---- ---- ---- 0 = Layer Flip X
-e-- ---- ---- ---- Activate Row-scroll
--d- ---- ---- ----
---c ba9- ---- ----
---- ---8 7654 3210 Scroll X
2.w f--- ---- ---- ---- 0 = Layer Flip Y
-e-- ---- ---- ---- Activate Row-select
--d- ---- ---- ---- 0 = 8x8 tiles, 1 = 16x16 tiles
---c ba9- ---- ----
---- ---8 7654 3210 Scroll Y
4.w fedc ba98 765- ----
---- ---- ---4 ---- Layer Disable
---- ---- ---- 3210 Varies*
*color bank for mcatadv or Layer-Layer priority for cave
There are more!
***************************************************************************
TODO:
de-fragmentation and merge drawing behavior into tmap038.cpp
***************************************************************************
*/
#include "emu.h"
#include "tmap038.h"
void tilemap038_device::vram_map(address_map &map)
{
map(0x0000, 0x0fff).rw(FUNC(tilemap038_device::vram_16x16_r), FUNC(tilemap038_device::vram_16x16_w)).share("vram_16x16");
map(0x1000, 0x17ff).rw(FUNC(tilemap038_device::lineram_r), FUNC(tilemap038_device::lineram_w)).share("lineram");
map(0x1800, 0x3fff).ram().share("scratchpad"); // scratchpad?
map(0x4000, 0x7fff).rw(FUNC(tilemap038_device::vram_8x8_r), FUNC(tilemap038_device::vram_8x8_w)).share("vram_8x8");
}
void tilemap038_device::vram_writeonly_map(address_map &map)
{
map(0x0000, 0x0fff).w(FUNC(tilemap038_device::vram_16x16_w)).share("vram_16x16");
map(0x1000, 0x17ff).w(FUNC(tilemap038_device::lineram_w)).share("lineram");
map(0x1800, 0x3fff).writeonly().share("scratchpad"); // scratchpad?
map(0x4000, 0x7fff).w(FUNC(tilemap038_device::vram_8x8_w)).share("vram_8x8");
}
void tilemap038_device::vram_16x16_map(address_map &map)
{
map(0x0000, 0x0fff).rw(FUNC(tilemap038_device::vram_16x16_r), FUNC(tilemap038_device::vram_16x16_w)).share("vram_16x16");
map(0x1000, 0x17ff).rw(FUNC(tilemap038_device::lineram_r), FUNC(tilemap038_device::lineram_w)).share("lineram");
map(0x1800, 0x3fff).ram().share("scratchpad"); // scratchpad?
}
void tilemap038_device::vram_16x16_writeonly_map(address_map &map)
{
map(0x0000, 0x0fff).w(FUNC(tilemap038_device::vram_16x16_w)).share("vram_16x16");
map(0x1000, 0x17ff).w(FUNC(tilemap038_device::lineram_w)).share("lineram");
map(0x1800, 0x3fff).writeonly().share("scratchpad"); // scratchpad?
}
/* Some games, that only ever use the 8x8 tiles and no line scroll,
use mirror ram. For example in donpachi, writes to 400000-403fff
and 408000-407fff both go to the 8x8 tilemap ram. Use this function
in this cases. Note that the get_tile_info function looks in the
4000-7fff range for tiles, so we have to write the data there. */
void tilemap038_device::vram_8x8_map(address_map &map)
{
map(0x0000, 0x3fff).mirror(0x4000).rw(FUNC(tilemap038_device::vram_8x8_r), FUNC(tilemap038_device::vram_8x8_w)).share("vram_8x8");
}
DEFINE_DEVICE_TYPE(TMAP038, tilemap038_device, "tmap038", "038 Tilemap generator")
tilemap038_device::tilemap038_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, TMAP038, tag, owner, clock)
, m_vram_8x8(*this, "vram_8x8")
, m_vram_16x16(*this, "vram_16x16")
, m_lineram(*this, "lineram")
, m_vregs(nullptr)
, m_tiledim(false)
, m_gfxdecode(*this, finder_base::DUMMY_TAG)
, m_gfxno(0)
{
}
TILE_GET_INFO_MEMBER(tilemap038_device::get_tile_info)
{
u32 tile, code, color, pri;
if (m_tiledim)
{
tile = (tile_index % (512 / 8)) / 2 + ((tile_index / (512 / 8)) / 2) * (512 / 16);
tile = (m_vram_16x16 != nullptr) ? ((m_vram_16x16[tile * 2] << 16) + m_vram_16x16[(tile * 2) + 1]) : 0;
color = (tile & 0x3f000000) >> (32 - 8);
pri = (tile & 0xc0000000) >> (32 - 2);
code = (tile & 0x0000ffff) * 4;
code ^= tile_index & 1;
code ^= ((tile_index / (512 / 8)) & 1) * 2;
if (!m_038_cb.isnull())
m_038_cb(true, color, pri, code);
}
else if (!m_tiledim)
{
tile = (m_vram_8x8 != nullptr) ? ((m_vram_8x8[tile_index * 2] << 16) + m_vram_8x8[(tile_index * 2) + 1]) : 0;
color = (tile & 0x3f000000) >> (32 - 8);
pri = (tile & 0xc0000000) >> (32 - 2);
code = (tile & 0x0003ffff);
if (!m_038_cb.isnull())
m_038_cb(false, color, pri, code);
}
SET_TILE_INFO_MEMBER(m_gfxno, code, color, 0);
tileinfo.category = pri;
}
void tilemap038_device::device_start()
{
m_038_cb.bind_relative_to(*owner());
m_vregs = make_unique_clear<u16[]>(0x6/2);
if (m_vram_16x16 == nullptr && m_vram_8x8 == nullptr)
fatalerror("Tilemap 038 %s: VRAM not found",this->tag());
if (m_vram_8x8 == nullptr)
m_tiledim = true;
else if (m_vram_16x16 == nullptr)
m_tiledim = false;
m_tmap = &machine().tilemap().create(
*m_gfxdecode,
tilemap_get_info_delegate(FUNC(tilemap038_device::get_tile_info),this),
TILEMAP_SCAN_ROWS,
8,8, 512 / 8,512 / 8);
m_tmap->set_transparent_pen(0);
set_scroll_rows(1); // Initialize scroll rows
set_scroll_cols(1); // Initialize scroll cols
save_item(NAME(m_tiledim));
save_pointer(NAME(m_vregs), 0x6/2);
}
void tilemap038_device::device_reset()
{
}
u16 tilemap038_device::vram_8x8_r(offs_t offset)
{
return m_vram_8x8[offset];
}
void tilemap038_device::vram_8x8_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_vram_8x8[offset]);
if (!m_tiledim)
m_tmap->mark_tile_dirty(offset/2);
}
u16 tilemap038_device::vram_16x16_r(offs_t offset)
{
return m_vram_16x16[offset];
}
void tilemap038_device::vram_16x16_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_vram_16x16[offset]);
if (m_tiledim)
{
offset /= 2;
offset = (offset % (512 / 16)) * 2 + (offset / (512 / 16)) * (512 / 8) * 2;
m_tmap->mark_tile_dirty(offset + 0);
m_tmap->mark_tile_dirty(offset + 1);
m_tmap->mark_tile_dirty(offset + 0 + 512 / 8);
m_tmap->mark_tile_dirty(offset + 1 + 512 / 8);
}
}
void tilemap038_device::prepare()
{
/* Enable layers */
m_tmap->enable(enable());
// refresh tile size
if (m_vram_8x8 != nullptr && m_vram_16x16 != nullptr)
{
const bool new_tiledim = BIT(m_vregs[1], 13);
if (m_tiledim != new_tiledim)
{
m_tmap->mark_all_dirty();
m_tiledim = new_tiledim;
}
}
}
void tilemap038_device::draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u32 flags, u8 pri, u8 pri_mask) { draw_common(screen, bitmap, cliprect, flags, pri, pri_mask); }
void tilemap038_device::draw(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 flags, u8 pri, u8 pri_mask) { draw_common(screen, bitmap, cliprect, flags, pri, pri_mask); }
template<class _BitmapClass>
void tilemap038_device::draw_common(screen_device &screen, _BitmapClass &bitmap, const rectangle &cliprect, u32 flags, u8 pri, u8 pri_mask)
{
m_tmap->draw(screen, bitmap, cliprect, flags, pri, pri_mask);
}

106
src/mame/video/tmap038.h Normal file
View File

@ -0,0 +1,106 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia, Paul Priest, David Haywood
#ifndef MAME_VIDEO_TMAP038_H
#define MAME_VIDEO_TMAP038_H
#pragma once
#include "tilemap.h"
class tilemap038_device : public device_t
{
public:
tilemap038_device(const machine_config &mconfig, const char *tag, device_t *owner)
: tilemap038_device(mconfig, tag, owner, (u32)0)
{
}
tilemap038_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configurations
template <typename T> void set_gfxdecode_tag(T &&tag) { m_gfxdecode.set_tag(std::forward<T>(tag)); }
typedef device_delegate<void (bool tiledim, u32 &color, u32 &pri, u32 &code)> tmap038_cb_delegate;
void set_tile_callback(tmap038_cb_delegate cb) { m_038_cb = cb; }
void set_gfx(u16 no) { m_gfxno = no; }
// call to do the rendering etc.
template<class _BitmapClass>
void draw_common(screen_device &screen, _BitmapClass &bitmap, const rectangle &cliprect, u32 flags, u8 pri = 0, u8 pri_mask = ~0);
void prepare();
void draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u32 flags, u8 pri = 0, u8 pri_mask = ~0);
void draw(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u32 flags, u8 pri = 0, u8 pri_mask = ~0);
// access
void vram_map(address_map &map);
void vram_8x8_map(address_map &map);
void vram_16x16_map(address_map &map);
void vram_writeonly_map(address_map &map);
void vram_16x16_writeonly_map(address_map &map);
u16 vram_8x8_r(offs_t offset);
void vram_8x8_w(offs_t offset, u16 data, u16 mem_mask);
u16 vram_16x16_r(offs_t offset);
void vram_16x16_w(offs_t offset, u16 data, u16 mem_mask);
u16 lineram_r(offs_t offset) { return m_lineram[offset]; }
void lineram_w(offs_t offset, u16 data, u16 mem_mask = ~0) { COMBINE_DATA(&m_lineram[offset]); }
u16 vregs_r(offs_t offset) { return m_vregs[offset]; }
void vregs_w(offs_t offset, u16 data, u16 mem_mask = ~0) { COMBINE_DATA(&m_vregs[offset]); }
void mark_all_dirty() { m_tmap->mark_all_dirty(); };
void set_flip(u32 attributes) { m_tmap->set_flip(attributes); }
void set_palette_offset(u32 offset) { m_tmap->set_palette_offset(offset); }
void set_scroll_rows(u32 scroll_rows) { m_tmap->set_scroll_rows(scroll_rows); }
void set_scroll_cols(u32 scroll_cols) { m_tmap->set_scroll_cols(scroll_cols); }
void set_scrollx(int which, int value) { m_tmap->set_scrollx(which, value); }
void set_scrolly(int which, int value) { m_tmap->set_scrolly(which, value); }
// getters
u16 lineram(offs_t offset) const { return m_lineram[offset]; }
u16 rowscroll(offs_t line) const { return rowscroll_en() ? m_lineram[((line & 0x1ff) * 2) + 0] : 0; }
u16 rowselect(offs_t line) const { return rowselect_en() ? m_lineram[((line & 0x1ff) * 2) + 1] : 0; }
u16 vregs(offs_t offset) const { return m_vregs[offset]; }
// vregs
bool flipx() const { return BIT(~m_vregs[0], 15); }
bool rowscroll_en() const { return BIT(m_vregs[0], 14) && (m_lineram != nullptr); }
u16 scrollx() const { return m_vregs[0] & 0x1ff; }
bool flipy() const { return BIT(~m_vregs[1], 15); }
bool rowselect_en() const { return BIT(m_vregs[1], 14) && (m_lineram != nullptr); }
bool tiledim() const { return m_tiledim; }
u16 scrolly() const { return m_vregs[1] & 0x1ff; }
bool enable() const { return BIT(~m_vregs[2], 4); }
u16 external() const { return m_vregs[2] & 0xf; }
protected:
virtual void device_start() override;
virtual void device_reset() override;
private:
TILE_GET_INFO_MEMBER(get_tile_info);
optional_shared_ptr<u16> m_vram_8x8;
optional_shared_ptr<u16> m_vram_16x16;
optional_shared_ptr<u16> m_lineram;
std::unique_ptr<u16[]> m_vregs;
bool m_tiledim;
// set when creating device
required_device<gfxdecode_device> m_gfxdecode;
u16 m_gfxno;
tmap038_cb_delegate m_038_cb;
tilemap_t* m_tmap;
};
DECLARE_DEVICE_TYPE(TMAP038, tilemap038_device)
#endif // MAME_VIDEO_TMAP038_H