📄 williams.c
字号:
/* 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 + -