⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cps1.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************

  vidhrdw.c

  Functions to emulate the video hardware of the machine.

  Todo:
  7 unknown attribute bits on scroll 2/3.
  Speed, speed, speed...

  OUTPUT PORTS (preliminary)
  0x00-0x01     OBJ RAM base (/256)
  0x02-0x03     Scroll1 RAM base (/256)
  0x04-0x05     Scroll2 RAM base (/256)
  0x06-0x07     Scroll3 RAM base (/256)
  0x08-0x09     "Other" RAM - Scroll distortion (/256)
  0x0a-0x0b     Palette base (/256)
  0x0c-0x0d     Scroll 1 X
  0x0e-0x0f     Scroll 1 Y
  0x10-0x11     Scroll 2 X
  0x12-0x13     Scroll 2 Y
  0x14-0x15     Scroll 3 X
  0x16-0x17     Scroll 3 Y

  0x18-0x19     ????
  0x20-0x21     ????
  0x22-0x23     unknown but widely used - usually 0x0e
  0x24-0x25     ????


  0x4e-0x4f     ????
  0x5e-0x5f     ????

  Registers move from game to game.. following example strider
  0x66-0x67     Video control register (location varies according to game)
  0x6a-0x6b     Priority mask
  0x6c-0x6d     Priority mask
  0x6e-0x6f     Priority mask
  0x70-0x71     Control register (usually 0x003f)

  Fixed registers
  0x80-0x81     ????	    Sound output.
  0x88-0x89     ????	    Port thingy (sound fade???)

  Known Bug List
  ==============
  All games
  * Palette fades overflow palette.
  * Large sprites don't exit smoothly on the left side of the screen (e.g. Car
    in Mega Man attract mode)

  Magic Sword.
  * Distortion effect is mapped wrong.
  * Rogue scroll 2 character at end of level 1
  * during attract mode, characters are shown with a black background. There is
    a background, but the layers are disabled. I think this IS the correct
	behaviour.

  King of Dragons.
  * Distortion effect missing on player selection screen.

  1941
  * Brief flicker of scroll 2 when coining up / starting game.

  Captain Commando
  * Continue screen completely wrong

  SF2
  * Sprite lag on screens.
  * Japanese level still doesn't look 100%

  ffight
  * end of level 1 stairs: can see the player feet through them, and
  if you don't destroy the bin it gets covered by the ones behind it.
  * continue screen has garbage character tiled in the background

  mtwins
  * in the cave (with fire) and underwater, rowscroll is used. This
    doesn't seem to have any visible effect, but I think it is supposed
	to wave, to suggest hot air and water.
  * attract mode screens have garbage character tiled in the background

  cawing
  * priority: at end of level, the plane is drawn above the text
  * in level 2, you have to blow out tunnels in skyscrapers to
    fly thru. However, you can see the tunnel before you actually make it.
	Doesn't seem to be a priority problem, the gfx are just missing.
  * garbage characters inbetween text in attract mode

  knights
  * garbage characters left on screen during boot and under INSERT COIN.

  qad
  * in attract mode, "Dragons" is missing from the title screen, only
    "Quiz &" is visible.

  mercs
  * a few wrong scroll 2 tiles (check part 2 of the first attract mode round)


  Todo
  ====

  Implement CPS2 QSound system


  Unknown issues
  ==============

  There are often some redundant high bits in the scroll layer's attributes.


***************************************************************************/

#include "driver.h"
#include "vidhrdw/generic.h"
#include "drivers/cps1.h"
#include "types.h"
#include "osdepend.h"

#define VERBOSE 1

struct CPS1VIDCFG
{
	int layer_control;
	int priority0;	/* usually 0x00 */
	int priority1;
	int priority2;
	int priority3;
	int control_reg;  /* Control register? Usually contains 0x3f */
	int scrl1_enable_mask;
	int scrl2_enable_mask;
	int scrl3_enable_mask;
	int distort_alt;
};

/* Configuration tables */
/* ideally, the layer enable masks should consist of only one bit, */
/* but in many cases it is unknown which bit is which. */
static struct CPS1VIDCFG cps1_vid_cfg[]=
{
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x38,0x38,0x38,0}, /* 00 = Un Squadron */
	{0x70,0x6e,0x6c,0x6a,0x68,0x66, 0x20,0x10,0x08,0}, /* 01 = Willow */
	{0x6e,0x66,0x70,0x68,0x72,0x6a, 0x02,0x0c,0x0c,1}, /* 02 = Final Fight */
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x02,0x0c,0x0c,1}, /* 03 = ffightu */
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x02,0x0c,0x0c,0}, /* 04 = Strider */
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x02,0x04,0x08,0}, /* 05 = Ghouls */
	{0x68,0x66,0x64,0x62,0x60,0x70, 0x20,0x10,0x02,0}, /* 06 = Knights */
	{0x62,0x64,0x66,0x68,0x6a,0x6c, 0x20,0x06,0x06,2}, /* 07 = Magic Sword */
	{0x42,0x44,0x46,0x48,0x4a,0x4c, 0x04,0x22,0x22,0}, /* 08 = Nemo */
	{0x6c,0x6a,0x68,0x66,0x64,0x62, 0x02,0x04,0x08,0}, /* 09 = DWJ */
	{0x60,0x6e,0x6c,0x6a,0x68,0x70, 0x30,0x08,0x30,0}, /* 10 = KOD */
	{0x4c,0x4a,0x48,0x46,0x44,0x42, 0x10,0x0a,0x0a,0}, /* 11 = Carrier Air Wing */
	{0x54,0x52,0x50,0x4e,0x4c,0x4a, 0x08,0x12,0x12,3}, /* 12 = Street Fighter 2 */
	{0x62,0x64,0x66,0x68,0x6a,0x6c, 0x20,0x06,0x06,3}, /* 13 = sf2j */
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x02,0x0c,0x0c,3}, /* 14 = Street Fighter 2 (Turbo) */
	{0xdc,0xda,0xd8,0xd6,0xd4,0xd2, 0x10,0x0a,0x0a,3}, /* 15 = SF2 (Rev E) */
	{0x68,0x66,0x64,0x62,0x60,0x70, 0x20,0x04,0x08,2}, /* 16 = 3 Wonders */
	{0x6e,0x66,0x70,0x68,0x72,0x6a, 0x02,0x0c,0x0c,1}, /* 17 = Varth */
	{0x60,0x6e,0x6c,0x6a,0x68,0x70, 0x20,0x06,0x06,1}, /* 18 = varthj */
	{0x68,0x6a,0x6c,0x6e,0x70,0x72, 0x02,0x08,0x20,0}, /* 19 = 1941 */
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x02,0x0c,0x0c,0}, /* 20 = Megaman */
	{0x52,0x54,0x56,0x58,0x5a,0x5c, 0x38,0x38,0x38,1}, /* 21 = Mega Twins */
	{0x6c,0x00,0x00,0x00,0x00,0x62, 0x02,0x04,0x08,0}, /* 22 = Mercs (uses port 74) */
	{0x6c,0x00,0x00,0x00,0x00,0x52, 0x16,0x16,0x16,0}, /* 23 = Quiz and Dragons */
	{0x60,0x00,0x00,0x00,0x00,0x70, 0x20,0x14,0x14,0}, /* 24 = cworld2j */
	{0x66,0x00,0x00,0x00,0x00,0x70, 0x0e,0x0e,0x0e,0}, /* 25 = Pnickies */
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x0e,0x0e,0x0e,0}, /* 26 = qadj */
	{0x4a,0x4c,0x4e,0x40,0x42,0x44, 0x16,0x16,0x16,0}, /* 27 = Cadillacs & Dinosaurs */
	{0x52,0x54,0x56,0x48,0x4a,0x4c, 0x04,0x02,0x20,0}, /* 28 = Punisher */
	{0x60,0x6e,0x6c,0x6a,0x68,0x70, 0x20,0x12,0x12,0}, /* 29 = Captain Commando */
	{0x66,0x68,0x6a,0x6c,0x6e,0x70, 0x02,0x04,0x08,0}, /* 30 = wof */
	{0x56,0x40,0x42,0x68,0x6a,0x6c, 0x1c,0x1c,0x1c,0}, /* 31 = Slam Masters */
	{0x6a,0x6c,0x6e,0x70,0x72,0x5c, 0x1c,0x1c,0x1c,0}, /* 32 = Muscle Bomber Duo */
	{0x62,0x64,0x66,0x68,0x6a,0x6c, 0x10,0x08,0x04,0}, /* 33 = wofj */
};


INLINE int cps1_port(int offset)
{
	return READ_WORD(&cps1_output[offset]);
}

INLINE unsigned char * cps1_base(int offset)
{
	int base=cps1_port(offset)*256;
	return &cps1_gfxram[base&0x3ffff];
}

int cps1_output_r(int offset)
{
	return READ_WORD(&cps1_output[offset]);
}

void cps1_output_w(int offset, int data)
{
	int value;

	COMBINE_WORD_MEM(&cps1_output[offset],data);

	/* protections */
	switch (offset)
	{
		case 0x40:
		case 0x42:
			if (cps1_game_config->alternative==14 )
			{
				/* Only apply protection to sf2t (other games use 0x40-0x47)*/
				value=cps1_port(0x40);
				value*=cps1_port(0x42);
				/* Slight variation ... only one word result */
				WRITE_WORD(&cps1_output[0x44], value&0xffff);
			}
			else if (cps1_game_config->alternative==11)
			{
				/* Carrier Air Wing... unknown protection */
				WRITE_WORD(&cps1_output[0x40], 0x0406);
			}
			break;

		case 0x44:
		case 0x46:
		if (cps1_game_config->alternative==6)
			{
				/* Only apply protection to knights (other games use 0x40-0x47)*/
				value=cps1_port(0x44);
				value*=cps1_port(0x46);
				WRITE_WORD(&cps1_output[0x40], value>>16);
				WRITE_WORD(&cps1_output[0x42], value&0xffff);
			}
			break;

		case 0x4c:
		case 0x4e:
			if (cps1_game_config->alternative==16   /* 3wonders */
					|| cps1_game_config->alternative==18)   /* varthj */
			{
				/* Only apply protection to 3wonders (other games use 0x4c-0x4f)*/
				value=cps1_port(0x4c);
				value*=cps1_port(0x4e);
				WRITE_WORD(&cps1_output[0x48], value>>16);
				WRITE_WORD(&cps1_output[0x4a], value&0xffff);
			}
			break;

		case 0x5c:
		case 0x5e:
		if (cps1_game_config->alternative==10)
			{
				/* Only apply protection to KOD (other games use 0x58-0x5b)*/
				value=cps1_port(0x5c);
				value*=cps1_port(0x5e);
				WRITE_WORD(&cps1_output[0x58], value>>16);
				WRITE_WORD(&cps1_output[0x5a], value&0xffff);
			}
			break;
	}
}



/* Public variables */
unsigned char *cps1_gfxram;
unsigned char *cps1_output;
int cps1_gfxram_size;
int cps1_output_size;

/* Private */

/* Offset of each palette entry */
const int cps1_obj_palette    =0;
const int cps1_scroll1_palette=32;
const int cps1_scroll2_palette=32+32;
const int cps1_scroll3_palette=32+32+32;
#define cps1_palette_entries (32*4)  /* Number colour schemes in palette */

const int cps1_scroll1_size=0x4000;
const int cps1_scroll2_size=0x4000;
const int cps1_scroll3_size=0x4000;
const int cps1_obj_size    =0x4000;
const int cps1_other_size  =0x4000;
const int cps1_palette_size=cps1_palette_entries*32; /* Size of palette RAM */
static int cps1_flip_screen;    /* Flip screen on / off */

static unsigned char *cps1_scroll1;
static unsigned char *cps1_scroll2;
static unsigned char *cps1_scroll3;
static unsigned char *cps1_obj;
static unsigned char *cps1_palette;
static unsigned char *cps1_other;
static unsigned char *cps1_old_palette;

/* Working variables */
static int cps1_last_sprite_offset;     /* Offset of the last sprite */
static int cps1_layer_control;	  /* Layer control register */
static int cps1_layer_enabled[4];       /* Layer enabled [Y/N] */

int scroll1x, scroll1y, scroll2x, scroll2y, scroll3x, scroll3y;
struct CPS1config *cps1_game_config;
static unsigned char *cps1_scroll2_old;
static struct osd_bitmap *cps1_scroll2_bitmap;


/* Output ports */
#define CPS1_OBJ_BASE	   0x00    /* Base address of objects */
#define CPS1_SCROLL1_BASE       0x02    /* Base address of scroll 1 */
#define CPS1_SCROLL2_BASE       0x04    /* Base address of scroll 2 */
#define CPS1_SCROLL3_BASE       0x06    /* Base address of scroll 3 */
#define CPS1_OTHER_BASE	 0x08    /* Base address of other video */
#define CPS1_PALETTE_BASE       0x0a    /* Base address of palette */
#define CPS1_SCROLL1_SCROLLX    0x0c    /* Scroll 1 X */
#define CPS1_SCROLL1_SCROLLY    0x0e    /* Scroll 1 Y */
#define CPS1_SCROLL2_SCROLLX    0x10    /* Scroll 2 X */
#define CPS1_SCROLL2_SCROLLY    0x12    /* Scroll 2 Y */
#define CPS1_SCROLL3_SCROLLX    0x14    /* Scroll 3 X */
#define CPS1_SCROLL3_SCROLLY    0x16    /* Scroll 3 Y */

#define CPS1_SCROLL2_WIDTH      0x40
#define CPS1_SCROLL2_HEIGHT     0x40


/*
CPS1 VIDEO RENDERER

*/
const int cps1_gfx_region=1;	    /* MAME memory region to draw from */
static dword *cps1_gfx;		 /* Converted GFX memory */
static int *cps1_char_pen_usage;	/* pen usage array */
static int *cps1_tile16_pen_usage;      /* pen usage array */
static int *cps1_tile32_pen_usage;      /* pen usage array */
static int cps1_max_char;	       /* Maximum number of 8x8 chars */
static int cps1_max_tile16;	     /* Maximum number of 16x16 tiles */
static int cps1_max_tile32;	     /* Maximum number of 32x32 tiles */

int cps1_gfx_start(void)
{
	dword dwval;
	int size=Machine->memory_region_length[cps1_gfx_region];
	unsigned char *data = Machine->memory_region[cps1_gfx_region];
	int i,j,nchar,penusage,gfxsize;

	gfxsize=size/4;

	/* Set up maximum values */
	cps1_max_char  =(gfxsize/2)/8;
	cps1_max_tile16=(gfxsize/4)/8;
	cps1_max_tile32=(gfxsize/16)/8;

	cps1_gfx=malloc(gfxsize*sizeof(dword));
	if (!cps1_gfx)
	{
		return -1;
	}

	cps1_char_pen_usage=malloc(cps1_max_char*sizeof(int));
	if (!cps1_char_pen_usage)
	{
		return -1;
	}
	memset(cps1_char_pen_usage, 0, cps1_max_char*sizeof(int));

	cps1_tile16_pen_usage=malloc(cps1_max_tile16*sizeof(int));
	if (!cps1_tile16_pen_usage)
		return -1;
	memset(cps1_tile16_pen_usage, 0, cps1_max_tile16*sizeof(int));

	cps1_tile32_pen_usage=malloc(cps1_max_tile32*sizeof(int));
	if (!cps1_tile32_pen_usage)
	{
		return -1;
	}
	memset(cps1_tile32_pen_usage, 0, cps1_max_tile32*sizeof(int));

#if 0
	if (Machine->orientation & ORIENTATION_SWAP_XY)
	{
		unsigned char *p=data;
		for (i=0; i<gfxsize/2; i++)
		{
			int x;
		       nchar=i/8;  /* 8x8 char number */
		       dwval=0;

		       for (x=0; x<8; x++)
		       {
				int y=i%8;
				int n,mask;
				n=0;
				mask=0x80>>y;
				p=data+nchar*16+x*2;
				if (*(p+size/4)&mask)	   n|=1;
				if (*(p+size/4+1)&mask)	 n|=2;
				if (*(p+size/2+size/4)&mask)    n|=4;
				if (*(p+size/2+size/4+1)&mask)  n|=8;
				dwval|=n<<(28-x*4);
				penusage=1<<n;
				cps1_char_pen_usage[nchar]|=penusage;
				cps1_tile16_pen_usage[nchar/2]|=penusage;
				cps1_tile32_pen_usage[nchar/8]|=penusage;
		       }
		       cps1_gfx[2*i]=dwval;
		       dwval=0;
		       for (x=0; x<8; x++)
		       {
				int y=i%8;
				int n,mask;
				n=0;
				mask=0x80>>y;
				p=data+nchar*16+x*2;
				if (*(p)&mask)	   n|=1;
				if (*(p+1)&mask)	 n|=2;
				if (*(p+size/2)&mask)    n|=4;
				if (*(p+size/2+1)&mask)  n|=8;
				dwval|=n<<(28-x*4);
				penusage=1<<n;
				cps1_char_pen_usage[nchar]|=penusage;
				cps1_tile16_pen_usage[nchar/2]|=penusage;
				cps1_tile32_pen_usage[nchar/8]|=penusage;
		       }

		       cps1_gfx[2*i+1]=dwval;
		}

	}
	else
#endif
	{
		for (i=0; i<gfxsize/2; i++)
		{
		       nchar=i/8;  /* 8x8 char number */
		       dwval=0;
		       for (j=0; j<8; j++)
		       {
				int n,mask;
				n=0;
				mask=0x80>>j;
				if (*(data+size/4)&mask)	   n|=1;
				if (*(data+size/4+1)&mask)	 n|=2;
				if (*(data+size/2+size/4)&mask)    n|=4;
				if (*(data+size/2+size/4+1)&mask)  n|=8;
				dwval|=n<<(28-j*4);
				penusage=1<<n;
				cps1_char_pen_usage[nchar]|=penusage;
				cps1_tile16_pen_usage[nchar/2]|=penusage;
				cps1_tile32_pen_usage[nchar/8]|=penusage;
		       }
		       cps1_gfx[2*i]=dwval;
		       dwval=0;
		       for (j=0; j<8; j++)
		       {
				int n,mask;
				n=0;
				mask=0x80>>j;
				if (*(data)&mask)	  n|=1;
				if (*(data+1)&mask)	n|=2;
				if (*(data+size/2)&mask)   n|=4;
				if (*(data+size/2+1)&mask) n|=8;
				dwval|=n<<(28-j*4);
				penusage=1<<n;
				cps1_char_pen_usage[nchar]|=penusage;
				cps1_tile16_pen_usage[nchar/2]|=penusage;
				cps1_tile32_pen_usage[nchar/8]|=penusage;
		       }
		       cps1_gfx[2*i+1]=dwval;
		       data+=2;
		}
	}
	return 0;
}

void cps1_gfx_stop(void)
{
	if (cps1_gfx)
	{
		free(cps1_gfx);
	}
	if (cps1_char_pen_usage)
	{
		free(cps1_char_pen_usage);
	}
	if (cps1_tile16_pen_usage)
	{
		free(cps1_tile16_pen_usage);
	}
	if (cps1_tile32_pen_usage)
	{
		free(cps1_tile32_pen_usage);
	}
}

INLINE void cps1_draw_gfx(
	struct osd_bitmap *dest,
	const struct GfxElement *gfx,
	unsigned int code,
	int color,
	int flipx,
	int flipy,
	int sx,
	int sy,
	int tpens,
	int *pusage,
	int size,
	int max,
	int delta,
	int srcdelta)
{
	int i, j, ex, ey;
	dword dwval,n;
	dword *src;
	const unsigned short *paldata;

    tpens=(~tpens) & 0xffff;

    if ( code > max || !(tpens & pusage[code]))
	{
		/* No pens to draw (object is empty) */
		return;
	}

	if (Machine->orientation & ORIENTATION_SWAP_XY)
	{
		int temp;
		temp=sx;
		sx=sy;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -