From 081c073c8b0b119f4efbfecec9358cf3a10c4379 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 3 Mar 2023 05:35:32 +1100 Subject: jaleco/psychic5.cpp: Split system-specific code into derived classes. --- src/mame/jaleco/argus_v.cpp | 83 +++--- src/mame/jaleco/jalblend.cpp | 30 +- src/mame/jaleco/jalblend.h | 14 +- src/mame/jaleco/psychic5.cpp | 619 ++++++++++++++++++++++++++++++++++++----- src/mame/jaleco/psychic5.h | 121 -------- src/mame/jaleco/psychic5_v.cpp | 367 ------------------------ 6 files changed, 634 insertions(+), 600 deletions(-) delete mode 100644 src/mame/jaleco/psychic5.h delete mode 100644 src/mame/jaleco/psychic5_v.cpp diff --git a/src/mame/jaleco/argus_v.cpp b/src/mame/jaleco/argus_v.cpp index 360a3922412..5c7338512df 100644 --- a/src/mame/jaleco/argus_v.cpp +++ b/src/mame/jaleco/argus_v.cpp @@ -695,7 +695,8 @@ void argus_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, if (priority != pri) m_blend->drawgfx( *m_palette, - bitmap,cliprect,m_gfxdecode->gfx(0), + m_gfxdecode->gfx(0), + bitmap, cliprect, tile, color, flipx, flipy, @@ -806,13 +807,15 @@ void valtric_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect flipy = !flipy; } - m_blend->drawgfx(*m_palette, - bitmap,cliprect,m_gfxdecode->gfx(0), - tile, - color, - flipx, flipy, - sx, sy, - 15); + m_blend->drawgfx( + *m_palette, + m_gfxdecode->gfx(0), + bitmap, cliprect, + tile, + color, + flipx, flipy, + sx, sy, + 15); } } } @@ -854,13 +857,15 @@ void butasan_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect if ((offs >= 0x100 && offs <= 0x2ff) || (offs >= 0x400 && offs <= 0x57f)) { - m_blend->drawgfx(*m_palette, - bitmap,cliprect,m_gfxdecode->gfx(0), - tile, - color, - flipx, flipy, - sx, sy, - 7); + m_blend->drawgfx( + *m_palette, + m_gfxdecode->gfx(0), + bitmap, cliprect, + tile, + color, + flipx, flipy, + sx, sy, + 7); } else if ((offs >= 0x000 && offs <= 0x0ff) || (offs >= 0x300 && offs <= 0x3ff)) { @@ -868,13 +873,15 @@ void butasan_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect { td = (fx) ? (1 - i) : i; - m_blend->drawgfx(*m_palette, - bitmap,cliprect,m_gfxdecode->gfx(0), - tile + td, - color, - flipx, flipy, - sx + i * 16, sy, - 7); + m_blend->drawgfx( + *m_palette, + m_gfxdecode->gfx(0), + bitmap, cliprect, + tile + td, + color, + flipx, flipy, + sx + i * 16, sy, + 7); } } else if (offs >= 0x580 && offs <= 0x61f) @@ -888,13 +895,15 @@ void butasan_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect else td = (fx) ? (i * 2) + 1 - j : i * 2 + j; - m_blend->drawgfx(*m_palette, - bitmap,cliprect,m_gfxdecode->gfx(0), - tile + td, - color, - flipx, flipy, - sx + j * 16, sy - i * 16, - 7); + m_blend->drawgfx( + *m_palette, + m_gfxdecode->gfx(0), + bitmap, cliprect, + tile + td, + color, + flipx, flipy, + sx + j * 16, sy - i * 16, + 7); } } } @@ -909,13 +918,15 @@ void butasan_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect else td = (fx) ? (i * 4) + 3 - j : i * 4 + j; - m_blend->drawgfx(*m_palette, - bitmap,cliprect,m_gfxdecode->gfx(0), - tile + td, - color, - flipx, flipy, - sx + j * 16, sy - i * 16, - 7); + m_blend->drawgfx( + *m_palette, + m_gfxdecode->gfx(0), + bitmap, cliprect, + tile + td, + color, + flipx, flipy, + sx + j * 16, sy - i * 16, + 7); } } } diff --git a/src/mame/jaleco/jalblend.cpp b/src/mame/jaleco/jalblend.cpp index d6eb58728f7..18e826cc866 100644 --- a/src/mame/jaleco/jalblend.cpp +++ b/src/mame/jaleco/jalblend.cpp @@ -160,16 +160,34 @@ void jaleco_blend_device::drawgfx_common(palette_device &palette,BitmapClass &de } } -void jaleco_blend_device::drawgfx(palette_device &palette,bitmap_ind16 &dest_bmp,const rectangle &clip,gfx_element *gfx, - u32 code,u32 color,bool flipx,bool flipy,int offsx,int offsy, +void jaleco_blend_device::drawgfx( + palette_device &palette, + gfx_element *gfx, + bitmap_ind16 &dest_bmp, + const rectangle &clip, + u32 code, + u32 color, + bool flipx, + bool flipy, + int offsx, + int offsy, u8 transparent_color) { - jaleco_blend_device::drawgfx_common(palette,dest_bmp, clip, gfx, code, color, flipx, flipy, offsx, offsy, transparent_color); + drawgfx_common(palette, dest_bmp, clip, gfx, code, color, flipx, flipy, offsx, offsy, transparent_color); } -void jaleco_blend_device::drawgfx(palette_device &palette,bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, - u32 code,u32 color,bool flipx,bool flipy,int offsx,int offsy, +void jaleco_blend_device::drawgfx( + palette_device &palette, + gfx_element *gfx, + bitmap_rgb32 &dest_bmp, + const rectangle &clip, + u32 code, + u32 color, + bool flipx, + bool flipy, + int offsx, + int offsy, u8 transparent_color) { - jaleco_blend_device::drawgfx_common(palette,dest_bmp, clip, gfx, code, color, flipx, flipy, offsx, offsy, transparent_color); + drawgfx_common(palette, dest_bmp, clip, gfx, code, color, flipx, flipy, offsx, offsy, transparent_color); } diff --git a/src/mame/jaleco/jalblend.h b/src/mame/jaleco/jalblend.h index da0f4140b45..0c1306419f9 100644 --- a/src/mame/jaleco/jalblend.h +++ b/src/mame/jaleco/jalblend.h @@ -15,11 +15,17 @@ public: rgb_t func(rgb_t dest, rgb_t addMe); rgb_t func(rgb_t dest, rgb_t addMe, u8 alpha); - void drawgfx(palette_device &palette,bitmap_ind16 &dest_bmp,const rectangle &clip,gfx_element *gfx, - u32 code,u32 color,bool flipx,bool flipy,int offsx,int offsy, + void drawgfx( + palette_device &palette, gfx_element *gfx, + bitmap_ind16 &dest_bmp, const rectangle &clip, + u32 code, u32 color, + bool flipx, bool flipy, int offsx, int offsy, u8 transparent_color); - void drawgfx(palette_device &palette,bitmap_rgb32 &dest_bmp,const rectangle &clip,gfx_element *gfx, - u32 code,u32 color,bool flipx,bool flipy,int offsx,int offsy, + void drawgfx( + palette_device &palette, gfx_element *gfx, + bitmap_rgb32 &dest_bmp, const rectangle &clip, + u32 code, u32 color, + bool flipx, bool flipy, int offsx, int offsy, u8 transparent_color); protected: diff --git a/src/mame/jaleco/psychic5.cpp b/src/mame/jaleco/psychic5.cpp index 9cf821dc528..e14c4316906 100644 --- a/src/mame/jaleco/psychic5.cpp +++ b/src/mame/jaleco/psychic5.cpp @@ -330,68 +330,242 @@ Notes (23-Jan-2016 AS): */ #include "emu.h" -#include "psychic5.h" + +#include "jalblend.h" #include "cpu/z80/z80.h" #include "machine/gen_latch.h" #include "sound/ymopn.h" + +#include "emupal.h" #include "screen.h" #include "speaker.h" +#include "tilemap.h" +#include "machine/timer.h" #include -void psychic5_state::machine_start() +namespace { + +class psychic5_state_base : public driver_device { - // be lazy and assume banked ROM is always a power-of-two and multiple of page size - assert(!(m_bankrom->bytes() % 0x4000)); - assert(!(m_bankrom->bytes() & (m_bankrom->bytes() - 1))); +public: + psychic5_state_base(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_audiocpu(*this, "audiocpu"), + m_gfxdecode(*this, "gfxdecode"), + m_palette(*this, "palette"), + m_vrambank(*this, "vrambank"), + m_bankrom(*this, "bankrom"), + m_mainbank(*this, "mainbank"), + m_spriteram(*this, "spriteram"), + m_fg_videoram(*this, "fg_videoram"), + m_bg_videoram(*this, "bg_videoram"), + m_bg_control(*this, "bg_control"), + m_palette_ram_bg(*this, "palette_ram_bg"), + m_palette_ram_sp(*this, "palette_ram_sp"), + m_palette_ram_tx(*this, "palette_ram_tx") + { } + +protected: + required_device m_maincpu; + required_device m_audiocpu; + required_device m_gfxdecode; + required_device m_palette; + + memory_view m_vrambank; + + required_memory_region m_bankrom; + + required_memory_bank m_mainbank; + + required_shared_ptr m_spriteram; + required_shared_ptr m_fg_videoram; + required_shared_ptr m_bg_videoram; + required_shared_ptr m_bg_control; + required_shared_ptr m_palette_ram_bg; + required_shared_ptr m_palette_ram_sp; + required_shared_ptr m_palette_ram_tx; + + virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; + + uint8_t m_bg_clip_mode = 0; + tilemap_t *m_bg_tilemap = nullptr; + tilemap_t *m_fg_tilemap = nullptr; + int m_sx1 = 0; + int m_sy1 = 0; + int m_sy2 = 0; + + uint8_t bankselect_r(); + void bankselect_w(uint8_t data); + uint8_t vram_page_select_r(); + void vram_page_select_w(uint8_t data); + void fg_videoram_w(offs_t offset, uint8_t data); + void bg_videoram_w(offs_t offset, uint8_t data); + void sprite_col_w(offs_t offset, uint8_t data); + void bg_col_w(offs_t offset, uint8_t data); + void tx_col_w(offs_t offset, uint8_t data); + + void flipscreen_w(uint8_t data); + + TILE_GET_INFO_MEMBER(get_bg_tile_info); + TILE_GET_INFO_MEMBER(get_fg_tile_info); + + TIMER_DEVICE_CALLBACK_MEMBER(scanline); + + template void draw_sprites(T &&draw_sprite); + +private: + uint8_t m_bank_mask = 0; + + uint8_t m_bank_latch = 0; + + void change_palette(int offset, uint8_t* palram, int palbase); +}; - m_mainbank->configure_entries(0, m_bankrom->bytes() / 0x4000, m_bankrom->base(), 0x4000); - m_bank_mask = (m_bankrom->bytes() / 0x4000) - 1; - save_item(NAME(m_bank_latch)); -} +class psychic5_state : public psychic5_state_base +{ +public: + psychic5_state(const machine_config &mconfig, device_type type, const char *tag) : + psychic5_state_base(mconfig, type, tag), + m_blend(*this, "blend") + { + } -void psychic5_state::machine_reset() + void psychic5(machine_config &config) ATTR_COLD; + +protected: + virtual void machine_start() override ATTR_COLD; + virtual void machine_reset() override ATTR_COLD; + +private: + required_device m_blend; + + uint8_t m_title_screen = 0; + uint16_t m_palette_intensity = 0; + + void coin_counter_w(uint8_t data); + void title_screen_w(uint8_t data); + + void change_bg_palette(int color, int lo_offs, int hi_offs); + void set_background_palette_intensity(); + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void draw_background(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void main_map(address_map &map) ATTR_COLD; + void sound_map(address_map &map) ATTR_COLD; + void soundport_map(address_map &map) ATTR_COLD; +}; + + +class bombsa_state : public psychic5_state_base { - m_bank_latch = 0xff; - m_mainbank->set_entry(m_bank_latch & m_bank_mask); +public: + bombsa_state(const machine_config &mconfig, device_type type, const char *tag) : + psychic5_state_base(mconfig, type, tag) + { + } - flip_screen_set(0); -} + void bombsa(machine_config &config) ATTR_COLD; -/*************************************************************************** +protected: + virtual void machine_start() override ATTR_COLD; - Interrupt(s) +private: + uint8_t m_unknown = 0; + + void unknown_w(uint8_t data); + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void main_map(address_map &map) ATTR_COLD; + void sound_map(address_map &map) ATTR_COLD; + void soundport_map(address_map &map) ATTR_COLD; +}; + + +/*************************************************************************** + Palette color ***************************************************************************/ -TIMER_DEVICE_CALLBACK_MEMBER(psychic5_state::scanline) +void psychic5_state_base::change_palette(int offset, uint8_t* palram, int palbase) { - int scanline = param; + uint8_t const lo = palram[(offset) & ~1]; + uint8_t const hi = palram[(offset) | 1]; - if (scanline == 240) // vblank-out irq - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xd7); /* Z80 - RST 10h - vblank */ + int const color = offset >> 1; - if (scanline == 0) // sprite buffer irq - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xcf); /* Z80 - RST 08h */ + m_palette->set_pen_color(palbase + color, rgb_t(hi & 0x0f, pal4bit(lo >> 4), pal4bit(lo), pal4bit(hi >> 4))); +} + +void psychic5_state::change_bg_palette(int color, int lo_offs, int hi_offs) +{ + /* red,green,blue intensities */ + uint8_t const ir = pal4bit(m_palette_intensity >> 12); + uint8_t const ig = pal4bit(m_palette_intensity >> 8); + uint8_t const ib = pal4bit(m_palette_intensity >> 4); + uint8_t const ix = m_palette_intensity & 0x0f; + + rgb_t const irgb = rgb_t(ir,ig,ib); + + uint8_t const lo = m_palette_ram_bg[lo_offs]; + uint8_t const hi = m_palette_ram_bg[hi_offs]; + + /* red,green,blue component */ + uint8_t const r = pal4bit(lo >> 4); + uint8_t const g = pal4bit(lo); + uint8_t const b = pal4bit(hi >> 4); + + /* Grey background enable */ + if (m_bg_control[4] & 2) + { + uint8_t const val = (r + g + b) / 3; /* Grey */ + /* Just leave plain grey */ + m_palette->set_pen_color(color, m_blend->func(rgb_t(val, val, val), irgb, ix)); + } + else + { + /* Seems fishy, but the title screen would be black otherwise... */ + if (!(m_title_screen & 1)) + { + /* Leave the world as-is */ + m_palette->set_pen_color(color,m_blend->func(rgb_t(r,g,b), irgb, ix)); + } + } +} + +void psychic5_state::set_background_palette_intensity() +{ + constexpr unsigned BG_PAL_INTENSITY_RG = 0x1fe; + constexpr unsigned BG_PAL_INTENSITY_BU = 0x1ff; + m_palette_intensity = m_palette_ram_sp[BG_PAL_INTENSITY_BU] | + (m_palette_ram_sp[BG_PAL_INTENSITY_RG] << 8); + + /* for all of the background palette */ + for (int i = 0; i < 0x100; i++) + change_bg_palette(i + 0x100, i * 2, (i * 2) + 1); } /*************************************************************************** - Memory Handler(s) + Memory handlers ***************************************************************************/ -uint8_t psychic5_state::bankselect_r() +uint8_t psychic5_state_base::bankselect_r() { return m_bank_latch; } -void psychic5_state::bankselect_w(uint8_t data) +void psychic5_state_base::bankselect_w(uint8_t data) { if (m_bank_latch != data) { @@ -400,11 +574,16 @@ void psychic5_state::bankselect_w(uint8_t data) } } -void psychic5_state::psychic5_coin_counter_w(uint8_t data) +void psychic5_state::coin_counter_w(uint8_t data) { machine().bookkeeping().coin_counter_w(0, data & 0x01); machine().bookkeeping().coin_counter_w(1, data & 0x02); + flipscreen_w(data); +} + +void psychic5_state_base::flipscreen_w(uint8_t data) +{ // bit 7 toggles flip screen if (data & 0x80) { @@ -412,34 +591,344 @@ void psychic5_state::psychic5_coin_counter_w(uint8_t data) } } -void psychic5_state::bombsa_flipscreen_w(uint8_t data) + +uint8_t psychic5_state_base::vram_page_select_r() { - // bit 7 toggles flip screen - if (data & 0x80) + return *m_vrambank.entry(); +} + +void psychic5_state_base::vram_page_select_w(uint8_t data) +{ + m_vrambank.select(data & 1); +} + +void psychic5_state::title_screen_w(uint8_t data) +{ + m_title_screen = data; +} + + +void psychic5_state_base::sprite_col_w(offs_t offset, uint8_t data) +{ + m_palette_ram_sp[offset] = data; + change_palette(offset, m_palette_ram_sp, 0x000); +} + +void psychic5_state_base::bg_col_w(offs_t offset, uint8_t data) +{ + m_palette_ram_bg[offset] = data; + change_palette(offset, m_palette_ram_bg, 0x100); +} + +void psychic5_state_base::tx_col_w(offs_t offset, uint8_t data) +{ + m_palette_ram_tx[offset] = data; + change_palette(offset, m_palette_ram_tx, 0x200); +} + + +void psychic5_state_base::fg_videoram_w(offs_t offset, uint8_t data) +{ + m_fg_videoram[offset] = data; + m_fg_tilemap->mark_tile_dirty(offset >> 1); +} + +void psychic5_state_base::bg_videoram_w(offs_t offset, uint8_t data) +{ + m_bg_videoram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset >> 1); +} + + + +void bombsa_state::unknown_w(uint8_t data) +{ + m_unknown = data; +} + + +/*************************************************************************** + + Callbacks for the tilemap code + +***************************************************************************/ + +TILE_GET_INFO_MEMBER(psychic5_state_base::get_bg_tile_info) +{ + int offs = tile_index << 1; + int attr = m_bg_videoram[offs + 1]; + int code = m_bg_videoram[offs] | ((attr & 0xc0) << 2); + int color = attr & 0x0f; + int flags = TILE_FLIPYX((attr & 0x30) >> 4); + + tileinfo.set(1, code, color, flags); +} + +TILE_GET_INFO_MEMBER(psychic5_state_base::get_fg_tile_info) +{ + int offs = tile_index << 1; + int attr = m_fg_videoram[offs + 1]; + int code = m_fg_videoram[offs] | ((attr & 0xc0) << 2); + int color = attr & 0x0f; + int flags = TILE_FLIPYX((attr & 0x30) >> 4); + + tileinfo.set(2, code, color, flags); +} + + +/*************************************************************************** + + Screen refresh + +***************************************************************************/ + +template +inline void psychic5_state_base::draw_sprites(T &&draw_sprite) +{ + /* Draw the sprites */ + for (int offs = 0; offs < m_spriteram.bytes(); offs += 16) { - flip_screen_set(!flip_screen()); + int const attr = m_spriteram[offs + 13]; + if (attr & 2) // Bombs Away: disable sprite if enabled + continue; + int const code = m_spriteram[offs + 14] | ((attr & 0xc0) << 2); + int const color = m_spriteram[offs + 15] & 0x0f; + int flipx = attr & 0x10; + int flipy = attr & 0x20; + int sx = m_spriteram[offs + 12]; + int sy = m_spriteram[offs + 11]; + int const size = (attr & 0x08) ? 32:16; + + if (attr & 0x01) sx -= 256; + if (attr & 0x04) sy -= 256; + + if (flip_screen()) + { + sx = 224 - sx; + sy = 224 - sy; + flipx = !flipx; + flipy = !flipy; + } + + if (size == 32) + { + int x0,x1,y0,y1; + + if (flipx) { x0 = 2; x1 = 0; } + else { x0 = 0; x1 = 2; } + + if (flipy) { y0 = 1; y1 = 0; } + else { y0 = 0; y1 = 1; } + + draw_sprite(code + x0 + y0, color, flipx, flipy, sx, sy); + draw_sprite(code + x0 + y1, color, flipx, flipy, sx, sy + 16); + draw_sprite(code + x1 + y0, color, flipx, flipy, sx + 16, sy); + draw_sprite(code + x1 + y1, color, flipx, flipy, sx + 16, sy + 16); + } + else + { + if (flip_screen()) + draw_sprite(code, color, flipx, flipy, sx + 16, sy + 16); + else + draw_sprite(code, color, flipx, flipy, sx, sy); + } + } +} + +void psychic5_state::draw_background(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + rectangle clip = cliprect; + + set_background_palette_intensity(); + + if (!(m_title_screen & 1)) + { + m_bg_clip_mode = 0; + m_sx1 = m_sy1 = m_sy2 = 0; } + else + { + int sy1_old = m_sy1; + int sx1_old = m_sx1; + int sy2_old = m_sy2; + + m_sy1 = m_spriteram[11]; /* sprite 0 */ + m_sx1 = m_spriteram[12]; + m_sy2 = m_spriteram[11+128]; /* sprite 8 */ + + switch (m_bg_clip_mode) + { + case 0: case 4: if (sy1_old != m_sy1) m_bg_clip_mode++; break; + case 2: case 6: if (sy2_old != m_sy2) m_bg_clip_mode++; break; + case 8: case 10: + case 12: case 14: if (sx1_old != m_sx1) m_bg_clip_mode++; break; + case 1: case 5: if (m_sy1 == 0xf0) m_bg_clip_mode++; break; + case 3: case 7: if (m_sy2 == 0xf0) m_bg_clip_mode++; break; + case 9: case 11: if (m_sx1 == 0xf0) m_bg_clip_mode++; break; + case 13: case 15: if (sx1_old == 0xf0) m_bg_clip_mode++; + [[fallthrough]]; + case 16: if (m_sy1 != 0x00) m_bg_clip_mode = 0; break; + } + + switch (m_bg_clip_mode) + { + case 0: case 4: case 8: case 12: case 16: + clip.set(0, 0, 0, 0); + break; + case 1: clip.min_y = m_sy1; break; + case 3: clip.max_y = m_sy2; break; + case 5: clip.max_y = m_sy1; break; + case 7: clip.min_y = m_sy2; break; + case 9: case 15: clip.min_x = m_sx1; break; + case 11: case 13: clip.max_x = m_sx1; break; + } + + if (flip_screen()) + clip.set(255 - clip.max_x, 255 - clip.min_x, 255 - clip.max_y, 255 - clip.min_y); + } + + m_bg_tilemap->draw(screen, bitmap, clip, 0, 0); } +uint32_t psychic5_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + uint16_t bg_scrollx = m_bg_control[0] | (m_bg_control[1] << 8); + m_bg_tilemap->set_scrollx(0, bg_scrollx); + uint16_t bg_scrolly = m_bg_control[2] | (m_bg_control[3] << 8); + m_bg_tilemap->set_scrolly(0, bg_scrolly); + + bitmap.fill(m_palette->black_pen(), cliprect); + if (m_bg_control[4] & 1) /* Backgound enable */ + draw_background(screen, bitmap, cliprect); + if (!(m_title_screen & 1)) + draw_sprites([this, &bitmap, &cliprect] (auto... args) { m_blend->drawgfx(*m_palette, m_gfxdecode->gfx(0), bitmap, cliprect, args..., 15); }); + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + +uint32_t bombsa_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + uint16_t bg_scrollx = m_bg_control[0] | (m_bg_control[1] << 8); + m_bg_tilemap->set_scrollx(0, bg_scrollx); + uint16_t bg_scrolly = m_bg_control[2] | (m_bg_control[3] << 8); + m_bg_tilemap->set_scrolly(0, bg_scrolly); + bitmap.fill(m_palette->black_pen(), cliprect); + + if (m_bg_control[4] & 1) /* Backgound enable */ + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + else + bitmap.fill(m_palette->pen(0x0ff), cliprect); + draw_sprites([this, &bitmap, &cliprect] (auto... args) { m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, args..., 15); }); + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + + /*************************************************************************** - Memory Map(s) + Initialize and destroy video hardware emulation ***************************************************************************/ -void psychic5_state::psychic5_main_map(address_map &map) +void psychic5_state_base::machine_start() +{ + // be lazy and assume banked ROM is always a power-of-two and multiple of page size + assert(!(m_bankrom->bytes() % 0x4000)); + assert(!(m_bankrom->bytes() & (m_bankrom->bytes() - 1))); + + m_mainbank->configure_entries(0, m_bankrom->bytes() / 0x4000, m_bankrom->base(), 0x4000); + m_bank_mask = (m_bankrom->bytes() / 0x4000) - 1; + + save_item(NAME(m_bg_clip_mode)); + save_item(NAME(m_sx1)); + save_item(NAME(m_sy1)); + save_item(NAME(m_sy2)); + + save_item(NAME(m_bank_latch)); +} + +void psychic5_state::machine_start() +{ + psychic5_state_base::machine_start(); + + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(psychic5_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(psychic5_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 32, 32); + m_fg_tilemap->set_transparent_pen(15); + + save_item(NAME(m_palette_intensity)); + save_item(NAME(m_title_screen)); +} + +void bombsa_state::machine_start() +{ + psychic5_state_base::machine_start(); + + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bombsa_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 128, 32); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bombsa_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 32, 32); + m_fg_tilemap->set_transparent_pen(15); + + save_item(NAME(m_unknown)); +} + +void psychic5_state_base::machine_reset() +{ + m_bank_latch = 0xff; + m_mainbank->set_entry(m_bank_latch & m_bank_mask); + + flip_screen_set(0); + + m_vrambank.select(0); + + m_bg_clip_mode = 0; +} + +void psychic5_state::machine_reset() +{ + psychic5_state_base::machine_reset(); + + m_title_screen = 0; + m_palette_intensity = 0; +} + + +/*************************************************************************** + + Interrupt(s) + +***************************************************************************/ + +TIMER_DEVICE_CALLBACK_MEMBER(psychic5_state_base::scanline) +{ + int const scanline = param; + + if (scanline == 240) // vblank-out irq + m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xd7); /* Z80 - RST 10h - vblank */ + + if (scanline == 0) // sprite buffer irq + m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xcf); /* Z80 - RST 08h */ +} + + + +/*************************************************************************** + + Memory Maps + +***************************************************************************/ + +void psychic5_state::main_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0xbfff).bankr(m_mainbank); map(0xc000, 0xdfff).view(m_vrambank); map(0xe000, 0xefff).ram(); map(0xf000, 0xf000).w("soundlatch", FUNC(generic_latch_8_device::write)); - map(0xf001, 0xf001).nopr().w(FUNC(psychic5_state::psychic5_coin_counter_w)); + map(0xf001, 0xf001).nopr().w(FUNC(psychic5_state::coin_counter_w)); map(0xf002, 0xf002).rw(FUNC(psychic5_state::bankselect_r), FUNC(psychic5_state::bankselect_w)); map(0xf003, 0xf003).rw(FUNC(psychic5_state::vram_page_select_r), FUNC(psychic5_state::vram_page_select_w)); map(0xf004, 0xf004).noprw(); // ??? - map(0xf005, 0xf005).nopr().w(FUNC(psychic5_state::psychic5_title_screen_w)); + map(0xf005, 0xf005).nopr().w(FUNC(psychic5_state::title_screen_w)); map(0xf006, 0xf1ff).noprw(); map(0xf200, 0xf7ff).ram().share("spriteram"); map(0xf800, 0xffff).ram(); @@ -455,22 +944,22 @@ void psychic5_state::psychic5_main_map(address_map &map) m_vrambank[1](0xc308, 0xc30c).ram().share(m_bg_control); - m_vrambank[1](0xc400, 0xc5ff).ram().w(FUNC(psychic5_state::sprite_col_w)).share(m_ps5_palette_ram_sp); - m_vrambank[1](0xc800, 0xc9ff).ram().w(FUNC(psychic5_state::bg_col_w)).share(m_ps5_palette_ram_bg); - m_vrambank[1](0xca00, 0xcbff).ram().w(FUNC(psychic5_state::tx_col_w)).share(m_ps5_palette_ram_tx); + m_vrambank[1](0xc400, 0xc5ff).ram().w(FUNC(psychic5_state::sprite_col_w)).share(m_palette_ram_sp); + m_vrambank[1](0xc800, 0xc9ff).ram().w(FUNC(psychic5_state::bg_col_w)).share(m_palette_ram_bg); + m_vrambank[1](0xca00, 0xcbff).ram().w(FUNC(psychic5_state::tx_col_w)).share(m_palette_ram_tx); m_vrambank[1](0xd000, 0xd7ff).ram().w(FUNC(psychic5_state::fg_videoram_w)).share(m_fg_videoram); } -void psychic5_state::psychic5_sound_map(address_map &map) +void psychic5_state::sound_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0xc000, 0xc7ff).ram(); map(0xe000, 0xe000).r("soundlatch", FUNC(generic_latch_8_device::read)); } -void psychic5_state::psychic5_soundport_map(address_map &map) +void psychic5_state::soundport_map(address_map &map) { map.global_mask(0xff); map(0x00, 0x01).w("ym1", FUNC(ym2203_device::write)); @@ -478,7 +967,7 @@ void psychic5_state::psychic5_soundport_map(address_map &map) } -void psychic5_state::bombsa_main_map(address_map &map) +void bombsa_state::main_map(address_map &map) { map(0x0000, 0x7fff).rom(); map(0x8000, 0xbfff).bankr(m_mainbank); @@ -487,17 +976,17 @@ void psychic5_state::bombsa_main_map(address_map &map) /* ports look like the other games */ map(0xd000, 0xd1ff).ram(); map(0xd000, 0xd000).w("soundlatch", FUNC(generic_latch_8_device::write)); // confirmed - map(0xd001, 0xd001).w(FUNC(psychic5_state::bombsa_flipscreen_w)); - map(0xd002, 0xd002).rw(FUNC(psychic5_state::bankselect_r), FUNC(psychic5_state::bankselect_w)); - map(0xd003, 0xd003).rw(FUNC(psychic5_state::vram_page_select_r), FUNC(psychic5_state::vram_page_select_w)); - map(0xd005, 0xd005).w(FUNC(psychic5_state::bombsa_unknown_w)); // ? + map(0xd001, 0xd001).w(FUNC(bombsa_state::flipscreen_w)); + map(0xd002, 0xd002).rw(FUNC(bombsa_state::bankselect_r), FUNC(bombsa_state::bankselect_w)); + map(0xd003, 0xd003).rw(FUNC(bombsa_state::vram_page_select_r), FUNC(bombsa_state::vram_page_select_w)); + map(0xd005, 0xd005).w(FUNC(bombsa_state::unknown_w)); // ? map(0xd200, 0xd7ff).ram().share(m_spriteram); map(0xd800, 0xdfff).ram(); map(0xe000, 0xffff).view(m_vrambank); - m_vrambank[0](0xe000, 0xffff).ram().w(FUNC(psychic5_state::bg_videoram_w)).share(m_bg_videoram); + m_vrambank[0](0xe000, 0xffff).ram().w(FUNC(bombsa_state::bg_videoram_w)).share(m_bg_videoram); m_vrambank[1](0xe000, 0xe000).portr("SYSTEM"); m_vrambank[1](0xe001, 0xe001).portr("P1"); @@ -507,14 +996,14 @@ void psychic5_state::bombsa_main_map(address_map &map) m_vrambank[1](0xe308, 0xe30c).ram().share(m_bg_control); - m_vrambank[1](0xe800, 0xefff).ram().w(FUNC(psychic5_state::fg_videoram_w)).share(m_fg_videoram); + m_vrambank[1](0xe800, 0xefff).ram().w(FUNC(bombsa_state::fg_videoram_w)).share(m_fg_videoram); - m_vrambank[1](0xf000, 0xf1ff).ram().w(FUNC(psychic5_state::sprite_col_w)).share(m_ps5_palette_ram_sp); - m_vrambank[1](0xf200, 0xf3ff).ram().w(FUNC(psychic5_state::bg_col_w)).share(m_ps5_palette_ram_bg); - m_vrambank[1](0xf400, 0xf5ff).ram().w(FUNC(psychic5_state::tx_col_w)).share(m_ps5_palette_ram_tx); + m_vrambank[1](0xf000, 0xf1ff).ram().w(FUNC(bombsa_state::sprite_col_w)).share(m_palette_ram_sp); + m_vrambank[1](0xf200, 0xf3ff).ram().w(FUNC(bombsa_state::bg_col_w)).share(m_palette_ram_bg); + m_vrambank[1](0xf400, 0xf5ff).ram().w(FUNC(bombsa_state::tx_col_w)).share(m_palette_ram_tx); } -void psychic5_state::bombsa_sound_map(address_map &map) +void bombsa_state::sound_map(address_map &map) { map(0x0000, 0xbfff).rom(); map(0xc000, 0xc7ff).ram(); @@ -522,7 +1011,7 @@ void psychic5_state::bombsa_sound_map(address_map &map) map(0xf000, 0xf000).nopw(); // Is this a confirm of some sort? } -void psychic5_state::bombsa_soundport_map(address_map &map) +void bombsa_state::soundport_map(address_map &map) { map.global_mask(0xff); map(0x00, 0x01).rw("ym1", FUNC(ym2203_device::read), FUNC(ym2203_device::write)); @@ -709,27 +1198,25 @@ void psychic5_state::psychic5(machine_config &config) { /* basic machine hardware */ Z80(config, m_maincpu, XTAL(12'000'000)/2); - m_maincpu->set_addrmap(AS_PROGRAM, &psychic5_state::psychic5_main_map); + m_maincpu->set_addrmap(AS_PROGRAM, &psychic5_state::main_map); TIMER(config, "scantimer").configure_scanline(FUNC(psychic5_state::scanline), "screen", 0, 1); Z80(config, m_audiocpu, XTAL(5'000'000)); - m_audiocpu->set_addrmap(AS_PROGRAM, &psychic5_state::psychic5_sound_map); - m_audiocpu->set_addrmap(AS_IO, &psychic5_state::psychic5_soundport_map); + m_audiocpu->set_addrmap(AS_PROGRAM, &psychic5_state::sound_map); + m_audiocpu->set_addrmap(AS_IO, &psychic5_state::soundport_map); config.set_maximum_quantum(attotime::from_hz(600)); /* Allow time for 2nd cpu to interleave */ /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_raw(XTAL(12'000'000)/2,394, 0, 256, 282, 16, 240); // was 53.8 Hz before, assume same as Bombs Away - screen.set_screen_update(FUNC(psychic5_state::screen_update_psychic5)); + screen.set_screen_update(FUNC(psychic5_state::screen_update)); GFXDECODE(config, m_gfxdecode, m_palette, gfx_psychic5); PALETTE(config, m_palette).set_entries(768); JALECO_BLEND(config, m_blend, 0); - MCFG_VIDEO_START_OVERRIDE(psychic5_state,psychic5) - /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -749,29 +1236,27 @@ void psychic5_state::psychic5(machine_config &config) ym2.add_route(3, "mono", 0.50); } -void psychic5_state::bombsa(machine_config &config) +void bombsa_state::bombsa(machine_config &config) { /* basic machine hardware */ Z80(config, m_maincpu, XTAL(12'000'000)/2); /* 6 MHz */ - m_maincpu->set_addrmap(AS_PROGRAM, &psychic5_state::bombsa_main_map); - TIMER(config, "scantimer").configure_scanline(FUNC(psychic5_state::scanline), "screen", 0, 1); + m_maincpu->set_addrmap(AS_PROGRAM, &bombsa_state::main_map); + TIMER(config, "scantimer").configure_scanline(FUNC(bombsa_state::scanline), "screen", 0, 1); Z80(config, m_audiocpu, XTAL(5'000'000)); - m_audiocpu->set_addrmap(AS_PROGRAM, &psychic5_state::bombsa_sound_map); - m_audiocpu->set_addrmap(AS_IO, &psychic5_state::bombsa_soundport_map); + m_audiocpu->set_addrmap(AS_PROGRAM, &bombsa_state::sound_map); + m_audiocpu->set_addrmap(AS_IO, &bombsa_state::soundport_map); config.set_maximum_quantum(attotime::from_hz(600)); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_raw(XTAL(12'000'000)/2,394, 0, 256, 282, 16, 240); /* Measured as: VSync 54Hz, HSync 15.25kHz */ - screen.set_screen_update(FUNC(psychic5_state::screen_update_bombsa)); + screen.set_screen_update(FUNC(bombsa_state::screen_update)); GFXDECODE(config, m_gfxdecode, m_palette, gfx_bombsa); PALETTE(config, m_palette).set_entries(768); - MCFG_VIDEO_START_OVERRIDE(psychic5_state,bombsa) - /* sound hardware */ SPEAKER(config, "mono").front_center(); @@ -950,7 +1435,9 @@ ROM_START( bombsa ) ROM_LOAD( "82s137.3t", 0x200, 0x400, CRC(59e44236) SHA1(f53d99694fa5acd7cc51dd78e09f0d2ef730e7a4) ) ROM_END +} // anonymous namespace + GAME( 1987, psychic5, 0, psychic5, psychic5, psychic5_state, empty_init, ROT270, "Jaleco / NMK", "Psychic 5 (World)", MACHINE_SUPPORTS_SAVE ) // "Oversea's version V2.00 CHANGED BY TAMIO NAKASATO" text present in ROM, various modifications (English names, more complete attract demo etc.) GAME( 1987, psychic5j, psychic5, psychic5, psychic5, psychic5_state, empty_init, ROT270, "Jaleco / NMK", "Psychic 5 (Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 1988, bombsa, 0, bombsa, bombsa, psychic5_state, empty_init, ROT270, "Jaleco", "Bombs Away (prototype)", MACHINE_IS_INCOMPLETE | MACHINE_SUPPORTS_SAVE ) +GAME( 1988, bombsa, 0, bombsa, bombsa, bombsa_state, empty_init, ROT270, "Jaleco", "Bombs Away (prototype)", MACHINE_IS_INCOMPLETE | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/jaleco/psychic5.h b/src/mame/jaleco/psychic5.h deleted file mode 100644 index 5c80cd48c23..00000000000 --- a/src/mame/jaleco/psychic5.h +++ /dev/null @@ -1,121 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Jarek Parchanski -#ifndef MAME_JALECO_PSYCHIC5_H -#define MAME_JALECO_PSYCHIC5_H - -#pragma once - -#include "jalblend.h" - -#include "machine/timer.h" - -#include "emupal.h" -#include "tilemap.h" - -class psychic5_state : public driver_device -{ -public: - psychic5_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_audiocpu(*this, "audiocpu"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_blend(*this, "blend"), - m_vrambank(*this, "vrambank"), - m_bankrom(*this, "bankrom"), - m_mainbank(*this, "mainbank"), - m_spriteram(*this, "spriteram"), - m_fg_videoram(*this, "fg_videoram"), - m_bg_videoram(*this, "bg_videoram"), - m_bg_control(*this, "bg_control"), - m_ps5_palette_ram_bg(*this, "palette_ram_bg"), - m_ps5_palette_ram_sp(*this, "palette_ram_sp"), - m_ps5_palette_ram_tx(*this, "palette_ram_tx") - { } - - void psychic5(machine_config &config); - void bombsa(machine_config &config); - -protected: - virtual void machine_start() override ATTR_COLD; - virtual void machine_reset() override ATTR_COLD; - virtual void video_start() override ATTR_COLD; - virtual void video_reset() override ATTR_COLD; - -private: - required_device m_maincpu; - required_device m_audiocpu; - required_device m_gfxdecode; - required_device m_palette; - optional_device m_blend; - - memory_view m_vrambank; - - required_memory_region m_bankrom; - - required_memory_bank m_mainbank; - - required_shared_ptr m_spriteram; - required_shared_ptr m_fg_videoram; - required_shared_ptr m_bg_videoram; - required_shared_ptr m_bg_control; - required_shared_ptr m_ps5_palette_ram_bg; - required_shared_ptr m_ps5_palette_ram_sp; - required_shared_ptr m_ps5_palette_ram_tx; - - uint8_t m_bank_mask = 0; - - uint8_t m_bank_latch = 0; - uint8_t m_bg_clip_mode = 0; - uint8_t m_title_screen = 0; - tilemap_t *m_bg_tilemap = nullptr; - tilemap_t *m_fg_tilemap = nullptr; - uint16_t m_palette_intensity = 0; - uint8_t m_bombsa_unknown = 0; - int m_sx1 = 0; - int m_sy1 = 0; - int m_sy2 = 0; - - uint8_t bankselect_r(); - void bankselect_w(uint8_t data); - uint8_t vram_page_select_r(); - void vram_page_select_w(uint8_t data); - void fg_videoram_w(offs_t offset, uint8_t data); - void bg_videoram_w(offs_t offset, uint8_t data); - void sprite_col_w(offs_t offset, uint8_t data); - void bg_col_w(offs_t offset, uint8_t data); - void tx_col_w(offs_t offset, uint8_t data); - - /* psychic5 specific */ - void psychic5_coin_counter_w(uint8_t data); - void psychic5_title_screen_w(uint8_t data); - - /* bombsa specific */ - void bombsa_flipscreen_w(uint8_t data); - void bombsa_unknown_w(uint8_t data); - - TILE_GET_INFO_MEMBER(get_bg_tile_info); - TILE_GET_INFO_MEMBER(get_fg_tile_info); - - DECLARE_VIDEO_START(psychic5); - DECLARE_VIDEO_START(bombsa); - - TIMER_DEVICE_CALLBACK_MEMBER(scanline); - - uint32_t screen_update_psychic5(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - uint32_t screen_update_bombsa(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void change_palette(int offset, uint8_t* palram, int palbase); - void change_bg_palette(int color, int lo_offs, int hi_offs); - void set_background_palette_intensity(); - void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect); - void bombsa_main_map(address_map &map); - void bombsa_sound_map(address_map &map); - void bombsa_soundport_map(address_map &map); - void psychic5_main_map(address_map &map); - void psychic5_sound_map(address_map &map); - void psychic5_soundport_map(address_map &map); - void draw_background(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); //only used by psychic5 -}; - -#endif // MAME_JALECO_PSYCHIC5_H diff --git a/src/mame/jaleco/psychic5_v.cpp b/src/mame/jaleco/psychic5_v.cpp deleted file mode 100644 index 6a2cb753dc3..00000000000 --- a/src/mame/jaleco/psychic5_v.cpp +++ /dev/null @@ -1,367 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Jarek Parchanski -/*************************************************************************** - Psychic 5 - Bombs Away - - Functions to emulate the video hardware of the machine. - -***************************************************************************/ - -#include "emu.h" -#include "psychic5.h" - - -#define BG_PAL_INTENSITY_RG 0x1fe -#define BG_PAL_INTENSITY_BU 0x1ff - - -/*************************************************************************** - Palette color -***************************************************************************/ - -void psychic5_state::change_palette(int offset, uint8_t* palram, int palbase) -{ - uint8_t lo = palram[(offset) & ~1]; - uint8_t hi = palram[(offset) | 1]; - - int color = offset >> 1; - - m_palette->set_pen_color(palbase + color, rgb_t(hi & 0x0f, pal4bit(lo >> 4), pal4bit(lo), pal4bit(hi >> 4))); -} - -void psychic5_state::change_bg_palette(int color, int lo_offs, int hi_offs) -{ - uint8_t r,g,b,lo,hi,ir,ig,ib,ix; - rgb_t irgb; - - /* red,green,blue intensities */ - ir = pal4bit(m_palette_intensity >> 12); - ig = pal4bit(m_palette_intensity >> 8); - ib = pal4bit(m_palette_intensity >> 4); - ix = m_palette_intensity & 0x0f; - - irgb = rgb_t(ir,ig,ib); - - lo = m_ps5_palette_ram_bg[lo_offs]; - hi = m_ps5_palette_ram_bg[hi_offs]; - - /* red,green,blue component */ - r = pal4bit(lo >> 4); - g = pal4bit(lo); - b = pal4bit(hi >> 4); - - /* Grey background enable */ - if (m_bg_control[4] & 2) - { - uint8_t val = (r + g + b) / 3; /* Grey */ - /* Just leave plain grey */ - m_palette->set_pen_color(color,m_blend->func(rgb_t(val,val,val),irgb,ix)); - } - else - { - /* Seems fishy, but the title screen would be black otherwise... */ - if (!(m_title_screen & 1)) - { - /* Leave the world as-is */ - m_palette->set_pen_color(color,m_blend->func(rgb_t(r,g,b),irgb,ix)); - } - } -} - -void psychic5_state::set_background_palette_intensity() -{ - int i; - m_palette_intensity = m_ps5_palette_ram_sp[BG_PAL_INTENSITY_BU] | - (m_ps5_palette_ram_sp[BG_PAL_INTENSITY_RG]<<8); - - /* for all of the background palette */ - for (i = 0; i < 0x100; i++) - change_bg_palette(i+0x100,i*2,i*2+1); -} - - -/*************************************************************************** - Memory handler -***************************************************************************/ - -uint8_t psychic5_state::vram_page_select_r() -{ - return *m_vrambank.entry(); -} - -void psychic5_state::vram_page_select_w(uint8_t data) -{ - m_vrambank.select(data & 1); -} - -void psychic5_state::psychic5_title_screen_w(uint8_t data) -{ - m_title_screen = data; -} - - - -void psychic5_state::sprite_col_w(offs_t offset, uint8_t data) -{ - m_ps5_palette_ram_sp[offset] = data; - change_palette(offset,m_ps5_palette_ram_sp, 0x000); -} - -void psychic5_state::bg_col_w(offs_t offset, uint8_t data) -{ - m_ps5_palette_ram_bg[offset] = data; - change_palette(offset,m_ps5_palette_ram_bg, 0x100); -} - -void psychic5_state::tx_col_w(offs_t offset, uint8_t data) -{ - m_ps5_palette_ram_tx[offset] = data; - change_palette(offset,m_ps5_palette_ram_tx, 0x200); -} - - -void psychic5_state::fg_videoram_w(offs_t offset, uint8_t data) -{ - m_fg_videoram[offset] = data; - m_fg_tilemap->mark_tile_dirty(offset >> 1); -} - -void psychic5_state::bg_videoram_w(offs_t offset, uint8_t data) -{ - m_bg_videoram[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset >> 1); -} - - - -void psychic5_state::bombsa_unknown_w(uint8_t data) -{ - m_bombsa_unknown = data; -} - - -/*************************************************************************** - Callbacks for the tilemap code -***************************************************************************/ - -TILE_GET_INFO_MEMBER(psychic5_state::get_bg_tile_info) -{ - int offs = tile_index << 1; - int attr = m_bg_videoram[offs + 1]; - int code = m_bg_videoram[offs] | ((attr & 0xc0) << 2); - int color = attr & 0x0f; - int flags = TILE_FLIPYX((attr & 0x30) >> 4); - - tileinfo.set(1, code, color, flags); -} - -TILE_GET_INFO_MEMBER(psychic5_state::get_fg_tile_info) -{ - int offs = tile_index << 1; - int attr = m_fg_videoram[offs + 1]; - int code = m_fg_videoram[offs] | ((attr & 0xc0) << 2); - int color = attr & 0x0f; - int flags = TILE_FLIPYX((attr & 0x30) >> 4); - - tileinfo.set(2, code, color, flags); -} - - -/*************************************************************************** - Initialize and destroy video hardware emulation -***************************************************************************/ - -void psychic5_state::video_start() -{ - save_item(NAME(m_bg_clip_mode)); - save_item(NAME(m_palette_intensity)); - save_item(NAME(m_sx1)); - save_item(NAME(m_sy1)); - save_item(NAME(m_sy2)); -} - - -VIDEO_START_MEMBER(psychic5_state,psychic5) -{ - video_start(); - - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(psychic5_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32); - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(psychic5_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 32, 32); - m_fg_tilemap->set_transparent_pen(15); - - save_item(NAME(m_title_screen)); - -} - -VIDEO_START_MEMBER(psychic5_state,bombsa) -{ - video_start(); - - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(psychic5_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 128, 32); - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(psychic5_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 32, 32); - m_fg_tilemap->set_transparent_pen(15); - - save_item(NAME(m_bombsa_unknown)); -} - -void psychic5_state::video_reset() -{ - m_vrambank.select(0); - - m_bg_clip_mode = 0; - m_title_screen = 0; - m_palette_intensity = 0; -} - - - -/*************************************************************************** - Screen refresh -***************************************************************************/ - -#define DRAW_SPRITE(code, sx, sy) \ - if (m_blend) \ - m_blend->drawgfx(*m_palette, bitmap, cliprect, m_gfxdecode->gfx(0), code, color, flipx, flipy, sx, sy, 15); \ - else \ - m_gfxdecode->gfx(0)->transpen(bitmap, cliprect, code, color, flipx, flipy, sx, sy, 15); - -void psychic5_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - /* Draw the sprites */ - for (int offs = 0; offs < m_spriteram.bytes(); offs += 16) - { - int attr = m_spriteram[offs + 13]; - if(attr & 2) // Bombs Away: disable sprite if enabled - continue; - int code = m_spriteram[offs + 14] | ((attr & 0xc0) << 2); - int color = m_spriteram[offs + 15] & 0x0f; - int flipx = attr & 0x10; - int flipy = attr & 0x20; - int sx = m_spriteram[offs + 12]; - int sy = m_spriteram[offs + 11]; - int size = (attr & 0x08) ? 32:16; - - if (attr & 0x01) sx -= 256; - if (attr & 0x04) sy -= 256; - - if (flip_screen()) - { - sx = 224 - sx; - sy = 224 - sy; - flipx = !flipx; - flipy = !flipy; - } - - if (size == 32) - { - int x0,x1,y0,y1; - - if (flipx) { x0 = 2; x1 = 0; } - else { x0 = 0; x1 = 2; } - - if (flipy) { y0 = 1; y1 = 0; } - else { y0 = 0; y1 = 1; } - - DRAW_SPRITE(code + x0 + y0, sx, sy) - DRAW_SPRITE(code + x0 + y1, sx, sy + 16) - DRAW_SPRITE(code + x1 + y0, sx + 16, sy) - DRAW_SPRITE(code + x1 + y1, sx + 16, sy + 16) - } - else - { - if (flip_screen()) - DRAW_SPRITE(code, sx + 16, sy + 16) - else - DRAW_SPRITE(code, sx, sy) - } - } -} - -void psychic5_state::draw_background(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - rectangle clip = cliprect; - - set_background_palette_intensity(); - - if (!(m_title_screen & 1)) - { - m_bg_clip_mode = 0; - m_sx1 = m_sy1 = m_sy2 = 0; - } - else - { - int sy1_old = m_sy1; - int sx1_old = m_sx1; - int sy2_old = m_sy2; - - m_sy1 = m_spriteram[11]; /* sprite 0 */ - m_sx1 = m_spriteram[12]; - m_sy2 = m_spriteram[11+128]; /* sprite 8 */ - - switch (m_bg_clip_mode) - { - case 0: case 4: if (sy1_old != m_sy1) m_bg_clip_mode++; break; - case 2: case 6: if (sy2_old != m_sy2) m_bg_clip_mode++; break; - case 8: case 10: - case 12: case 14: if (sx1_old != m_sx1) m_bg_clip_mode++; break; - case 1: case 5: if (m_sy1 == 0xf0) m_bg_clip_mode++; break; - case 3: case 7: if (m_sy2 == 0xf0) m_bg_clip_mode++; break; - case 9: case 11: if (m_sx1 == 0xf0) m_bg_clip_mode++; break; - case 13: case 15: if (sx1_old == 0xf0) m_bg_clip_mode++; - [[fallthrough]]; - case 16: if (m_sy1 != 0x00) m_bg_clip_mode = 0; break; - } - - switch (m_bg_clip_mode) - { - case 0: case 4: case 8: case 12: case 16: - clip.set(0, 0, 0, 0); - break; - case 1: clip.min_y = m_sy1; break; - case 3: clip.max_y = m_sy2; break; - case 5: clip.max_y = m_sy1; break; - case 7: clip.min_y = m_sy2; break; - case 9: case 15: clip.min_x = m_sx1; break; - case 11: case 13: clip.max_x = m_sx1; break; - } - - if (flip_screen()) - clip.set(255 - clip.max_x, 255 - clip.min_x, 255 - clip.max_y, 255 - clip.min_y); - } - - m_bg_tilemap->draw(screen, bitmap, clip, 0, 0); -} - -uint32_t psychic5_state::screen_update_psychic5(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - uint16_t bg_scrollx = m_bg_control[0] | (m_bg_control[1] << 8); - m_bg_tilemap->set_scrollx(0, bg_scrollx); - uint16_t bg_scrolly = m_bg_control[2] | (m_bg_control[3] << 8); - m_bg_tilemap->set_scrolly(0, bg_scrolly); - - bitmap.fill(m_palette->black_pen(), cliprect); - if (m_bg_control[4] & 1) /* Backgound enable */ - draw_background(screen, bitmap, cliprect); - if (!(m_title_screen & 1)) - draw_sprites(bitmap, cliprect); - m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} - -uint32_t psychic5_state::screen_update_bombsa(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - uint16_t bg_scrollx = m_bg_control[0] | (m_bg_control[1] << 8); - m_bg_tilemap->set_scrollx(0, bg_scrollx); - uint16_t bg_scrolly = m_bg_control[2] | (m_bg_control[3] << 8); - m_bg_tilemap->set_scrolly(0, bg_scrolly); - bitmap.fill(m_palette->black_pen(), cliprect); - - if (m_bg_control[4] & 1) /* Backgound enable */ - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - else - bitmap.fill(m_palette->pen(0x0ff), cliprect); - draw_sprites(bitmap, cliprect); - m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} -- cgit v1.2.3