コード例 #1
0
static void draw_vdp(mame_bitmap *bitmap, const rectangle *cliprect, int priority)
{
	int x, y;

	for (y = cliprect->min_y; y <= cliprect->max_y; y++)
	{
		UINT16 *src = BITMAP_ADDR16(tempbitmap, y, 0);
		UINT16 *dst = BITMAP_ADDR16(bitmap, y, 0);
		UINT8 *pri = BITMAP_ADDR8(priority_bitmap, y, 0);

		for (x = cliprect->min_x; x <= cliprect->max_x; x++)
		{
			UINT16 pix = src[x];
			if (pix != 0xffff)
			{
				dst[x] = pix;
				pri[x] |= priority;
			}
		}
	}
}
コード例 #2
0
ファイル: segas18.c プロジェクト: Paulodx/sdl-mame-wii
static void draw_vdp(const device_config *screen, bitmap_t *bitmap, const rectangle *cliprect, int priority)
{
	int x, y;
	bitmap_t *priority_bitmap = screen->machine->priority_bitmap;

	for (y = cliprect->min_y; y <= cliprect->max_y; y++)
	{
		UINT16 *src = BITMAP_ADDR16(tempbitmap, y, 0);
		UINT16 *dst = BITMAP_ADDR16(bitmap, y, 0);
		UINT8 *pri = BITMAP_ADDR8(priority_bitmap, y, 0);

		for (x = cliprect->min_x; x <= cliprect->max_x; x++)
		{
			UINT16 pix = src[x];
			if (pix != 0xffff)
			{
				dst[x] = pix;
				pri[x] |= priority;
			}
		}
	}
}
コード例 #3
0
ファイル: segas18.c プロジェクト: cdenix/psmame
static void draw_vdp(device_t *screen, bitmap_t *bitmap, const rectangle *cliprect, int priority)
{
	segas1x_state *state = screen->machine().driver_data<segas1x_state>();
	int x, y;
	bitmap_t *priority_bitmap = screen->machine().priority_bitmap;

	for (y = cliprect->min_y; y <= cliprect->max_y; y++)
	{
		UINT16 *src = BITMAP_ADDR16(state->m_tmp_bitmap, y, 0);
		UINT16 *dst = BITMAP_ADDR16(bitmap, y, 0);
		UINT8 *pri = BITMAP_ADDR8(priority_bitmap, y, 0);

		for (x = cliprect->min_x; x <= cliprect->max_x; x++)
		{
			UINT16 pix = src[x];
			if (pix != 0xffff)
			{
				dst[x] = pix;
				pri[x] |= priority;
			}
		}
	}
}
コード例 #4
0
ファイル: mcatadv.c プロジェクト: nitrologic/emu
static void draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect )
{
	UINT16 *source = spriteram_old;
	UINT16 *finish = source + (spriteram_size/2)/2;
	int global_x = mcatadv_vidregs[0]-0x184;
	int global_y = mcatadv_vidregs[1]-0x1f1;

	UINT16 *destline;
	UINT8 *priline;
	UINT8 *sprdata = memory_region ( machine, "gfx1" );

	int xstart, xend, xinc;
	int ystart, yend, yinc;

	if( vidregs_old[2] == 0x0001 ) /* Double Buffered */
	{
		source += (spriteram_size/2)/2;
		finish += (spriteram_size/2)/2;
	}
	else if( vidregs_old[2] ) /* I suppose it's possible that there is 4 banks, haven't seen it used though */
	{
		logerror("Spritebank != 0/1\n");
	}

	while ( source<finish )
	{
		int pen = (source[0]&0x3f00)>>8;
		int tileno = source[1]&0xffff;
		int pri = (source[0]&0xc000)>>14;
		int x = source[2]&0x3ff;
		int y = source[3]&0x3ff;
		int flipy = source[0] & 0x0040;
		int flipx = source[0] & 0x0080;

		int height = ((source[3]&0xf000)>>12)*16;
		int width = ((source[2]&0xf000)>>12)*16;
		int offset = tileno * 256;

		int drawxpos, drawypos;
		int xcnt,ycnt;
		int pix;

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

#if 0 // For Flipscreen/Cocktail
		if(mcatadv_vidregs[0]&0x8000)
		{
			flipx = !flipx;
		}
		if(mcatadv_vidregs[1]&0x8000)
		{
			flipy = !flipy;
		}
#endif

		if (source[3] != source[0]) // 'hack' don't draw sprites while its testing the ram!
		{
			if(!flipx) { xstart = 0;        xend = width;  xinc = 1; }
			else       { xstart = width-1;  xend = -1;     xinc = -1; }
			if(!flipy) { ystart = 0;        yend = height; yinc = 1; }
			else       { ystart = height-1; yend = -1;     yinc = -1; }

			for (ycnt = ystart; ycnt != yend; ycnt += yinc) {
				drawypos = y+ycnt-global_y;

				if ((drawypos >= cliprect->min_y) && (drawypos <= cliprect->max_y)) {
					destline = BITMAP_ADDR16(bitmap, drawypos, 0);
					priline = BITMAP_ADDR8(machine->priority_bitmap, drawypos, 0);

					for (xcnt = xstart; xcnt != xend; xcnt += xinc) {
						drawxpos = x+xcnt-global_x;

						if((priline[drawxpos] < pri)) {
							if (offset >= 0x500000*2) offset = 0;
							pix = sprdata[offset/2];

							if (offset & 1)  pix = pix >> 4;
							pix &= 0x0f;

							if ((drawxpos >= cliprect->min_x) && (drawxpos <= cliprect->max_x) && pix)
								destline[drawxpos] = (pix + (pen << 4));
						}
						offset++;
					}
				}
				else  {
					offset += width;
				}
			}
		}
コード例 #5
0
ファイル: system16.c プロジェクト: broftkd/historic-mame
static void draw_sprite(running_machine *machine,
	mame_bitmap *bitmap,
	const rectangle *cliprect,
	const UINT8 *addr, int pitch,
	const pen_t *paldata,
	int x0, int y0, int screen_width, int screen_height,
	int width, int height,
	int flipx, int flipy,
	int priority,
	int shadow,
	int shadow_pen, int eos )
{
	const pen_t *shadow_base = machine->remapped_colortable + machine->gfx[0]->color_base + (machine->drv->total_colors/2);
	const UINT8 *source;
	int full_shadow=shadow&SYS16_SPR_SHADOW;
	int partial_shadow=shadow&SYS16_SPR_PARTIAL_SHADOW;
	int shadow_mask=(machine->drv->total_colors/2)-1;
	int sx, x, xcount;
	int sy, y, ycount = 0;
	int dx,dy;
	UINT16 *dest;
	UINT8 *pri;
	unsigned pen, data;

	priority = 1<<priority;

	if( flipy ){
		dy = -1;
		y0 += screen_height-1;
	}
	else {
		dy = 1;
	}

	if( flipx ){
		dx = -1;
		x0 += screen_width-1;
	}
	else {
		dx = 1;
	}

	if (!eos)
	{
		sy = y0;
		for( y=height; y; y-- ){
			ycount += screen_height;
			while( ycount>=height ){
				if( sy>=cliprect->min_y && sy<=cliprect->max_y ){
					source = addr;
					dest = BITMAP_ADDR16(bitmap, sy, 0);
					pri = BITMAP_ADDR8(priority_bitmap, sy, 0);
					sx = x0;
					xcount = 0;
					for( x=width; x; x-=2 ){
						data = (unsigned)*source++; /* next 2 pixels */
						pen = data>>4;
						xcount += screen_width;
						while( xcount>=width )
						{
							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
								if(!(pri[sx]&priority)){
									if (full_shadow)
										dest[sx] = shadow_base[dest[sx]&shadow_mask];
									else if (partial_shadow && pen==shadow_pen)
										dest[sx] = shadow_base[dest[sx]&shadow_mask];
									else
										dest[sx] = paldata[pen];
								}
							}
							xcount -= width;
							sx+=dx;
						}
						pen = data&0xf;
						xcount += screen_width;
						while( xcount>=width )
						{
							if( pen && pen!=0xf && sx>=cliprect->min_x && sx<=cliprect->max_x ){
								if(!(pri[sx]&priority)){
									if (full_shadow)
										dest[sx] = shadow_base[dest[sx]&shadow_mask];
									else if (partial_shadow && pen==shadow_pen)
										dest[sx] = shadow_base[dest[sx]&shadow_mask];
									else
										dest[sx] = paldata[pen];
								}
							}
							xcount -= width;
							sx+=dx;
						}
					}
				}
				ycount -= height;
				sy+=dy;
			}
			addr += pitch;
		}
コード例 #6
0
ファイル: taito_f2.c プロジェクト: DarrenBranford/MAME4iOS
static void taito_f2_tc360_spritemixdraw( running_machine *machine, bitmap_t *dest_bmp, const rectangle *clip, const gfx_element *gfx,
		UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy, int scalex, int scaley )
{
	taitof2_state *state = machine->driver_data<taitof2_state>();
	int pal_base = gfx->color_base + gfx->color_granularity * (color % gfx->total_colors);
	const UINT8 *source_base = gfx_element_get_data(gfx, code % gfx->total_elements);
	bitmap_t *priority_bitmap = gfx->machine->priority_bitmap;
	int sprite_screen_height = (scaley * gfx->height + 0x8000) >> 16;
	int sprite_screen_width = (scalex * gfx->width + 0x8000) >> 16;

	if (!scalex || !scaley)
		return;

	if (sprite_screen_width && sprite_screen_height)
	{
		/* compute sprite increment per screen pixel */
		int dx = (gfx->width << 16) / sprite_screen_width;
		int dy = (gfx->height << 16) / sprite_screen_height;

		int ex = sx + sprite_screen_width;
		int ey = sy + sprite_screen_height;

		int x_index_base;
		int y_index;

		if (flipx)
		{
			x_index_base = (sprite_screen_width - 1) * dx;
			dx = -dx;
		}
		else
		{
			x_index_base = 0;
		}

		if (flipy)
		{
			y_index = (sprite_screen_height - 1) * dy;
			dy = -dy;
		}
		else
		{
			y_index = 0;
		}

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

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

			for (y = sy; y < ey; y++)
			{
				const UINT8 *source = source_base + (y_index >> 16) * gfx->line_modulo;
				UINT16 *dest = BITMAP_ADDR16(dest_bmp, y, 0);
				UINT8 *pri = BITMAP_ADDR8(priority_bitmap, y, 0);

				int x, x_index = x_index_base;
				for (x = sx; x < ex; x++)
				{
					int c = source[x_index >> 16];
					if (c && (pri[x] & 0x80) == 0)
					{
						UINT8 tilemap_priority = 0, sprite_priority = 0;

						// Get tilemap priority (0 - 0xf) for this destination pixel
						if (pri[x] & 0x10) tilemap_priority = state->tilepri[4];
						else if (pri[x] & 0x8) tilemap_priority = state->tilepri[3];
						else if (pri[x] & 0x4) tilemap_priority = state->tilepri[2];
						else if (pri[x] & 0x2) tilemap_priority = state->tilepri[1];
						else if (pri[x] & 0x1) tilemap_priority = state->tilepri[0];

						// Get sprite priority (0 - 0xf) for this source pixel
						if ((color & 0xc0) == 0xc0)
							sprite_priority = state->spritepri[3];
						else if ((color & 0xc0) == 0x80)
							sprite_priority = state->spritepri[2];
						else if ((color & 0xc0) == 0x40)
							sprite_priority = state->spritepri[1];
						else if ((color & 0xc0) == 0x00)
							sprite_priority = state->spritepri[0];

						// Blend mode 1 - Sprite under tilemap, use sprite palette with tilemap data
						if ((state->spriteblendmode & 0xc0) == 0xc0 && sprite_priority == (tilemap_priority - 1))
						{
							dest[x] = ((pal_base + c) & 0xfff0) | (dest[x] & 0xf);
						}
						// Blend mode 1 - Sprite over tilemap, use sprite data with tilemap palette
						else if ((state->spriteblendmode & 0xc0) == 0xc0 && sprite_priority == (tilemap_priority + 1))
						{
							if (dest[x] & 0xf)
								dest[x] = (dest[x] & 0xfff0) | ((pal_base + c) & 0xf);
							else
								dest[x] = pal_base + c;
						}
						// Blend mode 2 - Sprite under tilemap, use sprite data with tilemap palette
						else if ((state->spriteblendmode & 0xc0) == 0x80 && sprite_priority == (tilemap_priority - 1))
						{
							dest[x] = (dest[x] & 0xffef);
						}
						// Blend mode 2 - Sprite over tilemap, alternate sprite palette, confirmed in Pulirula level 2
						else if ((state->spriteblendmode & 0xc0) == 0x80 && sprite_priority == (tilemap_priority + 1))
						{
							dest[x] = ((pal_base + c) & 0xffef); // Pulirula level 2, Liquid Kids attract mode
						}
						// No blending
						else
						{
							if (sprite_priority > tilemap_priority) // Ninja Kids confirms tilemap takes priority in equal value case
								dest[x] = pal_base + c;
						}
						pri[x] |= 0x80;
					}

					x_index += dx;
				}

				y_index += dy;
			}
		}
コード例 #7
0
// utility function to render a clipped scanline vertically or horizontally
inline void k053250_t::pdraw_scanline32(bitmap_t *bitmap, const pen_t *palette, UINT8 *source,
									  const rectangle *cliprect, int linepos, int scroll, int zoom,
									  UINT32 clipmask, UINT32 wrapmask, UINT32 orientation, bitmap_t *priority, UINT8 pri)
{
// a sixteen-bit fixed point resolution should be adequate to our application
#define FIXPOINT_PRECISION		16
#define FIXPOINT_PRECISION_HALF	(1<<(FIXPOINT_PRECISION-1))

	int end_pixel, flip, dst_min, dst_max, dst_start, dst_length;

	UINT32 src_wrapmask;
	UINT8  *src_base;
	int src_fx, src_fdx;
	int pix_data, dst_offset;
	const pen_t *pal_base;
	UINT8  *pri_base;
	UINT32 *dst_base;
	int dst_adv;

	// flip X and flip Y also switch role when the X Y coordinates are swapped
	if (!(orientation & ORIENTATION_SWAP_XY))
	{
		flip = orientation & ORIENTATION_FLIP_X;
		dst_min = cliprect->min_x;
		dst_max = cliprect->max_x;
	}
	else
	{
		flip = orientation & ORIENTATION_FLIP_Y;
		dst_min = cliprect->min_y;
		dst_max = cliprect->max_y;
	}

	if (clipmask)
	{
		// reject scanlines that are outside of the target bitmap's right(bottom) clip boundary
		dst_start = -scroll;
		if (dst_start > dst_max) return;

		// calculate target length
		dst_length = clipmask + 1;
		if (zoom) dst_length = (dst_length << 6) / zoom;

		// reject scanlines that are outside of the target bitmap's left(top) clip boundary
		end_pixel = dst_start + dst_length - 1;
		if (end_pixel < dst_min) return;

		// clip scanline tail
		if ((end_pixel -= dst_max) > 0) dst_length -= end_pixel;

		// reject zero-length scanlines
		if (dst_length <= 0) return;

		// calculate zoom factor
		src_fdx = zoom << (FIXPOINT_PRECISION-6);

		// clip scanline head
		end_pixel = dst_min;
		if ((end_pixel -= dst_start) > 0)
		{
			// chop scanline to the correct length and move target start location to the left(top) clip boundary
			dst_length -= end_pixel;
			dst_start = dst_min;

			// and skip the source for the left(top) clip region
			src_fx = end_pixel * src_fdx + FIXPOINT_PRECISION_HALF;
		}
		else
			// the point five bias is to ensure even distribution of stretched or shrinked pixels
			src_fx = FIXPOINT_PRECISION_HALF;

		// adjust flipped source
		if (flip)
		{
			// start from the target's clipped end if the scanline is flipped
			dst_start = dst_max + dst_min - dst_start - (dst_length-1);

			// and move source start location to the opposite end
			src_fx += (dst_length-1) * src_fdx - 1;
			src_fdx = -src_fdx;
		}
	}
	else
	{
		// draw wrapped scanline at virtual bitmap boundary when source clipping is off
		dst_start = dst_min;
		dst_length = dst_max - dst_min + 1;	// target scanline spans the entire visible area
		src_fdx = zoom << (FIXPOINT_PRECISION-6);

		// pre-advance source for the clipped region
		if (!flip)
			src_fx = (scroll + dst_min) * src_fdx + FIXPOINT_PRECISION_HALF;
		else
		{
			src_fx = (scroll + dst_max) * src_fdx + FIXPOINT_PRECISION_HALF-1;
			src_fdx = -src_fdx;
		}
	}

	if (!(orientation & ORIENTATION_SWAP_XY))
	{
		// calculate target increment for horizontal scanlines which is exactly one
		dst_adv = 1;
		dst_offset = dst_length;
		pri_base = BITMAP_ADDR8(priority, linepos, dst_start + dst_offset);
		dst_base = BITMAP_ADDR32(bitmap, linepos, dst_start + dst_length);
	}
	else
	{
		// calculate target increment for vertical scanlines which is the bitmap's pitch value
		dst_adv = bitmap->rowpixels;
		dst_offset= dst_length * dst_adv;
		pri_base = BITMAP_ADDR8(priority, dst_start, linepos + dst_offset);
		dst_base = BITMAP_ADDR32(bitmap, dst_start, linepos + dst_offset);
	}

	// generalized
	src_base = source;

	// there is no need to wrap source offsets along with source clipping
	// so we set all bits of the wrapmask to one
	src_wrapmask = (clipmask) ? ~0 : wrapmask;

	pal_base = palette;
	dst_offset = -dst_offset; // negate target offset in order to terminated draw loop at zero condition

	if (pri)
	{
		// draw scanline and update priority bitmap
		do
		{
			pix_data = src_base[(src_fx>>FIXPOINT_PRECISION) & src_wrapmask];
			src_fx += src_fdx;

			if (pix_data)
			{
				pix_data = pal_base[pix_data];
				pri_base[dst_offset] = pri;
				dst_base[dst_offset] = pix_data;
			}
		}
		while (dst_offset += dst_adv);
	}
	else
	{
		// draw scanline but do not update priority bitmap
		do
		{
コード例 #8
0
void deco_bac06_device::custom_tilemap_draw(running_machine &machine,
        bitmap_t *bitmap,
        const rectangle *cliprect,
        tilemap_t *tilemap_ptr,
        const UINT16 *rowscroll_ptr,
        const UINT16 *colscroll_ptr,
        const UINT16 *control0,
        const UINT16 *control1,
        int flags,
        UINT16 penmask,
        UINT16 pencondition,
        UINT16 colprimask,
        UINT16 colpricondition
                                           )
{
    const bitmap_t *src_bitmap = tilemap_get_pixmap(tilemap_ptr);
    const bitmap_t *flags_bitmap = tilemap_get_flagsmap(tilemap_ptr);
    int x, y, p, colpri;
    int column_offset=0, src_x=0, src_y=0;
    UINT32 scrollx = 0;
    UINT32 scrolly = 0;

    if (control1)
    {
        scrollx = control1[0];
        scrolly = control1[1];
    }

    int width_mask;
    int height_mask;
    int row_scroll_enabled = 0;
    int col_scroll_enabled = 0;

    if (control0)
    {
        row_scroll_enabled = (rowscroll_ptr && (control0[0]&0x4));
        col_scroll_enabled = (colscroll_ptr && (control0[0]&0x8));
    }

    if (!src_bitmap)
        return;

    width_mask = src_bitmap->width - 1;
    height_mask = src_bitmap->height - 1;

    /* Column scroll & row scroll may per applied per pixel, there are
    shift registers for each which control the granularity of the row/col
    offset (down to per line level for row, and per 8 lines for column).

    Nb:  The row & col selectors are _not_ affected by the shape of the
    playfield (ie, 256*1024, 512*512 or 1024*256).  So even if the tilemap
    width is only 256, 'src_x' should not wrap at 256 in the code below (to
    do so would mean the top half of row RAM would never be accessed which
    is incorrect).

    Nb2:  Real hardware exhibits a strange bug with column scroll on 'mode 2'
    (256*1024) - the first column has a strange additional offset, but
    curiously the first 'wrap' (at scroll offset 256) does not have this offset,
    it is displayed as expected.  The bug is confimed to only affect this mode,
    the other two modes work as expected.  This bug is not emulated, as it
    doesn't affect any games.
    */

    if (flip_screen_get(machine))
        src_y = (src_bitmap->height - 256) - scrolly;
    else
        src_y = scrolly;

    for (y=0; y<=cliprect->max_y; y++) {
        if (row_scroll_enabled)
            src_x=scrollx + rowscroll_ptr[(src_y >> (control1[3]&0xf))&(0x1ff>>(control1[3]&0xf))];
        else
            src_x=scrollx;

        if (flip_screen_get(machine))
            src_x=(src_bitmap->width - 256) - src_x;

        for (x=0; x<=cliprect->max_x; x++) {
            if (col_scroll_enabled)
                column_offset=colscroll_ptr[((src_x >> 3) >> (control1[2]&0xf))&(0x3f>>(control1[2]&0xf))];

            p = *BITMAP_ADDR16(src_bitmap, (src_y + column_offset)&height_mask, src_x&width_mask);
            colpri =  *BITMAP_ADDR8(flags_bitmap, (src_y + column_offset)&height_mask, src_x&width_mask)&0xf;

            src_x++;
            if ((flags&TILEMAP_DRAW_OPAQUE) || (p&m_bppmask))
            {


                if ((p&penmask)==pencondition)
                    if((colpri&colprimask)==colpricondition)
                        *BITMAP_ADDR16(bitmap, y, x) = p+(colpri&m_gfxcolmask)*m_bppmult;
            }
        }
        src_y++;
    }