📄 sdl_vglvideo.c
字号:
if ((modes[i]->ModeInfo.Xsize == width) && (modes[i]->ModeInfo.Ysize == height) && ((modes[i]->ModeInfo.Type == VIDBUF8) || (modes[i]->ModeInfo.Type == VIDBUF16) || (modes[i]->ModeInfo.Type == VIDBUF32))) { mode_found = 1; break; } } if (mode_found == 0) { SDL_SetError("No matching video mode found"); return NULL; } /* Shutdown previous videomode (if any) */ if (VGLCurMode != NULL) VGLEnd(); /* Try to set the requested linear video mode */ if (VGLInit(modes[i]->ModeId) != 0) { SDL_SetError("Unable to switch to requested mode"); return NULL; } VGLCurMode = SDL_realloc(VGLCurMode, sizeof(VGLMode)); VGLCurMode->ModeInfo = *VGLDisplay; VGLCurMode->Depth = modes[i]->Depth; VGLCurMode->ModeId = modes[i]->ModeId; VGLCurMode->Rmask = modes[i]->Rmask; VGLCurMode->Gmask = modes[i]->Gmask; VGLCurMode->Bmask = modes[i]->Bmask; /* Workaround a bug in libvgl */ if (VGLCurMode->ModeInfo.PixelBytes == 0) (VGLCurMode->ModeInfo.PixelBytes = 1); current->w = VGLCurMode->ModeInfo.Xsize; current->h = VGLCurMode->ModeInfo.Ysize; current->pixels = VGLCurMode->ModeInfo.Bitmap; current->pitch = VGLCurMode->ModeInfo.Xsize * VGLCurMode->ModeInfo.PixelBytes; current->flags = (SDL_FULLSCREEN | SDL_HWSURFACE); /* Check if we are in a pseudo-color mode */ if (VGLCurMode->ModeInfo.Type == VIDBUF8) current->flags |= SDL_HWPALETTE; /* Check if we can do doublebuffering */ if (flags & SDL_DOUBLEBUF) { if (VGLCurMode->ModeInfo.Xsize * 2 <= VGLCurMode->ModeInfo.VYsize) { current->flags |= SDL_DOUBLEBUF; flip_page = 0; flip_address[0] = (byte *)current->pixels; flip_address[1] = (byte *)current->pixels + current->h * current->pitch; VGL_FlipHWSurface(this, current); } } if (! SDL_ReallocFormat(current, modes[i]->Depth, VGLCurMode->Rmask, VGLCurMode->Gmask, VGLCurMode->Bmask, 0)) { return NULL; } /* Update hardware acceleration info */ VGL_UpdateVideoInfo(this); /* Set the blit function */ this->UpdateRects = VGL_DirectUpdate; /* We're done */ return current;}/* We don't actually allow hardware surfaces other than the main one */static int VGL_AllocHWSurface(_THIS, SDL_Surface *surface){ return -1;}static void VGL_FreeHWSurface(_THIS, SDL_Surface *surface){ return;}/* We need to wait for vertical retrace on page flipped displays */static int VGL_LockHWSurface(_THIS, SDL_Surface *surface){ if (surface == SDL_VideoSurface) { SDL_mutexP(hw_lock); } return 0;}static void VGL_UnlockHWSurface(_THIS, SDL_Surface *surface){ if (surface == SDL_VideoSurface) { SDL_mutexV(hw_lock); }}static int VGL_FlipHWSurface(_THIS, SDL_Surface *surface){// VGLWaitRetrace(); if (VGLPanScreen(VGLDisplay, 0, flip_page * surface->h) < 0) { SDL_SetError("VGLPanSreen() failed"); return -1; } flip_page = !flip_page; surface->pixels = flip_address[flip_page]; return 0;}static void VGL_DirectUpdate(_THIS, int numrects, SDL_Rect *rects){ return;}static void VGL_BankedUpdate(_THIS, int numrects, SDL_Rect *rects){ return;}int VGL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors){ int i; for(i = 0; i < ncolors; i++) { VGLSetPaletteIndex(firstcolor + i, colors[i].r>>2, colors[i].g>>2, colors[i].b>>2); } return 1;}/* Note: If we are terminated, this could be called in the middle of another SDL video routine -- notably UpdateRects.*/void VGL_VideoQuit(_THIS){ int i, j; /* Return the keyboard to the normal state */ VGLKeyboardEnd(); /* Reset the console video mode if we actually initialised one */ if (VGLCurMode != NULL) { VGLEnd(); SDL_free(VGLCurMode); VGLCurMode = NULL; } /* Clear the lock mutex */ if (hw_lock != NULL) { SDL_DestroyMutex(hw_lock); hw_lock = NULL; } /* Free video mode lists */ for (i = 0; i < NUM_MODELISTS; i++) { if (SDL_modelist[i] != NULL) { for (j = 0; SDL_modelist[i][j] != NULL; ++j) { SDL_free(SDL_modelist[i][j]); } SDL_free(SDL_modelist[i]); SDL_modelist[i] = NULL; } } if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { /* Direct screen access, not a memory buffer */ this->screen->pixels = NULL; }}#define VGL_RED_INDEX 0#define VGL_GREEN_INDEX 1#define VGL_BLUE_INDEX 2static VGLMode **VGLListModes(int depth, int mem_model){ static VGLMode **modes = NULL; VGLBitmap *vminfop; VGLMode **modesp, *modescp; video_info_t minfo; int adptype, i, modenum; if (modes == NULL) { modes = SDL_malloc(sizeof(VGLMode *) * M_VESA_MODE_MAX); bzero(modes, sizeof(VGLMode *) * M_VESA_MODE_MAX); } modesp = modes; for (modenum = 0; modenum < M_VESA_MODE_MAX; modenum++) { minfo.vi_mode = modenum; if (ioctl(0, CONS_MODEINFO, &minfo) || ioctl(0, CONS_CURRENT, &adptype)) continue; if (minfo.vi_mode != modenum) continue; if ((minfo.vi_flags & V_INFO_GRAPHICS) == 0) continue; if ((mem_model != -1) && ((minfo.vi_mem_model & mem_model) == 0)) continue; if ((depth > 1) && (minfo.vi_depth != depth)) continue; /* reallocf can fail */ if ((*modesp = reallocf(*modesp, sizeof(VGLMode))) == NULL) return NULL; modescp = *modesp; vminfop = &(modescp->ModeInfo); bzero(vminfop, sizeof(VGLBitmap)); vminfop->Type = NOBUF; vminfop->PixelBytes = 1; /* Good default value */ switch (minfo.vi_mem_model) { case V_INFO_MM_PLANAR: /* we can handle EGA/VGA planar modes only */ if (!(minfo.vi_depth != 4 || minfo.vi_planes != 4 || (adptype != KD_EGA && adptype != KD_VGA))) vminfop->Type = VIDBUF4; break; case V_INFO_MM_PACKED: /* we can do only 256 color packed modes */ if (minfo.vi_depth == 8) vminfop->Type = VIDBUF8; break; case V_INFO_MM_VGAX: vminfop->Type = VIDBUF8X; break;#if defined(__FREEBSD__) && (defined(__DragonFly__) || __FreeBSD_version >= 500000) case V_INFO_MM_DIRECT: vminfop->PixelBytes = minfo.vi_pixel_size; switch (vminfop->PixelBytes) { case 2: vminfop->Type = VIDBUF16; break;#if notyet case 3: vminfop->Type = VIDBUF24; break;#endif case 4: vminfop->Type = VIDBUF32; break; default: break; }#endif default: break; } if (vminfop->Type == NOBUF) continue; switch (vminfop->Type) { case VIDBUF16: case VIDBUF32: modescp->Rmask = ((1 << minfo.vi_pixel_fsizes[VGL_RED_INDEX]) - 1) << minfo.vi_pixel_fields[VGL_RED_INDEX]; modescp->Gmask = ((1 << minfo.vi_pixel_fsizes[VGL_GREEN_INDEX]) - 1) << minfo.vi_pixel_fields[VGL_GREEN_INDEX]; modescp->Bmask = ((1 << minfo.vi_pixel_fsizes[VGL_BLUE_INDEX]) - 1) << minfo.vi_pixel_fields[VGL_BLUE_INDEX]; break; default: break; } vminfop->Xsize = minfo.vi_width; vminfop->Ysize = minfo.vi_height; modescp->Depth = minfo.vi_depth; /* XXX */ if (minfo.vi_mode >= M_VESA_BASE) modescp->ModeId = _IO('V', minfo.vi_mode - M_VESA_BASE); else modescp->ModeId = _IO('S', minfo.vi_mode); /* Sort list */ for (i = 0; modes + i < modesp ; i++) { if (modes[i]->ModeInfo.Xsize * modes[i]->ModeInfo.Ysize > vminfop->Xsize * modes[i]->ModeInfo.Ysize) continue; if ((modes[i]->ModeInfo.Xsize * modes[i]->ModeInfo.Ysize == vminfop->Xsize * vminfop->Ysize) && (modes[i]->Depth >= modescp->Depth)) continue; *modesp = modes[i]; modes[i] = modescp; modescp = *modesp; vminfop = &(modescp->ModeInfo); } modesp++; } if (*modesp != NULL) { SDL_free(*modesp); *modesp = NULL; } return modes;}static voidVGLWaitRetrace(void){ while (!(inb(0x3DA) & 8)); while (inb(0x3DA) & 8);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -