summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/jalblend.c
blob: 4dac6cc5f856708abbddb3af39a181a29fe7bc5d (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                                             
                

                     

                                                        







                                                     
                                                         



                                                                                
                                                                                                                     










                                                          






                              
                                    





                                                      
                                                          
 
























                                                  

 
                                                                                       
                                                                                                                         
                                                                              
 

                                    
                                                                                                         

                       

                           
                
         
                                                                                                                                
                                                                                                            
                                                                                                 

                                                          
 

                                      
 

                                                        
 


                                       
 


                                      
 



























                                                                  
 




                                                                                
                                 
                                                                                                     


















                                                                                                                    
                                         
                                                        
                                 
                         
 





                                                                                
                                                                                                     


                                                                                     
                                         

                                                                           
                                                 





                                                                                                                    
                                                         

                                                                                                           
                                                         
                                                 
                                                                
                                         
                                                        




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

    Jaleco color blend emulation

****************************************************************************

    This implements the behaviour of color blending/alpha hardware
    found in a small set of machines from the late 80's.

    Thus far, Psychic 5, Argus, and Valtric are presumed to use it.

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

#include "emu.h"
#include "jalblend.h"


/* each palette entry contains a fourth 'alpha' value */
static UINT8 *jal_blend_table;


static void jal_blend_reset(running_machine &machine)
{
	memset(jal_blend_table, 0, 0xc00);
}

void jal_blend_init(running_machine &machine, int enable)
{
	if (enable)
	{
		jal_blend_table = auto_alloc_array_clear(machine, UINT8, 0xc00);
		machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(FUNC(jal_blend_reset), &machine));
	}
	else
	{
		jal_blend_table = NULL;
	}
}

void jal_blend_set(int color, UINT8 val)
{
	if (jal_blend_table) jal_blend_table[color] = val;
}

/*
 * 'Alpha' Format
 * ------------------
 *
 * Bytes     | Use
 * -76543210-+----------------
 *  ----x--- | blend enable flag (?)
 *  -----x-- | red add/subtract
 *  ------x- | green add/subtract
 *  -------x | blue add/subtract
 */

/* basically an add/subtract function with clamping */
rgb_t jal_blend_func(rgb_t dest, rgb_t addMe, UINT8 alpha)
{
	int r, g, b;
	int ir, ig, ib;

	r = (int)RGB_RED  (dest);
	g = (int)RGB_GREEN(dest);
	b = (int)RGB_BLUE (dest);

	ir = (int)RGB_RED  (addMe);
	ig = (int)RGB_GREEN(addMe);
	ib = (int)RGB_BLUE (addMe);

	if (alpha & 4)
		{ r -= ir; if (r < 0) r = 0; }
	else
		{ r += ir; if (r > 255) r = 255; }
	if (alpha & 2)
		{ g -= ig; if (g < 0) g = 0; }
	else
		{ g += ig; if (g > 255) g = 255; }
	if (alpha & 1)
		{ b -= ib; if (b < 0) b = 0; }
	else
		{ b += ib; if (b > 255) b = 255; }

	return MAKE_RGB(r,g,b);
}

void jal_blend_drawgfx(bitmap_t *dest_bmp,const rectangle *clip,const gfx_element *gfx,
							UINT32 code,UINT32 color,int flipx,int flipy,int offsx,int offsy,
							int transparent_color)
{
	if (jal_blend_table == NULL)
	{
		drawgfx_transpen(dest_bmp,clip,gfx,code,color,flipx,flipy,offsx,offsy,transparent_color);
		return;
	}

	/* Start drawing */
	if (gfx)
	{
		const pen_t *pal = &gfx->machine().pens[gfx->color_base + gfx->color_granularity * (color % gfx->total_colors)];
		const UINT8 *alpha = &jal_blend_table[gfx->color_granularity * (color % gfx->total_colors)];
		const UINT8 *source_base = gfx_element_get_data(gfx, code % gfx->total_elements);
		int x_index_base, y_index, sx, sy, ex, ey;
		int xinc, yinc;

		xinc = flipx ? -1 : 1;
		yinc = flipy ? -1 : 1;

		x_index_base = flipx ? gfx->width-1 : 0;
		y_index = flipy ? gfx->height-1 : 0;

		/* start coordinates */
		sx = offsx;
		sy = offsy;

		/* end coordinates */
		ex = sx + gfx->width;
		ey = sy + gfx->height;

		if (clip)
		{
			if (sx < clip->min_x)
			{ /* clip left */
				int pixels = clip->min_x-sx;
				sx += pixels;
				x_index_base += xinc*pixels;
			}
			if (sy < clip->min_y)
			{ /* clip top */
				int pixels = clip->min_y-sy;
				sy += pixels;
				y_index += yinc*pixels;
			}
			/* NS 980211 - fixed incorrect clipping */
			if (ex > clip->max_x+1)
			{ /* clip right */
				ex = clip->max_x+1;
			}
			if (ey > clip->max_y+1)
			{ /* clip bottom */
				ey = clip->max_y+1;
			}
		}

		if (ex > sx)
		{ /* skip if inner loop doesn't draw anything */
			int x, y;

			/* 32-bit destination bitmap */
			if (dest_bmp->bpp == 32)
			{
				/* taken from case 7: TRANSPARENCY_ALPHARANGE */
				for (y = sy; y < ey; y++)
				{
					const UINT8 *source = source_base + y_index*gfx->line_modulo;
					UINT32 *dest = BITMAP_ADDR32(dest_bmp, y, 0);
					int x_index = x_index_base;
					for (x = sx; x < ex; x++)
					{
						int c = source[x_index];
						if (c != transparent_color)
						{
							if (alpha[c] & 8)
							{
								/* Comp with clamp */
								dest[x] = jal_blend_func(dest[x], pal[c], alpha[c]);
							}
							else
							{
								/* Skip the costly alpha step altogether */
								dest[x] = pal[c];
							}
						}
						x_index += xinc;
					}
					y_index += yinc;
				}
			}

			/* 16-bit destination bitmap */
			else
			{
				/* taken from case 7: TRANSPARENCY_ALPHARANGE */
				for (y = sy; y < ey; y++)
				{
					const UINT8 *source = source_base + y_index*gfx->line_modulo;
					UINT16 *dest = BITMAP_ADDR16(dest_bmp, y, 0);
					int x_index = x_index_base;
					for (x = sx; x < ex; x++)
					{
						int c = source[x_index];
						if (c != transparent_color)
						{
							if (alpha[c] & 8)
							{
								/* Comp with clamp */
								dest[x] = jal_blend_func(dest[x], pal[c], alpha[c]);
							}
							else
							{
								/* Skip the costly alpha step altogether */
								dest[x] = pal[c];
							}
						}
						x_index += xinc;
					}
					y_index += yinc;
				}
			}
		}
	}
}