📄 zgv_io.c
字号:
int zvga_hasmode(int mode){if(mode<0 || mode>GLASTMODE) return 0;return(modes[mode].has_mode);}void sdl_exit(void){SDL_ShowCursor(SDL_ENABLE);SDL_Quit();}int zvga_init(void){int ret;int f;if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)<0) { fprintf(stderr,"zgv: SDL init failed - %s\n",SDL_GetError()); exit(1); }/* in case it was installed setuid root */setgid(getgid());setuid(getuid());atexit(sdl_exit);SDL_WM_SetCaption("zgv-sdl","zgv-sdl");for(f=1;f<=GLASTMODE;f++) { ret=SDL_VideoModeOK(modes[f].width,modes[f].height, modes[f].bitsperpixel, SCRNMODE_FLAGS| (modes[f].colors<=256?SDL_HWPALETTE:0)); if(modes[f].bitsperpixel<=8) modes[f].has_mode=ret; else modes[f].has_mode=(modes[f].bitsperpixel==ret); }SDL_EnableKeyRepeat(250,50);SDL_EnableUNICODE(1);SDL_ShowCursor(SDL_DISABLE);return 0;}int zvga_setcolor(int col){current_colour=col;return 0;}int zvga_setmode(int mode){if(mode==TEXT) return -1;if(!zvga_hasmode(mode)) { fprintf(stderr,"zgv: error: bad vga_setmode(%d) call, this is probably a bug.\n",mode); exit(1); }else { SDL_Surface *ret; if(cfg.svgalib_mouse) save_mouse_pos(); if((ret=SDL_SetVideoMode(modes[mode].width,modes[mode].height, modes[mode].bitsperpixel, SCRNMODE_FLAGS| (modes[mode].colors<=256?SDL_HWPALETTE:0)))); { current_mode=mode; if(modes[mode].colors<=256) zvga_setpalette(0,0,0,0); surface=ret; if(cfg.svgalib_mouse) restore_mouse_pos(); /* not sure if it's guaranteed to be blank, so play it safe. * This also updates scrnchange vars, which is important. */ zvga_clear(); return 0; } }return -1;}int zvga_setpalette(int idx,int r,int g,int b){caller_pal[idx*3]=r;caller_pal[idx*3+1]=g;caller_pal[idx*3+2]=b;sdl_pal[idx].r=(r*255)/63;sdl_pal[idx].g=(g*255)/63;sdl_pal[idx].b=(b*255)/63;palchanged=1;return 0;}int zvga_setpalvec(int start,int num,int *pal){int f;for(f=start;f<start+num;f++) zvga_setpalette(f,pal[f*3],pal[f*3+1],pal[f*3+2]);pal_update();return num;}int zvga_setrgbcolor(int r,int g,int b){current_colour=((r<<16)|(g<<8)|b);return 0;}static int forceesc=0;void zgv_io_screen_update(void){if(forceesc) return;if(scrnchange_line_min<=scrnchange_line_max) { SDL_UpdateRect(surface,0,scrnchange_line_min,modes[current_mode].width, scrnchange_line_max-scrnchange_line_min+1); }scrnchange_line_min=(1<<30);scrnchange_line_max=-1;}static int mouseevent=0;int zgv_io_readnbkey(void){SDL_Event event;int key;/* if we received SDL_QUIT, return Escs (which exit *everything* in zgv) * continuously, and avoid any screen update. This is the fastest way to * do a clean exit, as ugly as it is. */if(forceesc) return(27);zgv_io_screen_update();while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_USEREVENT: /* timer giving us a poke :-) */ zgv_io_timer_flag=1; break; case SDL_KEYDOWN: /* check for various special/awkward keys */ switch(event.key.keysym.sym) { case SDLK_F1: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F1:RK_F1); case SDLK_F2: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F2:RK_F2); case SDLK_F3: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F3:RK_F3); case SDLK_F4: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F4:RK_F4); case SDLK_F5: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F5:RK_F5); case SDLK_F6: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F6:RK_F6); case SDLK_F7: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F7:RK_F7); case SDLK_F8: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F8:RK_F8); case SDLK_F9: return((event.key.keysym.mod&KMOD_SHIFT)?RK_SHIFT_F9:RK_F9); case SDLK_F10: return(RK_F10); case SDLK_F11: return(RK_F11); case SDLK_F12: return(RK_F12); case SDLK_LEFT: return(RK_CURSOR_LEFT); case SDLK_DOWN: return(RK_CURSOR_DOWN); case SDLK_UP: return(RK_CURSOR_UP); case SDLK_RIGHT: return(RK_CURSOR_RIGHT); case SDLK_HOME: return(RK_HOME); case SDLK_END: return(RK_END); case SDLK_PAGEUP: return(RK_PAGE_UP); case SDLK_PAGEDOWN: return(RK_PAGE_DOWN); case SDLK_INSERT: return(RK_INSERT); case SDLK_DELETE: return(RK_DELETE); case SDLK_RETURN: return(RK_ENTER); default: /* stop complaints */ } if(event.key.keysym.sym==SDLK_SPACE && (event.key.keysym.mod&KMOD_CTRL)) return(RK_CTRLSPACE); /* the rest can be dealt with the Unicode mapping + alt stuff */ key=(event.key.keysym.unicode&0x7f); if(event.key.keysym.mod&(KMOD_ALT|KMOD_META)) key+=128; return(key); case SDL_QUIT: forceesc=1; return(27); case SDL_MOUSEBUTTONDOWN: if(event.button.button==SDL_BUTTON_LEFT) zmouse_state|=MOUSE_LEFTBUTTON; else if(event.button.button==SDL_BUTTON_RIGHT) zmouse_state|=MOUSE_RIGHTBUTTON; mouseevent=has_mouse; return(RK_NO_KEY); case SDL_MOUSEBUTTONUP: if(event.button.button==SDL_BUTTON_LEFT) zmouse_state&=~MOUSE_LEFTBUTTON; else if(event.button.button==SDL_BUTTON_RIGHT) zmouse_state&=~MOUSE_RIGHTBUTTON; mouseevent=has_mouse; return(RK_NO_KEY); case SDL_MOUSEMOTION: mouseevent=has_mouse; break; default: break; } }return(RK_NO_KEY);}int zgv_io_waitkey(void){int ret;while((ret=zgv_io_readnbkey())==RK_NO_KEY && !zgv_io_timer_flag) SDL_WaitEvent(NULL);return(ret);}int zgv_io_waitevent(void){int ret;mouseevent=0;while((ret=zgv_io_readnbkey())==RK_NO_KEY && !mouseevent && !zgv_io_timer_flag) SDL_WaitEvent(NULL);return(ret);}static SDL_TimerID our_timer;static Uint32 timer_sig(Uint32 interval,void *data){if(timer_in_use) { SDL_Event ev; ev.type=SDL_USEREVENT; SDL_PushEvent(&ev); }return(60*1000); /* wait a minute (as one-shots seem to be impossible :-( ) */}void zgv_io_timer_start(int delay_in_hundredths){if(timer_in_use) zgv_io_timer_stop();timer_in_use=1;zgv_io_timer_flag=0;our_timer=SDL_AddTimer(10*delay_in_hundredths,timer_sig,NULL);}void zgv_io_timer_stop(void){if(!timer_in_use) return;if(our_timer) SDL_RemoveTimer(our_timer);/* drop any unhandled events (XXX not sure this is the best approach, * but something like this is needed). */zgv_io_timer_flag=0;timer_in_use=0;}/* provide for a usable file-selector mode, to avoid problems when * using restrictive SDL outputs e.g. a single-mode VESA framebuffer. */void zgv_io_fixfsmode(int *mode){#define TRY_MODE(xx) \ if(modes[xx].has_mode && cfg.mode_allowed[xx]) \ { *mode=(xx); return; }TRY_MODE(G640x480x256);TRY_MODE(G800x600x256);TRY_MODE(G1024x768x256);TRY_MODE(G1280x1024x256);fprintf(stderr,"zgv: a 640x480, 800x600, 1024x768, or 1280x1024 mode is required.\n");exit(1);}#else /* BACKEND_SDL */int zmouse_getbutton(void) { return 0; }int zmouse_getx(void) { return 0; }int zmouse_gety(void) { return 0; }int zmouse_init_return_fd(char *dev,int type,int samplerate) { return -1; }void zmouse_setposition(int x,int y) {}int zmouse_update(void) { return 0; }int zvga_getmousetype(void) { return 0; }#endif /* BACKEND_SDL */#else /* BACKEND_SVGALIB *//* just the timer routines needed here, and dummy screen_update. */#include <stdio.h>#include <signal.h>#include <sys/time.h>static void timer_sig(int foo){if(timer_in_use) zgv_io_timer_flag=1;}void zgv_io_screen_update(void){/* nothing needed */}void zgv_io_timer_start(int delay_in_hundredths){struct itimerval itv;struct sigaction sa;if(timer_in_use) zgv_io_timer_stop();zgv_io_timer_flag=0;timer_in_use=1;sigemptyset(&sa.sa_mask); /* SIGALRM implicit */sa.sa_handler=timer_sig;sa.sa_flags=SA_RESTART;sigaction(SIGALRM,&sa,NULL);itv.it_value.tv_sec=delay_in_hundredths/100;itv.it_value.tv_usec=(delay_in_hundredths%100)*10000;itv.it_interval.tv_sec=itv.it_interval.tv_usec=0;setitimer(ITIMER_REAL,&itv,NULL);}void zgv_io_timer_stop(void){struct itimerval itv;itv.it_value.tv_sec=itv.it_value.tv_usec=0;itv.it_interval.tv_sec=itv.it_interval.tv_usec=0;setitimer(ITIMER_REAL,&itv,NULL);timer_in_use=0;}#endif /* BACKEND_SVGALIB */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -