summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/suna8.c
blob: dd51f1a559195f8289af2c8809158dde9eb47d69 (plain) (tree)






































































                                                                              
                
                           
 



                                                                            

                                     
                                                                
                         
 
                                                    
         
                                                                                                      
                                                 

                                                 
            
         

                                                                
         

                          
                                                                             







                                                        
                                                                         
 
                                               
                                                              



                                         
                                                                         
 

                                               



                                   
                                                                         
 
                                          
            
                                                               




                                          
                                                                         
 

                                               
            
                                                               







                                             
                                                                         

                   
 
                                               

                                                                                                                          












                                                     
                                                                                          



 
                                                                    
 
                                                                
 

                                     
         
                                                                                            


                                                                                  


            
                                                                                          
 
                                                                                                                
 
                                                             


      


                                                                       








                                                                            
                                                                                                     
 
                                                                
                                              


                                                

                                                         










                                                                     
                                          































































































                                                                                                                         
                                                             



                                                                                         
 
                                                                                       


                                                                                                                   
                                                                   





                         
                                                                                                   
 
                                                                
                                              

              

                                                         

                                
                                               











                                                         
                                                                                         


























                                                                                                  
                                                             



                                                                               
 
                                                                                       


                                                                                         
                                                                   













                                                                            
                      

                                                                                
                                          


                 
                                                                                                                   
         

                                                                                           
 





                                                                                                                                                                 








                                                                                   

                                                            

                                                                                                                              





            

                                                                        


                 
/***************************************************************************

                            -=  SunA 8 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 4 pages of 32x32 tile codes can
    be written like a tilemap made of 4 pages of 256x256 pixels. Each
    tile uses 2 bytes. Later games may use more pages through RAM
    banking.

    Sprites are rectangular regions of *tiles* fetched from there and
    sent to the screen. Each sprite uses 4 bytes, held within the last
    page of tiles.

    * Note: later games use a more complex format than the following,
            which is yet to be completely understood.

                            [ Sprites Format ]


    Offset:         Bits:               Value:

        0.b                             Y (Bottom up)

        1.b         7--- ----           Sprite Size (1 = 2x32 tiles; 0 = 2x2)

                    2x2 Sprites:
                    -65- ----           Tiles Row (height = 8 tiles)
                    ---4 ----           Page

                    2x32 Sprites:
                    -6-- ----           Ignore X (Multisprite)
                    --54 ----           Page

                    ---- 3210           Tiles Column (width = 2 tiles)

        2.b                             X

        3.b         7--- ----
                    -6-- ----           X (Sign Bit)
                    --54 3---
                    ---- -210           Tiles Bank


                        [ Sprite's Tiles Format ]


    Offset:         Bits:                   Value:

        0.b                             Code (Low Bits)

        1.b         7--- ----           Flip Y
                    -6-- ----           Flip X
                    --54 32--           Color
                    ---- --10           Code (High Bits)



    Set TILEMAPS to 1 to debug.
    Press Z (you see the "tilemaps" in RAM) or
    Press X (you see the "tilemaps" in ROM) then

    - use Q&W to cycle through the pages.
    - Use E&R to cycle through the tiles banks.
    - Use A&S to cycle through the ROM banks (only with X pressed, of course).

***************************************************************************/

#include "emu.h"
#include "includes/suna8.h"

/***************************************************************************
    For Debug: there's no tilemap, just sprites.
***************************************************************************/
#if TILEMAPS
static TILE_GET_INFO( get_tile_info )
{
	suna8_state *state = machine.driver_data<suna8_state>();
	UINT8 code, attr;

	if (machine.input().code_pressed(KEYCODE_X))
	{
		UINT8 *rom = machine.region("maincpu")->base() + 0x10000 + 0x4000 * state->m_trombank;
		code = rom[ 2 * tile_index + 0 ];
		attr = rom[ 2 * tile_index + 1 ];
	}
	else
	{
		code = state->m_spriteram[ 2 * tile_index + 0 ];
		attr = state->m_spriteram[ 2 * tile_index + 1 ];
	}
	SET_TILE_INFO(
			0,
			( (attr & 0x03) << 8 ) + code + state->m_tiles*0x400,
			(attr >> 2) & 0xf,
			TILE_FLIPYX( (attr >> 6) & 3 ));
}
#endif


READ8_HANDLER( suna8_banked_paletteram_r )
{
	suna8_state *state = space->machine().driver_data<suna8_state>();

	offset += state->m_palettebank * 0x200;
	return space->machine().generic.paletteram.u8[offset];
}

READ8_HANDLER( suna8_banked_spriteram_r )
{
	suna8_state *state = space->machine().driver_data<suna8_state>();

	offset += state->m_spritebank * 0x2000;
	return state->m_spriteram[offset];
}

WRITE8_HANDLER( suna8_spriteram_w )
{
	suna8_state *state = space->machine().driver_data<suna8_state>();

	state->m_spriteram[offset] = data;
#if TILEMAPS
	tilemap_mark_tile_dirty(state->m_bg_tilemap, offset/2);
#endif
}

WRITE8_HANDLER( suna8_banked_spriteram_w )
{
	suna8_state *state = space->machine().driver_data<suna8_state>();

	offset += state->m_spritebank * 0x2000;
	state->m_spriteram[offset] = data;
#if TILEMAPS
	tilemap_mark_tile_dirty(state->m_bg_tilemap, offset/2);
#endif
}

/*
    Banked Palette RAM. The data is scrambled
*/
WRITE8_HANDLER( brickzn_banked_paletteram_w )
{
	suna8_state *state = space->machine().driver_data<suna8_state>();
	int r,g,b;
	UINT16 rgb;

	offset += state->m_palettebank * 0x200;
	space->machine().generic.paletteram.u8[offset] = data;
	rgb = (space->machine().generic.paletteram.u8[offset&~1] << 8) + space->machine().generic.paletteram.u8[offset|1];
	r	=	(((rgb & (1<<0xc))?1:0)<<0) |
			(((rgb & (1<<0xb))?1:0)<<1) |
			(((rgb & (1<<0xe))?1:0)<<2) |
			(((rgb & (1<<0xf))?1:0)<<3);
	g	=	(((rgb & (1<<0x8))?1:0)<<0) |
			(((rgb & (1<<0x9))?1:0)<<1) |
			(((rgb & (1<<0xa))?1:0)<<2) |
			(((rgb & (1<<0xd))?1:0)<<3);
	b	=	(((rgb & (1<<0x4))?1:0)<<0) |
			(((rgb & (1<<0x3))?1:0)<<1) |
			(((rgb & (1<<0x6))?1:0)<<2) |
			(((rgb & (1<<0x7))?1:0)<<3);

	palette_set_color_rgb(space->machine(),offset/2,pal4bit(r),pal4bit(g),pal4bit(b));
}



static void suna8_vh_start_common(running_machine &machine, int dim)
{
	suna8_state *state = machine.driver_data<suna8_state>();

	state->m_text_dim = dim;
	if (!(state->m_text_dim > 0))
	{
		machine.generic.paletteram.u8 = auto_alloc_array(machine, UINT8, 0x200 * 2);
		state->m_spriteram = auto_alloc_array(machine, UINT8, 0x2000 * 2);
		state->m_spritebank  = 0;
		state->m_palettebank = 0;
	}

#if TILEMAPS
	state->m_bg_tilemap = tilemap_create(	machine, get_tile_info, tilemap_scan_cols,

								8, 8, 0x20*((state->m_text_dim > 0)?4:8), 0x20);

	tilemap_set_transparent_pen(state->m_bg_tilemap, 15);
#endif
}

VIDEO_START( suna8_textdim0 )	{ suna8_vh_start_common(machine, 0);  }
VIDEO_START( suna8_textdim8 )	{ suna8_vh_start_common(machine, 8);  }
VIDEO_START( suna8_textdim12 )	{ suna8_vh_start_common(machine, 12); }

/***************************************************************************


                                Sprites Drawing


***************************************************************************/

static void draw_normal_sprites(running_machine &machine, bitmap_t *bitmap,const rectangle *cliprect)
{
	suna8_state *state = machine.driver_data<suna8_state>();
	UINT8 *spriteram = state->m_spriteram;
	int i;
	int mx = 0;	// multisprite x counter

	int max_x = machine.primary_screen->width() - 8;
	int max_y = machine.primary_screen->height() - 8;

	for (i = 0x1d00; i < 0x2000; i += 4)
	{
		int srcpg, srcx,srcy, dimx,dimy, tx, ty;
		int gfxbank, colorbank = 0, flipx,flipy, multisprite;

		int y		=	spriteram[i + 0];
		int code	=	spriteram[i + 1];
		int x		=	spriteram[i + 2];
		int bank	=	spriteram[i + 3];

		if (state->m_text_dim > 0)
		{
			/* Older, simpler hardware */
			flipx = 0;
			flipy = 0;
			gfxbank = bank & 0x3f;
			switch( code & 0x80 )
			{
			case 0x80:
				dimx = 2;					dimy =	32;
				srcx  = (code & 0xf) * 2;	srcy = 0;
				srcpg = (code >> 4) & 3;
				break;
			case 0x00:
			default:
				dimx = 2;					dimy =	2;
				srcx  = (code & 0xf) * 2;	srcy = ((code >> 5) & 0x3) * 8 + 6;
				srcpg = (code >> 4) & 1;
				break;
			}
			multisprite = ((code & 0x80) && (code & 0x40));
		}
		else
		{
			/* Newer, more complex hardware (not finished yet!) */
			switch( code & 0xc0 )
			{
			case 0xc0:
				dimx = 4;					dimy = 32;
				srcx  = (code & 0xe) * 2;	srcy = 0;
				flipx = (code & 0x1);
				flipy = 0;
				gfxbank = bank & 0x1f;
				srcpg = (code >> 4) & 3;
				break;
			case 0x80:
				dimx = 2;					dimy = 32;
				srcx  = (code & 0xf) * 2;	srcy = 0;
				flipx = 0;
				flipy = 0;
				gfxbank = bank & 0x1f;
				srcpg = (code >> 4) & 3;
				break;
// hardhea2: fire code=52/54 bank=a4; player code=02/04/06 bank=08; arrow:code=16 bank=27
			case 0x40:
				dimx = 4;					dimy = 4;
				srcx  = (code & 0xe) * 2;
				flipx = code & 0x01;
				flipy = bank & 0x10;
				srcy  = (((bank & 0x80)>>4) + (bank & 0x04) + ((~bank >> 4)&2)) * 2;
				srcpg = (code >> 4) & 7;
				gfxbank = (bank & 0x3) + (srcpg & 4);	// brickzn: 06,a6,a2,b2->6. starfigh: 01->01,4->0
				colorbank = (bank & 8) >> 3;
				break;
			case 0x00:
			default:
				dimx = 2;					dimy = 2;
				srcx  = (code & 0xf) * 2;
				flipx = 0;
				flipy = 0;
				gfxbank = bank & 0x03;
				srcy  = (((bank & 0x80)>>4) + (bank & 0x04) + ((~bank >> 4)&3)) * 2;
				srcpg = (code >> 4) & 3;
				break;
			}
			multisprite = ((code & 0x80) && (bank & 0x80));
		}

		x = x - ((bank & 0x40) ? 0x100 : 0);
		y = (0x100 - y - dimy*8 ) & 0xff;

		/* Multi Sprite */
		if ( multisprite )	{	mx += dimx*8;	x = mx;	}
		else					mx = x;

		gfxbank	*= 0x400;

		for (ty = 0; ty < dimy; ty ++)
		{
			for (tx = 0; tx < dimx; tx ++)
			{
				int addr	=	(srcpg * 0x20 * 0x20) +
								((srcx + (flipx?dimx-tx-1:tx)) & 0x1f) * 0x20 +
								((srcy + (flipy?dimy-ty-1:ty)) & 0x1f);

				int tile	=	spriteram[addr*2 + 0];
				int attr	=	spriteram[addr*2 + 1];

				int tile_flipx	=	attr & 0x40;
				int tile_flipy	=	attr & 0x80;

				int sx		=	 x + tx * 8;
				int sy		=	(y + ty * 8) & 0xff;

				if (flipx)	tile_flipx = !tile_flipx;
				if (flipy)	tile_flipy = !tile_flipy;

				if (flip_screen_get(machine))
				{
					sx = max_x - sx;	tile_flipx = !tile_flipx;
					sy = max_y - sy;	tile_flipy = !tile_flipy;
				}

				drawgfx_transpen(	bitmap,cliprect,machine.gfx[0],
							tile + (attr & 0x3)*0x100 + gfxbank,
							((attr >> 2) & 0xf) | colorbank,	// hardhea2 player2
							tile_flipx, tile_flipy,
							sx, sy,15);
			}
		}

	}
}

static void draw_text_sprites(running_machine &machine, bitmap_t *bitmap,const rectangle *cliprect)
{
	suna8_state *state = machine.driver_data<suna8_state>();
	UINT8 *spriteram = state->m_spriteram;
	int i;

	int max_x = machine.primary_screen->width() - 8;
	int max_y = machine.primary_screen->height() - 8;

	/* Earlier games only */
	if (!(state->m_text_dim > 0))	return;

	for (i = 0x1900; i < 0x19ff; i += 4)
	{
		int srcpg, srcx,srcy, dimx,dimy, tx, ty;

		int y		=	spriteram[i + 0];
		int code	=	spriteram[i + 1];
		int x		=	spriteram[i + 2];
		int bank	=	spriteram[i + 3];

		if (~code & 0x80)	continue;

		dimx = 2;					dimy = state->m_text_dim;
		srcx  = (code & 0xf) * 2;	srcy = (y & 0xf0) / 8;
		srcpg = (code >> 4) & 3;

		x = x - ((bank & 0x40) ? 0x100 : 0);
		y = 0;

		bank	=	(bank & 0x3f) * 0x400;

		for (ty = 0; ty < dimy; ty ++)
		{
			for (tx = 0; tx < dimx; tx ++)
			{
				int real_ty	=	(ty < (dimy/2)) ? ty : (ty + 0x20 - dimy);

				int addr	=	(srcpg * 0x20 * 0x20) +
								((srcx + tx) & 0x1f) * 0x20 +
								((srcy + real_ty) & 0x1f);

				int tile	=	spriteram[addr*2 + 0];
				int attr	=	spriteram[addr*2 + 1];

				int flipx	=	attr & 0x40;
				int flipy	=	attr & 0x80;

				int sx		=	 x + tx * 8;
				int sy		=	(y + real_ty * 8) & 0xff;

				if (flip_screen_get(machine))
				{
					sx = max_x - sx;	flipx = !flipx;
					sy = max_y - sy;	flipy = !flipy;
				}

				drawgfx_transpen(	bitmap,cliprect,machine.gfx[0],
							tile + (attr & 0x3)*0x100 + bank,
							(attr >> 2) & 0xf,
							flipx, flipy,
							sx, sy,15);
			}
		}

	}
}

/***************************************************************************


                                Screen Drawing


***************************************************************************/

SCREEN_UPDATE( suna8 )
{
	/* see hardhead, hardhea2 test mode (press button 2 for both players) */
	bitmap_fill(bitmap,cliprect,0xff);

#ifdef MAME_DEBUG
#if TILEMAPS
	if (screen->machine().input().code_pressed(KEYCODE_Z) || screen->machine().input().code_pressed(KEYCODE_X))
	{
		suna8_state *state = screen->machine().driver_data<suna8_state>();
		int max_tiles = screen->machine().region("gfx1")->bytes() / (0x400 * 0x20);

		if (screen->machine().input().code_pressed_once(KEYCODE_Q))	{ state->m_page--;	tilemap_mark_all_tiles_dirty_all(screen->machine());	}
		if (screen->machine().input().code_pressed_once(KEYCODE_W))	{ state->m_page++;	tilemap_mark_all_tiles_dirty_all(screen->machine());	}
		if (screen->machine().input().code_pressed_once(KEYCODE_E))	{ state->m_tiles--;	tilemap_mark_all_tiles_dirty_all(screen->machine());	}
		if (screen->machine().input().code_pressed_once(KEYCODE_R))	{ state->m_tiles++;	tilemap_mark_all_tiles_dirty_all(screen->machine());	}
		if (screen->machine().input().code_pressed_once(KEYCODE_A))	{ state->m_trombank--;	tilemap_mark_all_tiles_dirty_all(screen->machine());	}
		if (screen->machine().input().code_pressed_once(KEYCODE_S))	{ state->m_trombank++;	tilemap_mark_all_tiles_dirty_all(screen->machine());	}

		state->m_rombank  &= 0xf;
		state->m_page  &= (state->m_text_dim > 0)?3:7;
		state->m_tiles %= max_tiles;
		if (state->m_tiles < 0) state->m_tiles += max_tiles;

		tilemap_set_scrollx(state->m_bg_tilemap, 0, 0x100 * state->m_page);
		tilemap_set_scrolly(state->m_bg_tilemap, 0, 0);
		tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0);
#if 1
	popmessage("%02X %02X %02X %02X - p%2X g%02X r%02X",
						state->m_rombank, state->m_palettebank, state->m_spritebank, state->m_unknown,
						state->m_page, state->m_tiles, state->m_trombank);
#endif
	}
	else
#endif
#endif
	{
		draw_normal_sprites(screen->machine() ,bitmap,cliprect);
		draw_text_sprites(screen->machine(), bitmap,cliprect);
	}
	return 0;
}