diff options
Diffstat (limited to 'src/mame/video/psikyo.cpp')
-rw-r--r-- | src/mame/video/psikyo.cpp | 323 |
1 files changed, 172 insertions, 151 deletions
diff --git a/src/mame/video/psikyo.cpp b/src/mame/video/psikyo.cpp index ae5885db06a..96cbbe08e5a 100644 --- a/src/mame/video/psikyo.cpp +++ b/src/mame/video/psikyo.cpp @@ -76,14 +76,14 @@ Offset: template<int Layer> TILE_GET_INFO_MEMBER(psikyo_state::get_tile_info) { - uint16_t code = ((uint16_t *)m_vram[Layer].target())[BYTE_XOR_BE(tile_index)]; + u16 code = ((u16 *)m_vram[Layer].target())[BYTE_XOR_BE(tile_index)]; SET_TILE_INFO_MEMBER(1, (code & 0x1fff) + 0x2000 * m_tilemap_bank[Layer], ((code >> 13) & 7) + (Layer * 0x40), 0); } -void psikyo_state::psikyo_switch_banks( int tmap, int bank ) +void psikyo_state::switch_bgbanks(u8 tmap, u8 bank) { if (bank != m_tilemap_bank[tmap]) { @@ -96,6 +96,8 @@ void psikyo_state::psikyo_switch_banks( int tmap, int bank ) VIDEO_START_MEMBER(psikyo_state,psikyo) { + m_spritelist = std::make_unique<sprite_t[]>(0x800/2*8*8); + m_sprite_ptr_pre = m_spritelist.get(); /* The Hardware is Capable of Changing the Dimensions of the Tilemaps, its safer to create the various sized tilemaps now as opposed to later */ @@ -110,21 +112,16 @@ VIDEO_START_MEMBER(psikyo_state,psikyo) m_tilemap[layer][size]->set_scroll_cols(1); } } - - m_spritebuf[0] = std::make_unique<uint32_t[]>(0x2000 / 4); - m_spritebuf[1] = std::make_unique<uint32_t[]>(0x2000 / 4); - - save_pointer(NAME(m_spritebuf[0]), 0x2000 / 4, 0); - save_pointer(NAME(m_spritebuf[1]), 0x2000 / 4, 1); save_item(NAME(m_old_linescroll)); + save_item(NAME(m_sprite_ctrl)); } VIDEO_START_MEMBER(psikyo_state,sngkace) { VIDEO_START_CALL_MEMBER( psikyo ); - psikyo_switch_banks(0, 0); // sngkace / samuraia don't use banking - psikyo_switch_banks(1, 1); // They share "gfx2" to save memory on other boards + switch_bgbanks(0, 0); // sngkace / samuraia don't use banking + switch_bgbanks(1, 1); // They share "gfx2" to save memory on other boards } @@ -173,62 +170,53 @@ Note: Not all sprites are displayed: in the top part of spriteram ***************************************************************************/ -void psikyo_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int trans_pen ) +void psikyo_state::get_sprites() { /* tile layers 0 & 1 have priorities 1 & 2 */ + m_sprite_ctrl = m_spriteram->buffer()[0x1ffe / 4] & 0xffff; static const int pri[] = { 0, 0xfc, 0xff, 0xff }; - int offs; - uint16_t *spritelist = (uint16_t *)(m_spritebuf[1].get() + 0x1800 / 4); - uint8_t *TILES = m_spritelut->base(); // Sprites LUT - int TILES_LEN = m_spritelut->bytes(); + const u16 *spritelist = (u16 *)(m_spriteram->buffer() + 0x1800 / 4); + const u8 *TILES = m_spritelut->base(); // Sprites LUT + u32 const TILES_LEN = m_spritelut->bytes(); - int width = m_screen->width(); - int height = m_screen->height(); + u16 const width = m_screen->width(); + u16 const height = m_screen->height(); /* Exit if sprites are disabled */ - if (spritelist[BYTE_XOR_BE((0x800 - 2) / 2)] & 1) return; + m_sprite_ptr_pre = m_spritelist.get(); + if (m_sprite_ctrl & 1) + return; /* Look for "end of sprites" marker in the sprites list */ - for (offs = 0/2 ; offs < (0x800 - 2)/2 ; offs += 2/2) // skip last "sprite" - { - uint16_t sprite = spritelist[BYTE_XOR_BE(offs)]; - if (sprite == 0xffff) - break; - } - - offs -= 2/2; - - // fprintf(stderr, "\n"); - for ( ; offs >= 0/2 ; offs -= 2/2) + for (int offs = 0/2 ; offs < (0x800 - 2)/2 ; offs += 2/2) // skip last "sprite" { - uint32_t *source; - int sprite; - - int x, y, attr, code, flipx, flipy, nx, ny, zoomx, zoomy; - int dx, dy, xstart, ystart, xend, yend, xinc, yinc; + int xstart, ystart, xend, yend, xinc, yinc; /* Get next entry in the list */ - sprite = spritelist[BYTE_XOR_BE(offs)]; + u16 sprite = spritelist[BYTE_XOR_BE(offs)]; + + if (sprite == 0xffff) + break; sprite %= 0x300; - source = &m_spritebuf[1][sprite * 8 / 4]; + const u32 *source = &m_spriteram->buffer()[sprite * 8 / 4]; /* Draw this sprite */ - y = source[0 / 4] >> 16; - x = source[0 / 4] & 0xffff; - attr = source[4 / 4] >> 16; - code = source[4 / 4] & 0x1ffff; + s32 y = source[0 / 4] >> 16; + s32 x = source[0 / 4] & 0xffff; + u16 const attr = source[4 / 4] >> 16; + u32 code = source[4 / 4] & 0x1ffff; - flipx = attr & 0x4000; - flipy = attr & 0x8000; + int flipx = attr & 0x4000; + int flipy = attr & 0x8000; - zoomx = ((x & 0xf000) >> 12); - zoomy = ((y & 0xf000) >> 12); - nx = ((x & 0x0e00) >> 9) + 1; - ny = ((y & 0x0e00) >> 9) + 1; - x = ((x & 0x01ff)); - y = ((y & 0x00ff)) - (y & 0x100); + u32 zoomx = ((x & 0xf000) >> 12); + u32 zoomy = ((y & 0xf000) >> 12); + u8 const nx = ((x & 0x0e00) >> 9) + 1; + u8 const ny = ((y & 0x0e00) >> 9) + 1; + x = ((x & 0x01ff)); + y = ((y & 0x00ff)) - (y & 0x100); /* 180-1ff are negative coordinates. Note that $80 pixels is the maximum extent of a sprite, which can therefore be moved @@ -256,29 +244,32 @@ void psikyo_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, co if (flipy) { ystart = ny - 1; yend = -1; yinc = -1; } else { ystart = 0; yend = ny; yinc = +1; } - for (dy = ystart; dy != yend; dy += yinc) + for (int dy = ystart; dy != yend; dy += yinc) { - for (dx = xstart; dx != xend; dx += xinc) + for (int dx = xstart; dx != xend; dx += xinc) { - int addr = (code * 2) & (TILES_LEN - 1); + u32 const addr = (code * 2) & (TILES_LEN - 1); + m_sprite_ptr_pre->gfx = 0; + m_sprite_ptr_pre->code = TILES[addr+1] * 256 + TILES[addr]; + m_sprite_ptr_pre->color = attr >> 8; + m_sprite_ptr_pre->flipx = flipx; + m_sprite_ptr_pre->flipy = flipy; if (zoomx == 32 && zoomy == 32) - m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect, - TILES[addr+1] * 256 + TILES[addr], - attr >> 8, - flipx, flipy, - x + dx * 16, y + dy * 16, - screen.priority(), - pri[(attr & 0xc0) >> 6],trans_pen); + { + m_sprite_ptr_pre->x = x + dx * 16; + m_sprite_ptr_pre->y = y + dy * 16; + } else - m_gfxdecode->gfx(0)->prio_zoom_transpen(bitmap,cliprect, - TILES[addr+1] * 256 + TILES[addr], - attr >> 8, - flipx, flipy, - x + (dx * zoomx) / 2, y + (dy * zoomy) / 2, - zoomx << 11,zoomy << 11, - screen.priority(),pri[(attr & 0xc0) >> 6],trans_pen); + { + m_sprite_ptr_pre->x = x + (dx * zoomx) / 2; + m_sprite_ptr_pre->y = y + (dy * zoomy) / 2; + } + m_sprite_ptr_pre->zoomx = zoomx << 11; + m_sprite_ptr_pre->zoomy = zoomy << 11; + m_sprite_ptr_pre->primask = pri[(attr & 0xc0) >> 6]; + m_sprite_ptr_pre++; code++; } } @@ -290,63 +281,53 @@ void psikyo_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, co // until I work out why it makes a partial copy of the sprite list, and how best to apply it // sprite placement of the explosion graphic seems incorrect compared to the original sets? (no / different zoom support?) // it might be a problem with the actual bootleg -void psikyo_state::draw_sprites_bootleg( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int trans_pen ) +void psikyo_state::get_sprites_bootleg() { /* tile layers 0 & 1 have priorities 1 & 2 */ + m_sprite_ctrl = m_spriteram->buffer()[0x1ffe / 4] & 0xffff; static const int pri[] = { 0, 0xfc, 0xff, 0xff }; - int offs; - uint16_t *spritelist = (uint16_t *)(m_spritebuf[1].get()+ 0x1800 / 4); - uint8_t *TILES = m_spritelut->base(); // Sprites LUT - int TILES_LEN = m_spritelut->bytes(); + const u16 *spritelist = (u16 *)(m_spriteram->buffer() + 0x1800 / 4); + const u8 *TILES = m_spritelut->base(); // Sprites LUT + u32 const TILES_LEN = m_spritelut->bytes(); - int width = m_screen->width(); - int height = m_screen->height(); + u16 const width = m_screen->width(); + u16 const height = m_screen->height(); /* Exit if sprites are disabled */ - if (spritelist[BYTE_XOR_BE((0x800 - 2) / 2)] & 1) + m_sprite_ptr_pre = m_spritelist.get(); + if (m_sprite_ctrl & 1) return; /* Look for "end of sprites" marker in the sprites list */ - for (offs = 0/2 ; offs < (0x800 - 2)/2 ; offs += 2/2) // skip last "sprite" - { - uint16_t sprite = spritelist[BYTE_XOR_BE(offs)]; - if (sprite == 0xffff) - break; - } - - offs -= 2/2; - - // fprintf(stderr, "\n"); - for ( ; offs >= 0/2 ; offs -= 2/2) + for (int offs = 0/2 ; offs < (0x800 - 2)/2 ; offs += 2/2) // skip last "sprite" { - uint32_t *source; - int sprite; - - int x, y, attr, code, flipx, flipy, nx, ny, zoomx, zoomy; - int dx, dy, xstart, ystart, xend, yend, xinc, yinc; + int xstart, ystart, xend, yend, xinc, yinc; /* Get next entry in the list */ - sprite = spritelist[BYTE_XOR_BE(offs)]; + u16 sprite = spritelist[BYTE_XOR_BE(offs)]; + + if (sprite == 0xffff) + break; sprite %= 0x300; - source = &m_spritebuf[1][sprite * 8 / 4]; + const u32 *source = &m_spriteram->buffer()[sprite * 8 / 4]; /* Draw this sprite */ - y = source[0] >> 16; - x = source[0] & 0xffff; - attr = source[1] >> 16; - code = source[1] & 0x1ffff; + s32 y = source[0 / 4] >> 16; + s32 x = source[0 / 4] & 0xffff; + u16 const attr = source[4 / 4] >> 16; + u32 code = source[4 / 4] & 0x1ffff; - flipx = attr & 0x4000; - flipy = attr & 0x8000; + int flipx = attr & 0x4000; + int flipy = attr & 0x8000; - zoomx = ((x & 0xf000) >> 12); - zoomy = ((y & 0xf000) >> 12); - nx = ((x & 0x0e00) >> 9) + 1; - ny = ((y & 0x0e00) >> 9) + 1; - x = ((x & 0x01ff)); - y = ((y & 0x00ff)) - (y & 0x100); + u32 zoomx = ((x & 0xf000) >> 12); + u32 zoomy = ((y & 0xf000) >> 12); + u8 const nx = ((x & 0x0e00) >> 9) + 1; + u8 const ny = ((y & 0x0e00) >> 9) + 1; + x = ((x & 0x01ff)); + y = ((y & 0x00ff)) - (y & 0x100); /* 180-1ff are negative coordinates. Note that $80 pixels is the maximum extent of a sprite, which can therefore be moved @@ -375,38 +356,70 @@ void psikyo_state::draw_sprites_bootleg( screen_device &screen, bitmap_ind16 &bi if (flipy) { ystart = ny - 1; yend = -1; yinc = -1; } else { ystart = 0; yend = ny; yinc = +1; } - for (dy = ystart; dy != yend; dy += yinc) + for (int dy = ystart; dy != yend; dy += yinc) { - for (dx = xstart; dx != xend; dx += xinc) + for (int dx = xstart; dx != xend; dx += xinc) { - int addr = (code * 2) & (TILES_LEN-1); + u32 const addr = (code * 2) & (TILES_LEN-1); + m_sprite_ptr_pre->gfx = 0; + m_sprite_ptr_pre->code = TILES[addr+1] * 256 + TILES[addr]; + m_sprite_ptr_pre->color = attr >> 8; + m_sprite_ptr_pre->flipx = flipx; + m_sprite_ptr_pre->flipy = flipy; if (zoomx == 32 && zoomy == 32) - m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect, - TILES[addr+1] * 256 + TILES[addr], - attr >> 8, - flipx, flipy, - x + dx * 16, y + dy * 16, - screen.priority(), - pri[(attr & 0xc0) >> 6],trans_pen); + { + m_sprite_ptr_pre->x = x + dx * 16; + m_sprite_ptr_pre->y = y + dy * 16; + } else - m_gfxdecode->gfx(0)->prio_zoom_transpen(bitmap,cliprect, - TILES[addr+1] * 256 + TILES[addr], - attr >> 8, - flipx, flipy, - x + (dx * zoomx) / 2, y + (dy * zoomy) / 2, - zoomx << 11,zoomy << 11, - screen.priority(),pri[(attr & 0xc0) >> 6],trans_pen); + { + m_sprite_ptr_pre->x = x + (dx * zoomx) / 2; + m_sprite_ptr_pre->y = y + (dy * zoomy) / 2; + } + m_sprite_ptr_pre->zoomx = zoomx << 11; + m_sprite_ptr_pre->zoomy = zoomy << 11; + m_sprite_ptr_pre->primask = pri[(attr & 0xc0) >> 6]; + m_sprite_ptr_pre++; code++; } } } } +void psikyo_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + struct sprite_t *sprite_ptr = m_sprite_ptr_pre; + u32 transmask = 0; + if (m_sprite_ctrl & 4) transmask |= (1 << 0); + if (m_sprite_ctrl & 8) transmask |= (1 << 15); + while (sprite_ptr != m_spritelist.get()) + { + sprite_ptr--; - + if (sprite_ptr->zoomx == 0x10000 && sprite_ptr->zoomy == 0x10000) + { + m_gfxdecode->gfx(sprite_ptr->gfx)->prio_transmask(bitmap,cliprect, + sprite_ptr->code, + sprite_ptr->color, + sprite_ptr->flipx,sprite_ptr->flipy, + sprite_ptr->x,sprite_ptr->y, + screen.priority(),sprite_ptr->primask,transmask); + } + else + { + m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transmask(bitmap,cliprect, + sprite_ptr->code, + sprite_ptr->color, + sprite_ptr->flipx,sprite_ptr->flipy, + sprite_ptr->x,sprite_ptr->y, + sprite_ptr->zoomx,sprite_ptr->zoomy, + screen.priority(),sprite_ptr->primask,transmask); + } + } +} /*************************************************************************** @@ -414,21 +427,20 @@ void psikyo_state::draw_sprites_bootleg( screen_device &screen, bitmap_ind16 &bi ***************************************************************************/ -int psikyo_state::tilemap_width( int size ) +u16 psikyo_state::tilemap_width(u8 size) { return (0x80 * 16) >> size; } -uint32_t psikyo_state::screen_update_psikyo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +u32 psikyo_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint16_t bgpen = 0; + u16 bgpen = 0; int i, layers_ctrl = -1; - uint32_t tmsize[2]; + u32 tmsize[2]; - uint32_t scrollx[2]{ m_vregs[0x406 / 4], m_vregs[0x40e / 4] }, scrolly[2]{ m_vregs[0x402 / 4], m_vregs[0x40a / 4] }; - uint32_t layer_ctrl[2]{ m_vregs[0x412 / 4], m_vregs[0x416 / 4] }; - uint32_t spr_ctrl = m_spritebuf[1][0x1ffe / 4]; + u32 scrollx[2]{ m_vregs[0x406 / 4], m_vregs[0x40e / 4] }, scrolly[2]{ m_vregs[0x402 / 4], m_vregs[0x40a / 4] }; + u32 layer_ctrl[2]{ m_vregs[0x412 / 4], m_vregs[0x416 / 4] }; tilemap_t *tmptilemap[2]; @@ -468,15 +480,15 @@ uint32_t psikyo_state::screen_update_psikyo(screen_device &screen, bitmap_ind16 /* For gfx banking for s1945jn/gunbird/btlkroad */ if (m_ka302c_banking) { - psikyo_switch_banks(layer, (layer_ctrl[layer] & 0x400) >> 10); + switch_bgbanks(layer, (layer_ctrl[layer] & 0x400) >> 10); } switch ((layer_ctrl[layer] & 0x00c0) >> 6) { - case 0: tmsize[layer] = 1; break; - case 1: tmsize[layer] = 2; break; - case 2: tmsize[layer] = 3; break; - default:tmsize[layer] = 0; break; + case 0: tmsize[layer] = 1; break; + case 1: tmsize[layer] = 2; break; + case 2: tmsize[layer] = 3; break; + default: tmsize[layer] = 0; break; } tmptilemap[layer] = m_tilemap[layer][tmsize[layer]]; @@ -499,7 +511,7 @@ uint32_t psikyo_state::screen_update_psikyo(screen_device &screen, bitmap_ind16 } for (i = 0; i < 256; i++) /* 256 screen lines */ { - int x0 = ((uint16_t *)m_vregs.target())[BYTE_XOR_BE((layer * 0x200)/2 + (i >> tile_rowscroll))]; + int x0 = ((u16 *)m_vregs.target())[BYTE_XOR_BE((layer * 0x200)/2 + (i >> tile_rowscroll))]; tmptilemap[layer]->set_scrollx( (i + scrolly[layer]) % (tilemap_width(tmsize[layer])), scrollx[layer] + x0 ); @@ -539,7 +551,7 @@ uint32_t psikyo_state::screen_update_psikyo(screen_device &screen, bitmap_ind16 tmptilemap[1]->draw(screen, bitmap, cliprect, layer_ctrl[1] & 2 ? TILEMAP_DRAW_OPAQUE : 0, 2); if (layers_ctrl & 4) - draw_sprites(screen, bitmap, cliprect, (spr_ctrl & 4 ? 0 : 15)); + draw_sprites(screen, bitmap, cliprect); return 0; } @@ -552,16 +564,15 @@ uint32_t psikyo_state::screen_update_psikyo(screen_device &screen, bitmap_ind16 */ -uint32_t psikyo_state::screen_update_psikyo_bootleg(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +u32 psikyo_state::screen_update_bootleg(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint16_t bgpen = 0; + u16 bgpen = 0; int i, layers_ctrl = -1; - uint32_t tmsize[2]; + u32 tmsize[2]; - uint32_t scrollx[2]{ m_vregs[0x406 / 4], m_vregs[0x40e / 4] }, scrolly[2]{ m_vregs[0x402 / 4], m_vregs[0x40a / 4] }; - uint32_t layer_ctrl[2]{ m_vregs[0x412 / 4], m_vregs[0x416 / 4] }; - uint32_t spr_ctrl = m_spritebuf[1][0x1ffe / 4]; + u32 scrollx[2]{ m_vregs[0x406 / 4], m_vregs[0x40e / 4] }, scrolly[2]{ m_vregs[0x402 / 4], m_vregs[0x40a / 4] }; + u32 layer_ctrl[2]{ m_vregs[0x412 / 4], m_vregs[0x416 / 4] }; tilemap_t *tmptilemap[2]; @@ -601,15 +612,15 @@ uint32_t psikyo_state::screen_update_psikyo_bootleg(screen_device &screen, bitma /* For gfx banking for s1945jn/gunbird/btlkroad */ if (m_ka302c_banking) { - psikyo_switch_banks(layer, (layer_ctrl[layer] & 0x400) >> 10); + switch_bgbanks(layer, (layer_ctrl[layer] & 0x400) >> 10); } switch ((layer_ctrl[layer] & 0x00c0) >> 6) { - case 0: tmsize[layer] = 1; break; - case 1: tmsize[layer] = 2; break; - case 2: tmsize[layer] = 3; break; - default: tmsize[layer] = 0; break; + case 0: tmsize[layer] = 1; break; + case 1: tmsize[layer] = 2; break; + case 2: tmsize[layer] = 3; break; + default: tmsize[layer] = 0; break; } tmptilemap[layer] = m_tilemap[layer][tmsize[layer]]; @@ -633,7 +644,7 @@ uint32_t psikyo_state::screen_update_psikyo_bootleg(screen_device &screen, bitma } for (i = 0; i < 256; i++) /* 256 screen lines */ { - int x0 = ((uint16_t *)m_vregs.target())[BYTE_XOR_BE((layer * 0x200)/2 + (i >> tile_rowscroll))]; + int x0 = ((u16 *)m_vregs.target())[BYTE_XOR_BE((layer * 0x200)/2 + (i >> tile_rowscroll))]; tmptilemap[layer]->set_scrollx( (i + scrolly[layer]) % (tilemap_width(tmsize[layer])), scrollx[layer] + x0 ); @@ -673,18 +684,28 @@ uint32_t psikyo_state::screen_update_psikyo_bootleg(screen_device &screen, bitma tmptilemap[1]->draw(screen, bitmap, cliprect, layer_ctrl[1] & 2 ? TILEMAP_DRAW_OPAQUE : 0, 2); if (layers_ctrl & 4) - draw_sprites_bootleg(screen, bitmap, cliprect, (spr_ctrl & 4 ? 0 : 15)); + draw_sprites(screen, bitmap, cliprect); return 0; } -WRITE_LINE_MEMBER(psikyo_state::screen_vblank_psikyo) +WRITE_LINE_MEMBER(psikyo_state::screen_vblank) +{ + // rising edge + if (state) + { + get_sprites(); + m_spriteram->copy(); + } +} + +WRITE_LINE_MEMBER(psikyo_state::screen_vblank_bootleg) { // rising edge if (state) { - memcpy(m_spritebuf[1].get(), m_spritebuf[0].get(), 0x2000); - memcpy(m_spritebuf[0].get(), m_spriteram, 0x2000); + get_sprites_bootleg(); // TODO : it's seems differ? + m_spriteram->copy(); } } |