📄 system16.c
字号:
if( data&0x8000 ){
fg_transparency[page][0][row][col] = 1;
fg_transparency[page][1][row][col] = 0;
}
else {
fg_transparency[page][0][row][col] = 0;
fg_transparency[page][1][row][col] = 1;
}
/*
Drawing a foreground tile into the tempbitmap and fatmask tempbitmap is slow!
This could easily be sped up with a custom routine.
*/
/* foreground (transparent) and background (opaque) tiles share the
same palette - we can't draw the tile with transparency_none
because pen#0 isn't transparent. */
rect.max_y = (rect.min_y = sy)+7;
rect.max_x = (rect.min_x = sx)+7;
fillbitmap( bitmap,palette_transparent_pen,&rect );
drawgfx( bitmap, gfx,
tile_number,
(data>>6)&0x7f, /* color */
0, 0, /* no need to flip */
sx, sy,
0, /* no need to clip */
TRANSPARENCY_PEN, 0 );
{ /* now, update the fatmask - one byte (0x00 or 0xff) for each pixel */
int x,y;
for( y=sy; y<sy+8; y++ ){
unsigned char *source = bitmap->line[y]+sx;
unsigned char *dest = fatmask->line[y]+sx;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
*dest++ = (*source++==palette_transparent_pen )?0xff:0x00;
}
}
}
*old_source = data;
}
old_source++;
} /* x */
} /* y */
old_fg_page[page]=sys16_fg_page[page];
} /* page */
}
void sys16_vh_stop( void ){
int page;
for( page=0; page<4; page++ ){
if( fg_page_buffer[page] ) free( fg_page_buffer[page] );
if( fg_bitmap[page] ) osd_free_bitmap( fg_bitmap[page] );
if( fg_fatmask[page] ) osd_free_bitmap( fg_fatmask[page] );
if( bg_page_buffer[page] ) free( bg_page_buffer[page] );
if( bg_bitmap[page] ) osd_free_bitmap( bg_bitmap[page] );
}
}
int sys16_vh_start( void ){
int page;
int fail = 0;
for( page=0; page<4; page++ ){
sys16_fg_page[page] = 0;
sys16_bg_page[page] = 0;
fg_page_buffer[page] = (unsigned short *)malloc(2*TILEMAP_ROWS*TILEMAP_COLS);
fg_bitmap[page] = osd_create_bitmap( TILEMAP_WIDTH, TILEMAP_HEIGHT );
fg_fatmask[page] = osd_create_bitmap( TILEMAP_WIDTH, TILEMAP_HEIGHT );
bg_page_buffer[page] = (unsigned short *)malloc(2*TILEMAP_ROWS*TILEMAP_COLS);
bg_bitmap[page] = osd_create_bitmap( TILEMAP_WIDTH, TILEMAP_HEIGHT );
if( fg_page_buffer[page]==0 || fg_bitmap[page]==0 || fg_fatmask[page]==0 ||
bg_page_buffer[page]==0 || bg_bitmap[page]==0 ) fail = 1;
}
if( fail ){
sys16_vh_stop();
return 1;
}
dirty_all();
{
int i;
/* initialize all entries to black - needed for Golden Axe*/
for( i=0; i<2048; i++ ){
palette_change_color( i, 0,0,0 );
}
}
sys16_tile_bank0 = 0;
sys16_tile_bank1 = 1;
sys16_fg_scrollx = 0;
sys16_fg_scrolly = 0;
sys16_bg_scrollx = 0;
sys16_bg_scrolly = 0;
sys16_refreshenable = 1;
/* common defaults */
sys16_update_proc = 0;
sys16_spritesystem = 1;
sys16_sprxoffset = -0xb8;
return 0;
}
/***************************************************************************/
extern void drawgfxpicture( /* helper function for drawing sprites */
struct osd_bitmap *bitmap,
const unsigned char *source,
int width, int screenheight,
const unsigned short *pal,
int xflip, int yflip,
int sx, int sy,
int zoom,
const struct rectangle *clip
);
void sys16_draw_sprites( struct osd_bitmap *bitmap, int priority ){
const struct rectangle *clip = &Machine->drv->visible_area;
const unsigned short *base_pal = Machine->gfx[0]->colortable + 1024;
const unsigned char *base_gfx = Machine->memory_region[2];
unsigned short *source = (unsigned short *)sys16_spriteram;
unsigned short *finish = source+MAX_SPRITES*8;
if( sys16_spritesystem==1 ){ /* standard sprite hardware */
do{
unsigned short attributes = source[4];
if( ((attributes>>6)&0x3) == priority ){
const unsigned char *gfx = base_gfx + source[3]*4 + (sys16_obj_bank[(attributes>>8)&0xf] << 17);
const unsigned short *pal = base_pal + ((attributes&0x3f)<<4);
int sy = source[0];
int end_line = sy>>8;
sy &= 0xff;
if( end_line == 0xff ) break;
{
int sx = source[1] + sys16_sprxoffset;
int zoom = source[5]&0x3ff;
int width = source[2];
int horizontal_flip = width&0x100;
int vertical_flip = width&0x80;
width = (width&0x7f)*4;
if( vertical_flip ){
width = 512-width;
}
if( horizontal_flip ){
gfx += 4;
if( vertical_flip ) gfx -= width*2;
}
else{
if( vertical_flip ) gfx -= width; else gfx += width;
}
drawgfxpicture(
bitmap,
gfx,
width, end_line - sy,
pal,
horizontal_flip, vertical_flip,
sx, sy,
zoom,
clip
);
/*osd_mark_dirty(sx, sy, sx+width-1, end_line-1, 0);*/
}
}
source += 8;
} while( source<finish );
}
else if( sys16_spritesystem==0 ){ /* passing shot */
do{
unsigned short attributes = source[5];
if( ((attributes>>14)&0x3) == priority ){
int sy = source[1];
if( sy != 0xffff ){
int bank = (attributes>>4)&0xf;
const unsigned short *pal = base_pal + ((attributes>>4)&0x3f0);
int number = source[2];
int horizontal_flip = number & 0x8000;
int zoom = source[4]&0x3ff;
int sx = source[0] + sys16_sprxoffset;
int width = source[3];
int vertical_flip = width&0x80;
int end_line = sy>>8;
sy = sy&0xff;
sy+=2;
end_line+=2;
if( vertical_flip ){
width &= 0x7f;
width = 0x80-width;
}
else{
width &= 0x7f;
}
if( horizontal_flip ){
bank = (bank-1) & 0xf;
if( vertical_flip ){
sx += 5;
}
else {
number += 1-width;
}
}
drawgfxpicture(
bitmap,
base_gfx + number*4 + (sys16_obj_bank[bank] << 17),
width*4, end_line - sy,
pal,
horizontal_flip, vertical_flip,
sx, sy,
zoom,
clip
);
/*osd_mark_dirty(sx, sy, sx+width*4-1, end_line-1, 0);*/
}
}
source += 8;
}while( source<finish );
}
}
static void palette_sprites( unsigned short *base ){
unsigned short *source = (unsigned short *)sys16_spriteram;
unsigned short *finish = source+MAX_SPRITES*8;
if( sys16_spritesystem==1 ){ /* standard sprite hardware */
do{
if( (source[0]>>8) == 0xff ) break;
base[source[4]&0x3f] = 1;
source+=8;
}while( source<finish );
}
else if( sys16_spritesystem==0 ){ /* passing shot */
do{
if( source[1]!=0xffff ) base[(source[5]>>8)&0x3f] = 1;
source+=8;
}while( source<finish );
}
}
/***************************************************************************/
static void draw_text(struct osd_bitmap *bitmap){
const struct GfxElement *gfx = Machine->gfx[0];
const unsigned short *source = (unsigned short *)sys16_textram;
int sx,sy;
for( sy = 0; sy < 28*8; sy+=8 ){
source += TILEMAP_COLS-40;
for( sx = 0; sx < 40*8; sx+=8 ){
unsigned short data = *source++;
int tile_number = data&0x1ff;
if( tile_number ){ /* skip spaces */
drawgfx(bitmap,gfx,
tile_number,
(data >> 9)%8, /* color */
0,0, /* no flip*/
sx,sy,
0, /* no need to clip */
TRANSPARENCY_PEN,0);
/*osd_mark_dirty(sx, sy, sx+8-1, sy+8-1, 0);*/
}
}
}
}
/***************************************************************************/
static void palette_background( unsigned char *base ){
const struct GfxElement *gfx = Machine->gfx[0];
const int mask = Machine->gfx[0]->total_elements - 1;
int page;
for (page=0; page < 4; page++){
const unsigned short *source = ((unsigned short *)sys16_tileram) +
sys16_bg_page[page]*0x800;
const unsigned short *finish = source+TILEMAP_COLS*TILEMAP_ROWS;
do {
unsigned short data = *source++;
int tile_number = (data&0xfff) +
0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
base[(data >> 6)%128] |= gfx->pen_usage[tile_number & mask];
}while( source<finish );
} /* next page */
}
static void palette_foreground( unsigned char *base ){
const struct GfxElement *gfx = Machine->gfx[0];
const int mask = Machine->gfx[0]->total_elements - 1;
int page;
for( page=0; page < 4; page++ ){
const unsigned short *source = ((unsigned short *)sys16_tileram) +
sys16_fg_page[page]*0x800;
int row,col;
unsigned long layer_opacity[TILEMAP_COLS];
for( col=0; col<TILEMAP_COLS; col++ ){
layer_opacity[col] = 0;
}
for( row=0; row<TILEMAP_ROWS; row++ ){
for( col=0; col<TILEMAP_COLS; col++ ){
unsigned short data = *source++;
int tile_number = (data&0xfff) +
0x1000*((data&0x1000)?sys16_tile_bank1:sys16_tile_bank0);
int pen_usage = gfx->pen_usage[tile_number & mask];
if( pen_usage&1 ) layer_opacity[col] |= (1<<row);
base[(data >> 6)%128] |= 0xFE & pen_usage;
}
}
/* compute screenwise opacity */
{
unsigned long temp[SCREENCOLS+2];
int sx = ((page&1)*512+320+sys16_fg_scrollx)&0x3ff;
int sy = ((page>>1)*256+256-sys16_fg_scrolly)&0x1ff;
int unaligned_x = sx&0x7;
int unaligned_y = sy&0x7;
if( sx>320 ) sx-=1024;
if( sy>224 ) sy-=512;
if( sy > -TILEMAP_HEIGHT && sy<224 ){
sx = sx/8+1;
sy = sy/8+1;
for( col=0; col<SCREENCOLS+2; col++ ){
int c = col-sx;
if( c>=0 && c<TILEMAP_COLS ){
if( sy>0 ){
temp[col] = layer_opacity[c]<<sy;
}
else {
temp[col] = layer_opacity[c]>>(-sy);
}
}
else {
temp[col] = 0;
}
}
if( unaligned_y ){
for( col=0; col<SCREENCOLS+2; col++ ){
temp[col] |= (temp[col]>>1)|(temp[col]<<1);
}
}
if( unaligned_x ){
for( col=1; col<SCREENCOLS+1; col++ ) temp[col] |= temp[col+1];
for( col=SCREENCOLS; col>=1; col-- ) temp[col] |= temp[col-1];
}
for( col=0; col<SCREENCOLS; col++ ){
screenwise_opacity[col] |= temp[col+1]>>1;
}
}
}
} /* next page */
}
static void palette_text( unsigned char *base ){
const struct GfxElement *gfx = Machine->gfx[0];
const int mask = Machine->gfx[0]->total_elements - 1;
const unsigned short *source = (unsigned short *)sys16_textram;
int sx,sy;
for( sy = 0; sy < 28*8; sy+=8 ){
source += TILEMAP_COLS-40;
for( sx = 0; sx < 40*8; sx+=8 ){
unsigned short data = *source++;
int tile_number = data&0x1ff;
if( tile_number ){ /* skip spaces */
base[(data >> 9)%8] |= 0xFE & gfx->pen_usage[tile_number & mask] & 0xfe;
}
}
}
}
static void refresh_palette( void ){
unsigned char *pal = &palette_used_colors[0];
/* compute palette usage */
unsigned char palette_map[128];
unsigned short sprite_map[MAX_SPRITES];
int i,j;
for( i=0; i<SCREENCOLS; i++ ) screenwise_opacity[i] = 0;
memset (palette_map, 0, sizeof (palette_map));
memset (sprite_map, 0, sizeof (sprite_map));
palette_background( palette_map );
palette_foreground( palette_map );
palette_text( palette_map );
palette_sprites( sprite_map );
/* expand the results */
for( i = 0; i < 128; i++ ){
int usage = palette_map[i];
if (usage){
for (j = 0; j < 8; j++)
if (usage & (1 << j))
pal[j] = PALETTE_COLOR_USED;
else
pal[j] = PALETTE_COLOR_UNUSED;
}
else {
memset (pal, PALETTE_COLOR_UNUSED, 8);
}
pal += 8;
}
for (i = 0; i < MAX_SPRITES; i++){
if ( sprite_map[i] ){
pal[0] = PALETTE_COLOR_UNUSED;
for (j = 1; j < 15; j++) pal[j] = PALETTE_COLOR_USED;
pal[15] = PALETTE_COLOR_UNUSED;
}
else {
memset( pal, PALETTE_COLOR_UNUSED, 16 );
}
pal += 16;
}
if( palette_recalc () ) dirty_all();
}
/***************************************************************************/
void sys16_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh){
if( sys16_update_proc ) sys16_update_proc();
if( sys16_refreshenable ){
int opacity_check = osd_key_pressed( OSD_KEY_O );
refresh_palette();
update_background();
update_foreground();
if( opacity_check ) fillbitmap( bitmap, 0, 0 );
draw_background(bitmap);
sys16_draw_sprites(bitmap,1);
if( !opacity_check ) draw_foreground(bitmap,0);
sys16_draw_sprites(bitmap,2);
if( !opacity_check ) draw_foreground(bitmap,1);
draw_text(bitmap);
sys16_draw_sprites(bitmap,3);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -