📄 video.c
字号:
if ( mode->format->palette ) { GAL_PixelFormat *vf = mode->format; GAL_DitherColors(vf->palette->colors, vf->BitsPerPixel); vf->DitheredPalette = TRUE; video->SetColors(this, 0, vf->palette->ncolors, vf->palette->colors); } /* Clear the surface to black */ video->offset_x = 0; video->offset_y = 0; mode->offset = 0;#if defined(_LITE_VERSION) && !defined(_STAND_ALONE) if (mgIsServer) {#endif GAL_SetClipRect(mode, NULL); GAL_ClearSurface(mode);#if defined(_LITE_VERSION) && !defined(_STAND_ALONE) }#endif#if 0 /* Now adjust the offsets to match the desired mode */ video->offset_x = (mode->w-width)/2; video->offset_y = (mode->h-height)/2; mode->offset = video->offset_y*mode->pitch + video->offset_x*mode->format->BytesPerPixel;#endif#ifdef DEBUG_VIDEO fprintf(stderr, "Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n", width, height, bpp, mode->w, mode->h, mode->format->BitsPerPixel, mode->offset);#endif mode->w = width; mode->h = height; GAL_SetClipRect(mode, NULL); } /* If we failed setting a video mode, return NULL... (Uh Oh!) */ if ( mode == NULL ) { return(NULL); }#if 0 /* Create a shadow surface if necessary */ /* There are three conditions under which we create a shadow surface: 1. We need a particular bits-per-pixel that we didn't get. 2. We need a hardware palette and didn't get one. 3. We need a software surface and got a hardware surface. */ if ( ( ( !(flags&GAL_ANYFORMAT) && (GAL_VideoSurface->format->BitsPerPixel != bpp)) || ( (flags&GAL_HWPALETTE) && !(GAL_VideoSurface->flags&GAL_HWPALETTE)) || /* If the surface is in hardware, video writes are visible as soon as they are performed, so we need to buffer them */ ( ((flags&GAL_HWSURFACE) == GAL_SWSURFACE) && (GAL_VideoSurface->flags&GAL_HWSURFACE)) ) ) { GAL_CreateShadowSurface(bpp); if ( GAL_ShadowSurface == NULL ) { GAL_SetError("Couldn't create shadow surface"); return(NULL); } GAL_PublicSurface = GAL_ShadowSurface; } else { GAL_PublicSurface = GAL_VideoSurface; }#endif video->info.vfmt = GAL_VideoSurface->format; /* We're done! */ return(GAL_PublicSurface);}/* * Convert a surface into the video pixel format. */GAL_Surface * GAL_DisplayFormat (GAL_Surface *surface){ Uint32 flags; if (!GAL_PublicSurface) { GAL_SetError("No video mode has been set"); return(NULL); } /* Set the flags appropriate for copying to display surface */ flags = (GAL_PublicSurface->flags&GAL_HWSURFACE);#ifdef AUTORLE_DISPLAYFORMAT flags |= (surface->flags & (GAL_SRCCOLORKEY|GAL_SRCALPHA)); flags |= GAL_RLEACCELOK;#else flags |= surface->flags & (GAL_SRCCOLORKEY|GAL_SRCALPHA|GAL_RLEACCELOK);#endif return(GAL_ConvertSurface(surface, GAL_PublicSurface->format, flags));}/* * Convert a surface into a format that's suitable for blitting to * the screen, but including an alpha channel. */GAL_Surface *GAL_DisplayFormatAlpha(GAL_Surface *surface){ GAL_PixelFormat *vf; GAL_PixelFormat *format; GAL_Surface *converted; Uint32 flags; /* default to ARGB8888 */ Uint32 amask = 0xff000000; Uint32 rmask = 0x00ff0000; Uint32 gmask = 0x0000ff00; Uint32 bmask = 0x000000ff; if (!GAL_PublicSurface) { GAL_SetError("No video mode has been set"); return(NULL); } vf = GAL_PublicSurface->format; switch(vf->BytesPerPixel) { case 2: /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. For anything else (like ARGB4444) it doesn't matter since we have no special code for it anyway */ if ( (vf->Rmask == 0x1f) && (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { rmask = 0xff; bmask = 0xff0000; } break; case 3: case 4: /* Keep the video format, as long as the high 8 bits are unused or alpha */ if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) { rmask = 0xff; bmask = 0xff0000; } break; default: /* We have no other optimised formats right now. When/if a new optimised alpha format is written, add the converter here */ break; } format = GAL_AllocFormat(32, rmask, gmask, bmask, amask); flags = GAL_PublicSurface->flags & GAL_HWSURFACE; flags |= surface->flags & (GAL_SRCALPHA | GAL_RLEACCELOK); converted = GAL_ConvertSurface(surface, format, flags); GAL_FreeFormat(format); return(converted);}/* * Update a specific portion of the physical screen */void GAL_UpdateRect(GAL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h){ GAL_VideoDevice *video = current_video; if ( screen && video->UpdateRects ) { GAL_Rect rect; /* Perform some checking */ if ( w == 0 ) w = screen->w; if ( h == 0 ) h = screen->h; if ( (int)(x+w) > screen->w ) return; if ( (int)(y+h) > screen->h ) return; /* Fill the rectangle */ rect.x = x; rect.y = y; rect.w = w; rect.h = h; GAL_UpdateRects(screen, 1, &rect); }}void GAL_UpdateRects (GAL_Surface *screen, int numrects, GAL_Rect *rects){ int i; GAL_VideoDevice *video = current_video; GAL_VideoDevice *this = current_video;#if 0 if ( screen == GAL_ShadowSurface ) { /* Blit the shadow surface using saved mapping */ GAL_Palette *pal = screen->format->palette; GAL_Color *saved_colors = NULL; if ( pal && !(GAL_VideoSurface->flags & GAL_HWPALETTE) ) { /* simulated 8bpp, use correct physical palette */ saved_colors = pal->colors; if ( video->physpal ) { /* physical palette different from logical */ pal->colors = video->physpal->colors; } } for ( i=0; i<numrects; ++i ) { GAL_LowerBlit(GAL_ShadowSurface, &rects[i], GAL_VideoSurface, &rects[i]); } if ( saved_colors ) pal->colors = saved_colors; /* Fall through to video surface update */ screen = GAL_VideoSurface; }#endif if ( screen == GAL_VideoSurface && video->UpdateRects ) {#if 0 /* Update the video surface */ if ( screen->offset ) { for ( i=0; i<numrects; ++i ) { rects[i].x += video->offset_x; rects[i].y += video->offset_y; } video->UpdateRects(this, numrects, rects); for ( i=0; i<numrects; ++i ) { rects[i].x -= video->offset_x; rects[i].y -= video->offset_y; } } else { video->UpdateRects(this, numrects, rects); }#else video->UpdateRects(this, numrects, rects);#endif }}#if 0/* * Performs hardware double buffering, if possible, or a full update if not. */int GAL_Flip(GAL_Surface *screen){ GAL_VideoDevice *video = current_video; /* Copy the shadow surface to the video surface */ if ( screen == GAL_ShadowSurface ) { GAL_Rect rect; GAL_Palette *pal = screen->format->palette; GAL_Color *saved_colors = NULL; if ( pal && !(GAL_VideoSurface->flags & GAL_HWPALETTE) ) { /* simulated 8bpp, use correct physical palette */ saved_colors = pal->colors; if ( video->physpal ) { /* physical palette different from logical */ pal->colors = video->physpal->colors; } } rect.x = 0; rect.y = 0; rect.w = screen->w; rect.h = screen->h; GAL_LowerBlit(GAL_ShadowSurface,&rect, GAL_VideoSurface,&rect); if ( saved_colors ) pal->colors = saved_colors; screen = GAL_VideoSurface; } if ( (screen->flags & GAL_DOUBLEBUF) == GAL_DOUBLEBUF ) { GAL_VideoDevice *this = current_video; return(video->FlipHWSurface(this, GAL_VideoSurface)); } else { GAL_UpdateRect(screen, 0, 0, 0, 0); } return(0);}#endifstatic void SetPalette_logical(GAL_Surface *screen, GAL_Color *colors, int firstcolor, int ncolors){ GAL_Palette *pal = screen->format->palette; GAL_Palette *vidpal; if ( colors != (pal->colors + firstcolor) ) { memcpy(pal->colors + firstcolor, colors, ncolors * sizeof(*colors)); }#if 0 vidpal = GAL_VideoSurface->format->palette; if ( (screen == GAL_ShadowSurface) && vidpal ) { /* * This is a shadow surface, and the physical * framebuffer is also indexed. Propagate the * changes to its logical palette so that * updates are always identity blits */ memcpy(vidpal->colors + firstcolor, colors, ncolors * sizeof(*colors)); }#endif GAL_FormatChanged(screen);}static int SetPalette_physical(GAL_Surface *screen, GAL_Color *colors, int firstcolor, int ncolors){ GAL_VideoDevice *video = current_video; int gotall = 1; if ( video->physpal ) { /* We need to copy the new colors, since we haven't * already done the copy in the logical set above. */ memcpy(video->physpal->colors + firstcolor, colors, ncolors * sizeof(*colors)); }#if 0 if ( screen == GAL_ShadowSurface ) { if ( GAL_VideoSurface->flags & GAL_HWPALETTE ) { /* * The real screen is also indexed - set its physical * palette. The physical palette does not include the * gamma modification, we apply it directly instead, * but this only happens if we have hardware palette. */ screen = GAL_VideoSurface; } else { /* * The video surface is not indexed - invalidate any * active shadow-to-video blit mappings. */ if ( screen->map->dst == GAL_VideoSurface ) { GAL_InvalidateMap(screen->map); } GAL_UpdateRect(screen, 0, 0, 0, 0); } }#endif if ( screen == GAL_VideoSurface ) { GAL_Color gcolors[256]; colors = gcolors; gotall = video->SetColors(video, firstcolor, ncolors, colors); if ( ! gotall ) { /* The video flags shouldn't have GAL_HWPALETTE, and the video driver is responsible for copying back the correct colors into the video surface palette. */ ; } } return gotall;}/* * Set the physical and/or logical colormap of a surface: * Only the screen has a physical colormap. It determines what is actually * sent to the display. * The logical colormap is used to map blits to/from the surface. * 'which' is one or both of GAL_LOGPAL, GAL_PHYSPAL * * Return nonzero if all colours were set as requested, or 0 otherwise. */int GAL_SetPalette(GAL_Surface *screen, int which, GAL_Color *colors, int firstcolor, int ncolors){ GAL_Palette *pal; int gotall; int palsize; if ( ! current_video ) { return 0; } if ( screen != GAL_PublicSurface ) { /* only screens have physical palettes */ which &= ~GAL_PHYSPAL; } else if( (screen->flags & GAL_HWPALETTE) != GAL_HWPALETTE ) { /* hardware palettes required for split colormaps */ which |= GAL_PHYSPAL | GAL_LOGPAL; } /* Verify the parameters */ pal = screen->format->palette; if( !pal ) { return 0; /* not a palettized surface */ } gotall = 1; palsize = 1 << screen->format->BitsPerPixel; if ( ncolors > (palsize - firstcolor) ) { ncolors = (palsize - firstcolor); gotall = 0; } if ( which & GAL_LOGPAL ) { /* * Logical palette change: The actual screen isn't affected, * but the internal colormap is altered so that the * interpretation of the pixel values (for blits etc) is * changed. */ SetPalette_logical(screen, colors, firstcolor, ncolors); } if ( which & GAL_PHYSPAL ) { GAL_VideoDevice *video = current_video; /* * Physical palette change: This doesn't affect the * program's idea of what the screen looks like, but changes * its actual appearance. */ if(!video) return gotall; /* video not yet initialized */ if(!video->physpal && !(which & GAL_LOGPAL) ) { /* Lazy physical palette allocation */ int size; GAL_Palette *pp = malloc(sizeof(*pp)); current_video->physpal = pp; pp->ncolors = pal->ncolors; size = pp->ncolors * sizeof(GAL_Color); pp->colors = malloc(size); memcpy(pp->colors, pal->colors, size); } if ( ! SetPalette_physical(screen, colors, firstcolor, ncolors) ) { gotall = 0; } } screen->format->DitheredPalette = FALSE; return gotall;}int GAL_SetColors(GAL_Surface *screen, GAL_Color *colors, int firstcolor, int ncolors){ return GAL_SetPalette(screen, GAL_LOGPAL | GAL_PHYSPAL, colors, firstcolor, ncolors);}/* * Clean up the video subsystem */void GAL_VideoQuit (void){ GAL_Surface *ready_to_go; if ( current_video ) { GAL_VideoDevice *video = current_video; GAL_VideoDevice *this = current_video;#if 0 /* Clean up allocated window manager items */ if ( GAL_PublicSurface ) { GAL_PublicSurface = NULL; }#endif /* Clean up the system video */ video->VideoQuit(this);#if 0 /* Free any lingering surfaces */ ready_to_go = GAL_ShadowSurface; GAL_ShadowSurface = NULL; GAL_FreeSurface(ready_to_go);#endif if (GAL_VideoSurface != NULL) { ready_to_go = GAL_VideoSurface; GAL_VideoSurface = NULL; GAL_FreeSurface(ready_to_go); } GAL_PublicSurface = NULL; /* Clean up miscellaneous memory */ if ( video->physpal ) { free(video->physpal->colors); free(video->physpal); video->physpal = NULL; } /* Finish cleaning up video subsystem */ video->free(this); current_video = NULL; } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -