summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/decospr.cpp
blob: ba893bf3726dab89dfac64fe7575ef86369d9f7b (plain) (tree)
1
2
3
4
5

                                                 


                        









                                                                                                                     
 

                                                                                                                  

           
 







             
             


                                                                
           

             
          
             





                       

                      

              
 
                                     
 

                                                                                                       
                                                                                                           
 

                                                                   


  


























































                                                                                                                         
                






                 
                                                                                                                       

                                                 

  

                    
                   
 
                                                        


                                 
 
                                                                            
 
                                                                                                               
                                                            
                                                       
                               
                                    
                                  


                              
                              
                                                          
 

                                                                                        



                                   

                                            
 
                         

                                                                                                                                                       


                                       






                                                     
                                          
 
                                                         

 
                            
                                                                                                                             
 
                                                                          
 

                                                                       
 

                                                  

 

                            
                                        

 
                               













                                   
                                                                                            
 
                                  
                 

                                                     

                                                                  







                                                   
                                       
 
 
                                                                      
                         
                                                        
 
                                                             
                                 
                                                             
                                 




                                                                                                            
 
 

                                                          

                                                
 

                                                













                                                                                           
 





                                                                                   
                                                       







                                                               

                                    





                                                               

                                 
 
                                               
                                 

                                                                                                                              
 

                                                         
                                            



                                                                
 


                                                            




                                                                            
 
                                                                    
                                         
                                                                       


                                                                    
 
                                                                            
                                         
 

 


                                                          
                                         

                                                                        
                                                                                                          
                                                 
                                                                                    
                                                         
                                                                                                                          
                                                                 
                                                                                               
                                                                                                                                             
                                                                                                             

                                                                                               
                                                                                               
                                                                                                                            
                                                                            
                                                                                                                                        
                                                                                                             

                                                                                               
                                                                                               
                                                                                                    
                                                                 
 

                                                                                             
                                                                 
                                                                                               
                                                                                                                                             


                                                                                                                             
                                                                                                                               
                                                                                                                                    
                                                                            
                                                                                                                                        


                                                                                                                             
                                                                                                                               
                                                                                                            
                                                                 
                                                         
                                                            
                                                         
                                                                                                                                   
                                                                                                                                     
                                                                                             
                                                                                            
                                                                              
                                                                               
                                                                                    
                                                                      
                                                                 
                                                                                                                                             


                                                                                                             
                                                                                                               
                                                                                            
                                                                 
 


                                                         










                                                            

                                                                         




                                              
                                                                           
                         
                                                             
































                                                                                                                    
                                         




                                                                  
                                                                            
                                                 
                                                                               
                                                         

                                                                                          
                                                                                                                          
                                                                 
                                                                                                                                     


                                                                                                             
                                                                                                                       
                                                                                                                            


                                                                                             
 
                                                                                                                          
                                                                 
                                                                                                                                     



                                                                                                               
                                                                                                                            
                                                                 
 
                                                         
                                                            
                                                         
                                                                                          
 
                                                                                                                          
                                                                 
                                                                                                                                



                                                                                                               
                                                                                                    
                                                                 
 
                                                                                             
 
                                                                                                                          
                                                                 
                                                                                                                                



                                                                                                               
                                                                                                    





                                                                                  
 
                                                                                                                  
                                                         
                                                                                                                                     
                                                                                                     
                                                                                                    
                                                                                      
                                                                                                       
                                                                                            
                                                         
 
                                                                                     
 
                                                                                                                  
                                                         
                                                                                                                                     
                                                                                                     
                                                                                                    
                                                                                      
                                                                                                       
                                                                                            
                                                         
                                                 
                                         






                                 
 

                                                                                                                      
 

                                                                                                                      
 

                                                                                                                     
                                                                                                                                                                                             
 
                                     
                                                                                                       

                 
                                                             
 

                          
 
                                                    
         
                                                   
                                          
 
                                
                 
                                                                    
                         
                                                          
 




                                                                                              
                                         




                                 
                                                                    
                         
                                                          
 
                                                  
                                 

                                                                         

                                                                                                 
                                                                                                
                                         
                                 


                         
 
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail, David Haywood
/* Data East Sprite Chip
   DECO 52

   This is a flexible implementation of the Data East Spite chip 52 emulation, used in a large number of drivers.

   Both list formats are supported (how is this selected on HW, external pin?)

   Support for rendering to a raw indexed 16-bitmap is available allowing you to do complex mixing, which is required
   if a game uses alpha blending at the mixing stage.

   Basic callbacks priority and colour are supported for use with pdrawgfx if render-to-bitmap mode isn't being used.

   There is also a very simply 'drawgfx' path for games where the sprites are only of one priority level.

   Several features are included to support the various clone / bootleg chips derived from this device, it appears
   to have been a popular base for Korean developers (much as the Tumble Pop code was)

   used by:

   dblewing.c
   tumblep.c
   dietgo.c
   supbtime.c
   simpl156.c
   deco156.c
   pktgaldx.c
   backfire.c
   darkseal.c
   sshangha.c (could probably use pdrawgfx, not m_sprite_bitmap)
   cbuster.c (could probably use pdrawgfx, not m_sprite_bitmap)
   mirage.c (could probably use pdrawgfx, not m_sprite_bitmap)
   cninja.c
   lemmings.c
   deco32.c
   rohga.c
   dassault.c
   boogwing.c

   (bootleg) esd16.c
   (bootleg) nmg5.c
   (bootleg) tumbleb.c
   (bootleg) crospang.c
   (bootleg) silvmil.c
   (bootleg) gotcha.c

   to convert:

   (any other bootleg / clone chips?)

   notes:
   does the chip natively support 5bpp (tattass / nslasher) in hw, or is it done with doubled up chips?
   the information in deco_tilegen1 lists 3x sprite chips on those games, but there are only 2 spritelists.

   likewise Rohga appears to have 2x DECO52 for 1 list of 6bpp gfx.

*/


/*

STANDARD FORMAT

offs +0
-------- --------
efFbSssy yyyyyyyy

s = size (height)
S = size (width) (double wings)
f = flipy
F = flipx
b = flash/blink
y = ypos
e = extra priority bit (or at least externally detectable by mixer circuits)

offs +1
-------- --------
tttttttt tttttttt

t = sprite tile

offs +2
-------- --------
ppcccccx xxxxxxxx

c = colour palette
p = priority
x = xpos

offs +3
-------- -------- (unused)

in reality all the colour / priority (and extra priority) bits are externally detectable and can be used for
priority and mixing, the sprite palette in twocrude for example isn't in a single block (there is a gap for the tilemaps)
but the mixing circuits take care of this

ALTERNATE FORMAT (used by Mutant Fighter, Captain America)

offs +0
-------- --------
fFbyyyyy yyyyyyyy

f = flipy
F = flipx
b = flash/blink
y = ypos

offs +1
-------- --------
xxxxxxxx xxxxxxxx

x = xpos

offs +2
-------- --------
ssssSSSS pppccccc

s = size (height)
S = size (width)

offs +3
-------- --------
tttttttt tttttttt

t = sprite tile

todo: the priority callback for using pdrawgfx should really pack those 8 bits, and pass them instead of currently just
passing offs+2 which lacks the extra priority bit

*/

#include "emu.h"
#include "decospr.h"
#include "screen.h"

DECOSPR_COLOUR_CB_MEMBER(decospr_device::default_col_cb)
{
	return (col >> 9) & 0x1f;
}

DEFINE_DEVICE_TYPE(DECO_SPRITE, decospr_device, "decospr", "DECO 52 Sprite")

decospr_device::decospr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, DECO_SPRITE, tag, owner, clock),
		device_video_interface(mconfig, *this),
		m_gfxregion(0),
		m_is_bootleg(false),
		m_bootleg_type(0),
		m_x_offset(0),
		m_y_offset(0),
		m_flipallx(0),
		m_transpen(0),
		m_gfxdecode(*this, finder_base::DUMMY_TAG)
{
	// default color callback
	m_col_cb =  decospr_col_cb_delegate(FUNC(decospr_device::default_col_cb), this);
}

void decospr_device::device_start()
{
	m_pri_cb.bind_relative_to(*owner());
	m_col_cb.bind_relative_to(*owner());

	m_alt_format = 0;
	m_pixmask = 0xf;
	m_raw_shift = 4; // set to 8 on tattass / nslashers for the custom mixing (because they have 5bpp sprites, and shifting by 4 isn't good enough)

	m_flip_screen = false;
	save_item(NAME(m_flip_screen));
}

void decospr_device::device_reset()
{
	//printf("decospr_device::device_reset()\n");
}

void decospr_device::alloc_sprite_bitmap()
{
	screen().register_screen_bitmap(m_sprite_bitmap);
}

template<class _BitmapClass>
void decospr_device::draw_sprites_common(_BitmapClass &bitmap, const rectangle &cliprect, uint16_t* spriteram, int sizewords)
{
	//printf("cliprect %04x, %04x\n", cliprect.min_y, cliprect.max_y);

	if (m_sprite_bitmap.valid() && !m_pri_cb.isnull())
		fatalerror("m_sprite_bitmap && m_pri_cb is invalid\n");

	if (m_sprite_bitmap.valid())
		m_sprite_bitmap.fill(0, cliprect);


	int offs, end, incr;

	bool flipscreen = m_flip_screen;


	if (!m_pri_cb.isnull())
	{
		offs = sizewords-4;
		end = -4;
		incr = -4;
	}
	else
	{
		offs = 0;
		end = sizewords;
		incr = 4;
	}

	while (offs!=end)
	{
		int x, y, sprite, colour, multi, mult2, fx, fy, inc, flash, mult, h, w, pri;

		if (!m_alt_format)
		{
			sprite = spriteram[offs + 1];
			y = spriteram[offs];

			if (m_is_bootleg && (m_bootleg_type == 1))
			{
				flash = y & 0x0400;
			}
			else
			{
				flash = y & 0x1000;
			}

			w = y & 0x0800;


			if (!(flash && (screen().frame_number() & 1)))
			{
				x = spriteram[offs + 2];

				if (!m_sprite_bitmap.valid())
				{
					colour = m_col_cb(x);
				}
				else
				{
					colour = (x >> 9) & 0x7f;
					if (y&0x8000) colour |= 0x80; // fghthist uses this to mark priority
				}


				if (!m_pri_cb.isnull())
					pri = m_pri_cb(x);
				else
					pri = 0;

				fx = y & 0x2000;
				fy = y & 0x4000;

				int tempwidth = 0;

				if (m_is_bootleg && (m_bootleg_type==1))  // puzzlove
				{
					tempwidth = (y & 0x1000) >> 12;
					tempwidth |= (y & 0x0200) >> 8;
				}
				else
				{
					tempwidth |= (y & 0x0600) >> 9;
				}

				multi = (1 << (tempwidth)) - 1; /* 1x, 2x, 4x, 8x height */

				/* bootleg support (esd16.c) */
				if (flipscreen) x = ((x&0x1ff) - m_x_offset)&0x1ff;
				else x = ((x&0x1ff) + m_x_offset)&0x1ff;
				y = ((y&0x1ff) + m_y_offset)&0x1ff;


				if (cliprect.max_x>256)
				{
					x = x & 0x01ff;
					y = y & 0x01ff;
					if (x >= 320) x -= 512;
					if (y >= 256) y -= 512;
					y = 240 - y;
					x = 304 - x;
				}
				else
				{
					x = x & 0x01ff;
					y = y & 0x01ff;
					if (x >= 256) x -= 512;
					if (y >= 256) y -= 512;
					y = 240 - y;
					x = 240 - x;
				}


				//if (x <= 320)
				{
					if (!m_is_bootleg) // several of the clone / bootleg chips don't do this, see jumpkids
						sprite &= ~multi;

					if (fy)
						inc = -1;
					else
					{
						sprite += multi;
						inc = 1;
					}

					if (flipscreen)
					{
						y = 240 - y;
						if (fy) fy = 0; else fy = 1;
						mult = 16;
					}
					else
						mult = -16;

					if (flipscreen ^ m_flipallx)
					{
						if (cliprect.max_x>256)
							x = 304 - x;
						else
							x = 240 - x;

						if (fx) fx = 0; else fx = 1;
					}



					mult2 = multi + 1;

					while (multi >= 0)
					{
						int ypos;
						ypos = y + mult * multi;
						if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y)-16))
						{
							if(!m_sprite_bitmap.valid())
							{
								if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y)-16))
								{
									if (!m_pri_cb.isnull())
										m_gfxdecode->gfx(m_gfxregion)->prio_transpen(bitmap,cliprect,
											sprite - multi * inc,
											colour,
											fx,fy,
											x,ypos,
											screen().priority(),pri,m_transpen);
									else
										m_gfxdecode->gfx(m_gfxregion)->transpen(bitmap,cliprect,
											sprite - multi * inc,
											colour,
											fx,fy,
											x,ypos,
											m_transpen);
								}

								// double wing uses this flag
								if (w)
								{
									if (!m_pri_cb.isnull())
										m_gfxdecode->gfx(m_gfxregion)->prio_transpen(bitmap,cliprect,
												(sprite - multi * inc)-mult2,
												colour,
												fx,fy,
												!flipscreen ? x-16 : x+16,ypos,
												screen().priority(),pri,m_transpen);
									else
										m_gfxdecode->gfx(m_gfxregion)->transpen(bitmap,cliprect,
												(sprite - multi * inc)-mult2,
												colour,
												fx,fy,
												!flipscreen ? x-16 : x+16,ypos,
												m_transpen);
								}
							}
							else
							{
								// if we have a sprite bitmap draw raw data to it for manual mixing
								m_gfxdecode->gfx(m_gfxregion)->transpen_raw(m_sprite_bitmap,cliprect,
									sprite - multi * inc,
									colour<<m_raw_shift,
									fx,fy,
									x,ypos,
									m_transpen);
								if (w)
								{
									m_gfxdecode->gfx(m_gfxregion)->transpen_raw(m_sprite_bitmap,cliprect,
										(sprite - multi * inc)-mult2,
										colour<<m_raw_shift,
										fx,fy,
										!flipscreen ? x-16 : x+16,ypos,
										m_transpen);
								}

							}
						}

						multi--;
					}
				}
			}
		}
		else // m_alt_format
		{
			y = spriteram[offs+0];
			sprite = spriteram[offs+3] & 0xffff;


			if (!m_pri_cb.isnull())
				pri = m_pri_cb(spriteram[offs+2]&0x00ff);
			else
				pri = 0;

			x = spriteram[offs+1];

			if (!((y&0x2000) && (screen().frame_number() & 1)))
			{
				if (!m_sprite_bitmap.valid())
					colour = (spriteram[offs+2] >>0) & 0x1f;
				else
					colour = (spriteram[offs+2] >>0) & 0xff; // store all bits for manual mixing


				h = (spriteram[offs+2]&0xf000)>>12;
				w = (spriteram[offs+2]&0x0f00)>> 8;
				fx = !(spriteram[offs+0]&0x4000);
				fy = !(spriteram[offs+0]&0x8000);

				if (!flipscreen) {
					x = x & 0x01ff;
					y = y & 0x01ff;
					if (x>0x180) x=-(0x200 - x);
					if (y>0x180) y=-(0x200 - y);

					if (fx) { mult=-16; x+=16*w; } else { mult=16; x-=16; }
					if (fy) { mult2=-16; y+=16*h; } else { mult2=16; y-=16; }
				} else {
					if (fx) fx=0; else fx=1;
					if (fy) fy=0; else fy=1;

					x = x & 0x01ff;
					y = y & 0x01ff;
					if (x&0x100) x=-(0x100 - (x&0xff));
					if (y&0x100) y=-(0x100 - (y&0xff));
					x = 304 - x;
					y = 240 - y;
					if (x >= 432) x -= 512;
					if (y >= 384) y -= 512;
					if (fx) { mult=-16; x+=16; } else { mult=16; x-=16*w; }
					if (fy) { mult2=-16; y+=16; } else { mult2=16; y-=16*h; }
				}
				int ypos;

				for (int xx=0; xx<w; xx++)
				{
					for (int yy=0; yy<h; yy++)
					{
						if(!m_sprite_bitmap.valid())
						{
							if (!m_pri_cb.isnull())
							{
								ypos = y + mult2 * (h-yy);

								if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y)-16))
								{
									m_gfxdecode->gfx(m_gfxregion)->prio_transpen(bitmap,cliprect,
											sprite + yy + h * xx,
											colour,
											fx,fy,
												x + mult * (w-xx),ypos,
											screen().priority(),pri,m_transpen);
								}

								ypos -= 512; // wrap-around y

								if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y-16)))
								{
									m_gfxdecode->gfx(m_gfxregion)->prio_transpen(bitmap,cliprect,
											sprite + yy + h * xx,
											colour,
											fx,fy,
											x + mult * (w-xx),ypos,
											screen().priority(),pri,m_transpen);
								}

							}
							else
							{
								ypos = y + mult2 * (h-yy);

								if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y)-16))
								{
									m_gfxdecode->gfx(m_gfxregion)->transpen(bitmap,cliprect,
											sprite + yy + h * xx,
											colour,
											fx,fy,
											x + mult * (w-xx),ypos,
											m_transpen);
								}

								ypos -= 512; // wrap-around y

								if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y-16)))
								{
									m_gfxdecode->gfx(m_gfxregion)->transpen(bitmap,cliprect,
											sprite + yy + h * xx,
											colour,
											fx,fy,
											x + mult * (w-xx),ypos,
											m_transpen);
								}
							}
						}
						else
						{
							ypos = y + mult2 * (h-yy);

							if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y)-16))
							{
								m_gfxdecode->gfx(m_gfxregion)->transpen_raw(m_sprite_bitmap,cliprect,
										sprite + yy + h * xx,
										colour<<m_raw_shift,
										fx,fy,
										x + mult * (w-xx),ypos,
										m_transpen);
							}

							ypos -= 512; // wrap-around y

							if ((ypos<=cliprect.max_y) && (ypos>=(cliprect.min_y-16)))
							{
								m_gfxdecode->gfx(m_gfxregion)->transpen_raw(m_sprite_bitmap,cliprect,
										sprite + yy + h * xx,
										colour<<m_raw_shift,
										fx,fy,
										x + mult * (w-xx),ypos,
										m_transpen);
							}
						}
					}
				}
			}
		}

		offs+=incr;
	}
}

void decospr_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, uint16_t* spriteram, int sizewords)
{ draw_sprites_common(bitmap, cliprect, spriteram, sizewords); }

void decospr_device::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t* spriteram, int sizewords)
{ draw_sprites_common(bitmap, cliprect, spriteram, sizewords); }


// inefficient, we should be able to mix in a single pass by comparing the existing priority bitmap from the tilemaps
void decospr_device::inefficient_copy_sprite_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t pri, uint16_t priority_mask, uint16_t colbase, uint16_t palmask, uint8_t alpha)
{
	if (!m_sprite_bitmap.valid())
		fatalerror("decospr_device::inefficient_copy_sprite_bitmap with no m_sprite_bitmap\n");

	int y, x;
	const pen_t *paldata = m_gfxdecode->palette().pens();

	uint16_t* srcline;
	uint32_t* dstline;

	for (y=cliprect.min_y;y<=cliprect.max_y;y++)
	{
		srcline= &m_sprite_bitmap.pix16(y);
		dstline= &bitmap.pix32(y);

		if (alpha==0xff)
		{
			for (x=cliprect.min_x;x<=cliprect.max_x;x++)
			{
				uint16_t pix = srcline[x];

				if (pix&0xf)
				{
					if ((pix & priority_mask) ==pri )
					{
						dstline[x] = paldata[(pix&palmask) + colbase];
					}
				}
			}
		}
		else
		{
			for (x=cliprect.min_x;x<=cliprect.max_x;x++)
			{
				uint16_t pix = srcline[x];

				if (pix&m_pixmask)
				{
					if ((pix & priority_mask) ==pri )
					{
						uint32_t pal1 = paldata[(pix&palmask) + colbase];
						uint32_t pal2 = dstline[x];
						dstline[x] = alpha_blend_r32(pal2, pal1, alpha);
					}
				}
			}
		}
	}
}