📄 sdl_directfb_video.c
字号:
SetDirectFBerror ("DirectFBInit", ret); goto error; } ret = DirectFBCreate (&dfb); if (ret) { SetDirectFBerror ("DirectFBCreate", ret); goto error; } ret = dfb->GetDisplayLayer (dfb, DLID_PRIMARY, &layer); if (ret) { SetDirectFBerror ("dfb->GetDisplayLayer", ret); goto error; } ret = dfb->CreateInputEventBuffer (dfb, DICAPS_ALL, DFB_FALSE, &events); if (ret) { SetDirectFBerror ("dfb->CreateEventBuffer", ret); goto error; } layer->EnableCursor (layer, 1); /* Query layer configuration to determine the current mode and pixelformat */ layer->GetConfiguration (layer, &dlc); /* If current format is not supported use LUT8 as the default */ if (DFBToSDLPixelFormat (dlc.pixelformat, vformat)) DFBToSDLPixelFormat (DSPF_LUT8, vformat); /* Enumerate the available fullscreen modes */ ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this); if (ret) { SetDirectFBerror ("dfb->EnumVideoModes", ret); goto error; } HIDDEN->modelist = SDL_calloc (HIDDEN->nummodes + 1, sizeof(SDL_Rect *)); if (!HIDDEN->modelist) { SDL_OutOfMemory(); goto error; } for (i = 0, rect = enumlist; rect; ++i, rect = rect->next ) { HIDDEN->modelist[i] = &rect->r; } HIDDEN->modelist[i] = NULL; /* Query card capabilities to get the video memory size */#if (DIRECTFB_MAJOR_VERSION == 0) && (DIRECTFB_MINOR_VERSION == 9) && (DIRECTFB_MICRO_VERSION < 23) dfb->GetCardCapabilities (dfb, &caps);#else dfb->GetDeviceDescription (dfb, &caps);#endif this->info.wm_available = 1; this->info.hw_available = 1; this->info.blit_hw = 1; this->info.blit_hw_CC = 1; this->info.blit_hw_A = 1; this->info.blit_fill = 1; this->info.video_mem = caps.video_memory / 1024; this->info.current_w = dlc.width; this->info.current_h = dlc.height; HIDDEN->initialized = 1; HIDDEN->dfb = dfb; HIDDEN->layer = layer; HIDDEN->eventbuffer = events; if (SDL_getenv("SDL_DIRECTFB_MGA_CRTC2") != NULL) HIDDEN->enable_mga_crtc2 = 1; if (HIDDEN->enable_mga_crtc2) { DFBDisplayLayerConfig dlc; DFBDisplayLayerConfigFlags failed; ret = dfb->GetDisplayLayer (dfb, 2, &HIDDEN->c2layer); if (ret) { SetDirectFBerror ("dfb->GetDisplayLayer(CRTC2)", ret); goto error; } ret = HIDDEN->layer->SetCooperativeLevel(HIDDEN->layer, DLSCL_EXCLUSIVE); if (ret) { SetDirectFBerror ("layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret); goto error; } ret = HIDDEN->c2layer->SetCooperativeLevel(HIDDEN->c2layer, DLSCL_EXCLUSIVE); if (ret) { SetDirectFBerror ("c2layer->SetCooperativeLevel(CRTC2, EXCLUSIVE)", ret); goto error; } HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0x0); /* Init the surface here as it got a fixed size */ dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE; dlc.buffermode = DLBM_BACKVIDEO; dlc.pixelformat = DSPF_RGB32; ret = HIDDEN->c2layer->TestConfiguration( HIDDEN->c2layer, &dlc, &failed ); if (ret) { SetDirectFBerror ("c2layer->TestConfiguration", ret); goto error; } ret = HIDDEN->c2layer->SetConfiguration( HIDDEN->c2layer, &dlc ); if (ret) { SetDirectFBerror ("c2layer->SetConfiguration", ret); goto error; } ret = HIDDEN->c2layer->GetSurface( HIDDEN->c2layer, &HIDDEN->c2frame ); if (ret) { SetDirectFBerror ("c2layer->GetSurface", ret); goto error; } HIDDEN->c2framesize.x = 0; HIDDEN->c2framesize.y = 0; HIDDEN->c2frame->GetSize( HIDDEN->c2frame, &HIDDEN->c2framesize.w, &HIDDEN->c2framesize.h); HIDDEN->c2frame->SetBlittingFlags( HIDDEN->c2frame, DSBLIT_NOFX ); HIDDEN->c2frame->SetColor( HIDDEN->c2frame, 0, 0, 0, 0xff ); /* Clear CRTC2 */ HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff ); HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 ); HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff ); HIDDEN->c2frame->Flip(HIDDEN->c2frame, NULL, 0 ); HIDDEN->c2frame->Clear(HIDDEN->c2frame, 0, 0, 0, 0xff ); HIDDEN->c2layer->SetOpacity(HIDDEN->c2layer, 0xFF ); /* Check if overscan is possibly set */ if (SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN") != NULL) { float overscan = 0; if (SDL_sscanf(SDL_getenv("SDL_DIRECTFB_MGA_OVERSCAN"), "%f", &overscan) == 1) if (overscan > 0 && overscan < 2) HIDDEN->mga_crtc2_stretch_overscan = overscan; } #ifdef DIRECTFB_CRTC2_DEBUG printf("CRTC2 overscan: %f\n", HIDDEN->mga_crtc2_stretch_overscan); #endif } return 0; error: if (events) events->Release (events); if (HIDDEN->c2frame) HIDDEN->c2frame->Release (HIDDEN->c2frame); if (HIDDEN->c2layer) HIDDEN->c2layer->Release (HIDDEN->c2layer); if (layer) layer->Release (layer); if (dfb) dfb->Release (dfb); return -1;}static SDL_Rect **DirectFB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags){ if (flags & SDL_FULLSCREEN) return HIDDEN->modelist; else if (SDLToDFBPixelFormat (format) != DSPF_UNKNOWN) return (SDL_Rect**) -1; return NULL;}static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags){ DFBResult ret; DFBSurfaceDescription dsc; DFBSurfacePixelFormat pixelformat; IDirectFBSurface *surface; fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", width, height, bpp, flags); flags |= SDL_FULLSCREEN; /* Release previous primary surface */ if (current->hwdata && current->hwdata->surface) { current->hwdata->surface->Release (current->hwdata->surface); current->hwdata->surface = NULL; /* And its palette if present */ if (current->hwdata->palette) { current->hwdata->palette->Release (current->hwdata->palette); current->hwdata->palette = NULL; } } else if (!current->hwdata) { /* Allocate the hardware acceleration data */ current->hwdata = (struct private_hwdata *) SDL_calloc (1, sizeof(*current->hwdata)); if (!current->hwdata) { SDL_OutOfMemory(); return NULL; } } /* Set cooperative level depending on flag SDL_FULLSCREEN */ if (flags & SDL_FULLSCREEN) { ret = HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_FULLSCREEN); if (ret && !HIDDEN->enable_mga_crtc2) { DirectFBError ("dfb->SetCooperativeLevel", ret); flags &= ~SDL_FULLSCREEN; } } else HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL); /* Set video mode */ ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp); if (ret) { if (flags & SDL_FULLSCREEN) { flags &= ~SDL_FULLSCREEN; HIDDEN->dfb->SetCooperativeLevel (HIDDEN->dfb, DFSCL_NORMAL); ret = HIDDEN->dfb->SetVideoMode (HIDDEN->dfb, width, height, bpp); } if (ret) { SetDirectFBerror ("dfb->SetVideoMode", ret); return NULL; } } /* Create primary surface */ dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT; dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer); ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface); if (ret && (flags & SDL_DOUBLEBUF)) { /* Try without double buffering */ dsc.caps &= ~DSCAPS_FLIPPING; ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface); } if (ret) { SetDirectFBerror ("dfb->CreateSurface", ret); return NULL; } current->w = width; current->h = height; current->flags = SDL_HWSURFACE | SDL_PREALLOC; if (flags & SDL_FULLSCREEN) { current->flags |= SDL_FULLSCREEN; this->UpdateRects = DirectFB_DirectUpdate; } else this->UpdateRects = DirectFB_WindowedUpdate; if (dsc.caps & DSCAPS_FLIPPING) current->flags |= SDL_DOUBLEBUF; surface->GetPixelFormat (surface, &pixelformat); DFBToSDLPixelFormat (pixelformat, current->format); /* Get the surface palette (if supported) */ if (DFB_PIXELFORMAT_IS_INDEXED( pixelformat )) { surface->GetPalette (surface, ¤t->hwdata->palette); current->flags |= SDL_HWPALETTE; } current->hwdata->surface = surface; /* MGA CRTC2 stuff */ if (HIDDEN->enable_mga_crtc2) { /* no stretching if c2ssize == c2framesize */ HIDDEN->c2ssize.x = 0, HIDDEN->c2ssize.y = 0; HIDDEN->c2ssize.w = width; HIDDEN->c2ssize.h = height; HIDDEN->c2dsize.x = 0, HIDDEN->c2dsize.y = 0; HIDDEN->c2dsize.w = width; HIDDEN->c2dsize.h = height; HIDDEN->mga_crtc2_stretch = 0; if (SDL_getenv("SDL_DIRECTFB_MGA_STRETCH") != NULL) { /* Normally assume a picture aspect ratio of 4:3 */ int zoom_aspect_x = 4, zoom_aspect_y = 3, i, j; for (i = 1; i < 20; i++) { for (j = 1; j < 10; j++) { if ((float)width/(float)i*(float)j == height) { zoom_aspect_x = i; zoom_aspect_y = j; /* break the loop */ i = 21; break; } } } #ifdef DIRECTFB_CRTC2_DEBUG printf("Source resolution: X: %d, Y: %d, Aspect ratio: %d:%d\n", width, height, zoom_aspect_x, zoom_aspect_y); printf("CRTC2 resolution: X: %d, Y: %d\n", HIDDEN->c2framesize.w, HIDDEN->c2framesize.h); #endif /* don't stretch only slightly smaller/larger images */ if ((float)width < (float)HIDDEN->c2framesize.w*0.95 || (float)height < (float)HIDDEN->c2framesize.h*0.95) { while ((float)HIDDEN->c2dsize.w < (float)HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan && (float)HIDDEN->c2dsize.h < (float)HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan) { HIDDEN->c2dsize.w+=zoom_aspect_x; HIDDEN->c2dsize.h+=zoom_aspect_y; } /* one step down */ HIDDEN->c2dsize.w-=zoom_aspect_x; HIDDEN->c2dsize.h-=zoom_aspect_y; #ifdef DIRECTFB_CRTC2_DEBUG printf("Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h); #endif HIDDEN->mga_crtc2_stretch = 1; } else if ((float)width > (float)HIDDEN->c2framesize.w*0.95 || (float)height > (float)HIDDEN->c2framesize.h*0.95) { while ((float)HIDDEN->c2dsize.w > (float)HIDDEN->c2framesize.w*HIDDEN->mga_crtc2_stretch_overscan || (float)HIDDEN->c2dsize.h > (float)HIDDEN->c2framesize.h*HIDDEN->mga_crtc2_stretch_overscan) { HIDDEN->c2dsize.w-=zoom_aspect_x; HIDDEN->c2dsize.h-=zoom_aspect_y; } #ifdef DIRECTFB_CRTC2_DEBUG printf("Down-Stretched resolution: X: %d, Y: %d\n", HIDDEN->c2dsize.w, HIDDEN->c2dsize.h); #endif HIDDEN->mga_crtc2_stretch = 1; } else { #ifdef DIRECTFB_CRTC2_DEBUG printf("Not stretching image\n"); #endif } /* Panning */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -