summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/tecmo16.c
blob: c31a2cc78302d763d46212be73d09287c25e157f (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                                  
                
                             
 




                                                                                
                                                                    

                                                          

                                     
                                                                         









                                                                   
                                                                    

                                                                 









                                        
                                                                    
                                                










                                                                                


                                                                    
 
                                

                                                                                                     

                            
                                                                                                    
 


                                                                                                      
 


                                                           
 


                                                       



                     


                                                                    
 
                                

                                                                                                     

                            
                                                                                                    
 


                                                                                                      
 




                                                           



                   


                                                                    
 
                                

                                                                                                     

                            











                                                                                                      





                                                                                
                                                                             

                                                            



                                     
                                                                             

                                                            



                                      
                                                                             

                                                            



                                      
                                                                             

                                                            




                                    
                                                                             

                                                            



                                       
                                                                             

                                                               





                                                                                
                                                                             

                                                                       



                                     
                                                                             

                                                                       



                                      
                                                                             

                                                                        



                                      
                                                                             

                                                                        



                                          
                                                                             

                                                                            



                                          
                                                                             

                                                                               




                                                                                       
                                                  
                                                                            

























                                                      
                                                    

                            


                                                                                                                                                                   










































































                                                                                                                                                                                         
                                                                                                                                            
 
                                                                    
                                                 












                                          
                                     
 
                                                                      









                                                                         
                                                 



























                                                                                                            
                                                















                                                                 
                                                                         






                                                                                                         
                                                                                                     
                                                                                    
                                                                                                                                       

                                                                            
                                                                                                          

                                                                   
                                                                                                     
                                                                                    
                                                                                                                                       

                                                                            
                                                                                                          

                                                                   
                                                                                                     
                                                                                    
                                                                                                                                       

                                                                            
                                                                                                          












                                                                                 
                                                                         






                                                                                                         
                                                                                                     
                                                                                    
                                                                                                                                       

                                                                            
                                                                                                          

                                                                   
                                                                                                     
                                                                                    
                                                                                                                                       

                                                                            
                                                                                                          

                                                                   
                                                                                                     
                                                                                    
                                                                                                                                       

                                                                            
                                                                                                          








                                                                                
                        
 

                                                                              
 


                                                              

                                                

                                                                                  

                                                        

                                                                                  

                                               
                                                                                                                            

                                                                       
                                                                                                                                          

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

  Ganbare Ginkun  (Japan)  (c)1995 TECMO
  Final StarForce (US)     (c)1992 TECMO
  Riot            (Japan)  (c)1992 NMK

  Based on sprite drivers from video/wc90.c by Ernesto Corvi (ernesto@imagina.com)

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

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


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

static TILE_GET_INFO( fg_get_tile_info )
{
	tecmo16_state *state = machine.driver_data<tecmo16_state>();
	int tile = state->m_videoram[tile_index] & 0x1fff;
	int color = state->m_colorram[tile_index] & 0x0f;

	/* bit 4 controls blending */
	tileinfo->category = (state->m_colorram[tile_index] & 0x10) >> 4;

	SET_TILE_INFO(
			1,
			tile,
			color | (tileinfo->category ? 0x70 : 0x00),
			0);
}

static TILE_GET_INFO( bg_get_tile_info )
{
	tecmo16_state *state = machine.driver_data<tecmo16_state>();
	int tile = state->m_videoram2[tile_index] & 0x1fff;
	int color = (state->m_colorram2[tile_index] & 0x0f)+0x10;

	SET_TILE_INFO(
			1,
			tile,
			color,
			0);
}

static TILE_GET_INFO( tx_get_tile_info )
{
	tecmo16_state *state = machine.driver_data<tecmo16_state>();
	int tile = state->m_charram[tile_index];
	SET_TILE_INFO(
			0,
			tile & 0x0fff,
			tile >> 12,
			0);
}

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

VIDEO_START( fstarfrc )
{
	tecmo16_state *state = machine.driver_data<tecmo16_state>();
	int width = machine.primary_screen->width();
	int height = machine.primary_screen->height();

	/* set up tile layers */
	state->m_tile_bitmap_bg = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);
	state->m_tile_bitmap_fg = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);

	/* set up sprites */
	state->m_sprite_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);

	state->m_fg_tilemap = tilemap_create(machine, fg_get_tile_info,tilemap_scan_rows,16,16,32,32);
	state->m_bg_tilemap = tilemap_create(machine, bg_get_tile_info,tilemap_scan_rows,16,16,32,32);
	state->m_tx_tilemap = tilemap_create(machine, tx_get_tile_info,tilemap_scan_rows, 8, 8,64,32);

	tilemap_set_transparent_pen(state->m_fg_tilemap,0);
	tilemap_set_transparent_pen(state->m_bg_tilemap,0);
	tilemap_set_transparent_pen(state->m_tx_tilemap,0);

	tilemap_set_scrolly(state->m_tx_tilemap,0,-16);
	state->m_flipscreen = 0;
	state->m_game_is_riot = 0;
}

VIDEO_START( ginkun )
{
	tecmo16_state *state = machine.driver_data<tecmo16_state>();
	int width = machine.primary_screen->width();
	int height = machine.primary_screen->height();

	/* set up tile layers */
	state->m_tile_bitmap_bg = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);
	state->m_tile_bitmap_fg = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);

	/* set up sprites */
	state->m_sprite_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);

	state->m_fg_tilemap = tilemap_create(machine, fg_get_tile_info,tilemap_scan_rows,16,16,64,32);
	state->m_bg_tilemap = tilemap_create(machine, bg_get_tile_info,tilemap_scan_rows,16,16,64,32);
	state->m_tx_tilemap = tilemap_create(machine, tx_get_tile_info,tilemap_scan_rows, 8, 8,64,32);

	tilemap_set_transparent_pen(state->m_fg_tilemap,0);
	tilemap_set_transparent_pen(state->m_bg_tilemap,0);
	tilemap_set_transparent_pen(state->m_tx_tilemap,0);
	state->m_flipscreen = 0;
	state->m_game_is_riot = 0;
}

VIDEO_START( riot )
{
	tecmo16_state *state = machine.driver_data<tecmo16_state>();
	int width = machine.primary_screen->width();
	int height = machine.primary_screen->height();

	/* set up tile layers */
	state->m_tile_bitmap_bg = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);
	state->m_tile_bitmap_fg = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);

	/* set up sprites */
	state->m_sprite_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16);

	state->m_fg_tilemap = tilemap_create(machine, fg_get_tile_info,tilemap_scan_rows,16,16,64,32);
	state->m_bg_tilemap = tilemap_create(machine, bg_get_tile_info,tilemap_scan_rows,16,16,64,32);
	state->m_tx_tilemap = tilemap_create(machine, tx_get_tile_info,tilemap_scan_rows, 8, 8,64,32);

	tilemap_set_transparent_pen(state->m_fg_tilemap,0);
	tilemap_set_transparent_pen(state->m_bg_tilemap,0);
	tilemap_set_transparent_pen(state->m_tx_tilemap,0);
	tilemap_set_scrolldy(state->m_tx_tilemap,-16,-16);
	state->m_flipscreen = 0;
	state->m_game_is_riot = 1;
}

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

WRITE16_HANDLER( tecmo16_videoram_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_videoram[offset]);
	tilemap_mark_tile_dirty(state->m_fg_tilemap,offset);
}

WRITE16_HANDLER( tecmo16_colorram_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_colorram[offset]);
	tilemap_mark_tile_dirty(state->m_fg_tilemap,offset);
}

WRITE16_HANDLER( tecmo16_videoram2_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_videoram2[offset]);
	tilemap_mark_tile_dirty(state->m_bg_tilemap,offset);
}

WRITE16_HANDLER( tecmo16_colorram2_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_colorram2[offset]);
	tilemap_mark_tile_dirty(state->m_bg_tilemap,offset);
}


WRITE16_HANDLER( tecmo16_charram_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_charram[offset]);
	tilemap_mark_tile_dirty(state->m_tx_tilemap,offset);
}

WRITE16_HANDLER( tecmo16_flipscreen_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	state->m_flipscreen = data & 0x01;
	flip_screen_set(space->machine(), state->m_flipscreen);
}

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

WRITE16_HANDLER( tecmo16_scroll_x_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_scroll_x_w);
	tilemap_set_scrollx(state->m_fg_tilemap,0,state->m_scroll_x_w);
}

WRITE16_HANDLER( tecmo16_scroll_y_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_scroll_y_w);
	tilemap_set_scrolly(state->m_fg_tilemap,0,state->m_scroll_y_w);
}

WRITE16_HANDLER( tecmo16_scroll2_x_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_scroll2_x_w);
	tilemap_set_scrollx(state->m_bg_tilemap,0,state->m_scroll2_x_w);
}

WRITE16_HANDLER( tecmo16_scroll2_y_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_scroll2_y_w);
	tilemap_set_scrolly(state->m_bg_tilemap,0,state->m_scroll2_y_w);
}

WRITE16_HANDLER( tecmo16_scroll_char_x_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_scroll_char_x_w);
	tilemap_set_scrollx(state->m_tx_tilemap,0,state->m_scroll_char_x_w);
}

WRITE16_HANDLER( tecmo16_scroll_char_y_w )
{
	tecmo16_state *state = space->machine().driver_data<tecmo16_state>();
	COMBINE_DATA(&state->m_scroll_char_y_w);
	tilemap_set_scrolly(state->m_tx_tilemap,0,state->m_scroll_char_y_w-16);
}

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

/* mix & blend the paletted 16-bit tile and sprite bitmaps into an RGB 32-bit bitmap */
static void blendbitmaps(running_machine &machine,
		bitmap_t *dest,bitmap_t *src1,bitmap_t *src2,bitmap_t *src3,
		int sx,int sy,const rectangle *clip)
{
	int ox;
	int oy;
	int ex;
	int ey;

	/* check bounds */
	ox = sx;
	oy = sy;

	ex = sx + src1->width - 1;
	if (sx < 0) sx = 0;
	if (sx < clip->min_x) sx = clip->min_x;
	if (ex >= dest->width) ex = dest->width - 1;
	if (ex > clip->max_x) ex = clip->max_x;
	if (sx > ex) return;

	ey = sy + src1->height - 1;
	if (sy < 0) sy = 0;
	if (sy < clip->min_y) sy = clip->min_y;
	if (ey >= dest->height) ey = dest->height - 1;
	if (ey > clip->max_y) ey = clip->max_y;
	if (sy > ey) return;

	{
		const pen_t *paldata = machine.pens;
		UINT32 *end;

		UINT16 *sd1 = (UINT16 *)src1->base;												/* source data   */
		UINT16 *sd2 = (UINT16 *)src2->base;
		UINT16 *sd3 = (UINT16 *)src3->base;

		int sw = ex-sx+1;														/* source width  */
		int sh = ey-sy+1;														/* source height */
		int sm = src1->rowpixels;												/* source modulo */

		UINT32 *dd = BITMAP_ADDR32(dest, sy, sx);								/* dest data     */
		int dm = dest->rowpixels;												/* dest modulo   */

		sd1 += (sx-ox);
		sd1 += sm * (sy-oy);
		sd2 += (sx-ox);
		sd2 += sm * (sy-oy);
		sd3 += (sx-ox);
		sd3 += sm * (sy-oy);

		sm -= sw;
		dm -= sw;

		while (sh)
		{

#define BLENDPIXEL(x)	if (sd3[x]) {														\
							if (sd2[x]) {													\
								dd[x] = paldata[sd2[x] | 0x0400] + paldata[sd3[x]];			\
							} else {														\
								dd[x] = paldata[sd1[x] | 0x0400] + paldata[sd3[x]];			\
							}																\
						} else {															\
							if (sd2[x]) {													\
								if (sd2[x] & 0x0800) {										\
									dd[x] = paldata[sd1[x] | 0x0400] + paldata[sd2[x]];		\
								} else {													\
									dd[x] = paldata[sd2[x]];								\
								}															\
							} else {														\
								dd[x] = paldata[sd1[x]];									\
							}																\
						}

			end = dd + sw;
			while (dd <= end - 8)
			{
				BLENDPIXEL(0);
				BLENDPIXEL(1);
				BLENDPIXEL(2);
				BLENDPIXEL(3);
				BLENDPIXEL(4);
				BLENDPIXEL(5);
				BLENDPIXEL(6);
				BLENDPIXEL(7);
				dd += 8;
				sd1 += 8;
				sd2 += 8;
				sd3 += 8;
			}
			while (dd < end)
			{
				BLENDPIXEL(0);
				dd++;
				sd1++;
				sd2++;
				sd3++;
			}
			dd += dm;
			sd1 += sm;
			sd2 += sm;
			sd3 += sm;
			sh--;

#undef BLENDPIXEL

		}
	}
}

static void draw_sprites(running_machine &machine, bitmap_t *bitmap_bg, bitmap_t *bitmap_fg, bitmap_t *bitmap_sp, const rectangle *cliprect)
{
	tecmo16_state *state = machine.driver_data<tecmo16_state>();
	UINT16 *spriteram16 = state->m_spriteram;
	int offs;
	static const UINT8 layout[8][8] =
	{
		{ 0, 1, 4, 5,16,17,20,21},
		{ 2, 3, 6, 7,18,19,22,23},
		{ 8, 9,12,13,24,25,28,29},
		{10,11,14,15,26,27,30,31},
		{32,33,36,37,48,49,52,53},
		{34,35,38,39,50,51,54,55},
		{40,41,44,45,56,57,60,61},
		{42,43,46,47,58,59,62,63}
	};

	bitmap_t *bitmap = bitmap_bg;

	for (offs = state->m_spriteram_size/2 - 8;offs >= 0;offs -= 8)
	{
		if (spriteram16[offs] & 0x04)	/* enable */
		{
			int code,color,sizex,sizey,flipx,flipy,xpos,ypos;
			int x,y,priority,priority_mask;

			code = spriteram16[offs+1];
			color = (spriteram16[offs+2] & 0xf0) >> 4;
			sizex = 1 << ((spriteram16[offs+2] & 0x03) >> 0);

			if(state->m_game_is_riot)
				sizey = sizex;
			else
				sizey = 1 << ((spriteram16[offs+2] & 0x0c) >> 2);

			if (sizex >= 2) code &= ~0x01;
			if (sizey >= 2) code &= ~0x02;
			if (sizex >= 4) code &= ~0x04;
			if (sizey >= 4) code &= ~0x08;
			if (sizex >= 8) code &= ~0x10;
			if (sizey >= 8) code &= ~0x20;
			flipx = spriteram16[offs] & 0x01;
			flipy = spriteram16[offs] & 0x02;
			xpos = spriteram16[offs+4];
			if (xpos >= 0x8000) xpos -= 0x10000;
			ypos = spriteram16[offs+3];
			if (ypos >= 0x8000) ypos -= 0x10000;
			priority = (spriteram16[offs] & 0xc0) >> 6;

			/* bg: 1; fg:2; text: 4 */
			switch (priority)
			{
				default:
				case 0x0: priority_mask = 0; break;
				case 0x1: priority_mask = 0xf0; break; /* obscured by text layer */
				case 0x2: priority_mask = 0xf0|0xcc; break;	/* obscured by foreground */
				case 0x3: priority_mask = 0xf0|0xcc|0xaa; break; /* obscured by bg and fg */
			}

			if (state->m_flipscreen)
			{
				flipx = !flipx;
				flipy = !flipy;
			}

			/* blending */
			if (spriteram16[offs] & 0x20)
			{
				color |= 0x80;

				for (y = 0;y < sizey;y++)
				{
					for (x = 0;x < sizex;x++)
					{
						int sx,sy;

						if (!state->m_flipscreen)
						{
							sx = xpos + 8*(flipx?(sizex-1-x):x);
							sy = ypos + 8*(flipy?(sizey-1-y):y);
						} else {
							sx = 256 - (xpos + 8*(!flipx?(sizex-1-x):x) + 8);
							sy = 256 - (ypos + 8*(!flipy?(sizey-1-y):y) + 8);
						}
						pdrawgfx_transpen_raw(bitmap,cliprect,machine.gfx[2],
								code + layout[y][x],
								machine.gfx[2]->color_base + color * machine.gfx[2]->color_granularity,
								flipx,flipy,
								sx,sy,
								machine.priority_bitmap, priority_mask,0);

						/* wrap around x */
						pdrawgfx_transpen_raw(bitmap,cliprect,machine.gfx[2],
								code + layout[y][x],
								machine.gfx[2]->color_base + color * machine.gfx[2]->color_granularity,
								flipx,flipy,
								sx-512,sy,
								machine.priority_bitmap, priority_mask,0);

						/* wrap around x */
						pdrawgfx_transpen_raw(bitmap,cliprect,machine.gfx[2],
								code + layout[y][x],
								machine.gfx[2]->color_base + color * machine.gfx[2]->color_granularity,
								flipx,flipy,
								sx+512,sy,
								machine.priority_bitmap, priority_mask,0);
					}
				}
			}
			else
			{
				bitmap = (priority >= 2) ? bitmap_bg : bitmap_fg;

				for (y = 0;y < sizey;y++)
				{
					for (x = 0;x < sizex;x++)
					{
						int sx,sy;

						if (!state->m_flipscreen)
						{
							sx = xpos + 8*(flipx?(sizex-1-x):x);
							sy = ypos + 8*(flipy?(sizey-1-y):y);
						} else {
							sx = 256 - (xpos + 8*(!flipx?(sizex-1-x):x) + 8);
							sy = 256 - (ypos + 8*(!flipy?(sizey-1-y):y) + 8);
						}
						pdrawgfx_transpen_raw(bitmap,cliprect,machine.gfx[2],
								code + layout[y][x],
								machine.gfx[2]->color_base + color * machine.gfx[2]->color_granularity,
								flipx,flipy,
								sx,sy,
								machine.priority_bitmap, priority_mask,0);

						/* wrap around x */
						pdrawgfx_transpen_raw(bitmap,cliprect,machine.gfx[2],
								code + layout[y][x],
								machine.gfx[2]->color_base + color * machine.gfx[2]->color_granularity,
								flipx,flipy,
								sx-512,sy,
								machine.priority_bitmap, priority_mask,0);

						/* wrap around x */
						pdrawgfx_transpen_raw(bitmap,cliprect,machine.gfx[2],
								code + layout[y][x],
								machine.gfx[2]->color_base + color * machine.gfx[2]->color_granularity,
								flipx,flipy,
								sx+512,sy,
								machine.priority_bitmap, priority_mask,0);
					}
				}
			}
		}
	}
}

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

SCREEN_UPDATE( tecmo16 )
{
	tecmo16_state *state = screen->machine().driver_data<tecmo16_state>();
	bitmap_fill(screen->machine().priority_bitmap,cliprect,0);

	bitmap_fill(state->m_tile_bitmap_bg, cliprect, 0x300);
	bitmap_fill(state->m_tile_bitmap_fg,     cliprect, 0);
	bitmap_fill(state->m_sprite_bitmap,      cliprect, 0);

	/* draw tilemaps into a 16-bit bitmap */
	tilemap_draw(state->m_tile_bitmap_bg, cliprect,state->m_bg_tilemap, 0, 1);
	tilemap_draw(state->m_tile_bitmap_fg, cliprect,state->m_fg_tilemap, 0, 2);
	/* draw the blended tiles at a lower priority
       so sprites covered by them will still be drawn */
	tilemap_draw(state->m_tile_bitmap_fg, cliprect,state->m_fg_tilemap, 1, 0);
	tilemap_draw(state->m_tile_bitmap_fg, cliprect,state->m_tx_tilemap, 0, 4);

	/* draw sprites into a 16-bit bitmap */
	draw_sprites(screen->machine(), state->m_tile_bitmap_bg, state->m_tile_bitmap_fg, state->m_sprite_bitmap, cliprect);

	/* mix & blend the tilemaps and sprites into a 32-bit bitmap */
	blendbitmaps(screen->machine(), bitmap, state->m_tile_bitmap_bg, state->m_tile_bitmap_fg, state->m_sprite_bitmap, 0, 0, cliprect);
	return 0;
}