⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 williams.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* swap halves of the keep mask and the solid color */
		keepmask = ((keepmask & 0xf0) >> 4) | ((keepmask & 0x0f) << 4);
		blitter_solid = ((blitter_solid & 0xf0) >> 4) | ((blitter_solid & 0x0f) << 4);

		/* loop over the height */
		for (i = 0; i < h; i++)
		{
			int pixdata;

			source = sstart & 0xffff;
			dest = dstart & 0xffff;

			/* left edge case */
			pixdata = cpu_readmem16 (source);
			(*blitter_w) (dest, (pixdata >> 4) & 0x0f, keepmask | 0xf0);

			source = (source + sxadv) & 0xffff;
			dest   = (dest + dxadv) & 0xffff;

			/* loop over the width */
			for (j = w-1; j > 0; j--)
			{
				pixdata = (pixdata << 8) | cpu_readmem16 (source);
				(*blitter_w) (dest, (pixdata >> 4) & 0xff, keepmask);

				source = (source + sxadv) & 0xffff;
				dest   = (dest + dxadv) & 0xffff;
			}

			/* right edge case */
			(*blitter_w) (dest, (pixdata << 4) & 0xf0, keepmask | 0x0f);

			sstart += syadv;
			dstart += dyadv;
		}
	}
}


/*
 *  Default blitting routines
 */

static void williams_transparent_blitter_w (int offset, int data, int keepmask)
{
	if (data)
	{
		int pix = williams_blitter_dest_r (offset);

		if (!(data & 0xf0)) keepmask |= 0xf0;
		if (!(data & 0x0f)) keepmask |= 0x0f;

		pix = (pix & keepmask) | (data & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}

static void williams_transparent_solid_blitter_w (int offset, int data, int keepmask)
{
	if (data)
	{
		int pix = williams_blitter_dest_r (offset);

		if (!(data & 0xf0)) keepmask |= 0xf0;
		if (!(data & 0x0f)) keepmask |= 0x0f;

		pix = (pix & keepmask) | (blitter_solid & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}

static void williams_opaque_blitter_w (int offset, int data, int keepmask)
{
	int pix = williams_blitter_dest_r (offset);
	pix = (pix & keepmask) | (data & ~keepmask);
	williams_blitter_dest_w (offset, pix);
}

static void williams_opaque_solid_blitter_w (int offset, int data, int keepmask)
{
	int pix = williams_blitter_dest_r (offset);
	pix = (pix & keepmask) | (blitter_solid & ~keepmask);
	williams_blitter_dest_w (offset, pix);
}


/*
 *  Remapping blitting routines; used by Blaster, maybe others
 */

static void remap_transparent_blitter_w (int offset, int data, int keepmask)
{
	data = williams_remap[data & 0xff];
	if (data)
	{
		int pix = williams_blitter_dest_r (offset);

		if (!(data & 0xf0)) keepmask |= 0xf0;
		if (!(data & 0x0f)) keepmask |= 0x0f;

		pix = (pix & keepmask) | (data & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}

static void remap_transparent_solid_blitter_w (int offset, int data, int keepmask)
{
	data = williams_remap[data & 0xff];
	if (data)
	{
		int pix = williams_blitter_dest_r (offset);

		if (!(data & 0xf0)) keepmask |= 0xf0;
		if (!(data & 0x0f)) keepmask |= 0x0f;

		pix = (pix & keepmask) | (blitter_solid & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}

static void remap_opaque_blitter_w (int offset, int data, int keepmask)
{
	int pix = williams_blitter_dest_r (offset);
	data = williams_remap[data & 0xff];
	pix = (pix & keepmask) | (data & ~keepmask);
	williams_blitter_dest_w (offset, pix);
}



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

	Utility functions to put 2 Pixels in the real bitmap

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

static void put_pix_normal (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int x = (offset / 256) * 2, y = offset % 256;
	unsigned char *dest = &williams_bitmap->line[y][x];
	*dest++ = p1;
	*dest = p2;
}

static void put_pix_fx (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int x = (williams_bitmap->width-2) - (offset / 256) * 2, y = offset % 256;
	unsigned char *dest = &williams_bitmap->line[y][x];
	*dest++ = p2;
	*dest = p1;
}

static void put_pix_fy (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int x = (offset / 256) * 2, y = (williams_bitmap->height-1) - (offset % 256);
	unsigned char *dest = &williams_bitmap->line[y][x];
	*dest++ = p1;
	*dest = p2;
}

static void put_pix_fx_fy (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int x = (williams_bitmap->width-2) - (offset / 256) * 2, y = (williams_bitmap->height-1) - (offset % 256);
	unsigned char *dest = &williams_bitmap->line[y][x];
	*dest++ = p2;
	*dest = p1;
}

static void put_pix_swap (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int y = (offset / 256) * 2, x = offset % 256;
	williams_bitmap->line[y][x] = p1;
	williams_bitmap->line[y+1][x] = p2;
}

static void put_pix_swap_fx (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int y = (offset / 256) * 2, x = (williams_bitmap->width-1) - offset % 256;
	williams_bitmap->line[y][x] = p1;
	williams_bitmap->line[y+1][x] = p2;
}

static void put_pix_swap_fy (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int y = (williams_bitmap->height-2) - (offset / 256) * 2, x = offset % 256;
	williams_bitmap->line[y][x] = p2;
	williams_bitmap->line[y+1][x] = p1;
}

static void put_pix_swap_fx_fy (int offset, int pix)
{
	int p1 = Machine->pens[pix >> 4], p2 = Machine->pens[pix & 0x0f];
	int y = (williams_bitmap->height-2) - (offset / 256) * 2, x = (williams_bitmap->width-1) - offset % 256;
	williams_bitmap->line[y][x] = p2;
	williams_bitmap->line[y+1][x] = p1;
}



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

	Defender-specific routines

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

/*
 * Defender video ram Write
 * Same as the others but Write in RAM[]
 */

void defender_videoram_w (int offset, int data)
{
	/* Write to the real video RAM */
	videoram[offset] = data;

	/* Put the pixels in our bitmap */
	(*put_pix) (offset, data);
}



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

	Sinistar-specific routines

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

int sinistar_vh_start (void)
{
	int result = williams_vh_start ();

	/* Sinistar uses special blitters with a clipping circuit */
	transparent_blitter_w = sinistar_transparent_blitter_w;
	transparent_solid_blitter_w = sinistar_transparent_solid_blitter_w;
	opaque_blitter_w = sinistar_opaque_blitter_w;
	opaque_solid_blitter_w = sinistar_opaque_solid_blitter_w;

	return result;
}


/*
 *  Sinistar blitting routines -- same as above, but also perform clipping
 */

static void sinistar_transparent_blitter_w (int offset, int data, int keepmask)
{
	if (data && (!sinistar_clip || offset < 0x7400))
	{
		int pix = williams_blitter_dest_r (offset);

		if (!(data & 0xf0)) keepmask |= 0xf0;
		if (!(data & 0x0f)) keepmask |= 0x0f;

		pix = (pix & keepmask) | (data & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}

static void sinistar_transparent_solid_blitter_w (int offset, int data, int keepmask)
{
	if (data && (!sinistar_clip || offset < 0x7400))
	{
		int pix = williams_blitter_dest_r (offset);

		if (!(data & 0xf0)) keepmask |= 0xf0;
		if (!(data & 0x0f)) keepmask |= 0x0f;

		pix = (pix & keepmask) | (blitter_solid & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}

static void sinistar_opaque_blitter_w (int offset, int data, int keepmask)
{
	if (!sinistar_clip || offset < 0x7400)
	{
		int pix = williams_blitter_dest_r (offset);
		pix = (pix & keepmask) | (data & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}

static void sinistar_opaque_solid_blitter_w (int offset, int data, int keepmask)
{
	if (!sinistar_clip || offset < 0x7400)
	{
		int pix = williams_blitter_dest_r (offset);
		pix = (pix & keepmask) | (blitter_solid & ~keepmask);
		williams_blitter_dest_w (offset, pix);
	}
}



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

	Blaster-specific routines

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

/*
 *  Create the palette
 */

void blaster_vh_convert_color_prom (unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
{
	/* Expand the lookup table so that we do one lookup per byte */
	williams_remap_lookup = malloc (256 * 256);
	if (williams_remap_lookup)
	{
		int i;

		for (i = 0; i < 256; i++)
		{
			const unsigned char *table = color_prom + (i & 0x7f) * 16;
			int j;
			for (j = 0; j < 256; j++)
				williams_remap_lookup[i * 256 + j] = (table[j >> 4] << 4) | table[j & 0x0f];
		}
	}
}


/*
 *  Blaster-specific screen refresh; handles the zero color palette change
 */

void blaster_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
{
	int i, j;
	int back_color;
	int pen0 = palette_transparent_pen;
	int back_pen;
	int first = -1;

	/* Recalculate palette */
	for (j = 0; j < 0x100; j++)
	{
		paletteram_BBGGGRRR_w(j + 16,blaster_color_zero_table[j] ^ 0xff);
	}


	if (palette_recalc ())
	{
		for (i = 0; i < 0x9800; i++)
			williams_videoram_w (i, williams_videoram[i]);
	}

	/* Copy williams_bitmap in bitmap */
	williams_vh_screenrefresh(bitmap,full_refresh);

	/* The color 0 of the palette can change at each video line */
	/* Since we cannot do that on a PC, we do that in a copy of the bitmap */
	/* This cannot be done in williams_bitmap because we have to keep the original bitmap intact */
	if ((*blaster_video_bits & 0x01) != 0)
	{
		back_color = 0;

		for (j = 0; j < 0x100; j++)
		{
			if ((blaster_color_zero_flags[j] & 0x01) != 0)
			{
				if ((blaster_color_zero_table[j] ^ 0xff) == 0)
					back_color = 0;
				else back_color = 16 + j;
			}

			/* Update the dirty marking */
			if (back_color == 0)
			{
				continue;
			}
			if (first == -1) first = j;

			/* change all 0-colored pixels on this line */
			back_pen = Machine->pens[back_color];
			for (i = 0; i < Machine->drv->screen_width - 2; i++)
				if (bitmap->line[j][i] == pen0)
					bitmap->line[j][i] = back_pen;
		}
	}
}


/*
 *  Blaster-specific video flags handler
 */

void blaster_video_bits_w (int offset, int data)
{
	*blaster_video_bits = data;
	blaster_erase_screen = data & 0x02;
}

int blaster_vh_start(void)
{
	int i;


	/* mark color 0 as transparent. We will draw the rainbow background behind it. */
	palette_used_colors[0] = PALETTE_COLOR_TRANSPARENT;
	for (i = 0;i < 256;i++)
	{
		/* mark as used only the colors used for the visible background lines */
		if (i < Machine->drv->visible_area.min_y ||
				i > Machine->drv->visible_area.max_y)
			palette_used_colors[16 + i] = PALETTE_COLOR_UNUSED;

		/* TODO: this leaves us with a total of 255+1 colors used, which is just */
		/* a bit too much for the palette system to handle them efficiently. */
		/* As a quick workaround, I set the top three lines to be always black. */
		/* To do it correctly, vh_screenrefresh() should group the background */
		/* lines of the same color and mark the others as COLOR_UNUSED. */
		/* The background is very redundant so this can be done easily. */
		palette_used_colors[16 + Machine->drv->visible_area.min_y] = PALETTE_COLOR_TRANSPARENT;
		palette_used_colors[16 + 1+Machine->drv->visible_area.min_y] = PALETTE_COLOR_TRANSPARENT;
		palette_used_colors[16 + 2+Machine->drv->visible_area.min_y] = PALETTE_COLOR_TRANSPARENT;
	}

	return williams_vh_start_sc2();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -