diff --git a/hash/supracan.xml b/hash/supracan.xml index dea4dbe489b..d31d96d350b 100644 --- a/hash/supracan.xml +++ b/hash/supracan.xml @@ -9,6 +9,7 @@ license:CC0-1.0 1995 AV Artisan Corp. @@ -29,7 +30,7 @@ license:CC0-1.0 [video] sprites may need buffering (noticeable on gameplay jumps) [video] intro raster effect is slightly off (btanb) [irq 5] 2nd fighter stage used with global flip y + mosaic (lake effect) -[video] enables window effect during ending and credits +[video] enables clipping effect during ending and credits ]]> @@ -48,7 +49,6 @@ license:CC0-1.0 Uses [video] blending during attract and title screen Wrong [video] ROZ paging for title screen Broken [video] during intro, uses bitmap mode -Broken [video] sprites during gameplay [video] uses per-tile priority during gameplay ]]> @@ -84,7 +84,7 @@ Broken [video] sprites during gameplay 1995 C&E Soft @@ -169,9 +169,8 @@ Erratic gameplay speed, controls [irq 3] as FRC, can potentially hang Funtech @@ -187,6 +186,10 @@ Erratic gameplay speed, controls [irq 3] as FRC Boom Zoo ~ Bao Bao Dong Wu Yuan 1996 Funtech + + diff --git a/src/mame/funtech/supracan.cpp b/src/mame/funtech/supracan.cpp index ead2bedaa84..909fbf98a55 100644 --- a/src/mame/funtech/supracan.cpp +++ b/src/mame/funtech/supracan.cpp @@ -1,6 +1,6 @@ // license: BSD-3-Clause // copyright-holders: Angelo Salese, Ryan Holtz -/*************************************************************************** +/************************************************************************************************** Super A'Can (c) 1995 Funtech @@ -10,7 +10,7 @@ References: - https://github.com/angelosa/hw_docs/blob/main/funtech_superacan/pergame.md -******************************************************************************* +=================================================================================================== INFO: @@ -61,7 +61,7 @@ STATUS: - All: are ALL the layers ROZ capable?? -***************************************************************************/ +**************************************************************************************************/ #include "emu.h" #include "cpu/m68000/m68000.h" @@ -378,7 +378,7 @@ void supracan_state::get_tilemap_info_common(int layer, tile_data &tileinfo, int tileinfo.set(region, tile, palette, TILE_FLIPXY(flipxy)); } -// I wonder how different this really is.. my guess, not at all. +// TODO: merge with normal layers. void supracan_state::get_roz_tilemap_info(int layer, tile_data &tileinfo, int count) { uint16_t *vram = m_vram; @@ -747,29 +747,28 @@ void supracan_state::draw_sprite_tile_masked(bitmap_ind16 &dst, bitmap_ind8 &mas } } +// [0] +// -e-- ---- ---- ---- sprite enable? +// ---h hhh- ---- ---- Y size (not always right) +// ---- ---y yyyy yyyy Y position +// [1] +// bbbb ---- ---- ---- Tile bank +// ---- h--- ---- ---- Horizontal flip +// ---- -v-- ---- ---- Vertical flip +// ---- --mm ---- ---- Masking mode +// ---- ---- ---- -www X size +// [2] +// zzz- ---- ---- ---- X scale +// ---- ???- ---- ---- Unknown, but often written. +// Values include 111 and 110 for the Super A'Can logo, 110 in the Sango Fighter intro, and 101/100 in the Boom Zoo intro. +// ---- ---x xxxx xxxx X position +// [3] +// d--- ---- ---- ---- Direct Sprite (use details from here, not looked up in vram) +// -ooo oooo oooo oooo Sprite address void supracan_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &maskmap, bitmap_ind8 &priomap, const rectangle &cliprect) { uint16_t *vram = m_vram; -// [0] -// -e-- ---- ---- ---- sprite enable? -// ---h hhh- ---- ---- Y size (not always right) -// ---- ---y yyyy yyyy Y position -// [1] -// bbbb ---- ---- ---- Tile bank -// ---- h--- ---- ---- Horizontal flip -// ---- -v-- ---- ---- Vertical flip -// ---- --mm ---- ---- Masking mode -// ---- ---- ---- -www X size -// [2] -// zzz- ---- ---- ---- X scale -// ---- ???- ---- ---- Unknown, but often written. -// Values include 111 and 110 for the Super A'Can logo, 110 in the Sango Fighter intro, and 101/100 in the Boom Zoo intro. -// ---- ---x xxxx xxxx X position -// [3] -// d--- ---- ---- ---- Direct Sprite (use details from here, not looked up in vram) -// -ooo oooo oooo oooo Sprite address - uint32_t skip_count = 0; uint32_t start_word = (m_sprite_base_addr >> 1) + skip_count * 4; uint32_t end_word = start_word + (m_sprite_count - skip_count) * 4; @@ -782,13 +781,12 @@ void supracan_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &maskmap, bi int x = vram[i + 2] & 0x01ff; int y = vram[i + 0] & 0x01ff; - int sprite_offset = (vram[i + 3])<< 1; - int bank = (vram[i + 1] & 0xf000) >> 12; int mask = (vram[i + 1] & 0x0300) >> 8; int sprite_xflip = (vram[i + 1] & 0x0800) >> 11; int sprite_yflip = (vram[i + 1] & 0x0400) >> 10; int prio = (vram[i + 2] >> 9) & 3; + const u16 sprite_ptr = vram[i + 3]; //int xscale = vram[i + 2] >> 13; gfx_element *gfx = m_gfxdecode->gfx(region); @@ -798,44 +796,31 @@ void supracan_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &maskmap, bi if ((vram[i + 0] & 0x4000)) { - #if 0 - printf("%d (unk %02x) (enable %02x) (unk Y2 %02x, %02x) (y pos %02x) (bank %01x) (flip %01x) (unknown %02x) (x size %02x) (xscale %01x) (unk %01x) (xpos %02x) (code %04x)\n", i, - (vram[i + 0] & 0x8000) >> 15, - (vram[i + 0] & 0x4000) >> 14, - (vram[i + 0] & 0x2000) >> 13, - (vram[i + 0] & 0x1e00) >> 8, - (vram[i + 0] & 0x01ff), - (vram[i + 1] & 0xf000) >> 12, - (vram[i + 1] & 0x0c00) >> 10, - (vram[i + 1] & 0x03f0) >> 4, - (vram[i + 1] & 0x000f), - (vram[i + 2] & 0xf000) >> 12, - (vram[i + 2] & 0x0e00) >> 8, - (vram[i + 2] & 0x01ff) >> 0, - (vram[i + 3] & 0xffff)); - #endif + int xsize = 1 << (vram[i + 1] & 7); + int ysize = ((vram[i + 0] & 0x1e00) >> 9) + 1; - if (vram[i + 3] & 0x8000) + // HACK: sonevil sets 1x1 tiles, and expecting to take this path. + // Most likely former condition is wrong, and it just "direct sprite" when latter occurs. + // magipool also wants latter, for the shot markers to work. + if (sprite_ptr & 0x8000 || (xsize == 1 && ysize == 1)) { - uint16_t data = vram[i + 3]; - int tile = (bank * 0x200) + (data & 0x03ff); + int tile = (bank * 0x200) + (sprite_ptr & 0x03ff); - int palette = (data & 0xf000) >> 12; // this might not be correct, due to the & 0x8000 condition above this would force all single tile sprites to be using palette >= 0x8 only + int palette = (sprite_ptr & 0xf000) >> 12; // this might not be correct, due to the & 0x8000 condition above this would force all single tile sprites to be using palette >= 0x8 only - // printf("sprite data %04x %04x %04x %04x\n", vram[i+0] , vram[i+1] , vram[i+2] ,vram[i+3] ); + // sonevil expect to flip X/Y thru the sprite pointer + int tile_xflip = sprite_xflip ^ ((sprite_ptr & 0x0800) >> 11); + int tile_yflip = sprite_yflip ^ ((sprite_ptr & 0x0400) >> 10); if (mask > 1) - draw_sprite_tile_mask(maskmap, cliprect, gfx, tile, sprite_xflip, sprite_yflip, x, y); + draw_sprite_tile_mask(maskmap, cliprect, gfx, tile, tile_xflip, tile_yflip, x, y); else if (mask == 1) - draw_sprite_tile_masked(bitmap, maskmap, priomap, cliprect, gfx, tile, palette, sprite_xflip, sprite_yflip, x, y, prio); + draw_sprite_tile_masked(bitmap, maskmap, priomap, cliprect, gfx, tile, palette, tile_xflip, tile_yflip, x, y, prio); else - draw_sprite_tile(bitmap, priomap, cliprect, gfx, tile, palette, sprite_xflip, sprite_yflip, x, y, prio); + draw_sprite_tile(bitmap, priomap, cliprect, gfx, tile, palette, tile_xflip, tile_yflip, x, y, prio); } else { - int xsize = 1 << (vram[i + 1] & 7); - int ysize = ((vram[i + 0] & 0x1e00) >> 9) + 1; - // I think the xsize must influence the ysize somehow, there are too many conflicting cases otherwise // there don't appear to be any special markers in the actual looked up tile data to indicate skip / end of list @@ -843,7 +828,7 @@ void supracan_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &maskmap, bi { for (int xtile = 0; xtile < xsize; xtile++) { - uint16_t data = vram[(sprite_offset + ytile * xsize + xtile) & VRAM_MASK]; + uint16_t data = vram[((sprite_ptr << 1) + ytile * xsize + xtile) & VRAM_MASK]; int tile = (bank * 0x200) + (data & 0x03ff); int palette = (data & 0xf000) >> 12; @@ -863,6 +848,7 @@ void supracan_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &maskmap, bi } } + // TODO: scaling #if 0 if (xscale == 0) continue; uint32_t delta = (1 << 17) / xscale; @@ -999,12 +985,11 @@ uint32_t supracan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm m_sprite_final_bitmap.fill(0x00, cliprect); m_sprite_mask_bitmap.fill(0x00, cliprect); m_prio_bitmap.fill(0xff, cliprect); - // TODO: pinpoint back layer color - // - A'Can logo wants 0x30 + // Back layer normally fills with 0x00 // - boomzoo (title) wants 0x00 // - sangofgt (1st fighter stage) wants 0x00 // - sonevil (intro) wants 0x00 - //bitmap.fill(0x80, cliprect); + // TODO: layer overlay happens from mixing registers (A'Can BIOS sets 0x02 there) bitmap.fill(0x00, cliprect); draw_sprites(m_sprite_final_bitmap, m_sprite_mask_bitmap, m_prio_bitmap, cliprect);