📄 cclimber.c
字号:
/***************************************************************************
vidhrdw.c
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#define BIGSPRITE_WIDTH 128
#define BIGSPRITE_HEIGHT 128
unsigned char *cclimber_bsvideoram;
int cclimber_bsvideoram_size;
unsigned char *cclimber_bigspriteram;
unsigned char *cclimber_column_scroll;
static unsigned char *bsdirtybuffer;
static struct osd_bitmap *bsbitmap;
static int flipscreen[2];
static int palettebank;
static int sidepanel_enabled;
/***************************************************************************
Convert the color PROMs into a more useable format.
Crazy Climber has three 32x8 palette PROMs.
The palette PROMs are connected to the RGB output this way:
bit 7 -- 220 ohm resistor -- BLUE
-- 470 ohm resistor -- BLUE
-- 220 ohm resistor -- GREEN
-- 470 ohm resistor -- GREEN
-- 1 kohm resistor -- GREEN
-- 220 ohm resistor -- RED
-- 470 ohm resistor -- RED
bit 0 -- 1 kohm resistor -- RED
***************************************************************************/
void cclimber_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
{
int i;
#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + (offs)])
for (i = 0;i < Machine->drv->total_colors;i++)
{
int bit0,bit1,bit2;
/* red component */
bit0 = (*color_prom >> 0) & 0x01;
bit1 = (*color_prom >> 1) & 0x01;
bit2 = (*color_prom >> 2) & 0x01;
*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* green component */
bit0 = (*color_prom >> 3) & 0x01;
bit1 = (*color_prom >> 4) & 0x01;
bit2 = (*color_prom >> 5) & 0x01;
*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* blue component */
bit0 = 0;
bit1 = (*color_prom >> 6) & 0x01;
bit2 = (*color_prom >> 7) & 0x01;
*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
color_prom++;
}
/* character and sprite lookup table */
/* they use colors 0-63 */
for (i = 0;i < TOTAL_COLORS(0);i++)
{
/* pen 0 always uses color 0 (background in River Patrol and Silver Land) */
if (i % 4 == 0) COLOR(0,i) = 0;
else COLOR(0,i) = i;
}
/* big sprite lookup table */
/* it uses colors 64-95 */
for (i = 0;i < TOTAL_COLORS(2);i++)
{
if (i % 4 == 0) COLOR(2,i) = 0;
else COLOR(2,i) = i + 64;
}
}
/***************************************************************************
Convert the color PROMs into a more useable format.
Swimmer has two 256x4 char/sprite palette PROMs and one 32x8 big sprite
palette PROM.
The palette PROMs are connected to the RGB output this way:
(the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel)
bit 3 -- 250 ohm resistor -- BLUE
-- 500 ohm resistor -- BLUE
-- 250 ohm resistor -- GREEN
bit 0 -- 500 ohm resistor -- GREEN
bit 3 -- 1 kohm resistor -- GREEN
-- 250 ohm resistor -- RED
-- 500 ohm resistor -- RED
bit 0 -- 1 kohm resistor -- RED
bit 7 -- 250 ohm resistor -- BLUE
-- 500 ohm resistor -- BLUE
-- 250 ohm resistor -- GREEN
-- 500 ohm resistor -- GREEN
-- 1 kohm resistor -- GREEN
-- 250 ohm resistor -- RED
-- 500 ohm resistor -- RED
bit 0 -- 1 kohm resistor -- RED
***************************************************************************/
void swimmer_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
{
int i,j,used,realcnt;
unsigned char allocated[256];
#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + (offs)])
/* The game has 256+32 colors, plus the river background, but we are */
/* limited to a maximum of 256. */
/* Luckily, many of the colors are duplicated, so the total number of */
/* different colors is less than 256 (in fact, less than the 96 used */
/* in Crazy Climber). We select the unique colors and put them in our */
/* palette. */
/* TODO: use the palette.c shrinking instead of doing our own. */
memset(palette,0,3 * Machine->drv->total_colors);
/* transparent black */
allocated[0] = 0;
palette[0] = 0;
palette[1] = 0;
palette[2] = 0;
/* non transparent black */
allocated[1] = 0;
palette[3] = 0;
palette[4] = 0;
palette[5] = 0;
used = 2;
realcnt = TOTAL_COLORS(0) / 2;
for (i = 0;i < realcnt;i++)
{
for (j = 0;j < used;j++)
{
if (allocated[j] == (color_prom[i] & 0x0f) + 16 * (color_prom[i+256] & 0x0f))
break;
}
if (j == used)
{
int bit0,bit1,bit2;
used++;
allocated[j] = (color_prom[i] & 0x0f) + 16 * (color_prom[i+256] & 0x0f);
/* red component */
bit0 = (color_prom[i] >> 0) & 0x01;
bit1 = (color_prom[i] >> 1) & 0x01;
bit2 = (color_prom[i] >> 2) & 0x01;
palette[3*j] = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
/* green component */
bit0 = (color_prom[i] >> 3) & 0x01;
bit1 = (color_prom[i+256] >> 0) & 0x01;
bit2 = (color_prom[i+256] >> 1) & 0x01;
palette[3*j + 1] = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
/* blue component */
bit0 = 0;
bit1 = (color_prom[i+256] >> 2) & 0x01;
bit2 = (color_prom[i+256] >> 3) & 0x01;
palette[3*j + 2] = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
}
if (i % 8 && j == 0) j = 1; /* avoid undesired transparency */
COLOR(0,i) = j;
/* Black background for the side panel */
if (i % 8)
{
COLOR(0,i+realcnt) = j;
}
else
{
/* Opaque black */
COLOR(0,i+realcnt) = 1;
}
}
color_prom += 2 * 256;
for (i = 0;i < TOTAL_COLORS(2);i++)
{
for (j = 0;j < used;j++)
{
if (allocated[j] == color_prom[i])
break;
}
if (j == used)
{
int bit0,bit1,bit2;
used++;
allocated[j] = color_prom[i];
/* red component */
bit0 = (color_prom[i] >> 0) & 0x01;
bit1 = (color_prom[i] >> 1) & 0x01;
bit2 = (color_prom[i] >> 2) & 0x01;
palette[3*j] = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
/* green component */
bit0 = (color_prom[i] >> 3) & 0x01;
bit1 = (color_prom[i] >> 4) & 0x01;
bit2 = (color_prom[i] >> 5) & 0x01;
palette[3*j + 1] = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
/* blue component */
bit0 = 0;
bit1 = (color_prom[i] >> 6) & 0x01;
bit2 = (color_prom[i] >> 7) & 0x01;
palette[3*j + 2] = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
}
if (i % 8 == 0) j = 0; /* enforce transparency */
else if (j == 0) j = 1; /* avoid undesired transparency */
COLOR(2,i) = j;
}
}
/***************************************************************************
Swimmer can directly set the background color.
The latch is connected to the RGB output this way:
(the 500 and 250 ohm resistors are made of 1 kohm resistors in parallel)
bit 7 -- 250 ohm resistor -- RED
-- 500 ohm resistor -- RED
-- 250 ohm resistor -- GREEN
-- 500 ohm resistor -- GREEN
-- 1 kohm resistor -- GREEN
-- 250 ohm resistor -- BLUE
-- 500 ohm resistor -- BLUE
bit 0 -- 1 kohm resistor -- BLUE
***************************************************************************/
void swimmer_bgcolor_w(int offset,int data)
{
int bit0,bit1,bit2;
int r,g,b;
/* red component */
bit0 = 0;
bit1 = (data >> 6) & 0x01;
bit2 = (data >> 7) & 0x01;
r = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
/* green component */
bit0 = (data >> 3) & 0x01;
bit1 = (data >> 4) & 0x01;
bit2 = (data >> 5) & 0x01;
g = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
/* blue component */
bit0 = (data >> 0) & 0x01;
bit1 = (data >> 1) & 0x01;
bit2 = (data >> 2) & 0x01;
b = 0x20 * bit0 + 0x40 * bit1 + 0x80 * bit2;
palette_change_color(0,r,g,b);
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
int cclimber_vh_start(void)
{
if (generic_vh_start() != 0)
return 1;
if ((bsdirtybuffer = malloc(cclimber_bsvideoram_size)) == 0)
{
generic_vh_stop();
return 1;
}
memset(bsdirtybuffer,1,cclimber_bsvideoram_size);
if ((bsbitmap = osd_create_bitmap(BIGSPRITE_WIDTH,BIGSPRITE_HEIGHT)) == 0)
{
free(bsdirtybuffer);
generic_vh_stop();
return 1;
}
return 0;
}
/***************************************************************************
Stop the video hardware emulation.
***************************************************************************/
void cclimber_vh_stop(void)
{
osd_free_bitmap(bsbitmap);
free(bsdirtybuffer);
generic_vh_stop();
}
void cclimber_flipscreen_w(int offset,int data)
{
if (flipscreen[offset] != (data & 1))
{
flipscreen[offset] = data & 1;
memset(dirtybuffer,1,videoram_size);
}
}
void cclimber_colorram_w(int offset,int data)
{
if (colorram[offset] != data)
{
/* bit 5 of the address is not used for color memory. There is just */
/* 512 bytes of memory; every two consecutive rows share the same memory */
/* region. */
offset &= 0xffdf;
dirtybuffer[offset] = 1;
dirtybuffer[offset + 0x20] = 1;
colorram[offset] = data;
colorram[offset + 0x20] = data;
}
}
void cclimber_bigsprite_videoram_w(int offset,int data)
{
if (cclimber_bsvideoram[offset] != data)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -