📄 vgadisp.c
字号:
width,(gif_delaycount<2)?height:height/gif_delaycount, &redraw); if(redraw) graphicson(); break; case 'q': case 'k': py-=MOVSTP; break; case 'a': case 'j': py+=MOVSTP; break; case 'o': case 'h': px-=MOVSTP; break; case 'p': case 'l': px+=MOVSTP; break; case 'Q': case 'K': case RK_CURSOR_UP: py-=BIGSTP; break; case 'A': case 'J': case RK_CURSOR_DOWN: py+=BIGSTP; break; case 'O': case 'H': case RK_CURSOR_LEFT: px-=BIGSTP; break; case 'P': case 'L': case RK_CURSOR_RIGHT: px+=BIGSTP; break; case 'e': /* animate */ { int ret; if(cfg.repeat_timer || tagview_mode) alarm(0); /* cancel timeout for this image */ ret=animate_gif(orient_current_state); if(cfg.repeat_timer || tagview_mode) repeat_sig=0; /* clear it in case */ if(doing_auto_animate) /* no need for redraw */ { switch(ret) /* change file if requested */ { case -1: goto do_prev_file; case 1: goto do_next_file; case 2: goto do_next_and_tag; } break; /* else just exit switch(key) */ } /* need clear as (if zoomed) full pic will take less space, * or (if rotated) pic effectively has different shape. */ vga_clear(); redraw=1; break; } case 'm': /* mirror */ fx_mirror(); orient_current_state=orient_state_mirror[orient_current_state]; px=py=0; redraw=1; break; case 'f': /* flip */ fx_flip(); orient_current_state=orient_state_flip[orient_current_state]; px=py=0; redraw=1; break; case 'r': /* rotate clockwise */ fx_rot(); vga_clear(); orient_current_state=orient_state_rot_cw[orient_current_state]; px=py=0; redraw=1; break; case 'R': /* rotate anti-clockwise */ fx_rot(); fx_flip(); fx_mirror(); vga_clear(); orient_current_state=orient_state_rot_acw[orient_current_state]; px=py=0; redraw=1; break; case 128+'n': /* restore original orientation (state 0) */ orient_change_state(orient_current_state,0,1); orient_current_state=0; px=py=0; redraw=1; break; case 128+'o': /* re-use previous pic's orientation */ orient_change_state(orient_current_state,orient_lastpicexit_state,1); orient_current_state=orient_lastpicexit_state; px=py=0; redraw=1; break; case 128+'s': /* save current orientation, overriding until Esc */ orient_override_state=orient_current_state; orient_override=1; break; case 128+'r': /* reduce only */ cfg.zoom_reduce_only=(!cfg.zoom_reduce_only); scaling=redraw=1; px=py=0; vga_clear(); break; case 'z': zoom=(!zoom); scaling=redraw=1; px=py=0; vga_clear(); break; case 'Z': cfg.automodefit=(!cfg.automodefit); if(cfg.automodefit) do_auto_mode_fit(); scaling=redraw=1; px=py=0; graphicson(); break; case '[': if(change_mode_size(0)) redraw=1,graphicson(); break; case ']': if(change_mode_size(1)) redraw=1,graphicson(); break; case 'i': interp=(!interp); redraw=1; break; case '!': inextpix=(inextpix==1)?2:1; redraw=1; break; case '?': /* showhelp restores mouse pos */ showhelp(zgv_ttyfd,"- KEYS FOR VIEWER -",viewerhelp); save_mouse_pos(); graphicson(); redraw=1; break; case '/': /* showhelp restores mouse pos */ showhelp(zgv_ttyfd,"- SELECTING VIDEO MODES -",viewermodeshelp); save_mouse_pos(); /* falls through to `refresh screen' */ case 12: case 18: /* 12,18 = Ctrl-L, Ctrl-R */ graphicson(); redraw=1; break; case 'N'-0x40: pic_incr=1; quitshow=1; break; case 'P'-0x40: pic_incr=-1; quitshow=1; break; case RK_ENTER: do_next_file: pic_incr=1; quitshow=2; break; case ' ': do_next_and_tag: pic_incr=1; quitshow=3; break; case 127: case 8: do_prev_file: pic_incr=-1; quitshow=2; break; case 'c': case 'C': if(curvgamode==G640x480x16) { cfg.viewer16col=!cfg.viewer16col; filterpal(palette); /* implicit gamma change (see apply_gamma()) */ graphicson(); /* palette has to change */ redraw=1; } break; case 128+'c': /* alt-c */ if(curvgamode==G640x480x16 && cfg.viewer16col) { cfg.fastdither16col=!cfg.fastdither16col; redraw=1; } break; case RK_ESC: case 'x': quitshow=1; } } /* if an auto-animate finished, exit */ if(doing_auto_animate) break; if(!allow_zoom()) { int swidth=width*scaling,sheight=height*scaling; if(sheight<=scrnhigh) py=0; else if(sheight-py<scrnhigh) py=sheight-scrnhigh; if(swidth<=scrnwide) px=0; else if(swidth-px<scrnwide) px=swidth-scrnwide; if(px<0) px=0; if(py<0) py=0; if(scaling>1) { npx=px/scaling; npy=py/scaling; } } else px=py=npx=npy=0; if(redraw || opx!=px || opy!=py) { if(vkludge && vkcache_reinit) init_vkludge_cache(); vkcache_reinit=0; redrawgif(px,py,npx,npy); } if(repeat_sig==2) repeat_sig--; }graphicsoff();/* make sure we ignore any previous GIF animation stuff in future */gif_delaycount=0;if(cfg.selecting) show_dimensions(px,py,scaling);if(cfg.repeat_timer || tagview_mode) { alarm(0); saved_px=px; saved_py=py; if(quitshow==1) tagview_mode=0; }/* save orientation state as last-picture-exit state */orient_lastpicexit_state=orient_current_state;/* caller must do mouse restore */return(quitshow);}/* save old contents of area to put right-button menu on, and draw it. */static void draw_rb_menu(){int light,medium,dark,black; /* for menu */int mwhite,mblack; /* for mouse pointer */int f,y;rbm_xysize(viewer_menu_data,&rb_save_width,&rb_save_height);if(scrnpixelsize<1) scrnpixelsize=1; /* sanity check */if((rb_save=malloc(rb_save_width*rb_save_height*scrnpixelsize))==NULL) return;switch(curvgamode) { /* for 16-colour and 8-bit generic-VGA, don't use vgagl. * though I have many modes listed here, in truth it's only * 640x480x4 and 360x480x8 this can possibly be called for. * (NB: can't use scrnwide here, as that's twice phys. width in 360x480.) */ case G640x480x16: case G320x200x256: case G320x240x256: case G320x400x256: case G360x480x256: for(y=0;y<rb_save_height;y++) vga_getscansegment(rb_save+rb_save_width*y, vga_getxdim()-rb_save_width,y,rb_save_width); break; /* otherwise use vgagl */ default: /* may not be current context if 8-bit mode, so make sure. */ gl_setcontextvga(curvgamode); gl_getbox(scrnwide-rb_save_width,0,rb_save_width,rb_save_height,rb_save); }/* grey out (make non-active) any ones we shouldn't allow. * this is nasty, but decl of viewer_menu_data notes that there's * a nasty thing here, so it should be ok. */f=1;viewer_menu_data[f++].active=mode_is_usable_now(G360x480x256);viewer_menu_data[f++].active=mode_is_usable_now(G640x480x16);viewer_menu_data[f++].active=mode_is_usable_now(G640x480x256);viewer_menu_data[f++].active=mode_is_usable_now(G800x600x256);viewer_menu_data[f++].active=mode_is_usable_now(G1024x768x256);viewer_menu_data[f++].active=mode_is_usable_now(G640x480x32K);viewer_menu_data[f++].active=mode_is_usable_now(G640x480x64K);viewer_menu_data[f++].active= mode_is_usable_now(G640x480x16M) || mode_is_usable_now(G640x480x16M32);viewer_menu_data[f++].active=mode_is_usable_now(G800x600x32K);viewer_menu_data[f++].active=mode_is_usable_now(G800x600x64K);viewer_menu_data[f++].active= mode_is_usable_now(G800x600x16M) || mode_is_usable_now(G800x600x16M32);viewer_menu_data[f++].active=mode_is_usable_now(G1024x768x32K);viewer_menu_data[f++].active=mode_is_usable_now(G1024x768x64K);viewer_menu_data[f++].active= mode_is_usable_now(G1024x768x16M) || mode_is_usable_now(G1024x768x16M32);rbm_set_active_flag(viewer_menu_data,"grey/colour",(curvgamode==G640x480x16));/* make some colours available if needed for light/medium/dark/black * colours. Here's the way this works: * - for 15/16/24-bit modes, just use the colours. * - for 8-bit, find closest matches and force those to the right * colour *temporarily*, i.e. while rb menu is onscreen. That means * we'll need a palette `redraw' (setpalvec) when screen is restored. * - for 640x480 4-bit, we kludge it a bit (see below). */switch(scrncols) { case 16: /* 640x480 16-colour */ if(cfg.viewer16col) { /* if in colour, they were reserved for us out of the 2nd 8 colours */ light=8; medium=9; dark=10; black=11; mwhite=light; mblack=black; } else { /* otherwise, we use some fixed greys which match the default * zgv setup fairly closely. */ light=9; medium=7; dark=5; black=0; mwhite=light; mblack=1; } break; case 256: /* 8-bit */ /* find and fix the colours */ rbm_find_and_fix_ui_cols(&light,&medium,&dark,&black,&mblack, palr64,palg64,palb64); mwhite=light; break; default: /* 15/16/24-bit */ light =((cfg.light.r<<18)|(cfg.light.g<<10)|(cfg.light.b<<2)); medium=((cfg.medium.r<<18)|(cfg.medium.g<<10)|(cfg.medium.b<<2)); dark =((cfg.dark.r<<18)|(cfg.dark.g<<10)|(cfg.dark.b<<2)); black =((cfg.black.r<<18)|(cfg.black.g<<10)|(cfg.black.b<<2)); /* mblack/mwhite should be in screen format */ mblack=1; /* black musn't be 0, unfortunately */ switch(scrncols) { case 32768: mwhite=GET15BITCOLOUR(4*cfg.light.r,4*cfg.light.g,4*cfg.light.b); break; case 65536: mwhite=GET16BITCOLOUR(4*cfg.light.r,4*cfg.light.g,4*cfg.light.b); break; default: mwhite=light; /* 24-bit is easy :-) */ } break; }mousecur_init(mblack,mwhite);/* restore old mouse pos. */restore_mouse_pos();/* now draw the thing */rbm_draw(viewer_menu_data,light,medium,dark,black);}/* restore old contents of area with right-button menu on. */static void undraw_rb_menu(){int y;/* save current mouse pos. */save_mouse_pos();if(rb_save==NULL) return; /* ran out of memory, can't do much! */switch(curvgamode) { /* again, not vgagl, and again, can't use scrnwide */ case G640x480x16: case G320x200x256: case G320x240x256: case G320x400x256: case G360x480x256: for(y=0;y<rb_save_height;y++) vga_drawscansegment(rb_save+rb_save_width*y, vga_getxdim()-rb_save_width,y,rb_save_width); break; /* vgagl */ default: gl_putbox(scrnwide-rb_save_width,0,rb_save_width,rb_save_height,rb_save); }if(scrncols==256) setpalvec(0,256,palrgb); /* restore palette */free(rb_save);}/* possibly have a mouse event to deal with for right-button menu. * uses pointer to key to fake keys to do stuff, and returns * 1 if we should stay in rb menu mode, else 0. */static int rb_menu_event(int *keyp){/* important to read both, even if not using both */int mleft=is_end_click_left(),mright=is_end_click_right();int key;if(!mleft) return(1);if(rb_ignore_first_left_click) { rb_ignore_first_left_click=0; return(1); }key=mright; /* a kludge to keep gcc -Wall quiet *//* get faked key for viewer_menu_data, or zero if none */*keyp=0;key=rbm_mousepos_to_key(viewer_menu_data,mouse_getx(),mouse_gety());if(key!=-1) /* -1 means quit menu with no key */ *keyp=key;return((key==0)); /* 1 if didn't match any, else 0 */}void repeat_sighandler(int foo){repeat_sig=1;}void setpalvec(int start,int num,int *pal){/* only relevant for 8-bit modes */if(pixelsize==1) { if(curvgamode!=G640x480x16) vga_setpalvec(start,num,pal); else { int f,c; unsigned char *dptr=dither16_rgb+start*3; int *sptr=pal+start*3; for(f=start;f<start+num;f++) { if(cfg.viewer16col) { /* used to adjust contrast here, but that's now done * more accurately using gamma in apply_gamma(). */ *dptr++=*sptr++; *dptr++=*sptr++; *dptr++=*sptr++; } else { c=(pal[f*3]*grey_red+pal[f*3+1]*grey_green+ pal[f*3+2]*grey_blue)/1000; if(c>63) c=63; dither16_greylookup[f]=c; } } } }}/* this routine is getting ridiculous */void redrawgif(int px,int py,int npx,int npy){int x,y,xdim;int x_add,y_add;byte *realline,*ptr;/* set line-draw routine depending on whether we need to do * 15/16/24-bit brightness/contrast or not. * `doing_hicol_bc' just saves us doing this test elsewhere. */eventuallydrawscansegment=eventuallydrawscansegment_without_bc;doing_hicol_bc=0;if(scrnpixelsize>1 && (brightness!=0 || contrast!=1.0 || picgamma!=1.0)) { eventuallydrawscansegment=eventuallydrawscansegment_with_bc; doing_hicol_bc=1; }if(allow_zoom()) drawzoomedgif();else { int swidth=width*scaling,sheight=height*scaling; int linelen=(swidth>scrnwide?scrnwide:swidth); /* draw non-zoomed pic */ x_add=y_add=0; /* these control the centering */ if(cfg.centreflag) { if(swidth<scrnwide) x_add=(scrnwide-swidth)>>1; if(sheight<scrnhigh) y_add=(scrnhigh-sheight)>>1; if(virtual) x_add>>=1; } if(swidth-px<scrnwide) xdim=swidth-px; else xdim=scrnwide; if((py>=sheight)||(px>=swidth)) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -