Esempio n. 1
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
            );

    /* 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 );
    }
}
Esempio n. 2
0
/*
 * 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);
}
Esempio n. 3
0
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);
}
Esempio n. 5
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);
}
Esempio n. 6
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;
}
Esempio n. 7
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);
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
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;
}
Esempio n. 11
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 );
    }
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
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);
}
Esempio n. 15
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);
}
Esempio n. 16
0
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;
}
Esempio n. 17
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;
}
Esempio n. 18
0
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;
}
Esempio n. 19
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;
}