📄 dec8.c
字号:
/***************************************************************************
Cobra Command:
Video hardware looks like early version of Bad Dudes, we appear to have
2 playfields and 1 text layer. Each playfield has 2 scroll registers and
4 control bytes:
Register 1: MSB set is reverse screen (playfield 1 only), always seems to be 2
Register 2: Unknown, seems to be always 0
Register 3: Unknown, 3 in foreground, 0 in background (so transparency setting?)
Register 4: Probably playfield shape, only 2 * 2 supported at moment (1)
Sprite hardware appears to be the same as Bad Dudes.
256 colours, palette generated by ram.
The Real Ghostbusters:
1 Deco VSC30 (M60348)
1 Deco HMC20 (M60232)
1 playfield, same as above, with rowscroll
1024 colours from 2 proms.
Sprite hardware close to above, there are some unused (unknown) bits per sprite.
Super Real Darwin:
1 playfield, x-scroll only
Closer to earlier Darwin 4078 board than above games.
Last Mission/Shackled:
Has 1 Deco VSC30 (M60348) (From readme file)
Has 1 Deco HMC20 (M60232) (From readme file)
1 playfield
Sprite hardware same as Karnov.
(Shackled) Palettes 8-15 for tiles seem to have priority over sprites.
Gondomania:
Has two large square surface mount chips: [ DRL 40, 8053, 8649a ]
Has 1 Deco VSC30 (M60348)
Has 1 Deco HMC20 (M60232)
Priority - all tiles with *pens* 8-15 appear over sprites with palettes 8-15.
Oscar:
Uses MXC-06 custom chip for sprites.
Uses BAC-06 custom chip for background.
I can't find what makes the fix chars...
Priority - tiles with palettes 8-15 have their *pens* 8-15 appearing over
sprites.
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
static unsigned char *palette_ram,*pf_video,*pf_dirty,*oscar_shared_mem;
static int scroll1[4],scroll2[4],pf1_attr[8],pf2_attr[8];
static struct osd_bitmap *pf1_bitmap,*pf2_bitmap;
unsigned char *dec8_row;
extern int ghost_prot;
static int blank_tile,shackled_priority;
/***************************************************************************
Convert the color PROMs into a more useable format.
Real Ghostbusters has two 1024x8 palette PROM.
I don't know the exact values of the resistors between the RAM and the
RGB output. I assumed these values (the same as Commando)
bit 7 -- 220 ohm resistor -- GREEN
-- 470 ohm resistor -- GREEN
-- 1 kohm resistor -- GREEN
-- 2.2kohm resistor -- GREEN
-- 220 ohm resistor -- RED
-- 470 ohm resistor -- RED
-- 1 kohm resistor -- RED
bit 0 -- 2.2kohm resistor -- RED
bit 7 -- unused
-- unused
-- unused
-- unused
-- 220 ohm resistor -- BLUE
-- 470 ohm resistor -- BLUE
-- 1 kohm resistor -- BLUE
bit 0 -- 2.2kohm resistor -- BLUE
***************************************************************************/
void ghostb_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
{
int i;
for (i = 0;i < Machine->drv->total_colors;i++)
{
int bit0,bit1,bit2,bit3;
bit0 = (color_prom[0] >> 0) & 0x01;
bit1 = (color_prom[0] >> 1) & 0x01;
bit2 = (color_prom[0] >> 2) & 0x01;
bit3 = (color_prom[0] >> 3) & 0x01;
*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
bit0 = (color_prom[0] >> 4) & 0x01;
bit1 = (color_prom[0] >> 5) & 0x01;
bit2 = (color_prom[0] >> 6) & 0x01;
bit3 = (color_prom[0] >> 7) & 0x01;
*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
bit0 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
bit2 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
bit3 = (color_prom[Machine->drv->total_colors] >> 3) & 0x01;
*(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
color_prom++;
}
}
void dec8_pf1_w(int offset, int data)
{
switch (offset)
{
case 0:
case 2:
case 4:
case 6:
pf1_attr[offset]=data;
}
}
void dec8_pf2_w(int offset, int data)
{
switch (offset)
{
case 0:
case 2:
case 4:
case 6:
pf2_attr[offset]=data;
}
}
void dec8_bac06_0_w(int offset, int data)
{
switch (offset) {
case 0:
case 2:
case 4:
case 6:
pf1_attr[offset]=data;
break;
case 0x10: /* Scroll registers */
case 0x11:
case 0x12:
case 0x13:
scroll1[offset-0x10]=data;
break;
}
}
void dec8_bac06_1_w(int offset, int data)
{
switch (offset) {
case 0:
case 2:
case 4:
case 6:
pf2_attr[offset]=data;
break;
case 0x10: /* Scroll registers */
case 0x11:
case 0x12:
case 0x13:
scroll2[offset-0x10]=data;
break;
}
}
void dec8_scroll1_w(int offset, int data)
{
scroll1[offset]=data;
}
void dec8_scroll2_w(int offset, int data)
{
scroll2[offset]=data;
}
void srdarwin_control_w(int offset, int data)
{
int bankaddress;
unsigned char *RAM = Machine->memory_region[0];
switch (offset) {
case 0: /* Top 3 bits - bank switch, bottom 4 - scroll MSB */
bankaddress = 0x10000 + (data >> 5) * 0x4000;
cpu_setbank(1,&RAM[bankaddress]);
scroll2[0]=data&0xf;
return;
case 1:
scroll2[1]=data;
return;
}
}
void lastmiss_control_w(int offset, int data)
{
int bankaddress;
unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];
/* Bottom 4 bits - bank switch, Bits 4 & 5 - Scroll MSBs */
bankaddress = 0x10000 + (data & 0x0f) * 0x4000;
cpu_setbank(1,&RAM[bankaddress]);
scroll2[0]=(data>>5)&1;
scroll2[2]=(data>>6)&1;
if (cpu_getpc()==0xfa51) cpu_reset(1); /* No way this can be right... */
if (cpu_getpc()==0xf9d2) cpu_reset(1); /* No way this can be right... */
}
void lastmiss_scrollx_w(int offset, int data)
{
scroll2[1]=data;
}
void lastmiss_scrolly_w(int offset, int data)
{
scroll2[3]=data;
}
void gondo_scroll_w(int offset, int data)
{
switch (offset) {
case 0x0: scroll2[1]=data; break;
case 0x8: scroll2[3]=data; break;
case 0x10: scroll2[0]=data;break;
}
}
/******************************************************************************/
/* 'Karnov' sprites, used by Gondomania, Last Mission, Shackled, Ghostbusters */
static void draw_sprites1(struct osd_bitmap *bitmap, int priority)
{
int offs,x,y,sprite,sprite2,colour,extra,fx,fy,inc;
for (offs = 0;offs < 0x800;offs += 8)
{
y=spriteram[offs+1]+(spriteram[offs]<<8);
if ((y&0x8000) == 0) continue;
fx=spriteram[offs+3];
if ((fx&0x1) == 0) continue;
extra=fx&0x10;
fy=fx&0x2;
fx=fx&0x4;
x = spriteram[offs+5]+(spriteram[offs+4]<<8);
colour = spriteram[offs+6] >> 4;
if (priority==1 && (colour&8)) continue;
if (priority==2 && !(colour&8)) continue;
sprite = spriteram[offs+7]+(spriteram[offs+6]<<8);
sprite &= 0x0fff;
if (extra) {y=y+16;sprite&=0xffe;}
x = x & 0x01ff;
y = y & 0x01ff;
x=(x+16)%0x200;
y=(y+16)%0x200;
x=256 - x;
y=256 - y;
/* Y Flip determines order of multi-sprite */
if (extra && fy) {
sprite2=sprite;
sprite++;
}
else sprite2=sprite+1;
drawgfx(bitmap,Machine->gfx[1],
sprite,
colour,fx,fy,x,y,
0,TRANSPARENCY_PEN,0);
/* 1 more sprite drawn underneath */
if (extra)
drawgfx(bitmap,Machine->gfx[1],
sprite2,
colour,fx,fy,x,y+16,
0,TRANSPARENCY_PEN,0);
}
}
/* 'Dec0' sprites, used by Cobra Command, Oscar */
static void draw_sprites2(struct osd_bitmap *bitmap, int priority)
{
int offs;
/* Sprites */
for (offs = 0;offs < 0x800;offs += 8)
{
int x,y,sprite,colour,multi,fx,fy,inc;
y =spriteram[offs+1]+(spriteram[offs]<<8);
if ((y&0x8000) == 0) continue;
x = spriteram[offs+5]+(spriteram[offs+4]<<8);
colour = ((x & 0xf000) >> 12);
if (priority==1 && (colour&8)) continue;
if (priority==2 && !(colour&8)) continue;
fx = y & 0x2000;
fy = y & 0x4000;
multi = (1 << ((y & 0x1800) >> 11)) - 1; /* 1x, 2x, 4x, 8x height */
/* multi = 0 1 3 7 */
sprite = spriteram[offs+3]+(spriteram[offs+2]<<8);
sprite &= 0x0fff;
x = x & 0x01ff;
y = y & 0x01ff;
if (x >= 256) x -= 512;
if (y >= 256) y -= 512;
x = 240 - x;
y = 240 - y;
sprite &= ~multi;
if (fy)
inc = -1;
else
{
sprite += multi;
inc = 1;
}
while (multi >= 0)
{
drawgfx(bitmap,Machine->gfx[1],
sprite - multi * inc,
colour,
fx,fy,
x,y - 16 * multi,
&Machine->drv->visible_area,TRANSPARENCY_PEN,0);
multi--;
}
}
}
/* Draw character tiles, each game has different colour masks */
static void draw_characters(struct osd_bitmap *bitmap, int mask, int shift)
{
int mx,my,tile,color,offs;
for (offs = 0x800 - 2;offs >= 0;offs -= 2) {
tile=videoram[offs+1]+((videoram[offs]&0xf)<<8);
if (!tile) continue;
color=(videoram[offs]&mask)>>shift;
mx = (offs/2) % 32;
my = (offs/2) / 32;
drawgfx(bitmap,Machine->gfx[0],
tile,color,0,0,8*mx,8*my,
&Machine->drv->visible_area,TRANSPARENCY_PEN,0);
}
}
/******************************************************************************/
void dec8_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
{
int my,mx,offs,color,tile;
int scrollx,scrolly;
if (palette_recalc())
memset(pf_dirty,1,0x800);
/* Playfield 2 - Foreground */
mx=-1; my=0;
for (offs = 0x000;offs < 0x400; offs += 2) {
mx++;
if (mx==16) {mx=0; my++;}
if (!pf_dirty[offs/2]) continue; else pf_dirty[offs/2]=0;
tile=pf_video[offs+1]+(pf_video[offs]<<8);
color = ((tile & 0xf000) >> 12);
tile=tile&0xfff;
drawgfx(pf2_bitmap,Machine->gfx[2],tile,
color, 0,0, 16*mx,16*my,
0,TRANSPARENCY_NONE,0);
}
mx=-1; my=0;
for (offs = 0x400;offs < 0x800; offs += 2) {
mx++;
if (mx==16) {mx=0; my++;}
if (!pf_dirty[offs/2]) continue; else pf_dirty[offs/2]=0;
tile=pf_video[offs+1]+(pf_video[offs]<<8);
color = ((tile & 0xf000) >> 12);
tile=tile&0xfff;
drawgfx(pf2_bitmap,Machine->gfx[2],tile,
color, 0,0, (16*mx)+256,16*my,
0,TRANSPARENCY_NONE,0);
}
/* Playfield 1 */
mx=-1; my=0;
for (offs = 0x800;offs < 0xc00; offs += 2) {
mx++;
if (mx==16) {mx=0; my++;}
if (!pf_dirty[offs/2]) continue; else pf_dirty[offs/2]=0;
tile=pf_video[offs+1]+(pf_video[offs]<<8);
color = ((tile & 0xf000) >> 12);
tile=tile&0xfff;
drawgfx(pf1_bitmap,Machine->gfx[3],tile,
color, 0,0, 16*mx,16*my,
0,TRANSPARENCY_NONE,0);
}
mx=-1; my=0;
for (offs = 0xc00;offs < 0x1000; offs += 2) {
mx++;
if (mx==16) {mx=0; my++;}
if (!pf_dirty[offs/2]) continue; else pf_dirty[offs/2]=0;
tile=pf_video[offs+1]+(pf_video[offs]<<8);
color = ((tile & 0xf000) >> 12);
tile=tile&0xfff;
drawgfx(pf1_bitmap,Machine->gfx[3],tile,
color, 0,0, (16*mx)+256,16*my,
0,TRANSPARENCY_NONE,0);
}
scrolly=-((scroll1[2]<<8)+scroll1[3]);
scrollx=-((scroll1[0]<<8)+scroll1[1]);
scrolly=-((scroll2[2]<<8)+scroll2[3]);
scrollx=-(((scroll2[0]&1)<<8)+scroll2[1]);
copyscrollbitmap(bitmap,pf2_bitmap,1,&scrollx,1,&scrolly,0,TRANSPARENCY_NONE,0);
/* Sprites */
draw_sprites2(bitmap,0);
/* Top layer */
draw_characters(bitmap,0x70,4);
}
void ghostb_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
{
int my,mx,offs,color,tile;
int scrollx,scrolly,fx,fy;
/* Playfield */
mx=-1; my=0;
for (offs = 0x000;offs < 0x400; offs += 2) {
mx++;
if (mx==16) {mx=0; my++;}
if (!pf_dirty[offs/2]) continue; else pf_dirty[offs/2]=0;
tile=pf_video[offs+1]+(pf_video[offs]<<8);
color = ((tile & 0xf000) >> 12);
tile=tile&0xfff;
drawgfx(pf2_bitmap,Machine->gfx[2],tile,
color, 0, 0, 16*mx,16*my,
0,TRANSPARENCY_NONE,0);
}
mx=-1; my=0;
for (offs = 0x400;offs < 0x800; offs += 2) {
mx++;
if (mx==16) {mx=0; my++;}
if (!pf_dirty[offs/2]) continue; else pf_dirty[offs/2]=0;
tile=pf_video[offs+1]+(pf_video[offs]<<8);
color = ((tile & 0xf000) >> 12);
tile=tile&0xfff;
drawgfx(pf2_bitmap,Machine->gfx[2],tile,
color, 0, 0, (16*mx)+256,16*my,
0,TRANSPARENCY_NONE,0);
}
/* Rowscroll */
if (pf2_attr[0]&0x4) {
int rscroll[256];
scrolly=-((scroll2[2]<<8)+scroll2[3]);
for (offs = 0;offs < 512;offs+=2)
rscroll[offs/2] = -( (dec8_row[offs]<<8) + dec8_row[offs+1] ) -((scroll2[0]<<8)+scroll2[1]);
copyscrollbitmap(bitmap,pf2_bitmap,256,rscroll,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
} else {
scrolly=-((scroll2[2]<<8)+scroll2[3]);
scrollx=-((scroll2[0]<<8)+scroll2[1]);
copyscrollbitmap(bitmap,pf2_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -