www.pudn.com > ngcd080s.zip > Video.c


/******************************************* 
**** VIDEO.C - Video Hardware Emulation **** 
*******************************************/ 
 
//-- Include Files ----------------------------------------------------------- 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include "../config/config.h" 
#include "../gui/gui.h" 
 
//-- Defines ----------------------------------------------------------------- 
#define VIDEO_TEXT		0 
#define VIDEO_NORMAL	1 
#define	VIDEO_SCANLINES	2 
 
#define	LINE_BEGIN	mydword = *((int *)fspr) 
#define LINE_MID	mydword = *((int *)fspr+1) 
#define PIXEL_LAST	col = (mydword&0x0F); if (col) *bm = paldata[col] 
#define PIXEL_R		col = (mydword&0x0F); if (col) *bm = paldata[col]; bm-- 
#define PIXEL_F		col = (mydword&0x0F); if (col) *bm = paldata[col]; bm++ 
#define SHIFT7		mydword >>= 28 
#define SHIFT6		mydword >>= 24 
#define SHIFT5		mydword >>= 20 
#define SHIFT4		mydword >>= 16 
#define SHIFT3		mydword >>= 12 
#define SHIFT2		mydword >>= 8 
#define SHIFT1		mydword >>= 4 
 
//-- Imported Variables ------------------------------------------------------ 
extern char				global_error[80]; 
extern unsigned char	*neogeo_fix_memory; 
extern unsigned char	*neogeo_spr_memory; 
extern BITMAP			*loading_pict; 
 
//-- Imported Functions ------------------------------------------------------ 
extern void		video_draw_fix(void); 
extern void		neogeo_fast_clear(void *, int); 
extern void		neogeo_fast_copy(void *, void *, int, int, int, int, int, int); 
extern void		neogeo_fast_copy_scanlines(void *, void *, int, int, int, int,  
					int, int); 
 
//-- Global Variables -------------------------------------------------------- 
char			*video_vidram; 
unsigned short	*video_paletteram_ng; 
unsigned short	video_palette_bank0_ng[4096]; 
unsigned short	video_palette_bank1_ng[4096]; 
unsigned short	*video_paletteram_pc; 
unsigned short	video_palette_bank0_pc[4096]; 
unsigned short	video_palette_bank1_pc[4096]; 
unsigned short	video_color_lut[32768]; 
short			video_modulo; 
unsigned short	video_pointer; 
int				video_dos_cx; 
int				video_dos_cy; 
int				video_mode = 0; 
unsigned short	*video_line_ptr[224]; 
unsigned char	video_fix_usage[4096]; 
unsigned char	video_spr_usage[32768]; 
BITMAP			*video_buffer; 
BITMAP			*game_title; 
unsigned char	video_shrinky[17]; 
char			full_y_skip[16]={0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; 
 
unsigned int	neogeo_frame_counter = 0; 
unsigned int	neogeo_frame_counter_speed = 4; 
 
unsigned int	video_hide_fps=1; 
int				video_scanlines_capable = 1; 
double			gamma_correction = 1.0; 
 
//-- Function Prototypes ----------------------------------------------------- 
int		video_init(void); 
void	video_shutdown(void); 
void	video_draw_line(int); 
int		video_set_mode(int); 
void	video_precalc_lut(void); 
void	video_flip_pages(void); 
void	video_draw_spr(unsigned int code, unsigned int color, int flipx, 
			int flipy, int sx, int sy, int zx, int zy); 
void	video_draw_screen1(void); 
void	video_draw_screen2(void); 
void	video_save_snapshot(void); 
void	video_setup(void); 
 
char	*video_getter(int ind, int *list_size) 
{ 
	static char *vmode_name[] = 
	{ 
		"VESA 1.x", 
		"VBE  2.0 (Banked)", 
		"VBE  2.0 (Linear)", 
		"VBE  3.0", 
		"VBE/AF" 
	}; 
 
   if (ind < 0) { 
      *list_size = 5; 
      return NULL; 
   } 
   else 
      return vmode_name[ind]; 
} 
 
DIALOG video_setup_dlg[] = 
{ 
   /* (dialog proc)   (x)  (y)  (w)  (h)    (fg)    (bg)  (key)  (flags)   (d1)  (d2)            (dp) */ 
 {d_neo_border_proc,   0,   0, 150, 200, 0x0000, 0x0000,      0,      0,     0,    0,                NULL}, 
 {d_neo_fbox_proc,     2,   2, 146,   8, 0x0000, 0x10E3,      0,      0,     0,    0,                NULL}, 
 {d_text_proc,        10,   3,   0,   0, 0xFFFF, 0x10E3,      0,      0,     0,    0,    "Video Settings"}, 
 {d_neo_gbox_proc,     5,  20, 140,  45, 0xC71C, 0x328A,      0,      0,     0,    0,        "VESA Setup"}, 
 {d_neo_list_proc,    10,  25, 130,  35, 0xC71C, 0x328A,      0,      0,     0,    0,        video_getter}, 
 {d_neo_gbox_proc,     5,  74, 140,  33, 0xC71C, 0x328A,      0,      0,     0,    0,      "Screen Setup"}, 
 {d_neo_radio_proc,   10,  80,  10,  10, 0xFFFF, 0x9596,    '4',      0,     0,    0,          "320x2&40"}, 
 {d_neo_radio_proc,   10,  92,  10,  10, 0xFFFF, 0x9596,    '8',      0,     0,    0,"320x4&80 Scanlines"}, 
 {d_neo_gbox_proc,     5, 115, 140,  45, 0xC71C, 0x328A,      0,      0,     0,    0,        "Sync Setup"}, 
 {d_neo_radio_proc,   10, 121,  10,  10, 0xFFFF, 0x9596,    'v',      0,     1,    0,            "&VSync"}, 
 {d_neo_radio_proc,   10, 133,  10,  10, 0xFFFF, 0x9596,    's',      0,     1,    0,    "&Speed Limiter"}, 
 {d_neo_radio_proc,   10, 145,  10,  10, 0xFFFF, 0x9596,    'n',      0,     1,    0,             "&None"}, 
 {d_neo_check_proc,   10, 164,  10,  10, 0xFFFF, 0x9596,    'f',      0,     0,    0, "Show &FPS Counter"}, 
 {d_neo_button_proc,  50, 180,  50,  15, 0x0000, 0x0000,    'o', D_EXIT,     0,    0,               "&OK"}, 
 {NULL,                0,   0,   0,   0, 0x0000, 0x0000,      0,      0,     0,    0,                NULL} 
}; 
 
static int mode_list[] =  
{ 
	GFX_VESA1, 
	GFX_VESA2B, 
	GFX_VESA2L, 
	GFX_VESA3, 
	GFX_VBEAF 
}; 
 
//---------------------------------------------------------------------------- 
int	video_init(void) 
{ 
	int		y; 
	unsigned short	*ptr; 
	FILE		*fp; 
	 
	video_precalc_lut(); 
	 
	video_vidram = calloc(1, 131072); 
	 
	if (video_vidram==NULL) { 
		strcpy(global_error, "VIDEO: Could not allocate vidram (128k)"); 
		return	0; 
	} 
	 
	memset(video_palette_bank0_ng, 0, 8192); 
	memset(video_palette_bank1_ng, 0, 8192); 
	memset(video_palette_bank0_pc, 0, 8192); 
	memset(video_palette_bank1_pc, 0, 8192); 
 
	video_paletteram_ng = video_palette_bank0_ng; 
	video_paletteram_pc = video_palette_bank0_pc; 
	video_modulo = 0; 
	video_pointer = 0; 
	 
	set_color_depth(16); 
	 
	if (!video_set_mode(VIDEO_SCANLINES)) 
		video_scanlines_capable = 0; 
 
	if (video_set_mode(VIDEO_NORMAL)==0) 
		return 0; 
 
	video_buffer = create_bitmap(320, 226); 
	loading_pict = create_bitmap(320, 240); 
	game_title = create_bitmap(144,80); 
 
	ptr = (unsigned short *)(video_buffer->line[0]) + 8; 
	 
	for(y=0;y<224;y++) { 
		video_line_ptr[y] = ptr; 
		ptr += 320; 
	} 
 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
void	video_shutdown(void) 
{ 
	free(video_vidram); 
	destroy_bitmap( video_buffer ); 
	destroy_bitmap( loading_pict ); 
	destroy_bitmap( game_title ); 
} 
 
//---------------------------------------------------------------------------- 
int	video_set_mode(int mode) 
{ 
	if ((video_scanlines_capable == 0)&&(mode == VIDEO_SCANLINES)) 
	{ 
		config_scanlines = 0; 
		mode = VIDEO_NORMAL; 
		clear(screen); 
	} 
	 
	if (video_mode != mode) 
	{ 
		switch( mode ) 
		{ 
			case	VIDEO_TEXT: 
				set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); 
				break; 
			case	VIDEO_NORMAL: 
				if (set_gfx_mode(GFX_AUTODETECT, 320, 240, 320, 240)<0) { 
					video_mode = -1; 
					strcpy(global_error, "VIDEO: FATAL - "); 
					strcat(global_error, allegro_error); 
					return 0; 
				} 
				break; 
			case	VIDEO_SCANLINES: 
				if (set_gfx_mode(GFX_AUTODETECT, 320, 480, 320, 480)<0) { 
					video_mode = -1; 
					strcpy(global_error, "VIDEO: FATAL - "); 
					strcat(global_error, allegro_error); 
					return 0; 
				} 
				break; 
		} 
 
		video_mode = mode; 
	} 
	 
	return 1; 
} 
//---------------------------------------------------------------------------- 
void	video_precalc_lut(void) 
{ 
	int	ndx, rr, rg, rb; 
 
	// Allegro 3.9.25 workaround: inverted r & b 
	 
	for(rr=0;rr<32;rr++) { 
		for(rg=0;rg<32;rg++) { 
			for(rb=0;rb<32;rb++) { 
				ndx = ((rr&1)<<14)|((rg&1)<<13)|((rb&1)<<12)|((rr&30)<<7) 
					|((rg&30)<<3)|((rb&30)>>1); 
				video_color_lut[ndx] = 
				     ((int)( 31 * pow( (double)rb / 31, 1 / gamma_correction ) )<<_rgb_r_shift_16) 
					|((int)( 63 * pow( (double)rg / 31, 1 / gamma_correction ) )<<_rgb_g_shift_16) 
					|((int)( 31 * pow( (double)rr / 31, 1 / gamma_correction ) )<<_rgb_b_shift_16); 
			} 
		} 
	} 
} 
 
//---------------------------------------------------------------------------- 
void video_draw_screen1() 
{ 
	static int	fc; 
	int			sx =0,sy =0,oy =0,my =0,zx = 1, rzy = 1; 
	int			offs,i,count,y,x; 
	int			tileno,tileatr,t1,t2,t3; 
	char		fullmode=0; 
	int			ddax=0,dday=0,rzx=15,yskip=0; 
 
	static int	fps = 0, eval_fps = 0; 
	static uclock_t	a = 0, b = 0; 
 
	neogeo_fast_clear(video_buffer->line[0], video_paletteram_pc[4095]); 
 
	for (count=0;count<0x300;count+=2) { 
		t3 = *((unsigned short *)( &video_vidram[0x10000 + count] )); 
		t1 = *((unsigned short *)( &video_vidram[0x10400 + count] )); 
		t2 = *((unsigned short *)( &video_vidram[0x10800 + count] )); 
 
		// If this bit is set this new column is placed next to last one 
		if (t1 & 0x40) { 
			sx += (rzx + 1); 
			if ( sx >= 0x1F0 ) 
				sx -= 0x200; 
 
			// Get new zoom for this column 
			zx = (t3 >> 8)&0x0F; 
 
			sy = oy; 
		} else {	// nope it is a new block 
			// Sprite scaling 
			zx = (t3 >> 8)&0x0F; 
 
			rzy = t3 & 0xff; 
 
			sx = (t2 >> 7); 
			if ( sx >= 0x1F0 ) 
				sx -= 0x200; 
 
			// Number of tiles in this strip 
			my = t1 & 0x3f; 
			if (my == 0x20) 
				fullmode = 1; 
			else if (my >= 0x21) 
				fullmode = 2;	// most games use 0x21, but 
			else  
				fullmode = 0;	// Alpha Mission II uses 0x3f 
 
			sy = 0x1F0 - (t1 >> 7); 
			if (sy > 0x100) sy -= 0x200; 
			 
			if (fullmode == 2 || (fullmode == 1 && rzy == 0xff)) 
			{ 
				while (sy < -16) sy += 2 * (rzy + 1); 
			} 
			oy = sy; 
 
		  	if(my==0x21) my=0x20; 
			else if(rzy!=0xff && my!=0) 
				my=((my*16*256)/(rzy+1) + 15)/16; 
 
            		if(my>0x20) my=0x20; 
 
			ddax=0;	// setup x zoom 
		} 
 
		rzx = zx; 
 
		// No point doing anything if tile strip is 0 
		if ((my==0)||(sx>311)) 
			continue; 
 
		// Setup y zoom 
		if(rzy==255) 
			yskip=16; 
		else 
			dday=0;	// =256; NS990105 mslug fix 
 
		offs = count<<6; 
 
		// my holds the number of tiles in each vertical multisprite block 
		for (y=0; y < my ;y++) { 
			tileno  = *((unsigned short *)(&video_vidram[offs])); 
			offs+=2; 
			tileatr = *((unsigned short *)(&video_vidram[offs])); 
			offs+=2; 
 
			if (tileatr&0x8) 
				tileno = (tileno&~7)|(neogeo_frame_counter&7); 
			else if (tileatr&0x4) 
				tileno = (tileno&~3)|(neogeo_frame_counter&3); 
				 
//			tileno &= 0x7FFF; 
			if (tileno>0x7FFF) 
				continue; 
 
			if (fullmode == 2 || (fullmode == 1 && rzy == 0xff)) 
			{ 
				if (sy >= 224) sy -= 2 * (rzy + 1); 
			} 
			else if (fullmode == 1) 
			{ 
				if (y == 0x10) sy -= 2 * (rzy + 1); 
			} 
			else if (sy > 0x100) sy -= 0x200; 
 
			if(rzy!=255) 
			{ 
				yskip=0; 
				video_shrinky[0]=0; 
				for(i=0;i<16;i++) 
				{ 
					video_shrinky[i+1]=0; 
					dday-=rzy+1; 
					if(dday<=0) 
					{ 
						dday+=256; 
						yskip++; 
						video_shrinky[yskip]++; 
					} 
					else 
						video_shrinky[yskip]++; 
				} 
			} 
 
            if (((tileatr>>8)||(tileno!=0))&&(sy<224)) 
			{ 
				video_draw_spr( 
					tileno, 
					tileatr >> 8, 
					tileatr & 0x01,tileatr & 0x02, 
					sx,sy,rzx,yskip); 
			} 
 
			sy +=yskip; 
		}  // for y 
	}  // for count 
 
	video_draw_fix(); 
	 
	if ((uclock() - a) > UCLOCKS_PER_SEC) 
	{ 
		a = uclock(); 
		fps = eval_fps; 
		eval_fps = -1; 
	} 
	 
	if (video_hide_fps == 0) 
		textprintf(video_buffer, font, 302, 0, 0x0000FF, "%03d", fps); 
	 
	if (config_vsync == 1) 
	{ 
		if ((uclock() - b) < (UCLOCKS_PER_SEC/60)) 
			vsync(); 
 
		b = uclock(); 
	} 
	 
	if (config_vsync == 2) 
	{ 
		while( (uclock() - b) < (UCLOCKS_PER_SEC/60) ); 
		b = uclock(); 
	} 
 
	if (config_scanlines) 
		neogeo_fast_copy_scanlines(video_buffer, screen, 16, 0, 8, 16, 304, 224); 
	else 
		neogeo_fast_copy(video_buffer, screen, 16, 0, 8, 8, 304, 224); 
	 
	if (fc >= neogeo_frame_counter_speed) { 
		neogeo_frame_counter++; 
		fc=0; 
	} 
 
	fc++; 
	eval_fps++; 
} 
 
void video_draw_screen2() 
{ 
	static int	fc; 
	int			sx =0,sy =0,oy =0,my =0,zx = 1, rzy = 1; 
	int			offs,i,count,y,x; 
	int			tileno,tileatr,t1,t2,t3; 
	char		fullmode=0; 
	int			ddax=0,dday=0,rzx=15,yskip=0; 
 
	static int	fps = 0, eval_fps = 0; 
	static uclock_t	a = 0, b = 0; 
 
	neogeo_fast_clear(video_buffer->line[0], video_paletteram_pc[4095]); 
 
	for (count=48;count<0x300;count+=2) { 
		t3 = *((unsigned short *)( &video_vidram[0x10000 + count] )); 
		t1 = *((unsigned short *)( &video_vidram[0x10400 + count] )); 
		t2 = *((unsigned short *)( &video_vidram[0x10800 + count] )); 
 
		// If this bit is set this new column is placed next to last one 
		if (t1 & 0x40) { 
			sx += (rzx + 1); 
			if ( sx >= 0x1F0 ) 
				sx -= 0x200; 
 
			// Get new zoom for this column 
			zx = (t3 >> 8)&0x0F; 
 
			sy = oy; 
		} else {	// nope it is a new block 
			// Sprite scaling 
			zx = (t3 >> 8)&0x0F; 
 
			rzy = t3 & 0xff; 
 
			sx = (t2 >> 7); 
			if ( sx >= 0x1F0 ) 
				sx -= 0x200; 
 
			// Number of tiles in this strip 
			my = t1 & 0x3f; 
			if (my == 0x20) 
				fullmode = 1; 
			else if (my >= 0x21) 
				fullmode = 2;	// most games use 0x21, but 
			else  
				fullmode = 0;	// Alpha Mission II uses 0x3f 
 
			sy = 0x1F0 - (t1 >> 7); 
			if (sy > 0x100) sy -= 0x200; 
			 
			if (fullmode == 2 || (fullmode == 1 && rzy == 0xff)) 
			{ 
				while (sy < -16) sy += 2 * (rzy + 1); 
			} 
			oy = sy; 
 
		  	if(my==0x21) my=0x20; 
			else if(rzy!=0xff && my!=0) 
				my=((my*16*256)/(rzy+1) + 15)/16; 
 
            		if(my>0x20) my=0x20; 
 
			ddax=0;	// setup x zoom 
		} 
 
		rzx = zx; 
 
		// No point doing anything if tile strip is 0 
		if ((my==0)||(sx>311)) 
			continue; 
 
		// Setup y zoom 
		if(rzy==255) 
			yskip=16; 
		else 
			dday=0;	// =256; NS990105 mslug fix 
 
		offs = count<<6; 
 
		// my holds the number of tiles in each vertical multisprite block 
		for (y=0; y < my ;y++) { 
			tileno  = *((unsigned short *)(&video_vidram[offs])); 
			offs+=2; 
			tileatr = *((unsigned short *)(&video_vidram[offs])); 
			offs+=2; 
 
			if (tileatr&0x8) 
				tileno = (tileno&~7)|(neogeo_frame_counter&7); 
			else if (tileatr&0x4) 
				tileno = (tileno&~3)|(neogeo_frame_counter&3); 
				 
//			tileno &= 0x7FFF; 
			if (tileno>0x7FFF) 
				continue; 
 
			if (fullmode == 2 || (fullmode == 1 && rzy == 0xff)) 
			{ 
				if (sy >= 224) sy -= 2 * (rzy + 1); 
			} 
			else if (fullmode == 1) 
			{ 
				if (y == 0x10) sy -= 2 * (rzy + 1); 
			} 
			else if (sy > 0x100) sy -= 0x200; 
 
			if(rzy!=255) 
			{ 
				yskip=0; 
				video_shrinky[0]=0; 
				for(i=0;i<16;i++) 
				{ 
					video_shrinky[i+1]=0; 
					dday-=rzy+1; 
					if(dday<=0) 
					{ 
						dday+=256; 
						yskip++; 
						video_shrinky[yskip]++; 
					} 
					else 
						video_shrinky[yskip]++; 
				} 
			} 
 
            if (((tileatr>>8)||(tileno!=0))&&(sy<224)) 
			{ 
				video_draw_spr( 
					tileno, 
					tileatr >> 8, 
					tileatr & 0x01,tileatr & 0x02, 
					sx,sy,rzx,yskip); 
			} 
 
			sy +=yskip; 
		}  // for y 
	}  // for count 
 
	for (count=0;count<48;count+=2) { 
		t3 = *((unsigned short *)( &video_vidram[0x10000 + count] )); 
		t1 = *((unsigned short *)( &video_vidram[0x10400 + count] )); 
		t2 = *((unsigned short *)( &video_vidram[0x10800 + count] )); 
 
		// If this bit is set this new column is placed next to last one 
		if (t1 & 0x40) { 
			sx += (rzx + 1); 
			if ( sx >= 0x1F0 ) 
				sx -= 0x200; 
 
			// Get new zoom for this column 
			zx = (t3 >> 8)&0x0F; 
 
			sy = oy; 
		} else {	// nope it is a new block 
			// Sprite scaling 
			zx = (t3 >> 8)&0x0F; 
 
			rzy = t3 & 0xff; 
 
			sx = (t2 >> 7); 
			if ( sx >= 0x1F0 ) 
				sx -= 0x200; 
 
			// Number of tiles in this strip 
			my = t1 & 0x3f; 
			if (my == 0x20) 
				fullmode = 1; 
			else if (my >= 0x21) 
				fullmode = 2;	// most games use 0x21, but 
			else  
				fullmode = 0;	// Alpha Mission II uses 0x3f 
 
			sy = 0x1F0 - (t1 >> 7); 
			if (sy > 0x100) sy -= 0x200; 
			 
			if (fullmode == 2 || (fullmode == 1 && rzy == 0xff)) 
			{ 
				while (sy < -16) sy += 2 * (rzy + 1); 
			} 
			oy = sy; 
 
		  	if(my==0x21) my=0x20; 
			else if(rzy!=0xff && my!=0) 
				my=((my*16*256)/(rzy+1) + 15)/16; 
 
            		if(my>0x20) my=0x20; 
 
			ddax=0;	// setup x zoom 
		} 
 
		rzx = zx; 
 
		// No point doing anything if tile strip is 0 
		if ((my==0)||(sx>311)) 
			continue; 
 
		// Setup y zoom 
		if(rzy==255) 
			yskip=16; 
		else 
			dday=0;	// =256; NS990105 mslug fix 
 
		offs = count<<6; 
 
		// my holds the number of tiles in each vertical multisprite block 
		for (y=0; y < my ;y++) { 
			tileno  = *((unsigned short *)(&video_vidram[offs])); 
			offs+=2; 
			tileatr = *((unsigned short *)(&video_vidram[offs])); 
			offs+=2; 
 
			if (tileatr&0x8) 
				tileno = (tileno&~7)|(neogeo_frame_counter&7); 
			else if (tileatr&0x4) 
				tileno = (tileno&~3)|(neogeo_frame_counter&3); 
				 
//			tileno &= 0x7FFF; 
			if (tileno>0x7FFF) 
				continue; 
 
			if (fullmode == 2 || (fullmode == 1 && rzy == 0xff)) 
			{ 
				if (sy >= 248) sy -= 2 * (rzy + 1); 
			} 
			else if (fullmode == 1) 
			{ 
				if (y == 0x10) sy -= 2 * (rzy + 1); 
			} 
			else if (sy > 0x110) sy -= 0x200; 
 
			if(rzy!=255) 
			{ 
				yskip=0; 
				video_shrinky[0]=0; 
				for(i=0;i<16;i++) 
				{ 
					video_shrinky[i+1]=0; 
					dday-=rzy+1; 
					if(dday<=0) 
					{ 
						dday+=256; 
						yskip++; 
						video_shrinky[yskip]++; 
					} 
					else 
						video_shrinky[yskip]++; 
				} 
			} 
 
            if (((tileatr>>8)||(tileno!=0))&&(sy<224)) 
			{ 
				video_draw_spr( 
					tileno, 
					tileatr >> 8, 
					tileatr & 0x01,tileatr & 0x02, 
					sx,sy,rzx,yskip); 
			} 
 
			sy +=yskip; 
		}  // for y 
	}  // for count 
 
	video_draw_fix(); 
	 
	if ((uclock() - a) > UCLOCKS_PER_SEC) 
	{ 
		a = uclock(); 
		fps = eval_fps; 
		eval_fps = -1; 
	} 
	 
	if (video_hide_fps == 0) 
		textprintf(video_buffer, font, 302, 0, 0x0000FF, "%03d", fps); 
	 
	if (config_vsync == 1) 
	{ 
		if ((uclock() - b) < (UCLOCKS_PER_SEC/60)) 
			vsync(); 
 
		b = uclock(); 
	} 
 
	if (config_vsync == 2) 
	{ 
		while( (uclock() - b) < (UCLOCKS_PER_SEC/60) ); 
		b = uclock(); 
	} 
 
	if (config_scanlines) 
		neogeo_fast_copy_scanlines(video_buffer, screen, 16, 0, 8, 16, 304, 224); 
	else 
		neogeo_fast_copy(video_buffer, screen, 16, 0, 8, 8, 304, 224); 
	 
	if (fc >= neogeo_frame_counter_speed) { 
		neogeo_frame_counter++; 
		fc=0; 
	} 
 
	fc++; 
	eval_fps++; 
} 
 
//       Without  flip    	    With Flip 
// 01: X0000000 00000000	00000000 0000000X 
// 02: X0000000 X0000000	0000000X 0000000X 
// 03: X0000X00 00X00000	00000X00 00X0000X 
// 04: X000X000 X000X000	000X000X 000X000X 
// 05: X00X00X0 0X00X000	000X00X0 0X00X00X 
// 06: X0X00X00 X0X00X00	00X00X0X 00X00X0X 
// 07: X0X0X0X0 0X0X0X00	00X0X0X0 0X0X0X0X 
// 08: X0X0X0X0 X0X0X0X0	0X0X0X0X 0X0X0X0X 
// 09: XX0X0X0X X0X0X0X0	0X0X0X0X X0X0X0XX 
// 10: XX0XX0X0 XX0XX0X0	0X0XX0XX 0X0XX0XX 
// 11: XXX0XX0X X0XX0XX0	0XX0XX0X X0XX0XXX 
// 12: XXX0XXX0 XXX0XXX0	0XXX0XXX 0XXX0XXX 
// 13: XXXXX0XX XX0XXXX0	0XXXX0XX XX0XXXXX 
// 14: XXXXXXX0 XXXXXXX0	0XXXXXXX 0XXXXXXX 
// 15: XXXXXXXX XXXXXXX0	0XXXXXXX XXXXXXXX 
// 16: XXXXXXXX XXXXXXXX	XXXXXXXX XXXXXXXX 
 
void	video_draw_spr(unsigned int code, unsigned int color, int flipx, 
			int flipy, int sx, int sy, int zx, int zy) 
{ 
	int						oy, ey, y, dy; 
	unsigned short			*bm; 
	int						col; 
	int						l; 
	int						mydword; 
	unsigned char			*fspr = 0; 
	char					*l_y_skip; 
	const unsigned short	*paldata; 
 
	// Check for total transparency, no need to draw 
	if (video_spr_usage[code] == 0) 
    		return; 
 
	if (sx <= -8) 
		return; 
 
   	if(zy == 16) 
		 l_y_skip = full_y_skip; 
	else 
		 l_y_skip = video_shrinky; 
 
	fspr = neogeo_spr_memory; 
 
	// Mish/AJP - Most clipping is done in main loop 
	oy = sy; 
  	ey = sy + zy -1; 	// Clip for size of zoomed object 
 
	if (sy < 0) 
		sy = 0; 
	if (ey >= 224) 
		ey = 223; 
 
	if (flipy)	// Y flip 
	{ 
		dy = -8; 
		fspr += (code+1)*128 - 8 - (sy-oy)*8; 
	} 
	else		// normal 
	{ 
		dy = 8; 
		fspr += code*128 + (sy-oy)*8; 
	} 
 
	paldata = &video_paletteram_pc[color*16]; 
	 
	if (flipx)	// X flip 
	{ 
		l=0; 
    		switch(zx) { 
		case	0: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_MID; 
				SHIFT7; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	1: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 1; 
				LINE_BEGIN; 
				SHIFT7; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT7; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	2: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 2; 
				LINE_BEGIN; 
				SHIFT5; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT5; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	3: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 3; 
				LINE_BEGIN; 
				SHIFT3; 
				PIXEL_R; 
				SHIFT4; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT3; 
				PIXEL_R; 
				SHIFT4; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	4: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 4; 
				LINE_BEGIN; 
				SHIFT3; 
				PIXEL_R; 
				SHIFT3; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT3; 
				PIXEL_R; 
				SHIFT3; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	5: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 5; 
				LINE_BEGIN; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT3; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT3; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		case	6: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 6; 
				LINE_BEGIN; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	7: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 7; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		case	8: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 8; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				LINE_MID; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	9: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 9; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		case	10: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 10; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				LINE_MID; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		case	11: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 11; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2;	 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2;	 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		case	12: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 12; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				LINE_MID; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT2; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		case	13: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 13; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		case	14: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 14; 
				LINE_BEGIN; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				LINE_MID; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	15: 
			for (y = sy;y <= ey;y++) 
			{ 
				fspr += l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx + 15; 
				LINE_BEGIN; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				LINE_MID; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_R; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break;		 
		} 
	} 
	else		// normal 
	{ 
		l=0; 
    		switch(zx) { 
		case	0: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	1: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	2: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT5; 
				PIXEL_F; 
				LINE_MID; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	3: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT4; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT4; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	4: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT3; 
				PIXEL_F; 
				SHIFT3; 
				PIXEL_F; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT3; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	5: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT3; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT3; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	6: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				LINE_MID; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	7: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	8: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	9: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	10: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	11: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2;	 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2;	 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	12: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT2; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	13: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	14: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		case	15: 
			for (y = sy ;y <= ey;y++) 
			{ 
				fspr+=l_y_skip[l]*dy; 
				bm  = (video_line_ptr[y]) + sx; 
				LINE_BEGIN; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				LINE_MID; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_F; 
				SHIFT1; 
				PIXEL_LAST; 
				l++; 
			} 
			break; 
		} 
	} 
} 
 
void	video_save_snapshot(void) 
{ 
	static int	snap_no = 0; 
	static char	name[30]; 
	BITMAP		*bmp; 
	PALETTE		pal; 
	 
	get_palette(pal); 
	bmp = create_sub_bitmap(video_buffer, 16, 0, 304, 224); 
	sprintf(name, "snap%04d.pcx", snap_no); 
	save_pcx(name, bmp, pal); 
	destroy_bitmap(bmp); 
	snap_no++; 
} 
 
void	video_setup(void) 
{ 
	int		ret, temp, i; 
	 
	temp = get_config_int(NULL, "scanlines", 0); 
	 
	if (video_scanlines_capable == 0) 
	{ 
		temp = 0; 
		video_setup_dlg[6].flags = D_SELECTED; 
		video_setup_dlg[7].flags = 32; 
	} 
	else 
	{ 
		if (temp==0) 
		{ 
			video_setup_dlg[6].flags = D_SELECTED; 
			video_setup_dlg[7].flags = 0; 
		} 
		else 
		{ 
			video_setup_dlg[6].flags = 0; 
			video_setup_dlg[7].flags = D_SELECTED; 
		} 
	} 
 
	temp = get_config_int(NULL, "vsync", 0); 
	switch(temp) 
	{ 
		case	1: 
			video_setup_dlg[9].flags = D_SELECTED; 
			video_setup_dlg[10].flags = 0; 
			video_setup_dlg[11].flags = 0; 
			break; 
		case	2: 
			video_setup_dlg[9].flags = 0; 
			video_setup_dlg[10].flags = D_SELECTED; 
			video_setup_dlg[11].flags = 0; 
			break; 
		default: 
			video_setup_dlg[9].flags = 0; 
			video_setup_dlg[10].flags = 0; 
			video_setup_dlg[11].flags = D_SELECTED; 
	}			 
 
	if (!video_hide_fps) 
		video_setup_dlg[12].flags = D_SELECTED; 
	else 
		video_setup_dlg[12].flags = 0; 
 
	temp = get_config_id(NULL, "gfx_card", GFX_VESA2L); 
	 
	for(i=0;i<5;i++) 
	{ 
		if (mode_list[i] == temp) 
		{ 
			video_setup_dlg[4].d1 = i; 
			break; 
		} 
	} 
 
	temp = video_setup_dlg[4].d1; 
 
	centre_dialog(video_setup_dlg); 
	ret = do_dialog(video_setup_dlg, 0); 
	 
	if (video_setup_dlg[6].flags!=0) 
	{ 
		config_scanlines = 0; 
		set_config_int(NULL, "scanlines", 0); 
	} 
	else 
	{ 
		config_scanlines = 1; 
		set_config_int(NULL, "scanlines", 1); 
	} 
	 
	if (video_setup_dlg[9].flags&D_SELECTED) 
	{ 
		config_vsync = 1; 
		set_config_int(NULL, "vsync", 1); 
	} 
 
	if (video_setup_dlg[10].flags&D_SELECTED) 
	{ 
		config_vsync = 2; 
		set_config_int(NULL, "vsync", 2); 
	} 
 
	if (video_setup_dlg[11].flags&D_SELECTED) 
	{ 
		config_vsync = 0; 
		set_config_int(NULL, "vsync", 0); 
	} 
					 
	if (video_setup_dlg[12].flags&D_SELECTED) 
		video_hide_fps = 0; 
	else 
		video_hide_fps = 1; 
		 
	if (video_setup_dlg[4].d1 != temp) 
	{ 
		ret = mode_list[video_setup_dlg[4].d1]; 
		i = video_scanlines_capable; 
		set_config_id(NULL, "gfx_card", ret); 
		 
		video_scanlines_capable = 1; 
 
		if (!video_set_mode(VIDEO_SCANLINES)) 
			video_scanlines_capable = 0; 
 
		if (!video_set_mode(VIDEO_NORMAL)) 
		{ 
			ret = mode_list[temp]; 
			set_config_id(NULL, "gfx_card", ret); 
			video_scanlines_capable = i; 
			video_set_mode(VIDEO_NORMAL); 
		} 
		 
		show_mouse(screen); 
		 
		config_scanlines = 1; 
	} 
}