summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/tecmosys.cpp
blob: 6b9e646f08d1d1b4e9572a06cd70d34a17c7455b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
                       
                                                            









                                                                            

                                                   
 



                                                                            


 
                                                                                                         
 
                                                                                                                   

 
                                                                            
 
                                                      
                                                                               

 
                                                                                                      
 


                                                                       
                                     
                                                                            
                                                                          


                                 
                                 









                                 

                                         









                                      
                                                                             


                            

                                                                                              
 

                                                                


                                                   

                                                               
 
                                                           
 
                                                            
 
                                                        


















                                                                                       
                                                     
 
                                                                                      

 
                                                                           










                                                                                                        
                                                                                     

                

                         
                                                    
         

                                                               
                                                            

                                                 
                                                                     



                 

                                                                                  
 
                                                       
 
                                                        
         

                                                                                     
 

                                                                
                 





                                                                                          
                                           
                                         

                                                    
                                            
                         
                                                                                           
                                                                     
                                                       
                         
                                               
                         
                                                                                    
                                                                                
                                                     
                         
                            
                         


                                                                              
                         


























                                                                                             
                                           
                         
                                                                                                              
                                                                                 
                                    
                                                                              


                            
                                                                                                                          
                                                                                 
                                                                 
                                                            
                                    
                                                                              





                         
                                                                                                              
 
                                 
 







                                                                                                                         
 


                                                                                                                         
 


                                                                                                                         
 
                                                      
 
                                                     

                                                                              
 
                                                     

                                                                              
 
                                                     

                                                                              
 
                                                     

                                                                              
 
                                       

                                                                                                                                 
                                                                               



                 
                                  
 
                                                          
                                     
 

                                                                      

                                                 
 

                                                                                                                                                                         
 

                                                                                                                                                                       
 

                                                                                                                                                                       
 

                                                                                                                                                                       
 
                                      
 
// license:BSD-3-Clause
// copyright-holders:Farfetch'd,David Haywood,Tomasz Slanina
/***************************************************************************

 tecmosys video driver

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

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


template<int Layer>
TILE_GET_INFO_MEMBER(tecmosys_state::get_tile_info)
{
	SET_TILE_INFO_MEMBER(Layer,
			m_vram[Layer][2*tile_index+1],
			(m_vram[Layer][2*tile_index]&0x3f),
			TILE_FLIPYX((m_vram[Layer][2*tile_index]&0xc0)>>6));
}


inline void tecmosys_state::set_color_555(pen_t color, int rshift, int gshift, int bshift, uint16_t data)
{
	m_palette->set_pen_color(color, pal5bit(data >> rshift), pal5bit(data >> gshift), pal5bit(data >> bshift));
}

WRITE16_MEMBER(tecmosys_state::tilemap_paletteram16_xGGGGGRRRRRBBBBB_word_w)
{
	COMBINE_DATA(&m_tilemap_paletteram16[offset]);
	set_color_555(offset+0x4000, 5, 10, 0, m_tilemap_paletteram16[offset]);
}

void tecmosys_state::render_sprites_to_bitmap(bitmap_rgb32 &bitmap, uint16_t extrax, uint16_t extray )
{
	int i;

	/* render sprites (with priority information) to temp bitmap */
	m_sprite_bitmap.fill(0x0000);
	/* there are multiple spritelists in here, to allow for buffering */
	for (i=(m_spritelist*0x4000)/2;i<((m_spritelist+1)*0x4000)/2;i+=8)
	{
		int xcnt,ycnt;
		int drawx, drawy;
		uint16_t* dstptr;

		int x, y;
		int address;
		int xsize = 16;
		int ysize = 16;
		int colour;
		int flipx, flipy;
		int priority;
		int zoomx, zoomy;

		x = m_spriteram[i+0]+386;
		y = (m_spriteram[i+1]+1);

		x-= extrax;
		y-= extray;

		y&=0x1ff;
		x&=0x3ff;

		if (x&0x200) x-=0x400;
		if (y&0x100) y-=0x200;

		address =  m_spriteram[i+5]| ((m_spriteram[i+4]&0x000f)<<16);

		address<<=8;

		flipx = (m_spriteram[i+4]&0x0040)>>6;
		flipy = (m_spriteram[i+4]&0x0080)>>7; // used by some move effects in tkdensho

		zoomx = (m_spriteram[i+2] & 0x0fff)>>0; // zoom?
		zoomy = (m_spriteram[i+3] & 0x0fff)>>0; // zoom?

		if ((!zoomx) || (!zoomy)) continue;

		ysize =  ((m_spriteram[i+6] & 0x00ff))*16;
		xsize =  (((m_spriteram[i+6] & 0xff00)>>8))*16;

		colour =  ((m_spriteram[i+4] & 0x3f00))>>8;

		priority = ((m_spriteram[i+4] & 0x0030))>>4;

		if (m_spriteram[i+4] & 0x8000) continue;

		for (ycnt = 0; ycnt < ysize; ycnt++)
		{
			int actualycnt = (ycnt * zoomy) >> 8;
			int actualysize = (ysize * zoomy) >> 8;

			if (flipy) drawy = y + (actualysize-1) - actualycnt;
			else drawy = y + actualycnt;

			for (xcnt = 0; xcnt < xsize; xcnt++)
			{
				int actualxcnt = (xcnt * zoomx) >> 8;
				int actualxsize = (xsize *zoomx) >> 8;

				if (flipx) drawx = x + (actualxsize-1) - actualxcnt;
				else drawx = x + actualxcnt;

				if ((drawx>=0 && drawx<320) && (drawy>=0 && drawy<240))
				{
					uint8_t data;

					dstptr = &m_sprite_bitmap.pix16(drawy, drawx);


					data =  (m_sprite_region[address]);


					if(data) dstptr[0] = (data + (colour*0x100)) | (priority << 14);
				}

				address++;
			}
		}
	}
}

void tecmosys_state::tilemap_copy_to_compose(uint16_t pri, const rectangle &cliprect)
{
	int y,x;
	uint16_t *srcptr;
	uint16_t *dstptr;
	for (y=cliprect.min_y;y<=cliprect.max_y;y++)
	{
		srcptr = &m_tmp_tilemap_renderbitmap.pix16(y);
		dstptr = &m_tmp_tilemap_composebitmap.pix16(y);
		for (x=cliprect.min_x;x<=cliprect.max_x;x++)
		{
			if ((srcptr[x]&0xf)!=0x0)
				dstptr[x] =  (srcptr[x]&0x7ff) | pri;
		}
	}
}


void tecmosys_state::do_final_mix(bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	pen_t const *const paldata = m_palette->pens();

	for (int y=cliprect.min_y;y<=cliprect.max_y;y++)
	{
		uint16_t const *const srcptr = &m_tmp_tilemap_composebitmap.pix16(y);
		uint16_t const *const srcptr2 = &m_sprite_bitmap.pix16(y);

		uint32_t *const dstptr = &bitmap.pix32(y);
		for (int x=cliprect.min_x;x<=cliprect.max_x;x++)
		{
			uint16_t const pri = srcptr[x] & 0xc000;
			uint16_t const pri2 = srcptr2[x] & 0xc000;

			uint16_t const penvalue = m_tilemap_paletteram16[srcptr[x]&0x7ff];
			uint32_t const colour = paldata[(srcptr[x]&0x7ff) | 0x4000];

			uint16_t penvalue2;
			uint32_t colour2;
			uint8_t mask = 0;
			bool is_transparent = false;
			if (srcptr2[x]&0xff)
			{
				penvalue2 = m_palette->basemem().read(srcptr2[x] & 0x3fff);
				colour2 = paldata[srcptr2[x]&0x3fff];
				mask = srcptr2[x]&0xff;
			}
			else if (srcptr[x]&0xf)
			{
				penvalue2 = m_tilemap_paletteram16[srcptr[x]&0x7ff];
				colour2 =   paldata[(srcptr[x]&0x7ff) | 0x4000];
				mask = srcptr[x]&0xf;
			}
			else
			{
				penvalue2 = m_palette->basemem().read(0x3f00);
				colour2 =   paldata[0x3f00];
				is_transparent = true;
			}

			auto const draw_blended =
					[] (uint32_t colour, uint32_t colour2, uint32_t &dst)
					{
						int b = (colour & 0x000000ff) >> 0;
						int g = (colour & 0x0000ff00) >> 8;
						int r = (colour & 0x00ff0000) >> 16;

						int const b2 = (colour2 & 0x000000ff) >> 0;
						int const g2 = (colour2 & 0x0000ff00) >> 8;
						int const r2 = (colour2 & 0x00ff0000) >> 16;

						r = (r + r2) >> 1;
						g = (g + g2) >> 1;
						b = (b + b2) >> 1;

						dst = b | (g<<8) | (r<<16);
					};
			auto const draw_bg =
					[this] (uint32_t colour, uint32_t src, uint32_t &dst)
					{
						if (src&0xf)
							dst = colour;
						else
							dst = m_palette->pen(0x3f00);
					};

			if (is_transparent)
			{
				if (((penvalue & 0x8000) && (srcptr[x]&0xf)) && (penvalue2 & 0x8000)) // blend
					draw_blended(colour, colour2, dstptr[x]);
				else
					draw_bg(colour, srcptr[x], dstptr[x]);
			}
			else
			{
				if (((penvalue & 0x8000) && (srcptr[x]&0xf)) && ((penvalue2 & 0x8000) && (mask))) // blend
					draw_blended(colour, colour2, dstptr[x]);
				else if ((pri2 >= pri) && (mask))
					dstptr[x] = colour2;
				else
					draw_bg(colour, srcptr[x], dstptr[x]);
			}
		}
	}
}


uint32_t tecmosys_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	bitmap.fill(0, cliprect);

	// TODO : Verify 0xc00000-0xc00003 scroll both flip screen and normal screen case, Bit 4 of 0xc00004 is unknown
	// TODO : is tilemap flip bits is correct?
	m_tilemap[0]->set_flip(((m_scroll[0][2] & 1) ? TILEMAP_FLIPX : 0) | ((m_scroll[0][2] & 2) ? TILEMAP_FLIPY : 0) );

	// TODO : Scroll is wrong/unverified when flip screen case
	m_tilemap[1]->set_flip(((m_scroll[1][2] & 1) ? TILEMAP_FLIPX : 0) | ((m_scroll[1][2] & 2) ? TILEMAP_FLIPY : 0) );
	m_tilemap[1]->set_scrolly(0, m_scroll[1][1]+16);
	m_tilemap[1]->set_scrollx(0, m_scroll[1][0]+104);

	m_tilemap[2]->set_flip(((m_scroll[2][2] & 1) ? TILEMAP_FLIPX : 0) | ((m_scroll[2][2] & 2) ? TILEMAP_FLIPY : 0) );
	m_tilemap[2]->set_scrolly(0, m_scroll[2][1]+17);
	m_tilemap[2]->set_scrollx(0, m_scroll[2][0]+106);

	m_tilemap[3]->set_flip(((m_scroll[3][2] & 1) ? TILEMAP_FLIPX : 0) | ((m_scroll[3][2] & 2) ? TILEMAP_FLIPY : 0) );
	m_tilemap[3]->set_scrolly(0, m_scroll[3][1]+17);
	m_tilemap[3]->set_scrollx(0, m_scroll[3][0]+106);

	m_tmp_tilemap_composebitmap.fill(0, cliprect);

	m_tmp_tilemap_renderbitmap.fill(0, cliprect);
	m_tilemap[1]->draw(screen, m_tmp_tilemap_renderbitmap, cliprect, 0,0);
	tilemap_copy_to_compose(0x0000, cliprect);

	m_tmp_tilemap_renderbitmap.fill(0, cliprect);
	m_tilemap[2]->draw(screen, m_tmp_tilemap_renderbitmap, cliprect, 0,0);
	tilemap_copy_to_compose(0x4000, cliprect);

	m_tmp_tilemap_renderbitmap.fill(0, cliprect);
	m_tilemap[3]->draw(screen, m_tmp_tilemap_renderbitmap, cliprect, 0,0);
	tilemap_copy_to_compose(0x8000, cliprect);

	m_tmp_tilemap_renderbitmap.fill(0, cliprect);
	m_tilemap[0]->draw(screen, m_tmp_tilemap_renderbitmap, cliprect, 0,0);
	tilemap_copy_to_compose(0xc000, cliprect);

	do_final_mix(bitmap, cliprect);

	// prepare sprites for NEXT frame - causes 1 frame palette errors, but prevents sprite lag in tkdensho, which is correct?
	render_sprites_to_bitmap(bitmap, m_880000regs[0x0], m_880000regs[0x1]);

	return 0;
}

void tecmosys_state::video_start()
{
	m_screen->register_screen_bitmap(m_sprite_bitmap);
	m_sprite_bitmap.fill(0x4000);

	m_screen->register_screen_bitmap(m_tmp_tilemap_composebitmap);
	m_screen->register_screen_bitmap(m_tmp_tilemap_renderbitmap);
	m_tmp_tilemap_composebitmap.fill(0x0000);
	m_tmp_tilemap_renderbitmap.fill(0x0000);

	m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tecmosys_state::get_tile_info<0>),this),TILEMAP_SCAN_ROWS,8,8,32*2,32*2);
	m_tilemap[0]->set_transparent_pen(0);

	m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tecmosys_state::get_tile_info<1>),this),TILEMAP_SCAN_ROWS,16,16,32,32);
	m_tilemap[1]->set_transparent_pen(0);

	m_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tecmosys_state::get_tile_info<2>),this),TILEMAP_SCAN_ROWS,16,16,32,32);
	m_tilemap[2]->set_transparent_pen(0);

	m_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tecmosys_state::get_tile_info<3>),this),TILEMAP_SCAN_ROWS,16,16,32,32);
	m_tilemap[3]->set_transparent_pen(0);

	save_item(NAME(m_spritelist));
}