📄 sdl_video.c
字号:
/*
* Update a specific portion of the physical screen
*/
void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
{
if ( screen ) {
SDL_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;
SDL_UpdateRects(screen, 1, &rect);
}
}
void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects)
{
int i;
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
if ( screen == SDL_ShadowSurface ) {
/* Blit the shadow surface using saved mapping */
SDL_Palette *pal = screen->format->palette;
SDL_Color *saved_colors = NULL;
if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
/* simulated 8bpp, use correct physical palette */
saved_colors = pal->colors;
if ( video->gammacols ) {
/* gamma-corrected palette */
pal->colors = video->gammacols;
} else if ( video->physpal ) {
/* physical palette different from logical */
pal->colors = video->physpal->colors;
}
}
if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) {
SDL_LockCursor();
SDL_DrawCursor(SDL_ShadowSurface);
for ( i=0; i<numrects; ++i ) {
SDL_LowerBlit(SDL_ShadowSurface, &rects[i],
SDL_VideoSurface, &rects[i]);
}
SDL_EraseCursor(SDL_ShadowSurface);
SDL_UnlockCursor();
} else {
for ( i=0; i<numrects; ++i ) {
SDL_LowerBlit(SDL_ShadowSurface, &rects[i],
SDL_VideoSurface, &rects[i]);
}
}
if ( saved_colors )
pal->colors = saved_colors;
/* Fall through to video surface update */
screen = SDL_VideoSurface;
}
if ( screen == SDL_VideoSurface ) {
/* 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);
}
}
}
/*
* Performs hardware double buffering, if possible, or a full update if not.
*/
int SDL_Flip(SDL_Surface *screen)
{
SDL_VideoDevice *video = current_video;
/* Copy the shadow surface to the video surface */
if ( screen == SDL_ShadowSurface ) {
SDL_Rect rect;
SDL_Palette *pal = screen->format->palette;
SDL_Color *saved_colors = NULL;
if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) {
/* simulated 8bpp, use correct physical palette */
saved_colors = pal->colors;
if ( video->gammacols ) {
/* gamma-corrected palette */
pal->colors = video->gammacols;
} else 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;
SDL_LowerBlit(SDL_ShadowSurface,&rect, SDL_VideoSurface,&rect);
if ( saved_colors )
pal->colors = saved_colors;
screen = SDL_VideoSurface;
}
if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
SDL_VideoDevice *this = current_video;
return(video->FlipHWSurface(this, SDL_VideoSurface));
} else {
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
return(0);
}
static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors,
int firstcolor, int ncolors)
{
SDL_Palette *pal = screen->format->palette;
SDL_Palette *vidpal;
if ( colors != (pal->colors + firstcolor) ) {
memcpy(pal->colors + firstcolor, colors,
ncolors * sizeof(*colors));
}
vidpal = SDL_VideoSurface->format->palette;
if ( (screen == SDL_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));
}
SDL_FormatChanged(screen);
}
static int SetPalette_physical(SDL_Surface *screen,
SDL_Color *colors, int firstcolor, int ncolors)
{
SDL_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 ( screen == SDL_ShadowSurface ) {
if ( SDL_VideoSurface->flags & SDL_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 = SDL_VideoSurface;
} else {
/*
* The video surface is not indexed - invalidate any
* active shadow-to-video blit mappings.
*/
if ( screen->map->dst == SDL_VideoSurface ) {
SDL_InvalidateMap(screen->map);
}
if ( video->gamma ) {
if( ! video->gammacols ) {
SDL_Palette *pp = video->physpal;
if(!pp)
pp = screen->format->palette;
video->gammacols = malloc(pp->ncolors
* sizeof(SDL_Color));
SDL_ApplyGamma(video->gamma,
pp->colors,
video->gammacols,
pp->ncolors);
} else {
SDL_ApplyGamma(video->gamma, colors,
video->gammacols
+ firstcolor,
ncolors);
}
}
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
}
if ( screen == SDL_VideoSurface ) {
SDL_Color gcolors[256];
if ( video->gamma ) {
SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors);
colors = gcolors;
}
gotall = video->SetColors(video, firstcolor, ncolors, colors);
if ( ! gotall ) {
/* The video flags shouldn't have SDL_HWPALETTE, and
the video driver is responsible for copying back the
correct colors into the video surface palette.
*/
;
}
SDL_CursorPaletteChanged();
}
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 SDL_LOGPAL, SDL_PHYSPAL
*
* Return nonzero if all colours were set as requested, or 0 otherwise.
*/
int SDL_SetPalette(SDL_Surface *screen, int which,
SDL_Color *colors, int firstcolor, int ncolors)
{
SDL_Palette *pal;
int gotall;
int palsize;
if ( ! current_video ) {
return 0;
}
if ( screen != SDL_PublicSurface ) {
/* only screens have physical palettes */
which &= ~SDL_PHYSPAL;
} else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) {
/* hardware palettes required for split colormaps */
which |= SDL_PHYSPAL | SDL_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 & SDL_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 & SDL_PHYSPAL ) {
SDL_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 & SDL_LOGPAL) ) {
/* Lazy physical palette allocation */
int size;
SDL_Palette *pp = malloc(sizeof(*pp));
current_video->physpal = pp;
pp->ncolors = pal->ncolors;
size = pp->ncolors * sizeof(SDL_Color);
pp->colors = malloc(size);
memcpy(pp->colors, pal->colors, size);
}
if ( ! SetPalette_physical(screen,
colors, firstcolor, ncolors) ) {
gotall = 0;
}
}
return gotall;
}
int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor,
int ncolors)
{
return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL,
colors, firstcolor, ncolors);
}
/*
* Clean up the video subsystem
*/
void SDL_VideoQuit (void)
{
SDL_Surface *ready_to_go;
if ( current_video ) {
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
/* Halt event processing before doing anything else */
SDL_StopEventLoop();
/* Clean up allocated window manager items */
if ( SDL_PublicSurface ) {
SDL_PublicSurface = NULL;
}
SDL_CursorQuit();
/* Just in case... */
SDL_WM_GrabInputOff();
/* Clean up the system video */
video->VideoQuit(this);
/* Free any lingering surfaces */
ready_to_go = SDL_ShadowSurface;
SDL_ShadowSurface = NULL;
SDL_FreeSurface(ready_to_go);
if ( SDL_VideoSurface != NULL ) {
ready_to_go = SDL_VideoSurface;
SDL_VideoSurface = NULL;
SDL_FreeSurface(ready_to_go);
}
SDL_PublicSurface = NULL;
/* Clean up miscellaneous memory */
if ( video->physpal ) {
free(video->physpal->colors);
free(video->physpal);
video->physpal = NULL;
}
if ( video->gammacols ) {
free(video->gammacols);
video->gammacols = NULL;
}
if ( video->gamma ) {
free(video->gamma);
video->gamma = NULL;
}
if ( video->wm_title != NULL ) {
free(video->wm_title);
video->wm_title = NULL;
}
if ( video->wm_icon != NULL ) {
free(video->wm_icon);
video->wm_icon = NULL;
}
/* Finish cleaning up video subsystem */
video->free(this);
current_video = NULL;
}
return;
}
/* Load the GL driver library */
int SDL_GL_LoadLibrary(const char *path)
{
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
int retval;
retval = -1;
if ( video && video->GL_LoadLibrary ) {
retval = video->GL_LoadLibrary(this, path);
} else {
SDL_SetError("No dynamic GL support in video driver");
}
return(retval);
}
void *SDL_GL_GetProcAddress(const char* proc)
{
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
void *func;
func = NULL;
if ( video->GL_GetProcAddress ) {
if ( video->gl_config.driver_loaded ) {
func = video->GL_GetProcAddress(this, proc);
} else {
SDL_SetError("No GL driver has been loaded");
}
} else {
SDL_SetError("No dynamic GL support in video driver");
}
return func;
}
/* Set the specified GL attribute for setting up a GL video mode */
int SDL_GL_SetAttribute( SDL_GLattr attr, int value )
{
int retval;
SDL_VideoDevice *video = current_video;
retval = 0;
switch (attr) {
case SDL_GL_RED_SIZE:
video->gl_config.red_size = value;
break;
case SDL_GL_GREEN_SIZE:
video->gl_config.green_size = value;
break;
case SDL_GL_BLUE_SIZE:
video->gl_config.blue_size = value;
break;
case SDL_GL_ALPHA_SIZE:
video->gl_config.alpha_size = value;
break;
case SDL_GL_DOUBLEBUFFER:
video->gl_config.double_buffer = value;
break;
case SDL_GL_BUFFER_SIZE:
video->gl_config.buffer_size = value;
break;
case SDL_GL_DEPTH_SIZE:
video->gl_config.depth_size = value;
break;
case SDL_GL_STENCIL_SIZE:
video->gl_config.stencil_size = value;
break;
case SDL_GL_ACCUM_RED_SIZE:
video->gl_config.accum_red_size = value;
break;
case SDL_GL_ACCUM_GREEN_SIZE:
video->gl_config.accum_green_size = value;
break;
case SDL_GL_ACCUM_BLUE_SIZE:
video->gl_config.accum_blue_size = value;
break;
case SDL_GL_ACCUM_ALPHA_SIZE:
video->gl_config.accum_alpha_size = value;
break;
default:
SDL_SetError("Unknown OpenGL attribute");
retval = -1;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -