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

📄 vgadisp.c

📁 zgv-5.6,一个Linux系统下的图片浏览器(VGA/SVGA)
💻 C
📖 第 1 页 / 共 5 页
字号:
struct modedesc_tag *md_ptr;/* here's the plan; * - we try to keep the number of pixels as close as possible: *   as this will probably be quite noticeable, *this takes priority*. * - we then try to match any 8-bit modes for EIGHT_BIT, or match *   24/16/15-bit modes (in that order) for HIGHCOLOUR. * - of course, the mode has to be either 8 or 15/16/24-bit as reqd. * * no support in this for 640x480x4 (16-colour) - because that's * a really weird special-case mode, you have to explicitly select it * if you want it. However, it sticks in 640x480x4 if selected and * modetype is FIX_TO_EIGHT_BIT, because it'd be totally annoying * otherwise. */if(curvgamode==G640x480x16 && modetype==FIX_TO_EIGHT_BIT) return;newmode=-1; pixdiff=(1<<30);numpixels=get_mode_width(curvgamode)*get_mode_height(curvgamode);/* account for effect of 'virtual' */if(curvgamode==G320x400x256 || curvgamode==G360x480x256)  numpixels*=2;for(md_ptr=modedesc;md_ptr->mode;md_ptr++)  {  f=md_ptr->mode;  if(!vga_hasmode(f) || cfg.mode_allowed[f]==0 ||     (vminfo=vga_getmodeinfo(f))==NULL)    continue;    mode_ok=0;  if(modetype==FIX_TO_EIGHT_BIT)    {    if(vminfo->colors==256) mode_ok=1;    }  else    {    if(vminfo->colors>256) mode_ok=1;    }    if(mode_ok==0) continue;    newnp=(vminfo->width)*(vminfo->height);  if(f==G320x400x256 || f==G360x480x256)    newnp*=2;   /* account for effect of 'virtual' */  newdiff=numpixels-newnp;  if(newdiff<0) newdiff=(-newdiff);    if(newdiff<=pixdiff)    {    newmode=f;    pixdiff=newdiff;    }  }/* we rely on the 15/16/32/24-bit mode number ordering to sort that * out for us (hence the `<=' above). */curvgamode=newmode;virtual=(curvgamode==G320x400x256 || curvgamode==G360x480x256);}int mode_ok_for_auto_switch(struct modedesc_tag *md_ptr){static int has640x480=-1;int f=md_ptr->mode;if(has640x480==-1)  has640x480=(vga_hasmode(G640x480x256) && cfg.mode_allowed[G640x480x256]);if(!vga_hasmode(f) || cfg.mode_allowed[f]==0)  return(0);/* don't use 320x200 modes (screwy aspect ratio). */if(md_ptr->width==320 && md_ptr->height==200)  return(0);  /* don't use 640x480x4 (too odd), or 320x400x8 (aspect ratio again). */if(f==G640x480x16 || f==G320x400x256)  return(0);/* skip 360x480x8 if a 640x480x8 mode exists. */if(f==G360x480x256 && has640x480)  return(0);/* obviously, has to be a compatible depth. */if((pixelsize==1 && md_ptr->bitspp!=8) ||   (pixelsize==3 && md_ptr->bitspp==8))  return(0);/* otherwise ok */return(1);}void do_auto_mode_fit(void){struct modedesc_tag *md_ptr;int w,h;int newmode=-1,newmode_w=(1<<30),newmode_h=(1<<30);int bigmode=-1,bigmode_w=0,bigmode_h=0;if(!cfg.automodefit) return;for(md_ptr=modedesc;md_ptr->mode;md_ptr++)  {  if(!mode_ok_for_auto_switch(md_ptr))    continue;    w=md_ptr->width*(1+(md_ptr->mode==G360x480x256));  h=md_ptr->height;    /* has to be >= pic size, but <= current best-fit mode. */  if(w>=width && h>=height && w<=newmode_w && h<=newmode_h)    newmode=md_ptr->mode,newmode_w=w,newmode_h=h;    /* also track biggest mode as backup in case no mode fits it all. */  if(w>=bigmode_w && h>=bigmode_h)    bigmode=md_ptr->mode,bigmode_w=w,bigmode_h=h;  }if(newmode==-1)  {  if(bigmode==-1)    newmode=curvgamode;		/* should be a can't-happen though */  else    newmode=bigmode;  }curvgamode=newmode;}/* arg is non-zero if want bigger mode, or zero if want smaller. * returns 0 if no mode fits. */int change_mode_size(int bigger){struct modedesc_tag *md_ptr;int w,h;int newmode=-1,diff,mindiff=(1<<30);for(md_ptr=modedesc;md_ptr->mode;md_ptr++)  {  if(!mode_ok_for_auto_switch(md_ptr))    continue;    w=md_ptr->width*(1+(md_ptr->mode==G360x480x256));  h=md_ptr->height;    if(bigger)    {    diff=(w-scrnwide)*(h-scrnhigh);    /* the <= in the diff bit gives us the best depth available */    if(w>scrnwide && h>scrnhigh && diff<=mindiff)      newmode=md_ptr->mode,mindiff=diff;    }  else    {    /* smaller */    diff=(scrnwide-w)*(scrnhigh-h);    if(w<scrnwide && h<scrnhigh && diff<=mindiff)      newmode=md_ptr->mode,mindiff=diff;    }  }if(newmode==-1)  return(0);curvgamode=newmode;return(1);}void aborted_file_cleanup(){switch(loading_file_type)  {  case _IS_GIF:    aborted_file_gif_cleanup();    break;  case _IS_JPEG:    aborted_file_jpeg_cleanup();    break;  case _IS_PNM:    aborted_file_pnm_cleanup();    break;  case _IS_TIFF:    aborted_file_tiff_cleanup();    break;  case _IS_BMP:    aborted_file_bmp_cleanup();    break;  case _IS_TGA:    aborted_file_tga_cleanup();    break;  case _IS_PNG:    aborted_file_png_cleanup();    break;  case _IS_XVPIC:    fprintf(stderr,"aborted xvpic load: can't happen!\n");    exit(1);  case _IS_PCX:    aborted_file_pcx_cleanup();    break;  case _IS_MRF:    aborted_file_mrf_cleanup();    break;  case _IS_PRF:    aborted_file_prf_cleanup();    break;  case _IS_XBM:    aborted_file_xbm_cleanup();    break;#ifdef PCD_SUPPORT  case _IS_PCD:    aborted_file_pcd_cleanup();    break;#endif  case _IS_XPM:    aborted_file_xpm_cleanup();    break;  }}void makerealpal(){int f;int r,rlo,g,glo,b,blo;int gval;for(f=0;f<256;f++)  {  r=palr[f]>>2; rlo=palr[f]&3;  g=palg[f]>>2; glo=palg[f]&3;  b=palb[f]>>2; blo=palb[f]&3;  if(cfg.fakecols)    {    gval=(rlo*grey_red+glo*grey_green+blo*grey_blue)/4;    /* so gval is sub-value, 0<=gval<1000. (really <750... :-( )     * possible emulated sub-values are...     * 0, 114 (b), 299 (r), 413 (r+b), 587 (g), 701 (g+b), 886 (r+g)     */      if(gval>=886)      r++,g++;    else if(gval>=701)      g++,b++;    else if(gval>=587)      g++;    else if(gval>=413)      r++,b++;    else if(gval>=299)      r++;    else if(gval>=114)      b++;    if(r>63) r=63; if(g>63) g=63; if(b>63) b=63;    }  palrgb[f*3  ]=palr64[f]=r;  palrgb[f*3+1]=palg64[f]=g;  palrgb[f*3+2]=palb64[f]=b;  }}void filterpal(byte *palette){int f;for(f=0;f<256;f++)   /* don't *really* need to know number of colours */  {  /* we also abuse this to get a brightness/contrast-ified index   * to use for high-colour mode b/c. :-) (Hence palt[].)   */  /* XXX it's debatable where gamma should be applied... */  if(cfg.bc_order_rev)    {    palr[f]=contrastup(dimmer(apply_gamma(palette[    f])));    palg[f]=contrastup(dimmer(apply_gamma(palette[256+f])));    palb[f]=contrastup(dimmer(apply_gamma(palette[512+f])));    palt[f]=contrastup(dimmer(apply_gamma(f)));    }  else    {    palr[f]=dimmer(contrastup(apply_gamma(palette[    f])));    palg[f]=dimmer(contrastup(apply_gamma(palette[256+f])));    palb[f]=dimmer(contrastup(apply_gamma(palette[512+f])));    palt[f]=dimmer(contrastup(apply_gamma(f)));    }  }makerealpal();}int dimmer(int a){a+=brightness;if(a<0) a=0;if(a>255) a=255;return(a);}int contrastup(int cp){float g;g=(float)(cp);g=128.+(g-128.)*contrast;if(g<0.) g=0.;if(g>255.) g=255.;return((int)g);}int apply_gamma(int val){int d16col=(curvgamode==G640x480x16 && cfg.viewer16col);/* the ==1.0 is a bit bogus, but likely to work if you've not * messed about with it too heavily - certainly it'll work if you * never changed it. :-) */if(picgamma==1.0 && !d16col)  return(val);/* use 2.2 as a base, assuming most people will have gamma 2.2 monitors * (the 8-colour dither is inherently linear gamma in all cases). */if(d16col)  return((int)(pow(val/255., 2.2/picgamma)*255.+0.5));return((int)(pow(val/255., 1./picgamma)*255.+0.5));}int get_mode_width(int vm){vga_modeinfo *vmi;vmi=vga_getmodeinfo(vm);return(vmi->width);}int get_mode_height(int vm){vga_modeinfo *vmi;vmi=vga_getmodeinfo(vm);return(vmi->height);}int get_mode_pixelbytes(int vm){vga_modeinfo *vmi;vmi=vga_getmodeinfo(vm);return(vmi->bytesperpixel);}int get_mode_numcols(int vm){vga_modeinfo *vmi;vmi=vga_getmodeinfo(vm);return(vmi->colors);}void do_16col_palette(){int paltmp[16*3],f,r,g,b;if(cfg.viewer16col)  {  /* colour */  for(f=r=0;r<2;r++)    for(g=0;g<2;g++)      for(b=0;b<2;b++,f+=3)        paltmp[f]=r*63,paltmp[f+1]=g*63,paltmp[f+2]=b*63;  /* FWIW, zero colours 8..15. It may seem wasteful not using these,   * but there's no way I can see to use them as part of an ordered   * dither which doesn't look awful (and error-diffused dithering   * is too slow).   */  for(;f<16*3;f+=3)    paltmp[f]=paltmp[f+1]=paltmp[f+2]=0;    /* actually, in that case, best to allocate some for right-button   * menu colours!   */  f=8;  paltmp[f*3  ]=cfg.light.r;  paltmp[f*3+1]=cfg.light.g;  paltmp[f*3+2]=cfg.light.b;  f++;  paltmp[f*3  ]=cfg.medium.r;  paltmp[f*3+1]=cfg.medium.g;  paltmp[f*3+2]=cfg.medium.b;  f++;  paltmp[f*3  ]=cfg.dark.r;  paltmp[f*3+1]=cfg.dark.g;  paltmp[f*3+2]=cfg.dark.b;  f++;  paltmp[f*3  ]=cfg.black.r;  paltmp[f*3+1]=cfg.black.g;  paltmp[f*3+2]=cfg.black.b;  }else  {  /* 16-grey palette */  for(f=0;f<16;f++)    paltmp[f*3]=paltmp[f*3+1]=paltmp[f*3+2]=(f*63)/15;  }vga_setpalvec(0,16,paltmp);}/* set new mode if needed, else just clear screen. */void setmode_or_clear(int newmode){if(vga_getcurrentmode()!=newmode)  vga_setmode(newmode); else  vga_clear();}void init_vkludge_cache(void){int x;/* invalidate any cached colours */memset(vkcache_valid,0,sizeof(vkcache_valid));/* the actual palette colours are fairly likely to crop up :-), * so index them automatically. */for(x=0;x<numcols;x++)  closest(pal32_no_bc[x*3],pal32_no_bc[x*3+1],pal32_no_bc[x*3+2]);}void graphicson(void){msgbox_draw_ok=0;vga_lockvc();if((vga_hasmode(curvgamode))&&(cfg.mode_allowed[curvgamode]))  setmode_or_clear(curvgamode);else  {  /* we haven't? Aaargh!!! Ok, use 640x480 or 360x480 instead. */  if((vga_hasmode(G640x480x256))&&(cfg.mode_allowed[G640x480x256]))    setmode_or_clear(curvgamode=G640x480x256);  else    {    if((vga_hasmode(G360x480x256))&&(cfg.mode_allowed[G360x480x256]))      setmode_or_clear(curvgamode=G360x480x256);    else      /* *must* have 320x200 (see rcfile.c for more info) */      setmode_or_clear(curvgamode=G320x200x256);    }  }virtual=0;if(curvgamode==G320x400x256 || curvgamode==G360x480x256)  virtual=1;if(curvgamode==G640x480x16)  do_16col_palette();if(pixelsize!=1) gl_setcontextvga(curvgamode);scrnwide=get_mode_width(curvgamode);scrnhigh=get_mode_height(curvgamode);scrnpixelsize=get_mode_pixelbytes(curvgamode);scrncols=get_mode_numcols(curvgamode);if(virtual)  scrnwide*=2;if(pixelsize==1)  setpalvec(0,256,palrgb);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -