/** * This is a semi-private blit function and it performs low-level surface * scaled blitting only. */ int SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) { static const Uint32 complex_copy_flags = ( SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_COLORKEY ); /* Save off the original dst width, height */ int dstW = dstrect->w; int dstH = dstrect->h; SDL_Rect full_rect; SDL_Rect final_dst = *dstrect; SDL_Rect final_src = *srcrect; /* Clip the dst surface to the dstrect */ full_rect.x = 0; full_rect.y = 0; full_rect.w = dst->w; full_rect.h = dst->h; if (!SDL_IntersectRect(&final_dst, &full_rect, &final_dst)) { return 0; } /* Did the dst width change? */ if ( dstW != final_dst.w ) { /* scale the src width appropriately */ final_src.w = final_src.w * dst->clip_rect.w / dstW; } /* Did the dst height change? */ if ( dstH != final_dst.h ) { /* scale the src width appropriately */ final_src.h = final_src.h * dst->clip_rect.h / dstH; } /* Clip the src surface to the srcrect */ full_rect.x = 0; full_rect.y = 0; full_rect.w = src->w; full_rect.h = src->h; if (!SDL_IntersectRect(&final_src, &full_rect, &final_src)) { return 0; } if (!(src->map->info.flags & SDL_COPY_NEAREST)) { src->map->info.flags |= SDL_COPY_NEAREST; SDL_InvalidateMap(src->map); } if ( !(src->map->info.flags & complex_copy_flags) && src->format->format == dst->format->format && !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { return SDL_SoftStretch( src, &final_src, dst, &final_dst ); } else { return SDL_LowerBlit( src, &final_src, dst, &final_dst ); } }
/* * Free a surface created by the above function. */ void SDL_FreeSurface(SDL_Surface * surface) { if (surface == NULL) { return; } if (surface->flags & SDL_DONTFREE) { return; } SDL_InvalidateMap(surface->map); if (--surface->refcount > 0) { return; } while (surface->locked > 0) { SDL_UnlockSurface(surface); } if (surface->flags & SDL_RLEACCEL) { SDL_UnRLESurface(surface, 0); } if (surface->format) { SDL_SetSurfacePalette(surface, NULL); SDL_FreeFormat(surface->format); surface->format = NULL; } if (!(surface->flags & SDL_PREALLOC)) { SDL_free(surface->pixels); } if (surface->map) { SDL_FreeBlitMap(surface->map); } SDL_free(surface); }
int SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key) { int flags; if (!surface) { return -1; } if (flag & SDL_RLEACCEL) { SDL_SetSurfaceRLE(surface, 1); } flags = surface->map->info.flags; if (flag) { surface->map->info.flags |= SDL_COPY_COLORKEY; surface->map->info.colorkey = key; } else { surface->map->info.flags &= ~SDL_COPY_COLORKEY; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return 0; }
/* * Set the color key in a blittable surface */ int SDL_SetColorKey (SDL_Surface *surface, Uint32 flag, Uint32 key) { /* Sanity check the flag as it gets passed in */ if ( flag & SDL_SRCCOLORKEY ) { if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK); } else { flag = SDL_SRCCOLORKEY; } } else { flag = 0; } /* Optimize away operations that don't change anything */ if ( (flag == (surface->flags & (SDL_SRCCOLORKEY|SDL_RLEACCELOK))) && (key == surface->format->colorkey) ) { return(0); } if ( flag ) { surface->flags |= SDL_SRCCOLORKEY; surface->format->colorkey = key; if ( flag & SDL_RLEACCELOK ) { surface->flags |= SDL_RLEACCELOK; } else { surface->flags &= ~SDL_RLEACCELOK; } } else { surface->flags &= ~(SDL_SRCCOLORKEY|SDL_RLEACCELOK); surface->format->colorkey = 0; } SDL_InvalidateMap(surface->map); return(0); }
/* This function sets the alpha channel of a surface */ int SDL_SetAlpha (SDL_Surface *surface, Uint32 flag, Uint8 value) { Uint32 oldflags = surface->flags; Uint32 oldalpha = surface->format->alpha; /* Sanity check the flag as it gets passed in */ if ( flag & SDL_SRCALPHA ) { if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { flag = (SDL_SRCALPHA | SDL_RLEACCELOK); } else { flag = SDL_SRCALPHA; } } else { flag = 0; } /* Optimize away operations that don't change anything */ if ( (flag == (surface->flags & (SDL_SRCALPHA|SDL_RLEACCELOK))) && (!flag || value == oldalpha) ) { return(0); } if(!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) SDL_UnRLESurface(surface, 1); if ( flag ) { SDL_VideoDevice *video = current_video; SDL_VideoDevice *this = current_video; surface->flags |= SDL_SRCALPHA; surface->format->alpha = value; if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { if ( (video->SetHWAlpha == NULL) || (video->SetHWAlpha(this, surface, value) < 0) ) { surface->flags &= ~SDL_HWACCEL; } } if ( flag & SDL_RLEACCELOK ) { surface->flags |= SDL_RLEACCELOK; } else { surface->flags &= ~SDL_RLEACCELOK; } } else { surface->flags &= ~SDL_SRCALPHA; surface->format->alpha = SDL_ALPHA_OPAQUE; } /* * The representation for software surfaces is independent of * per-surface alpha, so no need to invalidate the blit mapping * if just the alpha value was changed. (If either is 255, we still * need to invalidate.) */ if((surface->flags & SDL_HWACCEL) == SDL_HWACCEL || oldflags != surface->flags || (((oldalpha + 1) ^ (value + 1)) & 0x100)) SDL_InvalidateMap(surface->map); return(0); }
int SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette) { if (!surface) { return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface"); } if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) { return -1; } SDL_InvalidateMap(surface->map); return 0; }
/* * Set the color key in a blittable surface */ int SDL_SetColorKey (SDL_Surface *surface, Uint32 flag, Uint32 key) { /* Sanity check the flag as it gets passed in */ if ( flag & SDL_SRCCOLORKEY ) { if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK); } else { flag = SDL_SRCCOLORKEY; } } else { flag = 0; } /* Optimize away operations that don't change anything */ if ( (flag == (surface->flags & (SDL_SRCCOLORKEY|SDL_RLEACCELOK))) && (key == surface->format->colorkey) ) { return(0); } /* UnRLE surfaces before we change the colorkey */ if ( surface->flags & SDL_RLEACCEL ) { SDL_UnRLESurface(surface, 1); } if ( flag ) { SDL_VideoDevice *video = current_video; SDL_VideoDevice *this = current_video; surface->flags |= SDL_SRCCOLORKEY; surface->format->colorkey = key; if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { if ( (video->SetHWColorKey == NULL) || (video->SetHWColorKey(this, surface, key) < 0) ) { surface->flags &= ~SDL_HWACCEL; } } if ( flag & SDL_RLEACCELOK ) { surface->flags |= SDL_RLEACCELOK; } else { surface->flags &= ~SDL_RLEACCELOK; } } else { surface->flags &= ~(SDL_SRCCOLORKEY|SDL_RLEACCELOK); surface->format->colorkey = 0; } SDL_InvalidateMap(surface->map); return(0); }
int SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key) { int flags; if (!surface) { return SDL_InvalidParamError("surface"); } if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) { return SDL_InvalidParamError("key"); } if (flag & SDL_RLEACCEL) { SDL_SetSurfaceRLE(surface, 1); } flags = surface->map->info.flags; if (flag) { surface->map->info.flags |= SDL_COPY_COLORKEY; surface->map->info.colorkey = key; if (surface->format->palette) { surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT; ++surface->format->palette->version; if (!surface->format->palette->version) { surface->format->palette->version = 1; } } } else { if (surface->format->palette) { surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_OPAQUE; ++surface->format->palette->version; if (!surface->format->palette->version) { surface->format->palette->version = 1; } } surface->map->info.flags &= ~SDL_COPY_COLORKEY; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return 0; }
int SDL_SetSurfaceRLE(SDL_Surface * surface, int flag) { int flags; if (!surface) { return -1; } flags = surface->map->info.flags; if (flag) { surface->map->info.flags |= SDL_COPY_RLE_DESIRED; } else { surface->map->info.flags &= ~SDL_COPY_RLE_DESIRED; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return 0; }
int SDL_SetSurfaceAlphaMod(SDL_Surface * surface, Uint8 alpha) { int flags; if (!surface) { return -1; } surface->map->info.a = alpha; flags = surface->map->info.flags; if (alpha != 0xFF) { surface->map->info.flags |= SDL_COPY_MODULATE_ALPHA; } else { surface->map->info.flags &= ~SDL_COPY_MODULATE_ALPHA; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return 0; }
/** * This is a semi-private blit function and it performs low-level surface * scaled blitting only. */ int SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) { static const Uint32 complex_copy_flags = ( SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_COLORKEY ); if (!(src->map->info.flags & SDL_COPY_NEAREST)) { src->map->info.flags |= SDL_COPY_NEAREST; SDL_InvalidateMap(src->map); } if ( !(src->map->info.flags & complex_copy_flags) && src->format->format == dst->format->format && !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { return SDL_SoftStretch( src, srcrect, dst, dstrect ); } else { return SDL_LowerBlit( src, srcrect, dst, dstrect ); } }
int SDL_SetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode blendMode) { int flags, status; if (!surface) { return -1; } status = 0; flags = surface->map->info.flags; surface->map->info.flags &= ~(SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD); switch (blendMode) { case SDL_BLENDMODE_NONE: break; case SDL_BLENDMODE_BLEND: surface->map->info.flags |= SDL_COPY_BLEND; break; case SDL_BLENDMODE_ADD: surface->map->info.flags |= SDL_COPY_ADD; break; case SDL_BLENDMODE_MOD: surface->map->info.flags |= SDL_COPY_MOD; break; default: SDL_Unsupported(); status = -1; break; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return status; }
int SDL_SetSurfaceColorMod(SDL_Surface * surface, Uint8 r, Uint8 g, Uint8 b) { int flags; if (!surface) { return -1; } surface->map->info.r = r; surface->map->info.g = g; surface->map->info.b = b; flags = surface->map->info.flags; if (r != 0xFF || g != 0xFF || b != 0xFF) { surface->map->info.flags |= SDL_COPY_MODULATE_COLOR; } else { surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR; } if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } return 0; }
/* Figure out which of many blit routines to set up on a surface */ int SDL_CalculateBlit(SDL_Surface *surface) { int blit_index; /* Clean everything out to start */ if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { SDL_UnRLESurface(surface, 1); } surface->map->sw_blit = NULL; /* Figure out if an accelerated hardware blit is possible */ surface->flags &= ~SDL_HWACCEL; //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_CalculateBlit(): identity %d src hw %d dst hw %d video hw %d", (int)surface->map->identity, (int)(surface->flags & SDL_HWSURFACE), (int)(surface->map->dst->flags & SDL_HWSURFACE), (int)(current_video->info.blit_hw)); if ( surface->map->identity ) { int hw_blit_ok; if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { /* We only support accelerated blitting to hardware */ if ( surface->map->dst->flags & SDL_HWSURFACE ) { hw_blit_ok = current_video->info.blit_hw; } else { hw_blit_ok = 0; } if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { hw_blit_ok = current_video->info.blit_hw_CC; } if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { hw_blit_ok = current_video->info.blit_hw_A; } } else { /* We only support accelerated blitting to hardware */ if ( surface->map->dst->flags & SDL_HWSURFACE ) { hw_blit_ok = current_video->info.blit_sw; } else { hw_blit_ok = 0; } if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { hw_blit_ok = current_video->info.blit_sw_CC; } if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { hw_blit_ok = current_video->info.blit_sw_A; } } if ( hw_blit_ok ) { SDL_VideoDevice *video = current_video; SDL_VideoDevice *this = current_video; video->CheckHWBlit(this, surface, surface->map->dst); } } /* if an alpha pixel format is specified, we can accelerate alpha blits */ if (((surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE )&&(current_video->displayformatalphapixel)) { if ( (surface->flags & SDL_SRCALPHA) ) if ( current_video->info.blit_hw_A ) { SDL_VideoDevice *video = current_video; SDL_VideoDevice *this = current_video; video->CheckHWBlit(this, surface, surface->map->dst); } } /* Get the blit function index, based on surface mode */ /* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */ blit_index = 0; blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0; if ( surface->flags & SDL_SRCALPHA && (surface->format->alpha != SDL_ALPHA_OPAQUE || surface->format->Amask) ) { blit_index |= 2; } /* Check for special "identity" case -- copy blit */ if ( surface->map->identity && blit_index == 0 ) { surface->map->sw_data->blit = SDL_BlitCopy; /* Handle overlapping blits on the same surface */ if ( surface == surface->map->dst ) { surface->map->sw_data->blit = SDL_BlitCopyOverlap; } } else { if ( surface->format->BitsPerPixel < 8 ) { surface->map->sw_data->blit = SDL_CalculateBlit0(surface, blit_index); } else { switch ( surface->format->BytesPerPixel ) { case 1: surface->map->sw_data->blit = SDL_CalculateBlit1(surface, blit_index); break; case 2: case 3: case 4: surface->map->sw_data->blit = SDL_CalculateBlitN(surface, blit_index); break; default: surface->map->sw_data->blit = NULL; break; } } } /* Make sure we have a blit function */ if ( surface->map->sw_data->blit == NULL ) { SDL_InvalidateMap(surface->map); SDL_SetError("Blit combination not supported"); return(-1); } /* Choose software blitting function */ if(surface->flags & SDL_RLEACCELOK && (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) { if(surface->map->identity && (blit_index == 1 || (blit_index == 3 && !surface->format->Amask))) { if ( SDL_RLESurface(surface) == 0 ) surface->map->sw_blit = SDL_RLEBlit; } else if(blit_index == 2 && surface->format->Amask) { if ( SDL_RLESurface(surface) == 0 ) surface->map->sw_blit = SDL_RLEAlphaBlit; } } if ( surface->map->sw_blit == NULL ) { surface->map->sw_blit = SDL_SoftBlit; } return(0); }
/* * Convert a surface into the specified pixel format. */ SDL_Surface * SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, Uint32 flags) { SDL_Surface *convert; Uint32 copy_flags; SDL_Color copy_color; SDL_Rect bounds; /* Check for empty destination palette! (results in empty image) */ if (format->palette != NULL) { int i; for (i = 0; i < format->palette->ncolors; ++i) { if ((format->palette->colors[i].r != 0xFF) || (format->palette->colors[i].g != 0xFF) || (format->palette->colors[i].b != 0xFF)) break; } if (i == format->palette->ncolors) { SDL_SetError("Empty destination palette"); return (NULL); } } /* Create a new surface with the desired format */ convert = SDL_CreateRGBSurface(flags, surface->w, surface->h, format->BitsPerPixel, format->Rmask, format->Gmask, format->Bmask, format->Amask); if (convert == NULL) { return (NULL); } /* Copy the palette if any */ if (format->palette && convert->format->palette) { SDL_memcpy(convert->format->palette->colors, format->palette->colors, format->palette->ncolors * sizeof(SDL_Color)); convert->format->palette->ncolors = format->palette->ncolors; } /* Save the original copy flags */ copy_flags = surface->map->info.flags; copy_color.r = surface->map->info.r; copy_color.g = surface->map->info.g; copy_color.b = surface->map->info.b; copy_color.a = surface->map->info.a; surface->map->info.r = 0xFF; surface->map->info.g = 0xFF; surface->map->info.b = 0xFF; surface->map->info.a = 0xFF; surface->map->info.flags = 0; SDL_InvalidateMap(surface->map); /* Copy over the image data */ bounds.x = 0; bounds.y = 0; bounds.w = surface->w; bounds.h = surface->h; SDL_LowerBlit(surface, &bounds, convert, &bounds); /* Clean up the original surface, and update converted surface */ convert->map->info.r = copy_color.r; convert->map->info.g = copy_color.g; convert->map->info.b = copy_color.b; convert->map->info.a = copy_color.a; convert->map->info.flags = (copy_flags & ~(SDL_COPY_COLORKEY | SDL_COPY_BLEND | SDL_COPY_RLE_DESIRED | SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY)); surface->map->info.r = copy_color.r; surface->map->info.g = copy_color.g; surface->map->info.b = copy_color.b; surface->map->info.a = copy_color.a; surface->map->info.flags = copy_flags; SDL_InvalidateMap(surface->map); if (copy_flags & SDL_COPY_COLORKEY) { SDL_bool set_colorkey_by_color = SDL_FALSE; if (surface->format->palette) { if (format->palette && surface->format->palette->ncolors <= format->palette->ncolors && (SDL_memcmp(surface->format->palette->colors, format->palette->colors, surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) { /* The palette is identical, just set the same colorkey */ SDL_SetColorKey(convert, 1, surface->map->info.colorkey); } else if (format->Amask) { /* The alpha was set in the destination from the palette */ } else { set_colorkey_by_color = SDL_TRUE; } } else { set_colorkey_by_color = SDL_TRUE; } if (set_colorkey_by_color) { /* Set the colorkey by color, which needs to be unique */ Uint8 keyR, keyG, keyB, keyA; SDL_GetRGBA(surface->map->info.colorkey, surface->format, &keyR, &keyG, &keyB, &keyA); SDL_SetColorKey(convert, 1, SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA)); /* This is needed when converting for 3D texture upload */ SDL_ConvertColorkeyToAlpha(convert); } } SDL_SetClipRect(convert, &surface->clip_rect); /* Enable alpha blending by default if the new surface has an * alpha channel or alpha modulation */ if ((surface->format->Amask && format->Amask) || (copy_flags & (SDL_COPY_COLORKEY|SDL_COPY_MODULATE_ALPHA))) { SDL_SetSurfaceBlendMode(convert, SDL_BLENDMODE_BLEND); } if ((copy_flags & SDL_COPY_RLE_DESIRED) || (flags & SDL_RLEACCEL)) { SDL_SetSurfaceRLE(convert, SDL_RLEACCEL); } /* We're ready to go! */ return (convert); }
int SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect) { SDL_Rect fulldst; int srcx, srcy, w, h; /* Make sure the surfaces aren't locked */ if (!src || !dst) { return SDL_SetError("SDL_UpperBlit: passed a NULL surface"); } if (src->locked || dst->locked) { return SDL_SetError("Surfaces must not be locked during blit"); } /* If the destination rectangle is NULL, use the entire dest surface */ if (dstrect == NULL) { fulldst.x = fulldst.y = 0; fulldst.w = dst->w; fulldst.h = dst->h; dstrect = &fulldst; } /* clip the source rectangle to the source surface */ if (srcrect) { int maxw, maxh; srcx = srcrect->x; w = srcrect->w; if (srcx < 0) { w += srcx; dstrect->x -= srcx; srcx = 0; } maxw = src->w - srcx; if (maxw < w) w = maxw; srcy = srcrect->y; h = srcrect->h; if (srcy < 0) { h += srcy; dstrect->y -= srcy; srcy = 0; } maxh = src->h - srcy; if (maxh < h) h = maxh; } else { srcx = srcy = 0; w = src->w; h = src->h; } /* clip the destination rectangle against the clip rectangle */ { SDL_Rect *clip = &dst->clip_rect; int dx, dy; dx = clip->x - dstrect->x; if (dx > 0) { w -= dx; dstrect->x += dx; srcx += dx; } dx = dstrect->x + w - clip->x - clip->w; if (dx > 0) w -= dx; dy = clip->y - dstrect->y; if (dy > 0) { h -= dy; dstrect->y += dy; srcy += dy; } dy = dstrect->y + h - clip->y - clip->h; if (dy > 0) h -= dy; } /* Switch back to a fast blit if we were previously stretching */ if (src->map->info.flags & SDL_COPY_NEAREST) { src->map->info.flags &= ~SDL_COPY_NEAREST; SDL_InvalidateMap(src->map); } if (w > 0 && h > 0) { SDL_Rect sr; sr.x = srcx; sr.y = srcy; sr.w = dstrect->w = w; sr.h = dstrect->h = h; return SDL_LowerBlit(src, &sr, dst, dstrect); } dstrect->w = dstrect->h = 0; return 0; }
int SDL_WM_ToggleFullScreen(SDL_Surface * surface) { int length; void *pixels; Uint8 *src, *dst; int row; int window_w; int window_h; if (!SDL_PublicSurface) { SDL_SetError("SDL_SetVideoMode() hasn't been called"); return 0; } /* Copy the old bits out */ length = SDL_PublicSurface->w * SDL_PublicSurface->format->BytesPerPixel; pixels = SDL_malloc(SDL_PublicSurface->h * length); if (pixels) { src = (Uint8*)SDL_PublicSurface->pixels; dst = (Uint8*)pixels; for (row = 0; row < SDL_PublicSurface->h; ++row) { SDL_memcpy(dst, src, length); src += SDL_PublicSurface->pitch; dst += length; } } /* Do the physical mode switch */ if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) { if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) { return 0; } SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; } else { if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) { return 0; } SDL_PublicSurface->flags |= SDL_FULLSCREEN; } /* Recreate the screen surface */ SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); if (!SDL_WindowSurface) { /* We're totally hosed... */ return 0; } /* Center the public surface in the window surface */ SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h); SDL_VideoViewport.x = (window_w - SDL_VideoSurface->w)/2; SDL_VideoViewport.y = (window_h - SDL_VideoSurface->h)/2; SDL_VideoViewport.w = SDL_VideoSurface->w; SDL_VideoViewport.h = SDL_VideoSurface->h; /* Do some shuffling behind the application's back if format changes */ if (SDL_VideoSurface->format->format != SDL_WindowSurface->format->format) { if (SDL_ShadowSurface) { if (SDL_ShadowSurface->format->format == SDL_WindowSurface->format->format) { /* Whee! We don't need a shadow surface anymore! */ SDL_VideoSurface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(SDL_VideoSurface); SDL_free(SDL_ShadowSurface->pixels); SDL_VideoSurface = SDL_ShadowSurface; SDL_VideoSurface->flags |= SDL_PREALLOC; SDL_ShadowSurface = NULL; } else { /* No problem, just change the video surface format */ SDL_FreeFormat(SDL_VideoSurface->format); SDL_VideoSurface->format = SDL_WindowSurface->format; SDL_VideoSurface->format->refcount++; SDL_InvalidateMap(SDL_ShadowSurface->map); } } else { /* We can make the video surface the shadow surface */ SDL_ShadowSurface = SDL_VideoSurface; SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); SDL_ShadowSurface->pixels = SDL_malloc(SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); if (!SDL_ShadowSurface->pixels) { /* Uh oh, we're hosed */ SDL_ShadowSurface = NULL; return 0; } SDL_ShadowSurface->flags &= ~SDL_PREALLOC; SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0); SDL_VideoSurface->flags = SDL_ShadowSurface->flags; SDL_VideoSurface->flags |= SDL_PREALLOC; SDL_FreeFormat(SDL_VideoSurface->format); SDL_VideoSurface->format = SDL_WindowSurface->format; SDL_VideoSurface->format->refcount++; SDL_VideoSurface->w = SDL_ShadowSurface->w; SDL_VideoSurface->h = SDL_ShadowSurface->h; } } /* Update the video surface */ SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels + SDL_VideoViewport.y * SDL_VideoSurface->pitch + SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel); SDL_SetClipRect(SDL_VideoSurface, NULL); /* Copy the old bits back */ if (pixels) { src = (Uint8*)pixels; dst = (Uint8*)SDL_PublicSurface->pixels; for (row = 0; row < SDL_PublicSurface->h; ++row) { SDL_memcpy(dst, src, length); src += length; dst += SDL_PublicSurface->pitch; } SDL_Flip(SDL_PublicSurface); SDL_free(pixels); } /* We're done! */ return 1; }
static int SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags) { int w, h; /* We can't resize something we don't have... */ if (!SDL_VideoSurface) { return -1; } /* We probably have to recreate the window in fullscreen mode */ if (flags & SDL_FULLSCREEN) { return -1; } /* I don't think there's any change we can gracefully make in flags */ if (flags != SDL_VideoFlags) { return -1; } if (bpp != SDL_VideoSurface->format->BitsPerPixel) { return -1; } /* Resize the window */ SDL_GetWindowSize(SDL_VideoWindow, &w, &h); if (w != width || h != height) { SDL_SetWindowSize(SDL_VideoWindow, width, height); } /* If we're in OpenGL mode, just resize the stub surface and we're done! */ if (flags & SDL_OPENGL) { SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; return 0; } SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); if (!SDL_WindowSurface) { return -1; } if (SDL_VideoSurface->format != SDL_WindowSurface->format) { return -1; } SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; SDL_VideoSurface->pixels = SDL_WindowSurface->pixels; SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; SDL_SetClipRect(SDL_VideoSurface, NULL); if (SDL_ShadowSurface) { SDL_ShadowSurface->w = width; SDL_ShadowSurface->h = height; SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); SDL_ShadowSurface->pixels = SDL_realloc(SDL_ShadowSurface->pixels, SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); SDL_SetClipRect(SDL_ShadowSurface, NULL); SDL_InvalidateMap(SDL_ShadowSurface->map); } else { SDL_PublicSurface = SDL_VideoSurface; } ClearVideoSurface(); return 0; }
int SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags) { int w, h; Uint32 format; int access; void *pixels; int pitch; /* We can't resize something we don't have... */ if (!SDL_VideoWindow) { return -1; } /* We probably have to recreate the window in fullscreen mode */ if (flags & SDL_FULLSCREEN) { return -1; } /* I don't think there's any change we can gracefully make in flags */ if (flags != SDL_VideoFlags) { return -1; } /* Resize the window */ SDL_GetWindowSize(SDL_VideoWindow, &w, &h); if (w != width || h != height) { SDL_SetWindowSize(SDL_VideoWindow, width, height); } /* If we're in OpenGL mode, just resize the stub surface and we're done! */ if (flags & SDL_OPENGL) { SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; return 0; } /* Destroy the screen texture and recreate it */ SDL_QueryTexture(SDL_VideoTexture, &format, &access, &w, &h); SDL_DestroyTexture(SDL_VideoTexture); SDL_VideoTexture = SDL_CreateTexture(format, access, width, height); if (!SDL_VideoTexture) { return -1; } SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; if (SDL_QueryTexturePixels(SDL_VideoTexture, &pixels, &pitch) == 0) { SDL_VideoSurface->pixels = pixels; SDL_VideoSurface->pitch = pitch; } else { SDL_CalculatePitch(SDL_VideoSurface); SDL_VideoSurface->pixels = SDL_realloc(SDL_VideoSurface->pixels, SDL_VideoSurface->h * SDL_VideoSurface->pitch); } SDL_SetClipRect(SDL_VideoSurface, NULL); SDL_InvalidateMap(SDL_VideoSurface->map); if (SDL_ShadowSurface) { SDL_ShadowSurface->w = width; SDL_ShadowSurface->h = height; SDL_ShadowSurface->pitch = SDL_CalculatePitch(SDL_ShadowSurface); SDL_ShadowSurface->pixels = SDL_realloc(SDL_ShadowSurface->pixels, SDL_ShadowSurface->h * SDL_ShadowSurface->pitch); SDL_SetClipRect(SDL_ShadowSurface, NULL); SDL_InvalidateMap(SDL_ShadowSurface->map); } ClearVideoSurface(); return 0; }