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

📄 atarisy1.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		unsigned char *dp;
		int x, y, i;

		gfx = Machine->gfx[1];
		roadblst_pen_usage = malloc (gfx->total_elements * 4 * sizeof (short));
		if (!roadblst_pen_usage)
			return 1;
		memset (roadblst_pen_usage, 0, gfx->total_elements * 4 * sizeof (short));

		for (i = 0, entry = roadblst_pen_usage; i < gfx->total_elements; i++, entry += 4)
		{
			for (y = 0; y < gfx->height; y++)
			{
				dp = gfx->gfxdata->line[i * gfx->height + y];
				for (x = 0; x < gfx->width; x++)
				{
					int color = dp[x];
					entry[(color >> 4) & 3] |= 1 << (color & 15);
				}
			}
		}
	}

	pflookup = roadblst_pflookup;
	molookup = roadblst_molookup;
	pf_map_shift = 0;
	mo_map_shift = 0;
	return atarisys1_vh_start ();
}



/*************************************
 *
 *		Video system shutdown
 *
 *************************************/

void atarisys1_vh_stop (void)
{
	/* free bitmaps */
	if (playfieldbitmap)
		osd_free_bitmap (playfieldbitmap);
	playfieldbitmap = 0;
	if (tempbitmap)
		osd_free_bitmap (tempbitmap);
	tempbitmap = 0;

	/* free dirty buffers */
	if (pfmapped)
		free (pfmapped);
	pfmapped = 0;
	scrolllist = 0;

	/* free the RoadBlasters pen usage */
	if (roadblst_pen_usage)
		free (roadblst_pen_usage);
	roadblst_pen_usage = 0;
}



/*************************************
 *
 *		Graphics bank selection
 *
 *************************************/

void atarisys1_bankselect_w (int offset, int data)
{
	int oldword = READ_WORD (&atarisys1_bankselect[offset]);
	int newword = COMBINE_WORD (oldword, data);
	int diff = oldword ^ newword;

	/* update memory */
	WRITE_WORD (&atarisys1_bankselect[offset], newword);

	/* sound CPU reset */
	if (diff & 0x80)
	{
		if (data & 0x80)
			atarigen_sound_reset ();
		else
			cpu_halt (1, 0);
	}

	/* motion object bank select */
	atarisys1_update_display_list (cpu_getscanline ());

	/* playfield bank select */
	if (diff & 0x04)
	{
		int i, *pf;

		/* set the new bank globally */
		pfbank = (newword & 0x04) ? 0x80 : 0x00;

		/* and remap the entire playfield */
		for (i = atarigen_playfieldram_size / 2, pf = pfmapped; i >= 0; i--)
		{
			int val = READ_WORD (&atarigen_playfieldram[i * 2]);
			int map = pflookup[pfbank | ((val >> 8) & 0x7f)] | (val & 0xff) | ((val & 0x8000) << 9) | LDIRTYFLAG;
			*pf++ = map;
		}
	}
}



/*************************************
 *
 *		Playfield horizontal scroll
 *
 *************************************/

void atarisys1_hscroll_w (int offset, int data)
{
	int oldword = READ_WORD (&atarigen_hscroll[offset]);
	int newword = COMBINE_WORD (oldword, data);

	WRITE_WORD (&atarigen_hscroll[offset], newword);

	if (!offset && (oldword & 0x1ff) != (newword & 0x1ff))
	{
		int scrollval = ((oldword & 0x1ff) << 12) + (READ_WORD (&atarigen_vscroll[0]) & 0x1ff);
		int i, end = cpu_getscanline ();

		if (end > YDIM)
			end = YDIM;

		for (i = scrolllist_end; i < end; i++)
			scrolllist[i] = scrollval;
		scrolllist_end = end;
	}
}



/*************************************
 *
 *		Playfield vertical scroll
 *
 *************************************/

void atarisys1_vscroll_w (int offset, int data)
{
	int oldword = READ_WORD (&atarigen_vscroll[offset]);
	int newword = COMBINE_WORD (oldword, data);

	WRITE_WORD (&atarigen_vscroll[offset], newword);

	if (!offset && (oldword & 0x1ff) != (newword & 0x1ff))
	{
		int scrollval = ((READ_WORD (&atarigen_hscroll[0]) & 0x1ff) << 12) + (oldword & 0x1ff);
		int i, end = cpu_getscanline ();

		if (end > YDIM)
			end = YDIM;

		for (i = scrolllist_end; i < end; i++)
			scrolllist[i] = scrollval;
		scrolllist_end = end;
	}
}



/*************************************
 *
 *		Playfield RAM read/write handlers
 *
 *************************************/

int atarisys1_playfieldram_r (int offset)
{
	return READ_WORD (&atarigen_playfieldram[offset]);
}


void atarisys1_playfieldram_w (int offset, int data)
{
	int oldword = READ_WORD (&atarigen_playfieldram[offset]);
	int newword = COMBINE_WORD (oldword, data);

	if (oldword != newword)
	{
		int map, oldmap;

		WRITE_WORD (&atarigen_playfieldram[offset], newword);

		/* remap it now and mark it dirty in the process */
		map = pflookup[pfbank | ((newword >> 8) & 0x7f)] | (newword & 0xff) | ((newword & 0x8000) << 9) | LDIRTYFLAG;
		oldmap = pfmapped[offset / 2];
		pfmapped[offset / 2] = map;
	}
}



/*************************************
 *
 *		Sprite RAM read/write handlers
 *
 *************************************/

int atarisys1_spriteram_r (int offset)
{
	return READ_WORD (&atarigen_spriteram[offset]);
}


void atarisys1_spriteram_w (int offset, int data)
{
	int oldword = READ_WORD (&atarigen_spriteram[offset]);
	int newword = COMBINE_WORD (oldword, data);

	if (oldword != newword)
	{
		WRITE_WORD (&atarigen_spriteram[offset], newword);

		/* if modifying a timer, beware */
		if (((offset & 0x180) == 0x000 && READ_WORD (&atarigen_spriteram[offset | 0x080]) == 0xffff) ||
		    ((offset & 0x180) == 0x080 && newword == 0xffff))
		{
			/* if the timer is in the active bank, update the display list */
			if ((offset >> 9) == ((READ_WORD (&atarisys1_bankselect[0]) >> 3) & 7))
			{
				atarisys1_update_display_list (cpu_getscanline ());
			}
		}
	}
}



/*************************************
 *
 *		Motion object interrupt handlers
 *
 *************************************/

void atarisys1_int3off_callback (int param)
{
	/* clear the state */
	int3_state = 0;

	/* clear the interrupt generated as well */
	cpu_clear_pending_interrupts (0);

	/* make this timer go away */
	int3off_timer = 0;
}


void atarisys1_int3_callback (int param)
{
	/* generate the interrupt */
	cpu_cause_interrupt (0, 3);

	/* update the state */
	int3_state = 1;

	/* set a timer to turn it off */
	if (int3off_timer)
		timer_remove (int3off_timer);
	int3off_timer = timer_set (cpu_getscanlineperiod (), 0, atarisys1_int3off_callback);

	/* set ourselves up to go off next frame */
	int3_timer[param] = timer_set (TIME_IN_HZ (Machine->drv->frames_per_second), param, atarisys1_int3_callback);
}


int atarisys1_int3state_r (int offset)
{
	return int3_state ? 0x0080 : 0x0000;
}



/*************************************
 *
 *		Motion object list handlers
 *
 *************************************/

void atarisys1_update_display_list (int scanline)
{
	int bank = ((READ_WORD (&atarisys1_bankselect[0]) >> 3) & 7) * 0x200;
	unsigned char *base = &atarigen_spriteram[bank];
	unsigned char spritevisit[64], timer[YDIM];
	int link = 0, i;

	/* generic update first */
	if (!scanline)
	{
		scrolllist_end = 0;
		atarigen_update_display_list (base, 0, 0);
	}
	else
		atarigen_update_display_list (base, 0, scanline + 1);

	/* visit all the sprites and look for timers */
	memset (spritevisit, 0, sizeof (spritevisit));
	memset (timer, 0, sizeof (timer));
	while (!spritevisit[link])
	{
		int data2 = READ_WORD (&base[link * 2 + 0x080]);

		/* a picture of 0xffff is really an interrupt - gross! */
		if (data2 == 0xffff)
		{
			int data1 = READ_WORD (&base[link * 2 + 0x000]);
			int vsize = (data1 & 15) + 1;
			int ypos = (256 - (data1 >> 5) - vsize * 8) & 0x1ff;

			/* only generate timers on visible scanlines */
			if (ypos < YDIM)
				timer[ypos] = 1;
		}

		/* link to the next object */
		spritevisit[link] = 1;
		link = READ_WORD (&atarigen_spriteram[bank + link * 2 + 0x180]) & 0x3f;
	}

	/* update our interrupt timers */
	for (i = 0; i < YDIM; i++)
	{
		if (timer[i] && !int3_timer[i])
			int3_timer[i] = timer_set (cpu_getscanlinetime (i), i, atarisys1_int3_callback);
		else if (!timer[i] && int3_timer[i])
		{
			timer_remove (int3_timer[i]);
			int3_timer[i] = 0;
		}
	}
}


/*
 *---------------------------------------------------------------------------------
 *
 * 	Motion Object encoding
 *
 *		4 16-bit words are used total
 *
 *		Word 1: Vertical position
 *
 *			Bits 0-3   = vertical size of the object, in tiles
 *			Bits 5-13  = vertical position
 *			Bit  15    = horizontal flip
 *
 *		Word 2: Image
 *
 *			Bits 0-15  = index of the image; the upper 8 bits are passed through a
 *			             pair of lookup PROMs to select which graphics bank and color
 *			              to use (high bit of color is ignored and comes from Bit 15, below)
 *
 *		Word 3: Horizontal position
 *
 *			Bits 0-3   = horizontal size of the object, in tiles
 *			Bits 5-13  = horizontal position
 *			Bit  15    = special playfield priority
 *
 *		Word 4: Link
 *
 *			Bits 0-5   = link to the next motion object
 *
 *---------------------------------------------------------------------------------
 */

void atarisys1_calc_mo_colors (struct osd_bitmap *bitmap, struct rectangle *clip, unsigned short *data, void *param)
{
	unsigned char *colors = param;
	int lookup = molookup[data[1] >> 8];
	int color = LCOLOR (lookup);
	colors[color] = 1;
}

void atarisys1_render_mo (struct osd_bitmap *bitmap, struct rectangle *clip, unsigned short *data, void *param)
{
	struct atarisys1_mo_data *modata = param;
	int y, sy, redraw_val;

	/* extract data from the various words */
	int pict = data[1];
	int lookup = molookup[pict >> 8];
	int vsize = (data[0] & 15) + 1;
	int xpos = data[2] >> 5;
	int ypos = 256 - (data[0] >> 5) - vsize * 8;
	int color = LCOLOR (lookup);
	int bank = LBANK (lookup);
	int hflip = data[0] & 0x8000;
	int hipri = data[2] & 0x8000;

	/* adjust the final coordinates */
	xpos &= 0x1ff;
	ypos &= 0x1ff;
	redraw_val = (xpos << 23) + (ypos << 14) + vsize;
	if (xpos >= XDIM) xpos -= 0x200;
	if (ypos >= YDIM) ypos -= 0x200;

	/* bail if X coordinate is out of range */
	if (xpos <= -8 || xpos >= XDIM)
		return;

	/* do we have a priority color active? */
	if (modata->pcolor)
	{
		int *redraw_list = modata->redraw_list, *redraw = modata->redraw;
		int *r;

		/* if so, add an entry to the redraw list for later */
		for (r = redraw_list; r < redraw; )
			if (*r++ == redraw_val)
				break;

		/* but only add it if we don't have a matching entry already */
		if (r == redraw)
		{
			*redraw++ = redraw_val;
			modata->redraw = redraw;
		}
	}

	/*
	 *
	 *      case 1: normal
	 *
	 */

	if (!hipri)
	{
		/* loop over the height */
		for (y = 0, sy = ypos; y < vsize; y++, sy += 8, pict++)
		{
			/* clip the Y coordinate */
			if (sy <= clip->min_y - 8)
				continue;
			else if (sy > clip->max_y)
				break;

			/* draw the sprite */
			drawgfx (bitmap, Machine->gfx[bank],
					LPICT (lookup) | (pict & 0xff), color,
					hflip, 0, xpos, sy, clip, TRANSPARENCY_PEN, 0);
		}
	}

	/*
	 *
	 *      case 2: translucency
	 *
	 */

	else
	{
		struct rectangle tclip;

		/* loop over the height */
		for (y = 0, sy = ypos; y < vsize; y++, sy += 8, pict++)
		{
			/* clip the Y coordinate */
			if (sy <= clip->min_y - 8)
				continue;
			else if (sy > clip->max_y)
				break;

			/* draw the sprite in bright pink on the real bitmap */
			drawgfx (bitmap, Machine->gfx[bank],
					LPICT (lookup) | (pict & 0xff), 0x30 << mo_map_shift,
					hflip, 0, xpos, sy, clip, TRANSPARENCY_PEN, 0);

			/* also draw the sprite normally on the temp bitmap */
			drawgfx (tempbitmap, Machine->gfx[bank],
					LPICT (lookup) | (pict & 0xff), 0x20 << mo_map_shift,
					hflip, 0, xpos, sy, clip, TRANSPARENCY_NONE, 0);
		}

		/* now redraw the playfield tiles over top of the sprite */

⌨️ 快捷键说明

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