📄 copia de cps1.c
字号:
Start the video hardware emulation.
***************************************************************************/
int cps1_vh_start(void)
{
int i;
if (cps1_gfx_start())
{
return -1;
}
if (Machine->orientation & ORIENTATION_SWAP_XY)
{
cps1_scroll2_bitmap=osd_new_bitmap(CPS1_SCROLL2_HEIGHT*16,
CPS1_SCROLL2_WIDTH*16, Machine->scrbitmap->depth );
}
else
{
cps1_scroll2_bitmap=osd_new_bitmap(CPS1_SCROLL2_WIDTH*16,
CPS1_SCROLL2_HEIGHT*16, Machine->scrbitmap->depth );
}
if (!cps1_scroll2_bitmap)
{
return -1;
}
cps1_scroll2_old=malloc(cps1_scroll2_size);
if (!cps1_scroll2_old)
{
return -1;
}
memset(cps1_scroll2_old, 0xff, cps1_scroll2_size);
cps1_old_palette=(unsigned char *)malloc(cps1_palette_size);
if (!cps1_old_palette)
{
return -1;
}
memset(cps1_old_palette, 0xff, cps1_palette_size);
memset(cps1_gfxram, 0, cps1_gfxram_size); /* Clear GFX RAM */
memset(cps1_output, 0, cps1_output_size); /* Clear output ports */
if (!cps1_game_config)
{
return -1;
}
if (cps1_game_config->alternative >
sizeof(cps1_vid_cfg) / sizeof(cps1_vid_cfg[0]))
{
return -1;
}
cps1_layer_control=cps1_vid_cfg[cps1_game_config->alternative].layer_control;
/* Put in some defaults */
WRITE_WORD(&cps1_output[0x00], 0x9200);
WRITE_WORD(&cps1_output[0x02], 0x9000);
WRITE_WORD(&cps1_output[0x04], 0x9040);
WRITE_WORD(&cps1_output[0x06], 0x9080);
WRITE_WORD(&cps1_output[0x08], 0x9100);
WRITE_WORD(&cps1_output[0x0a], 0x90c0);
/* Set up old base */
cps1_get_video_base(); /* Calculate base pointers */
cps1_get_video_base(); /* Calculate old base pointers */
/*
Some games interrogate a couple of registers on bootup.
These are CPS1 board B self test checks. They wander from game to
game.
*/
if (cps1_game_config->cpsb_addr)
{
WRITE_WORD(&cps1_output[cps1_game_config->cpsb_addr],
cps1_game_config->cpsb_value);
}
for (i=0; i<4; i++)
{
cps1_transparency_scroll[i]=0xffff;
}
return 0;
}
/***************************************************************************
Stop the video hardware emulation.
***************************************************************************/
void cps1_vh_stop(void)
{
if (cps1_old_palette)
free(cps1_old_palette);
if (cps1_scroll2_bitmap)
osd_free_bitmap(cps1_scroll2_bitmap);
if (cps1_scroll2_old)
free(cps1_scroll2_old);
cps1_gfx_stop();
}
/***************************************************************************
Build palette from palette RAM
12 bit RGB with a 4 bit brightness value.
***************************************************************************/
void cps1_build_palette(void)
{
int offset;
for (offset = 0; offset < cps1_palette_entries*16; offset++)
{
int palette = READ_WORD (&cps1_palette[offset * 2]);
if (palette != READ_WORD (&cps1_old_palette[offset * 2]) )
{
int red, green, blue, bright;
bright= (palette>>12);
if (bright) bright += 2;
red = ((palette>>8)&0x0f) * bright;
green = ((palette>>4)&0x0f) * bright;
blue = (palette&0x0f) * bright;
palette_change_color (offset, red, green, blue);
WRITE_WORD(&cps1_old_palette[offset * 2], palette);
}
}
}
/***************************************************************************
Scroll 1 (8x8)
Attribute word layout:
0x0001 colour
0x0002 colour
0x0004 colour
0x0008 colour
0x0010 colour
0x0020 X Flip
0x0040 Y Flip
0x0080
0x0100
0x0200
0x0400
0x0800
0x1000
0x2000
0x4000
0x8000
***************************************************************************/
void cps1_palette_scroll1(unsigned short *base)
{
int x,y, offs, offsx;
int scrlxrough=(scroll1x>>3)+8;
int scrlyrough=(scroll1y>>3);
int elements = Machine->gfx[0]->total_elements;
for (x=0; x<0x36; x++)
{
offsx=(scrlxrough+x)*0x80;
offsx&=0x1fff;
for (y=0; y<0x20; y++)
{
int code, colour, offsy;
int n=scrlyrough+y;
offsy=( (n&0x1f)*4 | ((n&0x20)*0x100)) & 0x3fff;
offs=offsy+offsx;
offs &= 0x3fff;
code=READ_WORD(&cps1_scroll1[offs]);
colour=READ_WORD(&cps1_scroll1[offs+2]);
code+=cps1_game_config->bank_scroll1*0x08000;
base[colour&0x1f] |=
cps1_char_pen_usage[code % cps1_max_char]&0x7fff;
}
}
}
void cps1_render_scroll1(struct osd_bitmap *bitmap, int priority)
{
int x,y, offs, offsx, sx, sy, ytop;
int scrlxrough=(scroll1x>>3)+4;
int scrlyrough=(scroll1y>>3);
sx=-(scroll1x&0x07);
ytop=-(scroll1y&0x07)+32;
for (x=0; x<0x35; x++)
{
sy=ytop;
offsx=(scrlxrough+x)*0x80;
offsx&=0x1fff;
for (y=0; y<0x20; y++)
{
int code, offsy, colour;
int n=scrlyrough+y;
offsy=( (n&0x1f)*4 | ((n&0x20)*0x100)) & 0x3fff;
offs=offsy+offsx;
offs &= 0x3fff;
code=READ_WORD(&cps1_scroll1[offs]);
colour=READ_WORD(&cps1_scroll1[offs+2]);
if (code != 0x20)
{
/* 0x0020 appears to never be drawn */
code+=cps1_game_config->bank_scroll1*0x08000;
if (!priority || colour & 0x0180)
{
cps1_draw_scroll1(bitmap,
code,
colour&0x1f,
colour&0x20,
colour&0x40,
sx,sy);
}
}
sy+=8;
}
sx+=8;
}
}
/***************************************************************************
Sprites
=======
Sprites are represented by a number of 8 byte values
xx xx yy yy nn nn aa aa
where xxxx = x position
yyyy = y position
nnnn = tile number
aaaa = attribute word
0x0001 colour
0x0002 colour
0x0004 colour
0x0008 colour
0x0010 colour
0x0020 X Flip
0x0040 Y Flip
0x0080 unknown
0x0100 X block size (in sprites)
0x0200 X block size
0x0400 X block size
0x0800 X block size
0x1000 Y block size (in sprites)
0x2000 Y block size
0x4000 Y block size
0x8000 Y block size
The end of the table (may) be marked by an attribute value of 0xff00.
***************************************************************************/
void cps1_find_last_sprite(void) /* Find the offset of last sprite */
{
int offset=6;
/* Locate the end of table marker */
while (offset < cps1_obj_size)
{
int colour=READ_WORD(&cps1_obj[offset]);
if (colour == 0xff00)
{
/* Marker found. This is the last sprite. */
cps1_last_sprite_offset=offset-6-8;
return;
}
offset+=8;
}
/* Sprites must use full sprite RAM */
cps1_last_sprite_offset=cps1_obj_size-8;
}
/* Find used colours */
void cps1_palette_sprites(unsigned short *base)
{
int i;
int gng_obj_kludge=cps1_game_config->gng_sprite_kludge;
for (i=cps1_last_sprite_offset; i>=0; i-=8)
{
int x=READ_WORD(&cps1_obj[i]);
int y=READ_WORD(&cps1_obj[i+2]);
if (x && y)
{
int colour=READ_WORD(&cps1_obj[i+6]);
int col=colour&0x1f;
unsigned int code=READ_WORD(&cps1_obj[i+4]);
code+=cps1_game_config->bank_obj*0x04000;
if (gng_obj_kludge == 1 && code >= 0x01000)
{
code += 0x4000;
}
if (gng_obj_kludge == 2 && code >= 0x02a00)
{
code += 0x4000;
}
if ( colour & 0xff00 )
{
int nys, nxs;
int nx=(colour & 0x0f00) >> 8;
int ny=(colour & 0xf000) >> 12;
nx++;
ny++;
if (colour & 0x40) /* Y Flip */ /* Y flip */
{
if (colour &0x20)
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
int cod=code+(nx-1)-nxs+0x10*(ny-1-nys);
base[col] |=
cps1_tile16_pen_usage[cod % cps1_max_tile16];
}
}
}
else
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
int cod=code+nxs+0x10*(ny-1-nys);
base[col] |=
cps1_tile16_pen_usage[cod % cps1_max_tile16];
}
}
}
}
else
{
if (colour &0x20)
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
int cod=code+(nx-1)-nxs+0x10*nys;
base[col] |=
cps1_tile16_pen_usage[cod % cps1_max_tile16];
}
}
}
else
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
int cod=code+nxs+0x10*nys;
base[col] |=
cps1_tile16_pen_usage[cod % cps1_max_tile16];
}
}
}
}
base[col]&=0x7fff;
}
else
{
base[col] |=
cps1_tile16_pen_usage[code % cps1_max_tile16]&0x7fff;
}
}
}
}
void cps1_render_sprites(struct osd_bitmap *bitmap, int priority)
{
int i;
int base_obj=0;
int gng_obj_kludge=cps1_game_config->gng_sprite_kludge;
/* Draw the sprites */
for (i=cps1_last_sprite_offset; i>=0; i-=8)
{
int x=READ_WORD(&cps1_obj[i]);
int y=READ_WORD(&cps1_obj[i+2]);
if (x && y )
{
unsigned int code=READ_WORD(&cps1_obj[i+4]);
int colour=READ_WORD(&cps1_obj[i+6]);
int col=colour&0x1f;
code+=cps1_game_config->bank_obj*0x04000;
if (y & 0x0300)
{
if (colour & 0xff00)
{
y=-0x200+y;
}
else
{
y &= 0x1ff;
}
}
x-=0x20;
y+=0x20;
if (gng_obj_kludge == 1 && code >= 0x01000)
{
code += 0x4000;
}
if (gng_obj_kludge == 2 && code >= 0x02a00)
{
code += 0x4000;
}
if (colour & 0xff00 )
{
/* handle blocked sprites */
int nx=(colour & 0x0f00) >> 8;
int ny=(colour & 0xf000) >> 12;
int nxs, nys;
nx++;
ny++;
if (colour & 0x40)
{
/* Y flip */
if (colour &0x20)
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
cps1_draw_tile16(bitmap,Machine->gfx[1],
code+(nx-1)-nxs+0x10*(ny-1-nys),
col&0x1f,
1,1,
x+nxs*16,y+nys*16,0x8000);
}
}
}
else
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
cps1_draw_tile16(bitmap,Machine->gfx[1],
code+nxs+0x10*(ny-1-nys),
col&0x1f,
0,1,
x+nxs*16,y+nys*16,0x8000 );
}
}
}
}
else
{
if (colour &0x20)
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
cps1_draw_tile16(bitmap,Machine->gfx[1],
code+(nx-1)-nxs+0x10*nys,
col&0x1f,
1,0,
x+nxs*16,y+nys*16,0x8000
);
}
}
}
else
{
for (nys=0; nys<ny; nys++)
{
for (nxs=0; nxs<nx; nxs++)
{
cps1_draw_tile16(bitmap,Machine->gfx[1],
code+nxs+0x10*nys,
col&0x1f,
0,0,
x+nxs*16,y+nys*16, 0x8000);
}
}
}
}
}
else
{
/* Simple case... 1 sprite */
cps1_draw_tile16(bitmap,Machine->gfx[1],
code,
col&0x1f,
colour&0x20,colour&0x40,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -