mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
jaleco/psychic5.cpp: Split system-specific code into derived classes.
This commit is contained in:
parent
413aa761bf
commit
081c073c8b
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -330,18 +330,508 @@ 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 <cassert>
|
||||
|
||||
|
||||
void psychic5_state::machine_start()
|
||||
namespace {
|
||||
|
||||
class psychic5_state_base : public driver_device
|
||||
{
|
||||
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<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
|
||||
memory_view m_vrambank;
|
||||
|
||||
required_memory_region m_bankrom;
|
||||
|
||||
required_memory_bank m_mainbank;
|
||||
|
||||
required_shared_ptr<uint8_t> m_spriteram;
|
||||
required_shared_ptr<uint8_t> m_fg_videoram;
|
||||
required_shared_ptr<uint8_t> m_bg_videoram;
|
||||
required_shared_ptr<uint8_t> m_bg_control;
|
||||
required_shared_ptr<uint8_t> m_palette_ram_bg;
|
||||
required_shared_ptr<uint8_t> m_palette_ram_sp;
|
||||
required_shared_ptr<uint8_t> 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 <typename T> 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);
|
||||
};
|
||||
|
||||
|
||||
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(machine_config &config) ATTR_COLD;
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override ATTR_COLD;
|
||||
virtual void machine_reset() override ATTR_COLD;
|
||||
|
||||
private:
|
||||
required_device<jaleco_blend_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
|
||||
{
|
||||
public:
|
||||
bombsa_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
psychic5_state_base(mconfig, type, tag)
|
||||
{
|
||||
}
|
||||
|
||||
void bombsa(machine_config &config) ATTR_COLD;
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override ATTR_COLD;
|
||||
|
||||
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
|
||||
***************************************************************************/
|
||||
|
||||
void psychic5_state_base::change_palette(int offset, uint8_t* palram, int palbase)
|
||||
{
|
||||
uint8_t const lo = palram[(offset) & ~1];
|
||||
uint8_t const hi = palram[(offset) | 1];
|
||||
|
||||
int const 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)
|
||||
{
|
||||
/* 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 handlers
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t psychic5_state_base::bankselect_r()
|
||||
{
|
||||
return m_bank_latch;
|
||||
}
|
||||
|
||||
void psychic5_state_base::bankselect_w(uint8_t data)
|
||||
{
|
||||
if (m_bank_latch != data)
|
||||
{
|
||||
m_bank_latch = data;
|
||||
m_mainbank->set_entry(data & m_bank_mask);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
flip_screen_set(!flip_screen());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t psychic5_state_base::vram_page_select_r()
|
||||
{
|
||||
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 <typename T>
|
||||
inline void psychic5_state_base::draw_sprites(T &&draw_sprite)
|
||||
{
|
||||
/* Draw the sprites */
|
||||
for (int offs = 0; offs < m_spriteram.bytes(); offs += 16)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Initialize and destroy video hardware emulation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
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));
|
||||
@ -350,26 +840,67 @@ void psychic5_state::machine_start()
|
||||
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_reset()
|
||||
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::scanline)
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(psychic5_state_base::scanline)
|
||||
{
|
||||
int scanline = param;
|
||||
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 */
|
||||
@ -382,64 +913,22 @@ TIMER_DEVICE_CALLBACK_MEMBER(psychic5_state::scanline)
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Memory Handler(s)
|
||||
Memory Maps
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
uint8_t psychic5_state::bankselect_r()
|
||||
{
|
||||
return m_bank_latch;
|
||||
}
|
||||
|
||||
void psychic5_state::bankselect_w(uint8_t data)
|
||||
{
|
||||
if (m_bank_latch != data)
|
||||
{
|
||||
m_bank_latch = data;
|
||||
m_mainbank->set_entry(data & m_bank_mask);
|
||||
}
|
||||
}
|
||||
|
||||
void psychic5_state::psychic5_coin_counter_w(uint8_t data)
|
||||
{
|
||||
machine().bookkeeping().coin_counter_w(0, data & 0x01);
|
||||
machine().bookkeeping().coin_counter_w(1, data & 0x02);
|
||||
|
||||
// bit 7 toggles flip screen
|
||||
if (data & 0x80)
|
||||
{
|
||||
flip_screen_set(!flip_screen());
|
||||
}
|
||||
}
|
||||
|
||||
void psychic5_state::bombsa_flipscreen_w(uint8_t data)
|
||||
{
|
||||
// bit 7 toggles flip screen
|
||||
if (data & 0x80)
|
||||
{
|
||||
flip_screen_set(!flip_screen());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Memory Map(s)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void psychic5_state::psychic5_main_map(address_map &map)
|
||||
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 )
|
||||
|
@ -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<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
optional_device<jaleco_blend_device> m_blend;
|
||||
|
||||
memory_view m_vrambank;
|
||||
|
||||
required_memory_region m_bankrom;
|
||||
|
||||
required_memory_bank m_mainbank;
|
||||
|
||||
required_shared_ptr<uint8_t> m_spriteram;
|
||||
required_shared_ptr<uint8_t> m_fg_videoram;
|
||||
required_shared_ptr<uint8_t> m_bg_videoram;
|
||||
required_shared_ptr<uint8_t> m_bg_control;
|
||||
required_shared_ptr<uint8_t> m_ps5_palette_ram_bg;
|
||||
required_shared_ptr<uint8_t> m_ps5_palette_ram_sp;
|
||||
required_shared_ptr<uint8_t> 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
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user