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; } }