📄 dec0.c
字号:
/***************************************************************************
Dec0 Video emulation - Bryan McPhail, mish@tendril.force9.net
*********************************************************************
Sprite data: The unknown bits seem to be unused.
Byte 0:
Bit 0 : Y co-ord hi bit
Bit 1,2: ?
Bit 3,4 : Sprite height (1x, 2x, 4x, 8x)
Bit 5 - X flip
Bit 6 - Y flip
Bit 7 - Only display Sprite if set
Byte 1: Y-coords
Byte 2:
Bit 0,1,2,3: Hi bits of sprite number
Bit 4,5,6,7: (Probably unused MSB's of sprite)
Byte 3: Low bits of sprite number
Byte 4:
Bit 0 : X co-ords hi bit
Bit 1,2: ??
Bit 3: Sprite flash (sprite is displayed every other frame)
Bit 4,5,6,7: - Colour
Byte 5: X-coords
**********************************************************************
Palette data
0x000 - character palettes (Sprites on Midnight R)
0x200 - sprite palettes (Characters on Midnight R)
0x400 - tiles 1
0x600 - tiles 2
Bad Dudes, Robocop, Heavy Barrel, Hippodrome - 24 bit rgb
Sly Spy, Midnight Resistance - 12 bit rgb
Tile data
4 bit palette select, 12 bit tile select
**********************************************************************
Playfield 1 - 8*8 tiles
Playfield 2 - 16*16 tiles
Playfield 3 - 16*16 tiles
Playfield control registers:
bank 0:
0: mostly unknown (82, 86, 8e...)
bit 3 (0x4) set enables rowscroll (true for all games)
bit 4 (0x8) set _disables_ colscroll!??! (see Heavy Barrel pf3)
bit 8 (0x80) set in playfield 1 is reverse screen (set via dip-switch)
bit 8 (0x80) in other playfields unknown
2: unknown (00 in bg, 03 in fg+text - maybe controls pf transparency?)
4: unknown (always 00)
6: playfield shape: 00 = 4x1, 01 = 2x2, 02 = 1x4
bank 1:
0: horizontal scroll
2: vertical scroll
4: unknown (08 in Hippodrome, 05 in HB, 00 in the others) (colscroll style?)
6: Style of rowscroll (maybe only low 3 bits) (see below)
Rowscroll style - bank 1 register 6:
0: 256 scroll registers (Robocop)
1: 128?
2: 64?
3: 32 scroll registers (Heavy Barrel, Midres)
4: 16 scroll registers (Bad Dudes, Sly Spy)
5: 8? (Hippodrome)
6: 4 scroll registers (Heavy Barrel)
7: 2 scroll registers (Heavy Barrel, used on other games but registers kept at 0)
Priority:
Bit 0 set = Playfield 3 drawn over Playfield 2
~ = Playfield 2 drawn over Playfield 3
Bit 1 set = Sprites are drawn inbetween playfields
~ = Sprites are on top of playfields
Bit 2
Bit 3 set = ...
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#define TEXTRAM_SIZE 0x2000 /* Size of text layer */
#define TILERAM_SIZE 0x800 /* Size of background and foreground */
/* Video */
unsigned char *dec0_pf1_data,*dec0_pf2_data,*dec0_pf3_data;
static unsigned char *dec0_pf1_dirty,*dec0_pf3_dirty,*dec0_pf2_dirty;
static struct osd_bitmap *dec0_pf1_bitmap;
static int dec0_pf1_current_shape;
static struct osd_bitmap *dec0_pf2_bitmap;
static int dec0_pf2_current_shape;
static struct osd_bitmap *dec0_pf3_bitmap;
static int dec0_pf3_current_shape;
unsigned char *dec0_pf1_rowscroll,*dec0_pf2_rowscroll,*dec0_pf3_rowscroll;
unsigned char *dec0_pf1_colscroll,*dec0_pf2_colscroll,*dec0_pf3_colscroll;
static unsigned char dec0_pf1_control_0[8];
static unsigned char dec0_pf1_control_1[8];
static unsigned char dec0_pf2_control_0[8];
static unsigned char dec0_pf2_control_1[8];
static unsigned char dec0_pf3_control_0[8];
static unsigned char dec0_pf3_control_1[8];
static int dec0_pri;
/* Prototypes for this file */
void dec0_vh_stop (void);
/******************************************************************************/
static void update_24bitcol(int offset)
{
int r,g,b;
r = (READ_WORD(&paletteram[offset]) >> 0) & 0xff;
g = (READ_WORD(&paletteram[offset]) >> 8) & 0xff;
b = (READ_WORD(&paletteram_2[offset]) >> 0) & 0xff;
palette_change_color(offset / 2,r,g,b);
}
void dec0_paletteram_w_rg(int offset,int data)
{
COMBINE_WORD_MEM(&paletteram[offset],data);
update_24bitcol(offset);
}
void dec0_paletteram_w_b(int offset,int data)
{
COMBINE_WORD_MEM(&paletteram_2[offset],data);
update_24bitcol(offset);
}
/******************************************************************************/
/* pf23priority: 1 -> pf2 transparent, pf3 not transparent */
/* 0 -> pf2 not transparent, pf3 transparent */
static void dec0_update_palette(int pf23priority)
{
int offs;
int color,code,i;
int colmask[16];
int pal_base;
memset(palette_used_colors,PALETTE_COLOR_UNUSED,Machine->drv->total_colors * sizeof(unsigned char));
pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = 0; offs < TEXTRAM_SIZE;offs += 2)
{
code = READ_WORD(&dec0_pf1_data[offs]);
color = (code & 0xf000) >> 12;
code &= 0x0fff;
colmask[color] |= Machine->gfx[0]->pen_usage[code];
}
for (color = 0;color < 16;color++)
{
if (colmask[color] & (1 << 0))
palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = 0; offs < TILERAM_SIZE;offs += 2)
{
code = READ_WORD(&dec0_pf2_data[offs]);
color = (code & 0xf000) >> 12;
code &= 0x0fff;
colmask[color] |= Machine->gfx[1]->pen_usage[code];
}
for (color = 0;color < 16;color++)
{
if (colmask[color] & (1 << 0))
palette_used_colors[pal_base + 16 * color] = pf23priority ? PALETTE_COLOR_USED : PALETTE_COLOR_TRANSPARENT;
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = 0; offs < TILERAM_SIZE;offs += 2)
{
code = READ_WORD(&dec0_pf3_data[offs]);
color = (code & 0xf000) >> 12;
code &= 0x0fff;
colmask[color] |= Machine->gfx[2]->pen_usage[code];
}
for (color = 0;color < 16;color++)
{
if (colmask[color] & (1 << 0))
palette_used_colors[pal_base + 16 * color] = pf23priority ? PALETTE_COLOR_TRANSPARENT : PALETTE_COLOR_USED;
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
pal_base = Machine->drv->gfxdecodeinfo[3].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = 0;offs < 0x800;offs += 8)
{
int x,y,sprite,multi;
y = READ_WORD(&spriteram[offs]);
if ((y&0x8000) == 0) continue;
x = READ_WORD(&spriteram[offs+4]);
color = (x & 0xf000) >> 12;
multi = (1 << ((y & 0x1800) >> 11)) - 1; /* 1x, 2x, 4x, 8x height */
/* multi = 0 1 3 7 */
x = x & 0x01ff;
if (x >= 256) x -= 512;
x = 240 - x;
if (x>256) continue; /* Speedup + save colours */
sprite = READ_WORD (&spriteram[offs+2]) & 0x0fff;
sprite &= ~multi;
while (multi >= 0)
{
colmask[color] |= Machine->gfx[3]->pen_usage[sprite + multi];
multi--;
}
}
for (color = 0;color < 16;color++)
{
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
if (palette_recalc())
{
memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
memset(dec0_pf2_dirty,1,TILERAM_SIZE);
memset(dec0_pf3_dirty,1,TILERAM_SIZE);
}
}
/******************************************************************************/
static void dec0_drawsprites(struct osd_bitmap *bitmap,int pri_mask,int pri_val)
{
int offs;
static int flash_counter;
flash_counter++;
for (offs = 0;offs < 0x800;offs += 8)
{
int x,y,sprite,colour,multi,fx,fy,inc,flash;
y = READ_WORD(&spriteram[offs]);
if ((y&0x8000) == 0) continue;
x = READ_WORD(&spriteram[offs+4]);
colour = x >> 12;
if ((colour & pri_mask) != pri_val) continue;
flash=x&0x800;
if (flash && flash_counter%2) continue;
fx = y & 0x2000;
fy = y & 0x4000;
multi = (1 << ((y & 0x1800) >> 11)) - 1; /* 1x, 2x, 4x, 8x height */
/* multi = 0 1 3 7 */
sprite = READ_WORD (&spriteram[offs+2]) & 0x0fff;
x = x & 0x01ff;
y = y & 0x01ff;
if (x >= 256) x -= 512;
if (y >= 256) y -= 512;
x = 240 - x;
y = 240 - y;
if (x>256) continue; /* Speedup */
sprite &= ~multi;
if (fy)
inc = -1;
else
{
sprite += multi;
inc = 1;
}
while (multi >= 0)
{
drawgfx(bitmap,Machine->gfx[3],
sprite - multi * inc,
colour,
fx,fy,
x,y - 16 * multi,
&Machine->drv->visible_area,TRANSPARENCY_PEN,0);
multi--;
}
}
}
/******************************************************************************/
static void dec0_pf1_update(void)
{
int offs,mx,my,color,tile,quarter;
int offsetx[4],offsety[4];
switch (READ_WORD(&dec0_pf1_control_0[6]))
{
case 0: /* 4x1 */
offsetx[0] = 0;
offsetx[1] = 256;
offsetx[2] = 512;
offsetx[3] = 768;
offsety[0] = 0;
offsety[1] = 0;
offsety[2] = 0;
offsety[3] = 0;
if (dec0_pf1_current_shape != 0)
{
osd_free_bitmap(dec0_pf1_bitmap);
dec0_pf1_bitmap = osd_create_bitmap(1024,256);
dec0_pf1_current_shape = 0;
memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
}
break;
case 1: /* 2x2 */
offsetx[0] = 0;
offsetx[1] = 0;
offsetx[2] = 256;
offsetx[3] = 256;
offsety[0] = 0;
offsety[1] = 256;
offsety[2] = 0;
offsety[3] = 256;
if (dec0_pf1_current_shape != 1)
{
osd_free_bitmap(dec0_pf1_bitmap);
dec0_pf1_bitmap = osd_create_bitmap(512,512);
dec0_pf1_current_shape = 1;
memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
}
break;
case 2: /* 1x4 */
offsetx[0] = 0;
offsetx[1] = 0;
offsetx[2] = 0;
offsetx[3] = 0;
offsety[0] = 0;
offsety[1] = 256;
offsety[2] = 512;
offsety[3] = 768;
if (dec0_pf1_current_shape != 2)
{
osd_free_bitmap(dec0_pf1_bitmap);
dec0_pf1_bitmap = osd_create_bitmap(256,1024);
dec0_pf1_current_shape = 2;
memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -