summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/suna16.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/suna16.c')
-rw-r--r--src/mame/video/suna16.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/mame/video/suna16.c b/src/mame/video/suna16.c
new file mode 100644
index 00000000000..ec7ab020e27
--- /dev/null
+++ b/src/mame/video/suna16.c
@@ -0,0 +1,245 @@
+/***************************************************************************
+
+ -= 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 "driver.h"
+
+static int color_bank;
+
+WRITE16_HANDLER( suna16_flipscreen_w )
+{
+ if (ACCESSING_LSB)
+ {
+ flip_screen_set( data & 1 );
+ color_bank = ( data & 4 ) >> 2;
+ }
+ if (data & ~(1|4)) logerror("CPU#0 PC %06X - Flip screen unknown bits: %04X\n", activecpu_get_pc(), data);
+}
+
+WRITE16_HANDLER( bestbest_flipscreen_w )
+{
+ if (ACCESSING_LSB)
+ {
+ flip_screen_set( data & 0x10 );
+// color_bank = ( data & 0x07 );
+ }
+ if (data & ~(0x10)) logerror("CPU#0 PC %06X - Flip screen unknown bits: %04X\n", activecpu_get_pc(), data);
+}
+
+
+/***************************************************************************
+
+
+ Banked Palette RAM. Format is xBBBBBGGGGRRRRR
+
+
+***************************************************************************/
+
+VIDEO_START( suna16 )
+{
+ paletteram16 = auto_malloc( machine->drv->total_colors * sizeof(UINT16) );
+}
+
+READ16_HANDLER( suna16_paletteram16_r )
+{
+ return paletteram16[offset + color_bank * 256];
+}
+
+WRITE16_HANDLER( suna16_paletteram16_w )
+{
+ offset += color_bank * 256;
+ data = COMBINE_DATA(&paletteram16[offset]);
+ palette_set_color_rgb( Machine, offset, pal5bit(data >> 0),pal5bit(data >> 5),pal5bit(data >> 10));
+}
+
+
+/***************************************************************************
+
+
+ Sprites Drawing
+
+
+***************************************************************************/
+
+static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, UINT16 *sprites, int gfx)
+{
+ int offs;
+
+ int max_x = machine->screen[0].width - 8;
+ int max_y = machine->screen[0].height - 8;
+
+ for ( 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;
+ }
+
+ drawgfx( bitmap, machine->gfx[gfx],
+ (tile & 0x3fff) + bank*0x4000,
+ attr + (color_bank << 4),
+ tile_flipx, tile_flipy,
+ sx, sy,
+ cliprect,TRANSPARENCY_PEN,15 );
+
+ tile_x += tile_xinc;
+ }
+
+ tile_y += tile_yinc;
+ }
+
+ }
+
+}
+
+
+/***************************************************************************
+
+
+ Screen Drawing
+
+
+***************************************************************************/
+
+VIDEO_UPDATE( suna16 )
+{
+ /* Suna Quiz indicates the background is the last pen */
+ fillbitmap(bitmap,machine->pens[0xff],cliprect);
+ draw_sprites(machine, bitmap, cliprect, spriteram16, 0);
+ return 0;
+}
+
+VIDEO_UPDATE( bestbest )
+{
+ int layers_ctrl = -1;
+
+#ifdef MAME_DEBUG
+if (input_code_pressed(KEYCODE_Z))
+{ int msk = 0;
+ if (input_code_pressed(KEYCODE_Q)) msk |= 1;
+ if (input_code_pressed(KEYCODE_W)) msk |= 2;
+ if (msk != 0) layers_ctrl &= msk;
+}
+#endif
+
+ /* Suna Quiz indicates the background is the last pen */
+ fillbitmap(bitmap,machine->pens[0xff],cliprect);
+ if (layers_ctrl & 1) draw_sprites(machine, bitmap, cliprect, spriteram16, 0);
+ if (layers_ctrl & 2) draw_sprites(machine, bitmap, cliprect, spriteram16_2, 1);
+ return 0;
+}