diff options
Diffstat (limited to 'src/mame/suna/suna16_v.cpp')
-rw-r--r-- | src/mame/suna/suna16_v.cpp | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/src/mame/suna/suna16_v.cpp b/src/mame/suna/suna16_v.cpp new file mode 100644 index 00000000000..e4d2ff1b216 --- /dev/null +++ b/src/mame/suna/suna16_v.cpp @@ -0,0 +1,247 @@ +// license:BSD-3-Clause +// copyright-holders:Luca Elia +/*************************************************************************** + + -= SunA 16 Bit Games =- + + driver by Luca Elia (l.elia@tin.it) + + + These games have only sprites, of a peculiar type: + + there is a region of memory where 32 pages of 32x32 tile codes can + be written like a tilemap made of 32 pages of 256x256 pixels. Each + tile uses 2 words. + + Sprites are rectangular regions of *tiles* fetched from there and + sent to the screen. Each sprite uses 4 words, held where the last + page of tiles would be. + + + [ Sprites Format ] + + + Offset: Bits: Value: + + 0.w fedc ---- ---- ---- Source Page (Low Bits) + ---- ba98 ---- ---- Source Column (Bit 8 = Sprite Flip X) + ---- ---- 7654 3210 Screen Y Position + + 2.w fedc ---- ---- ---- Tile Bank + ---- ba-- ---- ---- + ---- --9- ---- ---- Source Page (High Bit) + ---- ---8 7654 3210 Screen X Position + + $10000.w fedc ba98 ---- ---- + ---- ---- 76-- ---- Sprite Size: + 00 -> 16 x 16 (2x2 tiles) + 01 -> 32 x 32 (4x4 tiles) + 10 -> 16 x 256 (2x32 tiles) + 11 -> 32 x 256 (4x32 tiles) + ---- ---- --54 ---- ? (Bit 4 used by uballoon) + ---- ---- ---- 3210 Source Row + + $10002.w - + + + [ Sprite's Tiles Format ] + + + Offset: Bits: Value: + + 0.w f--- ---- ---- ---- Flip Y + -e-- ---- ---- ---- Flip X + --dc ba98 7654 3210 Code + + $10000.w fedc ba98 7654 ---- + ---- ---- ---- 3210 Color + + +***************************************************************************/ + +#include "emu.h" +#include "suna16.h" + +void suna16_state::flipscreen_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + if (ACCESSING_BITS_0_7) + { + flip_screen_set(data & 1 ); + m_color_bank = ( data & 4 ) >> 2; + } + if (data & ~(1|4)) logerror("CPU#0 PC %06X - Flip screen unknown bits: %04X\n", m_maincpu->pc(), data); +} + +void suna16_state::bestbest_flipscreen_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + if (ACCESSING_BITS_0_7) + { + flip_screen_set(data & 0x10 ); + //m_color_bank = ( data & 0x07 ); + } + if (data & ~(0x10)) logerror("CPU#0 PC %06X - Flip screen unknown bits: %04X\n", m_maincpu->pc(), data); +} + + +/*************************************************************************** + + + Banked Palette RAM. Format is xBBBBBGGGGRRRRR + + +***************************************************************************/ + +void suna16_state::video_start() +{ + m_paletteram = std::make_unique<uint16_t[]>(m_palette->entries()); + + save_item(NAME(m_color_bank)); + + m_color_bank = 0; +} + +uint16_t suna16_state::paletteram_r(offs_t offset) +{ + return m_paletteram[offset + m_color_bank * 256]; +} + +void suna16_state::paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + offset += m_color_bank * 256; + data = COMBINE_DATA(&m_paletteram[offset]); + m_palette->set_pen_color( offset, pal5bit(data >> 0),pal5bit(data >> 5),pal5bit(data >> 10)); +} + + +/*************************************************************************** + + + Sprites Drawing + + +***************************************************************************/ + +void suna16_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, uint16_t *sprites, int gfx) +{ + int max_x = m_screen->width() - 8; + int max_y = m_screen->height() - 8; + + for ( int offs = 0xfc00/2; offs < 0x10000/2 ; offs += 4/2 ) + { + int srcpg, srcx,srcy, dimx,dimy; + int tile_x, tile_xinc, tile_xstart; + int tile_y, tile_yinc; + int dx, dy; + int flipx, y0; + + int y = sprites[ offs + 0 + 0x00000 / 2 ]; + int x = sprites[ offs + 1 + 0x00000 / 2 ]; + int dim = sprites[ offs + 0 + 0x10000 / 2 ]; + + int bank = (x >> 12) & 0xf; + + srcpg = ((y & 0xf000) >> 12) + ((x & 0x0200) >> 5); // src page + srcx = ((y >> 8) & 0xf) * 2; // src col + srcy = ((dim >> 0) & 0xf) * 2; // src row + + switch ( (dim >> 4) & 0xc ) + { + case 0x0: dimx = 2; dimy = 2; y0 = 0x100; break; + case 0x4: dimx = 4; dimy = 4; y0 = 0x100; break; + case 0x8: dimx = 2; dimy = 32; y0 = 0x130; break; + default: + case 0xc: dimx = 4; dimy = 32; y0 = 0x120; break; + } + + if (dimx==4) { flipx = srcx & 2; srcx &= ~2; } + else { flipx = 0; } + + x = (x & 0xff) - (x & 0x100); + y = (y0 - (y & 0xff) - dimy*8 ) & 0xff; + + if (flipx) { tile_xstart = dimx-1; tile_xinc = -1; } + else { tile_xstart = 0; tile_xinc = +1; } + + tile_y = 0; tile_yinc = +1; + + for (dy = 0; dy < dimy * 8; dy += 8) + { + tile_x = tile_xstart; + + for (dx = 0; dx < dimx * 8; dx += 8) + { + int addr = (srcpg * 0x20 * 0x20) + + ((srcx + tile_x) & 0x1f) * 0x20 + + ((srcy + tile_y) & 0x1f); + + int tile = sprites[ addr + 0x00000 / 2 ]; + int attr = sprites[ addr + 0x10000 / 2 ]; + + int sx = x + dx; + int sy = (y + dy) & 0xff; + + int tile_flipx = tile & 0x4000; + int tile_flipy = tile & 0x8000; + + if (flipx) tile_flipx = !tile_flipx; + + if (flip_screen()) + { + sx = max_x - sx; + sy = max_y - sy; + tile_flipx = !tile_flipx; + tile_flipy = !tile_flipy; + } + + m_gfxdecode->gfx(gfx)->transpen(bitmap,cliprect, + (tile & 0x3fff) + bank*0x4000, + attr + (m_color_bank << 4), + tile_flipx, tile_flipy, + sx, sy,15 ); + + tile_x += tile_xinc; + } + + tile_y += tile_yinc; + } + + } + +} + + +/*************************************************************************** + + + Screen Drawing + + +***************************************************************************/ + +uint32_t suna16_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + /* Suna Quiz indicates the background is the last pen */ + bitmap.fill(0xff, cliprect); + draw_sprites(bitmap, cliprect, m_spriteram, 0); + return 0; +} + +uint32_t suna16_state::screen_update_bestbest(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + int layers_ctrl = -1; + +#ifdef MAME_DEBUG +if (machine().input().code_pressed(KEYCODE_Z)) +{ int msk = 0; + if (machine().input().code_pressed(KEYCODE_Q)) msk |= 1; + if (machine().input().code_pressed(KEYCODE_W)) msk |= 2; + if (msk != 0) layers_ctrl &= msk; +} +#endif + + /* Suna Quiz indicates the background is the last pen */ + bitmap.fill(0xff, cliprect); + if (layers_ctrl & 1) draw_sprites(bitmap, cliprect, m_spriteram, 0); + if (layers_ctrl & 2) draw_sprites(bitmap, cliprect, m_spriteram2, 1); + return 0; +} |