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

📄 system16.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
						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 + -