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

                    
                
                        
                              
 

                                         
                                                                      
                                            

                                                                      

                  
                                  





























                                                                
                                                                          



                       
                                                                      
                                                                                                    



                                     
                                                                               
                                            
                                
                                                                     

 
                                                                                                                   
 
                                                                      






















                                                                                           
                                    





















                                                       
 

                                  
 


                                                                                                                          
 











                                                
 


                                    
                                        













                                                   
                                             
                                       
                                         




                                            
                                                                                  
 









                                                                                  



                 
                                                                                                        
 
                                                                      

                                     

                                          





                                                               
                         
 
                                                                                



                                                                                            
 
                                                                
                                                                   
                                                                                          






                        
 
                                     
                                                             


                                                   
         


                                                                                                    
                                                                           

         
                                                                        
                           

                        


                                                       
                                                                             





                                                                                 
                                                                             
         


 
                                                                                                                     
 
                                                                      
                                            





                  





















                                       

                                         






                                                    
                                         
                                       
                                         
                                               



                                                  
                                           



                 
                                                                                                         
 
                                                                      
                                            







                                    




                                            
 
                                                

                                         
                                 
                                       
                                         
                                               


                                                                      
                                          


         
                         
 


                                                                         

                 
/* video/shangkid */

#include "emu.h"
#include "cpu/z80/z80.h"
#include "includes/shangkid.h"


static TILE_GET_INFO( get_bg_tile_info ){
	shangkid_state *state = machine.driver_data<shangkid_state>();
	UINT8 *videoram = state->m_videoram;
	int attributes = videoram[tile_index+0x800];
	int tile_number = videoram[tile_index]+0x100*(attributes&0x3);
	int color;

	if( state->m_gfx_type==1 )
	{
		/* Shanghai Kid:
            ------xx    bank
            -----x--    flipx
            xxxxx---    color
        */
		color = attributes>>3;
		color = (color&0x03)|((color&0x1c)<<1);
		SET_TILE_INFO(
				0,
				tile_number,
				color,
				(attributes&0x04)?TILE_FLIPX:0);
	}
	else
	{
		/* Chinese Hero:
            ------xx    bank
            -xxxxx--    color
            x-------    flipx?
        */
		color = (attributes>>2)&0x1f;
		SET_TILE_INFO(
				0,
				tile_number,
				color,
				(attributes&0x80)?TILE_FLIPX:0);
	}

	tileinfo->category =
		(machine.region( "proms" )->base()[0x800+color*4]==2)?1:0;
}

VIDEO_START( shangkid )
{
	shangkid_state *state = machine.driver_data<shangkid_state>();
	state->m_background = tilemap_create(machine, get_bg_tile_info,tilemap_scan_rows,8,8,64,32);
}

WRITE8_HANDLER( shangkid_videoram_w )
{
	shangkid_state *state = space->machine().driver_data<shangkid_state>();
	UINT8 *videoram = state->m_videoram;
	videoram[offset] = data;
	tilemap_mark_tile_dirty( state->m_background, offset&0x7ff );
}

static void draw_sprite(running_machine &machine, const UINT8 *source, bitmap_t *bitmap, const rectangle *cliprect)
{
	shangkid_state *state = machine.driver_data<shangkid_state>();
	const gfx_element *gfx;
	int transparent_pen;
	int bank_index;
	int c,r;
	int width,height;
	int sx,sy;

	int ypos		= 209 - source[0];
	int tile		= source[1]&0x3f;
	int xflip		= (source[1]&0x40)?1:0;
	int yflip		= (source[1]&0x80)?1:0;
	int bank		= source[2]&0x3f;
	int xsize		= (source[2]&0x40)?1:0;
	int ysize		= (source[2]&0x80)?1:0;
	int yscale		= source[3]&0x07;	/* 0x0 = smallest; 0x7 = biggest */
	int xpos		= ((source[4]+source[5]*255)&0x1ff)-23;
	int color		= source[6]&0x3f;
	int xscale		= source[7]&0x07;	/* 0x0 = smallest; 0x7 = biggest */

	/* adjust placement for small sprites */
	if( xsize==0 && xflip ) xpos -= 16;
	if( ysize==0 && yflip==0 ) ypos += 16;

	if( state->m_gfx_type == 1 )
	{
		/* Shanghai Kid */
		switch( bank&0x30 )
		{
		case 0x00:
		case 0x10:
			tile += 0x40*(bank&0xf);
			break;

		case 0x20:
			tile += 0x40*((bank&0x3)|0x10);
			break;

		case 0x30:
			tile += 0x40*((bank&0x3)|0x14);
			break;
		}
		bank_index = 0;
		transparent_pen = 3;
	}
	else
	{

		/* Chinese Hero */
		color >>= 1;

		// It's needed in level 7 to hide "bogus" sprites. Is it a sprite disable flag or an end sprite list flag?
		if(color == 0)
			return;

		switch( bank>>2 )
		{
		case 0x0: bank_index = 0; break;
		case 0x9: bank_index = 1; break;
		case 0x6: bank_index = 2; break;
		case 0xf: bank_index = 3; break;
		default:
			bank_index = 0;
			break;
		}

		if( bank&0x01 ) tile += 0x40;

		transparent_pen = 7;
	}

	gfx = machine.gfx[1+bank_index];

	width = (xscale+1)*2;
	height = (yscale+1)*2;

	/* center zoomed sprites */
	xpos += (16-width)*(xsize+1)/2;
	ypos += (16-height)*(ysize+1)/2;

	for( r=0; r<=ysize; r++ )
	{
		for( c=0; c<=xsize; c++ )
		{
			sx = xpos+(c^xflip)*width;
			sy = ypos+(r^yflip)*height;
			drawgfxzoom_transpen(
				bitmap,
				cliprect,
				gfx,
				tile+c*8+r,
				color,
				xflip,yflip,
				sx,sy,
				(width<<16)/16, (height<<16)/16,transparent_pen );

			// wrap around y
			drawgfxzoom_transpen(
				bitmap,
				cliprect,
				gfx,
				tile+c*8+r,
				color,
				xflip,yflip,
				sx,sy+256,
				(width<<16)/16, (height<<16)/16,transparent_pen );
		}
	}
}

static void shangkid_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect)
{
	shangkid_state *state = machine.driver_data<shangkid_state>();
	const UINT8 *source, *finish;

	finish = state->m_spriteram;
	source = state->m_spriteram+0x200;
	while( source>finish ){
		source -= 8;
		draw_sprite(machine, source, bitmap,cliprect );
	}
}

SCREEN_UPDATE( shangkid )
{
	shangkid_state *state = screen->machine().driver_data<shangkid_state>();
	int flipscreen = state->m_videoreg[1]&0x80;
	tilemap_set_flip( state->m_background, flipscreen?(TILEMAP_FLIPX|TILEMAP_FLIPY):0 );
	tilemap_set_scrollx( state->m_background,0,state->m_videoreg[0]-40 );
	tilemap_set_scrolly( state->m_background,0,state->m_videoreg[2]+0x10 );

	tilemap_draw( bitmap,cliprect,state->m_background,0,0 );
	shangkid_draw_sprites(screen->machine(), bitmap,cliprect );
	tilemap_draw( bitmap,cliprect,state->m_background,1,0 ); /* high priority tiles */
	return 0;
}


PALETTE_INIT( dynamski )
{
	int i;

	/* allocate the colortable */
	machine.colortable = colortable_alloc(machine, 0x20);

	/* create a lookup table for the palette */
	for (i = 0; i < 0x20; i++)
	{
		UINT16 data = (color_prom[i | 0x20] << 8) | color_prom[i];
		rgb_t color = MAKE_RGB(pal5bit(data >> 1), pal5bit(data >> 6), pal5bit(data >> 11));

		colortable_palette_set_color(machine.colortable, i, color);
	}

	/* color_prom now points to the beginning of the lookup table */
	color_prom += 0x40;

	/* characters */
	for (i = 0; i < 0x40; i++)
	{
		UINT8 ctabentry = color_prom[i] & 0x0f;
		colortable_entry_set_value(machine.colortable, i, ctabentry);
	}

	/* sprites */
	for (i = 0x40; i < 0x80; i++)
	{
		UINT8 ctabentry = (color_prom[(i - 0x40) + 0x100] & 0x0f) | 0x10;
		colortable_entry_set_value(machine.colortable, i, ctabentry);
	}
}


static void dynamski_draw_background(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, int pri )
{
	shangkid_state *state = machine.driver_data<shangkid_state>();
	UINT8 *videoram = state->m_videoram;
	int i;
	int sx,sy;
	int tile;
	int attr;
	int temp;

	for( i=0; i<0x400; i++ )
	{
		sx = (i%32)*8;
		sy = (i/32)*8;

		if( sy<16 )
		{
			temp = sx;
			sx = sy+256+16;
			sy = temp;
		}
		else if( sy>=256-16 )
		{
			temp = sx;
			sx = sy-256+16;
			sy = temp;
		}
		else
		{
			sx+=16;
		}

		tile = videoram[i];
		attr = videoram[i+0x400];
		/*
            x---.----   priority?
            -xx-.----   bank
        */
		if( pri==0 || (attr>>7)==pri )
		{
			tile += ((attr>>5)&0x3)*256;
			drawgfx_transpen(
				bitmap,
				cliprect,
				machine.gfx[0],
				tile,
				attr & 0x0f,
				0,0,//xflip,yflip,
				sx,sy,
				pri?3:-1 );
		}
	}
}

static void dynamski_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect )
{
	shangkid_state *state = machine.driver_data<shangkid_state>();
	UINT8 *videoram = state->m_videoram;
	int i;
	int sx,sy;
	int tile;
	int bank;
	int attr;
	int color;
	for( i=0x7e; i>=0x00; i-=2 )
	{
		bank = videoram[0x1b80+i];
		attr = videoram[0x1b81+i];
		tile = videoram[0xb80+i];
		color = videoram[0xb81+i];
		sy = 240-videoram[0x1380+i];

		sx = videoram[0x1381+i]-64+8+16;
		if( attr&1 ) sx += 0x100;

		drawgfx_transpen(
				bitmap,
				cliprect,
				machine.gfx[1],
				bank*0x40 + (tile&0x3f),
				color,
				tile&0x80,tile&0x40, /* flipx,flipy */
				sx,sy,3 );
	}
}

SCREEN_UPDATE( dynamski )
{
	dynamski_draw_background(screen->machine(), bitmap,cliprect, 0 );
	dynamski_draw_sprites(screen->machine(), bitmap,cliprect );
	dynamski_draw_background(screen->machine(), bitmap,cliprect, 1 );
	return 0;
}