pgm.cpp: Use struct for sprites, Use raw parameters for screen (#6971)

* pgm.cpp: fix timing of intro sequences in some games.
* pgm.cpp: Use generic gfx layout for foreground, Move VBlank IRQ into screen_vblank, Reduce duplicates, Add notes
This commit is contained in:
cam900 2020-07-25 07:47:51 +09:00 committed by GitHub
parent 2201be3d47
commit d0159e9f7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 83 deletions

View File

@ -321,6 +321,13 @@ void pgm_state::pgm_base_mem(address_map &map)
map(0x900000, 0x907fff).mirror(0x0f8000).rw(FUNC(pgm_state::videoram_r), FUNC(pgm_state::videoram_w)).share("videoram"); /* IGS023 VIDEO CHIP */
map(0xa00000, 0xa011ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0xb00000, 0xb0ffff).ram().share("videoregs"); /* Video Regs inc. Zoom Table */
//map(0xb01000, 0xb0103f) Zoom/Shrink table for sprites
//map(0xb02000, 0xb02001) Background scroll Y
//map(0xb03000, 0xb03001) Background scroll X
//map(0xb04000, 0xb04001) Unknown #0
//map(0xb05000, 0xb05001) Foreground scroll Y
//map(0xb06000, 0xb06001) Foreground scroll X?
//map(0xb0e000, 0xb0e001) Unknown #1
map(0xc00003, 0xc00003).r(m_soundlatch, FUNC(generic_latch_8_device::read)).w(FUNC(pgm_state::m68k_l1_w));
map(0xc00005, 0xc00005).rw("soundlatch2", FUNC(generic_latch_8_device::read), FUNC(generic_latch_8_device::write));
@ -444,17 +451,6 @@ INPUT_PORTS_END
Note that the bit indexes are reversed compared to usual gfx layouts
(0-7 = LSB to MSB) */
static const gfx_layout pgm8_charlayout =
{
8,8,
RGN_FRAC(1,1),
4,
{ STEP4(3,-1) },
{ STEP8(0,4) },
{ STEP8(0,4*8) },
8*32
};
static const gfx_layout pgm32_charlayout =
{
32,32,
@ -467,8 +463,8 @@ static const gfx_layout pgm32_charlayout =
};
GFXDECODE_START( gfx_pgm )
GFXDECODE_REVERSEBITS( "tiles", 0, pgm8_charlayout, 0x800, 32 ) /* 8x8x4 Tiles */
GFXDECODE_REVERSEBITS( "tiles", 0, pgm32_charlayout, 0x400, 32 ) /* 32x32x5 Tiles */
GFXDECODE_ENTRY( "tiles", 0, gfx_8x8x4_packed_lsb, 0x800, 32 ) /* 8x8x4 Tiles */
GFXDECODE_REVERSEBITS( "tiles", 0, pgm32_charlayout, 0x400, 32 ) /* 32x32x5 Tiles */
GFXDECODE_END
/*** Machine Driver **********************************************************/
@ -479,10 +475,11 @@ TIMER_DEVICE_CALLBACK_MEMBER(pgm_state::interrupt)
{
int scanline = param;
// already being generated by m_maincpu->set_vblank_int("screen", FUNC(pgm_state::irq6_line_hold));
// already being generated by screen.screen_vblank().set(FUNC(pgm_state::screen_vblank));;
// if (scanline == 224)
// m_maincpu->set_input_line(6, HOLD_LINE);
// vblank end interrupt
if (scanline == 0)
if (!m_irq4_disabled) m_maincpu->set_input_line(4, HOLD_LINE);
}
@ -497,7 +494,6 @@ void pgm_state::pgmbase(machine_config &config)
/* basic machine hardware */
M68000(config, m_maincpu, 20_MHz_XTAL); /* 20 mhz! verified on real board */
m_maincpu->set_addrmap(AS_PROGRAM, &pgm_state::pgm_basic_mem);
m_maincpu->set_vblank_int("screen", FUNC(pgm_state::irq6_line_hold));
TIMER(config, "scantimer").configure_scanline(FUNC(pgm_state::interrupt), "screen", 0, 1);
Z80(config, m_soundcpu, 33.8688_MHz_XTAL/4);
@ -510,10 +506,7 @@ void pgm_state::pgmbase(machine_config &config)
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60); // killing blade won't boot (just displays 'error') if this is lower than 59.9 or higher than 60.1 .. are actual PGM boards different to the Cave one?
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(64*8, 64*8);
screen.set_visarea(0*8, 56*8-1, 0*8, 28*8-1);
screen.set_raw(50_MHz_XTAL/5, 640, 0, 448, 264, 0, 224); // or 20MHz / 2? framerate verified
screen.set_screen_update(FUNC(pgm_state::screen_update));
screen.screen_vblank().set(FUNC(pgm_state::screen_vblank));
screen.set_palette(m_palette);

View File

@ -81,9 +81,20 @@ private:
u16 * m_bg_videoram;
u16 * m_tx_videoram;
u16 * m_rowscrollram;
std::unique_ptr<u16[]> m_spritebufferram; // buffered spriteram
/* video-related */
struct sprite_t
{
int x,y;
bool xgrow, ygrow;
u32 xzoom, yzoom;
u32 color, offs;
u32 width, height;
u8 flip, pri;
};
std::unique_ptr<sprite_t[]> m_spritelist;
struct sprite_t *m_sprite_ptr_pre;
tilemap_t *m_bg_tilemap;
tilemap_t *m_tx_tilemap;
@ -128,7 +139,8 @@ private:
void draw_sprite_new_zoomed(int wide, int high, int xpos, int ypos, int palt, int flip, bitmap_ind16 &bitmap, const rectangle &cliprect, bitmap_ind8 &priority_bitmap, u32 xzoom, bool xgrow, u32 yzoom, bool ygrow, int pri);
void draw_sprite_line_basic(int wide, u16* dest, u8* destpri, const rectangle &cliprect, int flip, int xpos, int pri, int realxsize, int palt, bool draw);
void draw_sprite_new_basic(int wide, int high, int xpos, int ypos, int palt, int flip, bitmap_ind16 &bitmap, const rectangle &cliprect, bitmap_ind8 &priority_bitmap, int pri);
void draw_sprites(bitmap_ind16& spritebitmap, const rectangle &cliprect, u16 *sprite_source, bitmap_ind8& priority_bitmap);
void draw_sprites(bitmap_ind16& spritebitmap, const rectangle &cliprect, bitmap_ind8& priority_bitmap);
void get_sprites();
void pgm_basic_mem(address_map &map);
void pgm_z80_io(address_map &map);
void pgm_z80_mem(address_map &map);

View File

@ -226,8 +226,6 @@ void pgm_arm_type1_state::pgm_arm_type1(machine_config &config) // ARM7 Shared m
/* protection CPU */
ARM7(config, m_prot, 20000000); // 55857E?
m_prot->set_addrmap(AS_PROGRAM, &pgm_arm_type1_state::_55857E_arm7_map);
// subdevice<screen_device>("screen")->set_refresh_hz(59.17); // Correct?
}
void pgm_arm_type1_state::pgm_arm_type1_sim(machine_config &config) // When simulated
@ -245,8 +243,6 @@ void pgm_arm_type1_state::pgm_arm_type1_cave(machine_config &config)
// pgm_arm_type1(config); // When ARM7 ROM is dumped and hooked up
m_maincpu->set_addrmap(AS_PROGRAM, &pgm_arm_type1_state::cavepgm_mem);
subdevice<screen_device>("screen")->set_refresh_hz(59.17); // verified on pcb
}
void pgm_arm_type1_state::arm7_type1_latch_init()

View File

@ -19,6 +19,9 @@
// bg pri is 2
// sprite already here is 1 / 3
static inline bool get_flipy(u8 flip) { return BIT(flip, 1); }
static inline bool get_flipx(u8 flip) { return BIT(flip, 0); }
inline void pgm_state::pgm_draw_pix(int xdrawpos, int pri, u16* dest, u8* destpri, const rectangle &cliprect, u16 srcdat)
{
if ((xdrawpos >= cliprect.min_x) && (xdrawpos <= cliprect.max_x))
@ -110,7 +113,7 @@ void pgm_state::draw_sprite_line(int wide, u16* dest, u8* destpri, const rectang
if (xzoombit && xgrow)
{ // double this column
if (!(flip & 0x01))
if (!get_flipx(flip))
xdrawpos = xpos + xcntdraw;
else
xdrawpos = xpos + realxsize - xcntdraw;
@ -119,7 +122,7 @@ void pgm_state::draw_sprite_line(int wide, u16* dest, u8* destpri, const rectang
xcntdraw++;
if (!(flip & 0x01))
if (!get_flipx(flip))
xdrawpos = xpos + xcntdraw;
else
xdrawpos = xpos + realxsize - xcntdraw;
@ -134,7 +137,7 @@ void pgm_state::draw_sprite_line(int wide, u16* dest, u8* destpri, const rectang
}
else //normal column
{
if (!(flip & 0x01))
if (!get_flipx(flip))
xdrawpos = xpos + xcntdraw;
else
xdrawpos = xpos + realxsize - xcntdraw;
@ -219,7 +222,7 @@ void pgm_state::draw_sprite_new_zoomed(int wide, int high, int xpos, int ypos, i
const int temp_abit = m_abit;
const int temp_boffset = m_boffset;
if (!(flip & 0x02))
if (!get_flipy(flip))
ydrawpos = ypos + ycntdraw;
else
ydrawpos = ypos + realysize - ycntdraw;
@ -242,7 +245,7 @@ void pgm_state::draw_sprite_new_zoomed(int wide, int high, int xpos, int ypos, i
m_abit = temp_abit;
m_boffset = temp_boffset;
if (!(flip & 0x02))
if (!get_flipy(flip))
ydrawpos = ypos + ycntdraw;
else
ydrawpos = ypos + realysize - ycntdraw;
@ -257,7 +260,7 @@ void pgm_state::draw_sprite_new_zoomed(int wide, int high, int xpos, int ypos, i
{
draw_sprite_line(wide, nullptr, nullptr, cliprect, xzoom, xgrow, flip, xpos, pri, realxsize, palt, false);
if (!(flip & 0x02))
if (!get_flipy(flip))
{
if (ydrawpos >= cliprect.max_y)
return;
@ -279,7 +282,7 @@ void pgm_state::draw_sprite_new_zoomed(int wide, int high, int xpos, int ypos, i
}
else /* normal line */
{
if (!(flip & 0x02))
if (!get_flipy(flip))
ydrawpos = ypos + ycntdraw;
else
ydrawpos = ypos + realysize - ycntdraw;
@ -294,7 +297,7 @@ void pgm_state::draw_sprite_new_zoomed(int wide, int high, int xpos, int ypos, i
{
draw_sprite_line(wide, nullptr, nullptr, cliprect, xzoom, xgrow, flip, xpos, pri, realxsize, palt, false);
if (!(flip & 0x02))
if (!get_flipy(flip))
{
if (ydrawpos >= cliprect.max_y)
return;
@ -337,7 +340,7 @@ void pgm_state::draw_sprite_line_basic(int wide, u16* dest, u8* destpri, const r
{
xoffset++;
if (!(flip & 0x01))
if (!get_flipx(flip))
xdrawpos = xpos + xcntdraw;
else
xdrawpos = xpos + realxsize - xcntdraw;
@ -376,7 +379,7 @@ void pgm_state::draw_sprite_line_basic(int wide, u16* dest, u8* destpri, const r
{
xoffset++;
if (!(flip & 0x01))
if (!get_flipx(flip))
xdrawpos = xpos + xcntdraw;
else
xdrawpos = xpos + realxsize - xcntdraw;
@ -425,7 +428,7 @@ void pgm_state::draw_sprite_new_basic(int wide, int high, int xpos, int ypos, in
while (ycnt < high)
{
if (!(flip & 0x02))
if (!get_flipy(flip))
ydrawpos = ypos + ycntdraw;
else
ydrawpos = ypos + realysize - ycntdraw;
@ -440,7 +443,7 @@ void pgm_state::draw_sprite_new_basic(int wide, int high, int xpos, int ypos, in
{
draw_sprite_line_basic(wide, nullptr, nullptr, cliprect, flip, xpos, pri, realxsize, palt, false);
if (!(flip & 0x02))
if (!get_flipy(flip))
{
if (ydrawpos >= cliprect.max_y)
return;
@ -458,42 +461,85 @@ void pgm_state::draw_sprite_new_basic(int wide, int high, int xpos, int ypos, in
}
void pgm_state::draw_sprites(bitmap_ind16& spritebitmap, const rectangle &cliprect, u16 *sprite_source, bitmap_ind8& priority_bitmap)
void pgm_state::draw_sprites(bitmap_ind16& spritebitmap, const rectangle &cliprect, bitmap_ind8& priority_bitmap)
{
/* ZZZZ Zxxx xxxx xxxx
zzzz z-yy yyyy yyyy
-ffp pppp Pvvv vvvv
vvvv vvvv vvvv vvvv
wwww wwwh hhhh hhhh
*/
struct sprite_t *sprite_ptr = m_sprite_ptr_pre;
while (sprite_ptr != m_spritelist.get())
{
sprite_ptr--;
const u16 *finish = m_spritebufferram.get() + (0xa00 / 2);
m_boffset = sprite_ptr->offs;
if ((!sprite_ptr->xzoom) && (!sprite_ptr->yzoom))
{
draw_sprite_new_basic(sprite_ptr->width, sprite_ptr->height,
sprite_ptr->x, sprite_ptr->y,
sprite_ptr->color, sprite_ptr->flip,
spritebitmap, cliprect, priority_bitmap,
sprite_ptr->pri);
}
else
{
draw_sprite_new_zoomed(sprite_ptr->width, sprite_ptr->height,
sprite_ptr->x, sprite_ptr->y,
sprite_ptr->color, sprite_ptr->flip,
spritebitmap, cliprect, priority_bitmap,
sprite_ptr->xzoom, sprite_ptr->xgrow, sprite_ptr->yzoom, sprite_ptr->ygrow, sprite_ptr->pri);
}
}
}
u16* start = sprite_source;
/*
Sprite list format (10 bytes per sprites, 256 entries)
Offset Bits
fedcba98 76543210
00 x------- -------- Horizontal Zoom/Shrink mode select
-xxxx--- -------- Horizontal Zoom/Shrink table select
-----xxx xxxxxxxx X position (11 bit signed)
02 x------- -------- Vertical Zoom/Shrink mode select
-xxxx--- -------- Vertical Zoom/Shrink table select
-----xxx xxxxxxxx Y position (10 bit signed)
04 -x------ -------- Flip Y
--x----- -------- Flip X
---xxxxx -------- Palette select (32 color each)
-------- x------- Priority (Over(0) or Under(1) background)
-------- -xxxxxxx Sprite mask ROM address MSB
06 xxxxxxxx xxxxxxxx Sprite mask ROM address LSB
08 x------- -------- Another sprite width bit?
-xxxxxx- -------- Sprite width (16 pixel each)
-------x xxxxxxxx Sprite height (1 pixel each)
*/
void pgm_state::get_sprites()
{
m_sprite_ptr_pre = m_spritelist.get();
u16 *sprite_source = &m_mainram[0];
const u16 *finish = &m_mainram[0xa00 / 2];
const u16* sprite_zoomtable = &m_videoregs[0x1000 / 2];
while (sprite_source < finish)
{
if (!sprite_source[4]) break; /* is this right? */
sprite_source += 5;
}
sprite_source -= 5;
while (sprite_source >= start)
{
int xpos = sprite_source[0] & 0x07ff;
int ypos = sprite_source[1] & 0x03ff;
int xzom = (sprite_source[0] & 0x7800) >> 11;
const bool xgrow = (sprite_source[0] & 0x8000) >> 15;
int yzom = (sprite_source[1] & 0x7800) >> 11;
const bool ygrow = (sprite_source[1] & 0x8000) >> 15;
const int palt = (sprite_source[2] & 0x1f00) >> 8;
const int flip = (sprite_source[2] & 0x6000) >> 13;
int boff = ((sprite_source[2] & 0x007f) << 16) | (sprite_source[3] & 0xffff);
const int wide = (sprite_source[4] & 0x7e00) >> 9;
const int high = sprite_source[4] & 0x01ff;
const int pri = (sprite_source[2] & 0x0080) >> 7;
int xzom = (sprite_source[0] & 0x7800) >> 11;
const bool xgrow = (sprite_source[0] & 0x8000) >> 15;
m_sprite_ptr_pre->x = (sprite_source[0] & 0x03ff) - (sprite_source[0] & 0x0400);
const u16* sprite_zoomtable = &m_videoregs[0x1000 / 2];
int yzom = (sprite_source[1] & 0x7800) >> 11;
const bool ygrow = (sprite_source[1] & 0x8000) >> 15;
m_sprite_ptr_pre->y = (sprite_source[1] & 0x01ff) - (sprite_source[1] & 0x0200);
m_sprite_ptr_pre->flip = (sprite_source[2] & 0x6000) >> 13;
m_sprite_ptr_pre->color = (sprite_source[2] & 0x1f00) >> 8;
m_sprite_ptr_pre->pri = (sprite_source[2] & 0x0080) >> 7;
m_sprite_ptr_pre->offs = ((sprite_source[2] & 0x007f) << 16) | (sprite_source[3] & 0xffff);
m_sprite_ptr_pre->width = (sprite_source[4] & 0x7e00) >> 9;
m_sprite_ptr_pre->height = sprite_source[4] & 0x01ff;
if (xgrow)
{
@ -507,19 +553,12 @@ void pgm_state::draw_sprites(bitmap_ind16& spritebitmap, const rectangle &clipre
yzom = 0x10 - yzom;
}
u32 xzoom = (sprite_zoomtable[xzom * 2] << 16) | sprite_zoomtable[xzom * 2 + 1];
u32 yzoom = (sprite_zoomtable[yzom * 2] << 16) | sprite_zoomtable[yzom * 2 + 1];
if (xpos > 0x3ff) xpos -= 0x800;
if (ypos > 0x1ff) ypos -= 0x400;
//if ((priority == 1) && (pri == 0)) break;
m_boffset = boff;
if ((!xzoom) && (!yzoom)) draw_sprite_new_basic(wide, high, xpos, ypos, palt, flip, spritebitmap, cliprect, priority_bitmap, pri);
else draw_sprite_new_zoomed(wide, high, xpos, ypos, palt, flip, spritebitmap, cliprect, priority_bitmap, xzoom, xgrow, yzoom, ygrow, pri);
sprite_source -= 5;
m_sprite_ptr_pre->xzoom = (sprite_zoomtable[xzom * 2] << 16) | sprite_zoomtable[xzom * 2 + 1];
m_sprite_ptr_pre->yzoom = (sprite_zoomtable[yzom * 2] << 16) | sprite_zoomtable[yzom * 2 + 1];
m_sprite_ptr_pre->xgrow = xgrow;
m_sprite_ptr_pre->ygrow = ygrow;
m_sprite_ptr_pre++;
sprite_source += 5;
}
}
@ -578,6 +617,9 @@ TILE_GET_INFO_MEMBER(pgm_state::get_bg_tile_info)
void pgm_state::video_start()
{
m_spritelist = std::make_unique<sprite_t[]>(0xa00/2/5);
m_sprite_ptr_pre = m_spritelist.get();
m_aoffset = 0;
m_abit = 0;
m_boffset = 0;
@ -588,10 +630,6 @@ void pgm_state::video_start()
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pgm_state::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 32, 32, 64, 16);
m_bg_tilemap->set_transparent_pen(31);
m_bg_tilemap->set_scroll_rows(16 * 32);
m_spritebufferram = make_unique_clear<u16[]>(0xa00/2);
save_pointer(NAME(m_spritebufferram), 0xa00/2);
}
u32 pgm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
@ -607,7 +645,7 @@ u32 pgm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 2);
draw_sprites(bitmap, cliprect, m_spritebufferram.get(), screen.priority());
draw_sprites(bitmap, cliprect, screen.priority());
m_tx_tilemap->set_scrolly(0, m_videoregs[0x5000/2]);
m_tx_tilemap->set_scrollx(0, m_videoregs[0x6000/2]); // Check
@ -623,6 +661,9 @@ WRITE_LINE_MEMBER(pgm_state::screen_vblank)
if (state)
{
/* first 0xa00 of main ram = sprites, seems to be buffered, DMA? */
memcpy(m_spritebufferram.get(), m_mainram, 0xa00);
get_sprites();
// vblank start interrupt
m_maincpu->set_input_line(M68K_IRQ_6, HOLD_LINE);
}
}