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

📄 liberatr.c

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

	if( lib_videoram )
	{
		free( lib_videoram ) ;
		lib_videoram = NULL ;
	}
	if( lib_raw_colorram )
	{
		free( lib_raw_colorram ) ;
		lib_raw_colorram = NULL ;
	}
	if( lib_basram )
	{
		free( lib_basram ) ;
		lib_basram = NULL ;
	}
	if( lib_planet_segs[0] )
	{
		for( i = 0 ; i < 256 ; i++ )
			if( (*lib_planet_segs[0]).view[i] )
				free( (*lib_planet_segs[0]).view[i] ) ;
		free( lib_planet_segs[0] ) ;
		lib_planet_segs[0] = NULL ;
	}
	if( lib_planet_segs[1] )
	{
		for( i = 0 ; i < 256 ; i++ )
			if( (*lib_planet_segs[1]).view[i] )
				free( (*lib_planet_segs[1]).view[i] ) ;
		free( lib_planet_segs[1] ) ;
		lib_planet_segs[1] = NULL ;
	}

	osd_free_bitmap(tmpbitmap);
	tmpbitmap = NULL ;

} /* liberator_vh_stop */

/********************************************************************************************
  lib_init_planet()

  The data for the planet is stored in ROM using a run-length type of encoding.  This
  function does the conversion to the above structures and then a smaller
  structure which is quicker to use in real time.

  Its a multi-step process, reflecting the history of the code.  Not quite as efficient
  as it might be, but this is not realtime stuff, so who cares...
 ********************************************************************************************/
static void
lib_init_planet()
{
	unsigned long	i, addr, cc, lg, misc, fsg, lgs, lts, x, nsegs, maxnsegs=0, totalnsegs=0, strt_scg ;
	unsigned long	x_a[32],cc_a[32],fsg_a[32] ;
	unsigned long	startlg, vdl, scg;
	unsigned char	*buf ;
	unsigned short	pprom ;
	LibSegs			*line = NULL ;
	LibView			*view = NULL ;

	/*
	// for each starting longitude
	*/
	for(startlg=0 ; startlg < 0x100 ; startlg++)
	{
		totalnsegs = 0 ;

		if( view == NULL )
			if( (view = (LibView *)calloc( 1, sizeof( LibView ) )) == NULL )
				return ;

		/*
		// for each latitude (vdl)
		*/
		for( vdl = 0 ; vdl <= 0x7f ; vdl++ )
		{
			/*
			// point to the structure which will hold the data for this line
			*/
			line = &(*view).line[ vdl ] ;

			/*
			// latitude scaling factor
			*/
			lts = ltscale[ vdl ] ;

			/*
			// for this latitude (vdl), load the 32 segments into the _a arrays
			*/
			memset( fsg_a , 0 , 32*sizeof(unsigned long) ) ;
			for( scg = 0 ; scg <= 0x1f ; scg++ )
			{
				/*
				// read the planet picture ROM and get the
				//   latitude and longitude scaled from the scaling PROMS
				*/
				addr = (vdl << 5) + scg ;
				if( lib_planetbit )
					pprom = (ROM[0x0000+addr] << 8) + ROM[0x1000+addr] ;
				else
					pprom = (ROM[0x2000+addr] << 8) + ROM[0x3000+addr] ;

				misc =  (pprom >> 12) & 0x07 ;
				cc   =  (pprom >>  8) & 0x0f ;
				lg   = ((pprom <<  1) & 0x1fe) + ((pprom >> 15) & 0x01) ;

				/*
				// scale the longitude limit (adding the starting longitude)
				*/
				addr = startlg + ( lg >> 1 ) + ( lg & 1 ) ;		/* shift with rounding */
				fsg        =
				fsg_a[scg] = (( addr & 0x100 ) ? 1 : 0) ;
				if( addr & 0x80 )
				{
					lgs = 0xff ;
				}
				else
				{
					addr = ((addr & 0x7f) << 1) + (((lg & 1) || fsg) ? 0 : 1) ;
					lgs = lgscale[ addr ] ;
				}

				/*
				// x_a  is the x coordinate limit for this segment
				// cc_a is the color of this segment
				*/
				x_a[ scg ]  = ((lts * lgs) + 0x80) >> 8 ;	/* round it */
				cc_a[ scg ] = cc ;

			} /* scg */

			/*
			// determine which segment is the western horizon and
			//   leave scg indexing it.
			*/
			for( scg = 0 ; scg < 0x20 ; scg++ )
				if( fsg_a[scg] ) break;
			if( scg >= 0x20 )
				scg = 0x1f ;

			/*
			// transfer from the temporary arrays to the structure
			*/
			(*line).xmax =  (lts * 0xc0) >> 8 ;
			if( (*line).xmax & 1 )
				(*line).xmax += 1 ; 				/* make it even */

			/*
			// as part of the quest to reduce memory usage (and to a lesser degree
			//   execution time), stitch together segments that have the same color
			*/
			nsegs = 0 ;
			i = 0 ;
			strt_scg = scg ;
			do {
				cc = cc_a[scg] ;
				while( cc == cc_a[scg] )
				{
					x = x_a[scg] ;
					scg = (scg+1) & 0x1f ;
					if( scg == strt_scg )
						break;
				}
				(*line).cc_a[ i ] = cc ;
				(*line).x_a[ i ]  = (x > (*line).xmax) ? (*line).xmax : x ;
				i++ ;
				nsegs++ ;
			} while( (i < 32) && (x <= (*line).xmax) ) ;
			if( nsegs > maxnsegs ) maxnsegs = nsegs ;
			totalnsegs += nsegs ;
			(*line).nsegs = nsegs ;

		} /* vdl */

		/* now that the all the lines have been processed, and we know how
		//   many segments it will take to store the description, allocate the
		//   space for it and copy the data to it.
		*/
		if( (buf = (unsigned char *)calloc( sizeof(unsigned char), 2*(128 + totalnsegs) ) ) == NULL)
			return ;
		(*lib_planet_segs[ lib_planetbit ]).view[ startlg ] = buf ;
		for( vdl = 0 ; vdl < 128 ; vdl++ )
		{
			line  = &(*view).line[ vdl ] ;
			nsegs  = (*line).nsegs ;
			*buf++ = nsegs ;
#if LIB_ASPECTRATIO_512x384
			/* calculate the tmpbitmap's x coordinate for the western horizon
			//   center of tmpbitmap - (the number of planet pixels) / 2 */
			*buf++ = Machine->drv->screen_width/2 - (((*line).xmax) + 1) / 2 ;
#elif LIB_ASPECTRATIO_342x256
			/* calculate the tmpbitmap's x coordinate for the western horizon
			//   center of tmpbitmap - (two thirds of number of planet pixels) / 2 */
			*buf++ = Machine->drv->screen_width/2 - (((*line).xmax + 1) * 2) / 6 ;
#endif
			for( i = 0 ; i < nsegs ; i++ )
			{
				*buf++ = (*line).cc_a[ i ] ;
				*buf++ = (*line).x_a[ i ] ;
			}

		}

	} /* startlg */

	if( view != NULL )
		free( view ) ;

	return ;

} /* lib_init_planet */


/********************************************************************************************/
static void lib_drawplanet(int data)
{
	unsigned int	vdl, scg, startlg ;
	unsigned int	xa , cc, base, x, y, nsegs  ;
	unsigned int	tbmX  ;
	unsigned char	*tbm ;
	unsigned char	*buf ;
	unsigned char reverse_map[256];


	for (x = 0;x < 0x20;x++)
		reverse_map[Machine->pens[x]] = x;

	startlg = data & 0xff ;

	if( lib_planet_segs[ lib_planetbit ] )
		buf = (*lib_planet_segs[ lib_planetbit ]).view[ startlg ] ;
	else
		return ;

	/*
	// for each latitude (vdl)
	*/
	for( vdl = 0 ; vdl <= 0x7f ; vdl++ )
	{
		/*
		// grab the color value for the base (if any) at this latitude
		*/
		base = lib_basram[ (vdl>>3) & 0x0f ] ;
		base = base ^ 0x0f ;

		x = 0 ;					/* from the western horizon */
		nsegs = *buf++ ;
		tbmX  = *buf++ ;

#if LIB_ASPECTRATIO_512x384

		y = ((64 + vdl) * 3 + 1) / 2 ;

#elif LIB_ASPECTRATIO_342x256

		y = 64 + vdl ;

#endif

		/*
		// run through the segments, drawing its color
		//   until its x_a value comes up.
		*/
		for( scg = 0 ; scg < nsegs ; scg++ )
		{
			cc = *buf++ ;
			xa = *buf++ ;
			if( (cc & 0x0c) == 0x0c )
				cc = base ;

			while( x < xa )
			{

#if LIB_ASPECTRATIO_512x384
				/* planet video doesn't overwrite bitmap video, so
				//   check the tmpbitmap where we want to draw into.
				// bitmap writes into the tmpbitmap all have bit 4 (0x10) set
				//   (they use pens 0x10-0x17)
				*/
				tbm = &(tmpbitmap->line[y][tbmX]) ;
				if (reverse_map[*tbm] <= 0x10)
					*tbm = Machine->pens[cc];
				if( (vdl & 1) == 0 )
				{
					tbm = &(tmpbitmap->line[y+1][tbmX]) ;
					if (reverse_map[*tbm] <= 0x10)
						*tbm = Machine->pens[cc];
				}

#elif LIB_ASPECTRATIO_342x256
				tbm = &(tmpbitmap->line[y][tbmX]) ;
				/* Draw the planet only over itself, or over black. */
				/* The planet uses pens 0x00-0x0f, black is 0x10 */
				if (reverse_map[*tbm] <= 0x10)
					*tbm = Machine->pens[cc];

				/* taking two out of three of the planet pixels.  skip over
				//   an x pixel every other tmpbitmap pixel */
				if( tbmX & 1 )
					x++ ;

#endif
				x++ ;
				tbmX++ ;

			} /* while */
		} /* scg */
	} /* vdl */

} /* lib_drawplanet */


/* -- eof -- */

⌨️ 快捷键说明

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