📄 liberatr.c
字号:
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 + -