📄 sdl_driver.c
字号:
if (SDL_WM_ToggleFullScreen(*surface)) { sdldebug("SDL_WM_ToggleFullScreen() seems to work on this system."); if (flags) *flags ^= SDL_FULLSCREEN; return(1); } /* if */ if ( !(SDL_GetVideoInfo()->wm_available) ) { sdldebug("No window manager. Not toggling fullscreen flag."); return(0); } /* if */ sdldebug("toggling fullscreen flag The Hard Way..."); tmpflags = (*surface)->flags; w = (*surface)->w; h = (*surface)->h; bpp = (*surface)->format->BitsPerPixel; if (flags == NULL) /* use the surface's flags. */ flags = &tmpflags; SDL_GetClipRect(*surface, &clip); /* save the contents of the screen. */ if ( (!(tmpflags & SDL_OPENGL)) && (!(tmpflags & SDL_OPENGLBLIT)) ) { framesize = (w * h) * ((*surface)->format->BytesPerPixel); pixels = malloc(framesize); if (pixels == NULL) return(0); memcpy(pixels, (*surface)->pixels, framesize); } /* if */#if 0 if ((*surface)->format->palette != NULL) { ncolors = (*surface)->format->palette->ncolors; palette = malloc(ncolors * sizeof (SDL_Color)); if (palette == NULL) { free(pixels); return(0); } /* if */ memcpy(palette, (*surface)->format->palette->colors, ncolors * sizeof (SDL_Color)); } /* if */#endif if (grabmouse) SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(1); *surface = SDL_SetVideoMode(w, h, bpp, (*flags) ^ SDL_FULLSCREEN); if (*surface != NULL) *flags ^= SDL_FULLSCREEN; else /* yikes! Try to put it back as it was... */ { *surface = SDL_SetVideoMode(w, h, bpp, tmpflags); if (*surface == NULL) /* completely screwed. */ { if (pixels != NULL) free(pixels); if (palette != NULL) free(palette); return(0); } /* if */ } /* if */ /* Unfortunately, you lose your OpenGL image until the next frame... */ if (pixels != NULL) { memcpy((*surface)->pixels, pixels, framesize); free(pixels); } /* if */#if 0 if (palette != NULL) { /* !!! FIXME : No idea if that flags param is right. */ SDL_SetPalette(*surface, SDL_LOGPAL, palette, 0, ncolors); free(palette); } /* if */#else setbrightness((char) curbrightness, (unsigned char *) &palette[0]);#endif SDL_SetClipRect(*surface, &clip); if (grabmouse) SDL_WM_GrabInput(SDL_GRAB_ON); SDL_ShowCursor(showmouse); output_surface_info(*surface); return(1);} /* attempt_fullscreen_toggle */ /* * The windib driver can't alert us to the keypad enter key, which * Ken's code depends on heavily. It sends it as the same key as the * regular return key. These users will have to hit SHIFT-ENTER, * which we check for explicitly, and give the engine a keypad enter * enter event. */static inline int handle_keypad_enter_hack(const SDL_Event *event){ static int kp_enter_hack = 0; int retval = 0; if (event->key.keysym.sym == SDLK_RETURN) { if (event->key.state == SDL_PRESSED) { if (event->key.keysym.mod & KMOD_SHIFT) { kp_enter_hack = 1; lastkey = scancodes[SDLK_KP_ENTER]; retval = 1; } /* if */ } /* if */ else /* key released */ { if (kp_enter_hack) { kp_enter_hack = 0; lastkey = scancodes[SDLK_KP_ENTER]; retval = 1; } /* if */ } /* if */ } /* if */ return(retval);} /* handle_keypad_enter_hack */static int sdl_key_filter(const SDL_Event *event){ SDL_GrabMode grab_mode = SDL_GRAB_OFF; int extended; int tmp; if ( (event->key.keysym.sym == SDLK_g) && (event->key.state == SDL_PRESSED) && (event->key.keysym.mod & KMOD_CTRL) ) { mouse_grabbed = ((mouse_grabbed) ? 0 : 1); if (mouse_grabbed) grab_mode = SDL_GRAB_ON; SDL_WM_GrabInput(grab_mode); return(0); } /* if */ else if ( ( (event->key.keysym.sym == SDLK_RETURN) || (event->key.keysym.sym == SDLK_KP_ENTER) ) && (event->key.state == SDL_PRESSED) && (event->key.keysym.mod & KMOD_ALT) ) { tmp = ((void *) frameplace == (void *) surface->pixels); attempt_fullscreen_toggle(&surface, &sdl_flags); assert(surface != NULL); if (tmp) frameplace = (long) surface->pixels; return(0); } /* if */ if (!handle_keypad_enter_hack(event)) lastkey = scancodes[event->key.keysym.sym]; if (lastkey == 0x0000) /* No DOS equivalent defined. */ return(0); extended = ((lastkey & 0xFF00) >> 8); if (extended != 0) { lastkey = extended; keyhandler(); lastkey = (scancodes[event->key.keysym.sym] & 0xFF); } /* if */ if (event->key.state == SDL_RELEASED) lastkey += 128; /* +128 signifies that the key is released in DOS. */ keyhandler(); return(0);} /* sdl_key_filter */static int root_sdl_event_filter(const SDL_Event *event){ switch (event->type) { case SDL_KEYUP: case SDL_KEYDOWN: return(sdl_key_filter(event)); case SDL_JOYBALLMOTION: case SDL_MOUSEMOTION: return(sdl_mouse_motion_filter(event)); case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONDOWN: return(sdl_mouse_button_filter(event)); case SDL_QUIT: /* !!! rcg TEMP */ SDL_Quit(); exit(0); } /* switch */ return(1);} /* root_sdl_event_filter */static void handle_events(void){ SDL_Event event; while (SDL_PollEvent(&event)) root_sdl_event_filter(&event);} /* handle_events */unsigned char _readlastkeyhit(void){ return(lastkey);} /* _readlastkeyhit *//* !!! I'd like this to be temporary. --ryan. */#if ((defined PLATFORM_UNIX) && (defined USE_I386_ASM))#define PROT_R_W_X (PROT_READ | PROT_WRITE | PROT_EXEC)int mprotect_align(const void *addr, size_t len, int prot){ int retval; unsigned long l = (unsigned long) addr; l -= (l % PAGESIZE); retval = mprotect((void *) l, len * 2, prot); assert(retval == 0); return(retval);} /* mprotect_align */void unprotect_ASM_pages(void){ mprotect_align((const void *) asm_sethlinesizes, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_setpalookupaddress, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_setuphlineasm4, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_hlineasm4, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_setupvlineasm, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_vlineasm4, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_tvlineasm1, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_tvlineasm2, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_tspritevline, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_thline, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_prohlineasm4, PAGESIZE, PROT_R_W_X); mprotect_align((const void *) asm_stretchhline, PAGESIZE, PROT_R_W_X);} /* unprotect_ASM_pages *//* global _sethlinesizes global _prosethlinesizes global _setvlinebpl global _setpalookupaddress global _prosetpalookupaddress global _setuphlineasm4 global _hlineasm4 global _prohlineasm4 global _setupvlineasm global _prosetupvlineasm global _setupmvlineasm global _setuptvlineasm global _prevlineasm1 global _vlineasm1 global _mvlineasm1 global _fixtransluscence global _settransnormal global _settransreverse global _tvlineasm1 global _vlineasm4 global _provlineasm4 global _mvlineasm4 global _setupspritevline global _spritevline global _msetupspritevline global _mspritevline global _tsetupspritevline global _tspritevline global _msethlineshift global _mhline global _mhlineskipmodify global _tsethlineshift global _thline global _thlineskipmodify global _setuptvlineasm2 global _tvlineasm2 global _setupslopevlin2 global _slopevlin2 global _setupslopevlin global _slopevlin global _setuprhlineasm4 global _rhlineasm4 global _setuprmhlineasm4 global _rmhlineasm4 global _setupqrhlineasm4 global _qrhlineasm4 global _setupdrawslab global _drawslab global _stretchhline global _mmxoverlay*/#endifstatic inline void init_debugging(void){ const char *envr = getenv(BUILD_SDLDEBUG); debug_hall_of_mirrors = (getenv(BUILD_HALLOFMIRRORS) != NULL); if (_sdl_debug_file != NULL) { fclose(_sdl_debug_file); _sdl_debug_file = NULL; } /* if */ if (envr != NULL) { if (strcmp(envr, "-") == 0) _sdl_debug_file = stdout; else _sdl_debug_file = fopen(envr, "w"); if (_sdl_debug_file == NULL) printf("BUILDSDL: -WARNING- Could not open debug file!\n"); else setbuf(_sdl_debug_file, NULL); } /* if */} /* init_debugging */#if (!defined __DATE__)#define __DATE__ "a long, long time ago"#endifstatic inline void output_sdl_versions(void){ const SDL_version *linked_ver = SDL_Linked_Version(); SDL_version compiled_ver; SDL_VERSION(&compiled_ver); sdldebug("SDL display driver for the BUILD engine initializing."); sdldebug(" sdl_driver.c by Ryan C. Gordon (icculus@clutteredmind.org)."); sdldebug("Compiled %s against SDL version %d.%d.%d ...", __DATE__, compiled_ver.major, compiled_ver.minor, compiled_ver.patch); sdldebug("Linked SDL version is %d.%d.%d ...", linked_ver->major, linked_ver->minor, linked_ver->patch);} /* output_sdl_versions */static int in_vmware = 0;static inline void detect_vmware(void){ /* !!! need root access to touch i/o ports on Linux. */ #if (!defined __linux__) in_vmware = (int) is_vmware_running(); #endif sdldebug("vmWare %s running.", (in_vmware) ? "is" : "is not");} /* detect_vmware *//* lousy -ansi flag. :) */static char *string_dupe(const char *str){ char *retval = malloc(strlen(str) + 1); if (retval != NULL) strcpy(retval, str); return(retval);} /* string_dupe */static void set_sdl_renderer(void){ const char *envr = getenv(BUILD_RENDERER);#ifdef USE_OPENGL int need_opengl_lib = 0;#endif if ((envr == NULL) || (strcmp(envr, ENVRSTR_RENDERER_SOFTWARE) == 0)) renderer = RENDERER_SOFTWARE;#ifdef USE_OPENGL#if 0 else if (strcmp(envr, ENVRSTR_RENDERER_OPENGL3D) == 0) { renderer = RENDERER_OPENGL3D; need_opengl_lib = 1; } /* else if */#endif#endif else { fprintf(stderr, "BUILDSDL: \"%s\" in the %s environment var is not available.\n", envr, BUILD_RENDERER); _exit(1); } /* else */ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) { fprintf(stderr, "BUILDSDL: SDL_Init() failed!\n"); fprintf(stderr, "BUILDSDL: SDL_GetError() says \"%s\".\n", SDL_GetError()); exit(1); } /* if */#ifdef USE_OPENGL if (need_opengl_lib) { if (opengl_load_library() == -1) { SDL_Quit(); fprintf(stderr, "BUILDSDL/GL: Failed to load OpenGL library!\n"); if (getenv(BUILD_SDLDEBUG) == NULL) { fprintf(stderr, "BUILDSDL/GL: Try setting environment variable" " %s for more info.\n", BUILD_SDLDEBUG); } /* if */ _exit(42); } /* if */ } /* if */#endif} /* set_sdl_renderer */static void init_renderer_names(void){ memset(renderer_name, '\0', sizeof (renderer_name)); renderer_name[RENDERER_SOFTWARE] = "RENDERER_SOFTWARE"; renderer_name[RENDERER_OPENGL3D] = "RENDERER_OPENGL3D";} /* init_renderer_names */void _platform_init(int argc, char **argv, const char *title, const char *icon){ _argc = argc; _argv = argv; init_renderer_names(); init_debugging(); #if ((PLATFORM_UNIX) && (defined USE_I386_ASM)) unprotect_ASM_pages(); #endif if (title == NULL) title = "BUILD"; if (icon == NULL) icon = "BUILD"; titlelong = string_dupe(title); titleshort = string_dupe(icon); if (getenv(BUILD_NOMOUSEGRAB) == NULL) mouse_grabbed = 1; else mouse_grabbed = 0; sdl_flags = ((getenv(BUILD_WINDOWED) == NULL) ? SDL_FULLSCREEN : 0); sdl_flags |= SDL_HWPALETTE; /*sdl_flags |= SDL_HWSURFACE; !!! */ /*sdl_flags |= SDL_DOUBLEBUF; */ memset(scancodes, '\0', sizeof (scancodes)); scancodes[SDLK_ESCAPE] = 0x01; scancodes[SDLK_1] = 0x02; scancodes[SDLK_2] = 0x03; scancodes[SDLK_3] = 0x04; scancodes[SDLK_4] = 0x05; scancodes[SDLK_5] = 0x06; scancodes[SDLK_6] = 0x07; scancodes[SDLK_7] = 0x08; scancodes[SDLK_8] = 0x09; scancodes[SDLK_9] = 0x0A; scancodes[SDLK_0] = 0x0B; scancodes[SDLK_EQUALS] = 0x4E; scancodes[SDLK_BACKSPACE] = 0x0E; scancodes[SDLK_TAB] = 0x0F; scancodes[SDLK_q] = 0x10; scancodes[SDLK_w] = 0x11; scancodes[SDLK_e] = 0x12; scancodes[SDLK_r] = 0x13; scancodes[SDLK_t] = 0x14; scancodes[SDLK_y] = 0x15; scancodes[SDLK_u] = 0x16; scancodes[SDLK_i] = 0x17; scancodes[SDLK_o] = 0x18; scancodes[SDLK_p] = 0x19; scancodes[SDLK_LEFTBRACKET] = 0x1A; scancodes[SDLK_RIGHTBRACKET] = 0x1B; scancodes[SDLK_RETURN] = 0x1C; scancodes[SDLK_LCTRL] = 0x1D; scancodes[SDLK_a] = 0x1E; scancodes[SDLK_s] = 0x1F; scancodes[SDLK_d] = 0x20; scancodes[SDLK_f] = 0x21; scancodes[SDLK_g] = 0x22; scancodes[SDLK_h] = 0x23; scancodes[SDLK_j] = 0x24; scancodes[SDLK_k] = 0x25; scancodes[SDLK_l] = 0x26;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -