20pacgal.cpp : Updates, Cleanups (#3642)

* 20pacgal.cpp : Add palette_device, Move video start functions into video_start, Reduce runtime tag lookups, Convert some arrays into std::unique_ptr, Make drawing sprite/chars functions related to cliprect, Add notes

* 20pacgal.cpp : Minor cleanup of palette
This commit is contained in:
cam900 2018-06-17 15:11:33 +09:00 committed by Vas Crabb
parent df98fc2024
commit b140887dd8
3 changed files with 97 additions and 59 deletions

View File

@ -45,6 +45,7 @@
* The timed interrupt is a kludge; it is supposed to be generated internally by
the Z180, but the cpu core doesn't support that yet.
* Is the clock divide 3 or 4?
* Galaga attract mode isn't correct; referenct : https://youtu.be/OQyWaN9fTgw?t=2m33s
+-------------------------------------------------------+
| +-------------+ |
@ -146,8 +147,12 @@ WRITE8_MEMBER(_20pacgal_state::_20pacgal_coin_counter_w)
WRITE8_MEMBER(_20pacgal_state::ram_bank_select_w)
{
m_game_selected = data & 1;
membank("bank1")->set_entry(m_game_selected);
if (m_game_selected != (data & 1))
{
m_game_selected = data & 1;
m_mainbank->set_entry(m_game_selected);
get_pens();
}
}
WRITE8_MEMBER(_20pacgal_state::ram_48000_w)
@ -194,7 +199,7 @@ void _25pacman_state::_25pacman_map(address_map &map)
map(0x04800, 0x05fff).ram();
map(0x06000, 0x06fff).writeonly().share("char_gfx_ram");
map(0x07000, 0x0717f).w(FUNC(_25pacman_state::sprite_ram_w));
// AM_RANGE(0x08000, 0x09fff) AM_READ_BANK("bank1") AM_WRITE(ram_48000_w)
// map(0x08000, 0x09fff).bankr("mainbank").w(FUNC(_20pacgal_state::ram_48000_w));
map(0x08000, 0x09fff).nopw();
map(0x0a000, 0x0bfff).w(FUNC(_25pacman_state::sprite_gfx_w));
map(0x0c000, 0x0dfff).nopw(); // is this the sound waveforms in a different format?
@ -215,7 +220,7 @@ void _20pacgal_state::_20pacgal_map(address_map &map)
map(0x45f00, 0x45fff).w("namco", FUNC(namco_cus30_device::namcos1_cus30_w));
map(0x46000, 0x46fff).writeonly().share("char_gfx_ram");
map(0x47100, 0x47100).ram(); /* leftover from original Galaga code */
map(0x48000, 0x49fff).bankr("bank1").w(FUNC(_20pacgal_state::ram_48000_w)); /* this should be a mirror of 08000-09fff */
map(0x48000, 0x49fff).bankr("mainbank").w(FUNC(_20pacgal_state::ram_48000_w)); /* this should be a mirror of 08000-09fff */
map(0x4c000, 0x4dfff).w(FUNC(_20pacgal_state::sprite_gfx_w));
map(0x4e000, 0x4e17f).w(FUNC(_20pacgal_state::sprite_ram_w));
map(0x4e180, 0x4feff).nopw();
@ -360,12 +365,11 @@ INPUT_PORTS_END
void _20pacgal_state::common_save_state()
{
m_ram_48000 = make_unique_clear<uint8_t[]>(0x2000);
save_item(NAME(m_game_selected));
save_item(NAME(m_ram_48000));
save_pointer(NAME(m_ram_48000.get()), 0x2000);
save_item(NAME(m_irq_mask));
save_item(NAME(m_sprite_gfx_ram));
save_item(NAME(m_sprite_ram));
save_item(NAME(m_sprite_color_lookup));
}
void _20pacgal_state::machine_start()
@ -373,8 +377,8 @@ void _20pacgal_state::machine_start()
common_save_state();
// membank currently used only by 20pacgal
membank("bank1")->configure_entry(0, memregion("maincpu")->base() + 0x08000);
membank("bank1")->configure_entry(1, m_ram_48000);
m_mainbank->configure_entry(0, memregion("maincpu")->base() + 0x08000);
m_mainbank->configure_entry(1, m_ram_48000.get());
}
void _25pacman_state::machine_start()

View File

@ -14,15 +14,18 @@
class _20pacgal_state : public driver_device
{
public:
_20pacgal_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
_20pacgal_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_video_ram(*this, "video_ram"),
m_char_gfx_ram(*this, "char_gfx_ram"),
m_stars_seed(*this, "stars_seed"),
m_stars_ctrl(*this, "stars_ctrl"),
m_flip(*this, "flip"),
m_proms(*this, "proms"),
m_mainbank(*this, "mainbank"),
m_maincpu(*this, "maincpu"),
m_eeprom(*this, "eeprom") { }
m_eeprom(*this, "eeprom"),
m_palette(*this, "palette") { }
/* memory pointers */
required_shared_ptr<uint8_t> m_video_ram;
@ -31,18 +34,22 @@ public:
required_shared_ptr<uint8_t> m_stars_ctrl;
required_shared_ptr<uint8_t> m_flip;
optional_memory_region m_proms;
optional_memory_bank m_mainbank;
/* machine state */
uint8_t m_game_selected; /* 0 = Ms. Pac-Man, 1 = Galaga */
/* devices */
required_device<cpu_device> m_maincpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<palette_device> m_palette;
/* memory */
uint8_t m_sprite_gfx_ram[0x2000];
uint8_t m_sprite_ram[0x180];
uint8_t m_sprite_color_lookup[0x100];
uint8_t m_ram_48000[0x2000];
std::unique_ptr<uint8_t[]> m_sprite_gfx_ram;
std::unique_ptr<uint8_t[]> m_sprite_ram;
std::unique_ptr<uint8_t[]> m_sprite_color_lookup;
std::unique_ptr<uint8_t[]> m_ram_48000;
/* 25pacman and 20pacgal store the sprite palette at a different address, this is a hardware difference and confirmed NOT to be a register */
uint8_t m_sprite_pal_base;
@ -60,14 +67,16 @@ public:
void init_20pacgal();
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
uint32_t screen_update_20pacgal(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(vblank_irq);
void get_pens(pen_t *pens);
DECLARE_PALETTE_INIT(starpal_init);
void get_pens();
void do_pen_lookup(bitmap_rgb32 &bitmap, const rectangle &cliprect);
void draw_sprites(bitmap_rgb32 &bitmap);
void draw_chars(bitmap_rgb32 &bitmap);
void draw_stars(bitmap_rgb32 &bitmap, const rectangle &cliprect );
void draw_sprite(bitmap_rgb32 &bitmap, int y, int x,
void draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect);
void draw_chars(bitmap_rgb32 &bitmap, const rectangle &cliprect);
void draw_stars(bitmap_rgb32 &bitmap, const rectangle &cliprect);
void draw_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, int y, int x,
uint8_t code, uint8_t color, int flip_y, int flip_x);
void common_save_state();
void _20pacgal(machine_config &config);

View File

@ -25,10 +25,11 @@
*
*************************************/
void _20pacgal_state::get_pens(pen_t *pens)
void _20pacgal_state::get_pens()
{
// TODO : Accurate palette when prom isn't exists
offs_t offs;
uint8_t *color_prom = memregion("proms")->base() + (NUM_PENS * m_game_selected);
uint8_t *color_prom = m_proms->base() + (NUM_PENS * m_game_selected);
for (offs = 0; offs < NUM_PENS ;offs++)
{
@ -52,14 +53,18 @@ void _20pacgal_state::get_pens(pen_t *pens)
bit2 = (*color_prom >> 7) & 0x01;
b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
pens[offs] = rgb_t(r, g, b);
m_palette->set_pen_color(offs, rgb_t(r, g, b));
color_prom++;
}
}
PALETTE_INIT_MEMBER(_20pacgal_state,starpal_init)
{
/* Star field */
/* palette for the stars */
for (offs = 0;offs < 64;offs++)
for (offs_t offs = 0;offs < 64;offs++)
{
int bits,r,g,b;
static const int map[4] = { 0x00, 0x47, 0x97 ,0xde };
@ -71,21 +76,18 @@ void _20pacgal_state::get_pens(pen_t *pens)
bits = (offs >> 4) & 0x03;
b = map[bits];
pens[NUM_PENS + offs] = rgb_t(r, g, b);
palette.set_pen_color(NUM_PENS + offs, rgb_t(r, g, b));
}
}
void _20pacgal_state::do_pen_lookup(bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int y, x;
pen_t pens[NUM_PENS + NUM_STAR_PENS];
const pen_t *pen = m_palette->pens();
get_pens(pens);
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
for(x = cliprect.min_x; x <= cliprect.max_x; x++)
bitmap.pix32(y, x) = pens[bitmap.pix32(y, x)];
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
for(int x = cliprect.min_x; x <= cliprect.max_x; x++)
bitmap.pix32(y, x) = pen[bitmap.pix32(y, x)];
}
@ -96,7 +98,7 @@ void _20pacgal_state::do_pen_lookup(bitmap_rgb32 &bitmap, const rectangle &clipr
*
*************************************/
void _20pacgal_state::draw_sprite(bitmap_rgb32 &bitmap, int y, int x,
void _20pacgal_state::draw_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, int y, int x,
uint8_t code, uint8_t color, int flip_y, int flip_x)
{
int sy;
@ -115,7 +117,7 @@ void _20pacgal_state::draw_sprite(bitmap_rgb32 &bitmap, int y, int x,
{
int x_sav = x;
if ((y >= 0) && (y < SCREEN_HEIGHT))
if ((y >= cliprect.min_y) && (y <= cliprect.max_y))
{
int sx;
uint32_t data;
@ -133,7 +135,7 @@ void _20pacgal_state::draw_sprite(bitmap_rgb32 &bitmap, int y, int x,
/* for each pixel in the row */
for (sx = 0; sx < 0x10; sx++)
{
if ((x >= 0) && (x < SCREEN_WIDTH))
if ((x >= cliprect.min_x) && (x <= cliprect.max_x))
{
offs_t pen = (data & 0xc0000000) >> 30;
uint8_t col;
@ -166,7 +168,7 @@ void _20pacgal_state::draw_sprite(bitmap_rgb32 &bitmap, int y, int x,
}
void _20pacgal_state::draw_sprites(bitmap_rgb32 &bitmap)
void _20pacgal_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int offs;
@ -202,7 +204,7 @@ void _20pacgal_state::draw_sprites(bitmap_rgb32 &bitmap)
for (y = 0; y <= size_y; y++)
for (x = 0; x <= size_x; x++)
draw_sprite(bitmap,
draw_sprite(bitmap, cliprect,
sy + (16 * y), sx + (16 * x),
code + code_offs[y ^ (size_y * flip_y)][x ^ (size_x * flip_x)],
color,
@ -218,7 +220,7 @@ void _20pacgal_state::draw_sprites(bitmap_rgb32 &bitmap)
*
*************************************/
void _20pacgal_state::draw_chars(bitmap_rgb32 &bitmap)
void _20pacgal_state::draw_chars(bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
offs_t offs;
@ -268,27 +270,33 @@ void _20pacgal_state::draw_chars(bitmap_rgb32 &bitmap)
int sx;
int x_sav = x;
uint16_t data = (gfx[8] << 8) | gfx[0];
/* for each pixel in the row */
for (sx = 0; sx < 8; sx++)
if ((y >= cliprect.min_y) && (y <= cliprect.max_y))
{
uint32_t col = ((data & 0x8000) >> 14) | ((data & 0x0800) >> 11);
uint16_t data = (gfx[8] << 8) | gfx[0];
/* pen bits A4-A11 */
if ( col != 0 )
bitmap.pix32(y, x) = (color_base | col) << 4;
/* for each pixel in the row */
for (sx = 0; sx < 8; sx++)
{
if ((x >= cliprect.min_x) && (x <= cliprect.max_x))
{
uint32_t col = ((data & 0x8000) >> 14) | ((data & 0x0800) >> 11);
/* next pixel */
if (flip)
x = x - 1;
else
x = x + 1;
/* pen bits A4-A11 */
if ( col != 0 )
bitmap.pix32(y, x) = (color_base | col) << 4;
if (sx == 0x03)
data = data << 5;
else
data = data << 1;
/* next pixel */
if (flip)
x = x - 1;
else
x = x + 1;
if (sx == 0x03)
data = data << 5;
else
data = data << 1;
}
}
}
/* next row */
@ -413,14 +421,28 @@ uint32_t _20pacgal_state::screen_update_20pacgal(screen_device &screen, bitmap_r
{
bitmap.fill(0, cliprect);
draw_stars(bitmap,cliprect);
draw_chars(bitmap);
draw_sprites(bitmap);
draw_chars(bitmap, cliprect);
draw_sprites(bitmap, cliprect);
do_pen_lookup(bitmap, cliprect);
return 0;
}
void _20pacgal_state::video_start()
{
m_sprite_gfx_ram = make_unique_clear<uint8_t[]>(0x2000);
m_sprite_ram = make_unique_clear<uint8_t[]>(0x180);
m_sprite_color_lookup = make_unique_clear<uint8_t[]>(0x100);
save_pointer(NAME(m_sprite_gfx_ram.get()), 0x2000);
save_pointer(NAME(m_sprite_ram.get()), 0x180);
save_pointer(NAME(m_sprite_color_lookup.get()), 0x100);
if (m_proms != nullptr)
get_pens();
}
/*************************************
*
@ -436,4 +458,7 @@ MACHINE_CONFIG_START(_20pacgal_state::_20pacgal_video)
MCFG_SCREEN_VISIBLE_AREA(0, SCREEN_WIDTH - 1, 0, SCREEN_HEIGHT - 1)
MCFG_SCREEN_UPDATE_DRIVER(_20pacgal_state, screen_update_20pacgal)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, _20pacgal_state, vblank_irq))
MCFG_PALETTE_ADD("palette", NUM_PENS + NUM_STAR_PENS)
MCFG_PALETTE_INIT_OWNER(_20pacgal_state,starpal_init)
MACHINE_CONFIG_END