Page MenuHomePhabricator (Chris)

sge_surface.cpp
No OneTemporary

Authored By
Unknown
Size
28 KB
Referenced Files
None
Subscribers
None

sge_surface.cpp

This document is not UTF8. It was detected as JIS and converted to UTF8 for display.
/*
* SDL Graphics Extension
* Pixel, surface and color functions
*
* Started 990815 (split from sge_draw 010611)
*
* License: LGPL v2+ (see the file LICENSE)
* (c)1999-2001 Anders Lindstr?m
*/
/*********************************************************************
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
*********************************************************************/
/*
* Some of this code is taken from the "Introduction to SDL" and
* John Garrison's PowerPak
*/
#include "SDL.h"
#include <math.h>
#include <string.h>
#include <stdarg.h>
#include "sge_surface.h"
/* Globals used for sge_Update/sge_Lock */
Uint8 _sge_update=1;
Uint8 _sge_lock=1;
/**********************************************************************************/
/** Misc. functions **/
/**********************************************************************************/
//==================================================================================
// Turns off automatic update (to avoid tearing).
//==================================================================================
void sge_Update_OFF(void)
{
_sge_update=0;
}
//==================================================================================
// Turns on automatic update (default)
//==================================================================================
void sge_Update_ON(void)
{
_sge_update=1;
}
//==================================================================================
// Turns off automatic locking of surfaces
//==================================================================================
void sge_Lock_OFF(void)
{
_sge_lock=0;
}
//==================================================================================
// Turns on automatic locking (default)
//==================================================================================
void sge_Lock_ON(void)
{
_sge_lock=1;
}
//==================================================================================
// Returns update&locking mode (1-on and 0-off)
//==================================================================================
Uint8 sge_getUpdate(void)
{
return _sge_update;
}
Uint8 sge_getLock(void)
{
return _sge_lock;
}
//==================================================================================
// SDL_UpdateRect does nothing if any part of the rectangle is outside the surface
// --- This version always work
//==================================================================================
void sge_UpdateRect(SDL_Surface *screen, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
{
if(_sge_update!=1 || screen != SDL_GetVideoSurface()){return;}
if(x>=screen->w || y>=screen->h){return;}
Sint16 a,b;
a=w; b=h;
if(x < 0){x=0;}
if(y < 0){y=0;}
if(a+x > screen->w){a=screen->w-x;}
if(b+y > screen->h){b=screen->h-y;}
SDL_UpdateRect(screen,x,y,a,b);
}
//==================================================================================
// Creates a 32bit (8/8/8/8) alpha surface
// Map colors with sge_MapAlpha() and then use the Uint32 color versions of
// SGEs routines
//==================================================================================
SDL_Surface *sge_CreateAlphaSurface(Uint32 flags, int width, int height)
{
return SDL_CreateRGBSurface(flags,width,height,32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
}
//==================================================================================
// Returns the Uint32 color value for a 32bit (8/8/8/8) alpha surface
//==================================================================================
Uint32 sge_MapAlpha(Uint8 R, Uint8 G, Uint8 B, Uint8 A)
{
Uint32 color=0;
color|=R<<24;
color|=G<<16;
color|=B<<8;
color|=A;
return color;
}
//==================================================================================
// Sets an SDL error string
// Accepts formated argument - like printf()
// SDL_SetError() also does this, but it does not use standard syntax (why?)
//==================================================================================
void sge_SetError(const char *format, ...)
{
char buf[256];
va_list ap;
#ifdef __WIN32__
va_start((va_list*)ap, format); //Stupid w32 crosscompiler
#else
va_start(ap, format);
#endif
vsprintf(buf, format, ap);
va_end(ap);
SDL_SetError(buf);
}
/**********************************************************************************/
/** Pixel functions **/
/**********************************************************************************/
//==================================================================================
// Fast put pixel
//==================================================================================
void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
*((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
*((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
/* Gack - slow, but endian correct */
*(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
*(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
*(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
*(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
}
break;
case 4: { /* Probably 32-bpp */
*((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
}
break;
}
}
}
//==================================================================================
// Fast put pixel (RGB)
//==================================================================================
void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
{
_PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B));
}
//==================================================================================
// Fastest put pixel functions (don't mess up indata, thank you)
//==================================================================================
void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
*((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
}
void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
*((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
}
void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
/* Gack - slow, but endian correct */
*(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
*(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
*(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
*(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
}
void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
*((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
}
void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
{
switch ( dest->format->BytesPerPixel ) {
case 1:
*((Uint8 *)dest->pixels + y*dest->pitch + x) = color;
break;
case 2:
*((Uint16 *)dest->pixels + y*dest->pitch/2 + x) = color;
break;
case 3:
_PutPixel24(dest,x,y,color);
break;
case 4:
*((Uint32 *)dest->pixels + y*dest->pitch/4 + x) = color;
break;
}
}
//==================================================================================
// Safe put pixel
//==================================================================================
void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
{
if ( SDL_MUSTLOCK(surface) && _sge_lock ) {
if ( SDL_LockSurface(surface) < 0 ) {
return;
}
}
_PutPixel(surface, x, y, color);
if ( SDL_MUSTLOCK(surface) && _sge_lock ) {
SDL_UnlockSurface(surface);
}
if(_sge_update!=1){return;}
sge_UpdateRect(surface, x, y, 1, 1);
}
//==================================================================================
// Safe put pixel (RGB)
//==================================================================================
void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B)
{
sge_PutPixel(surface,x,y, SDL_MapRGB(surface->format, R, G, B));
}
//==================================================================================
// Calculate y pitch offset
// (the y pitch offset is constant for the same y coord and surface)
//==================================================================================
Sint32 sge_CalcYPitch(SDL_Surface *dest,Sint16 y)
{
if(y>=sge_clip_ymin(dest) && y<=sge_clip_ymax(dest)){
switch ( dest->format->BytesPerPixel ) {
case 1:
return y*dest->pitch;
break;
case 2:
return y*dest->pitch/2;
break;
case 3:
return y*dest->pitch;
break;
case 4:
return y*dest->pitch/4;
break;
}
}
return -1;
}
//==================================================================================
// Put pixel with precalculated y pitch offset
//==================================================================================
void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
{
if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && ypitch>=0){
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
*((Uint8 *)surface->pixels + ypitch + x) = color;
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
*((Uint16 *)surface->pixels + ypitch + x) = color;
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
/* Gack - slow, but endian correct */
Uint8 *pix = (Uint8 *)surface->pixels + ypitch + x*3;
*(pix+surface->format->Rshift/8) = color>>surface->format->Rshift;
*(pix+surface->format->Gshift/8) = color>>surface->format->Gshift;
*(pix+surface->format->Bshift/8) = color>>surface->format->Bshift;
*(pix+surface->format->Ashift/8) = color>>surface->format->Ashift;
}
break;
case 4: { /* Probably 32-bpp */
*((Uint32 *)surface->pixels + ypitch + x) = color;
}
break;
}
}
}
//==================================================================================
// Get pixel
//==================================================================================
Uint32 sge_GetPixel(SDL_Surface *surface, Sint16 x, Sint16 y)
{
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
return *((Uint8 *)surface->pixels + y*surface->pitch + x);
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
return *((Uint16 *)surface->pixels + y*surface->pitch/2 + x);
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
Uint8 *pix;
int shift;
Uint32 color=0;
pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
shift = surface->format->Rshift;
color = *(pix+shift/8)<<shift;
shift = surface->format->Gshift;
color|= *(pix+shift/8)<<shift;
shift = surface->format->Bshift;
color|= *(pix+shift/8)<<shift;
shift = surface->format->Ashift;
color|= *(pix+shift/8)<<shift;
return color;
}
break;
case 4: { /* Probably 32-bpp */
return *((Uint32 *)surface->pixels + y*surface->pitch/4 + x);
}
break;
}
return 0;
}
//==================================================================================
// Put pixel with alpha blending
//==================================================================================
void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
{
if(x>=sge_clip_xmin(surface) && x<=sge_clip_xmax(surface) && y>=sge_clip_ymin(surface) && y<=sge_clip_ymax(surface)){
Uint32 Rmask = surface->format->Rmask, Gmask = surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
Uint32 R,G,B,A=0;
switch (surface->format->BytesPerPixel) {
case 1: { /* Assuming 8-bpp */
if( alpha == 255 ){
*((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
}else{
Uint8 *pixel = (Uint8 *)surface->pixels + y*surface->pitch + x;
Uint8 dR = surface->format->palette->colors[*pixel].r;
Uint8 dG = surface->format->palette->colors[*pixel].g;
Uint8 dB = surface->format->palette->colors[*pixel].b;
Uint8 sR = surface->format->palette->colors[color].r;
Uint8 sG = surface->format->palette->colors[color].g;
Uint8 sB = surface->format->palette->colors[color].b;
dR = dR + ((sR-dR)*alpha >> 8);
dG = dG + ((sG-dG)*alpha >> 8);
dB = dB + ((sB-dB)*alpha >> 8);
*pixel = SDL_MapRGB(surface->format, dR, dG, dB);
}
}
break;
case 2: { /* Probably 15-bpp or 16-bpp */
if( alpha == 255 ){
*((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
}else{
Uint16 *pixel = (Uint16 *)surface->pixels + y*surface->pitch/2 + x;
Uint32 dc = *pixel;
R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
if( Amask )
A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
*pixel= R | G | B | A;
}
}
break;
case 3: { /* Slow 24-bpp mode, usually not used */
Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
Uint8 rshift8=surface->format->Rshift/8;
Uint8 gshift8=surface->format->Gshift/8;
Uint8 bshift8=surface->format->Bshift/8;
Uint8 ashift8=surface->format->Ashift/8;
if( alpha == 255 ){
*(pix+rshift8) = color>>surface->format->Rshift;
*(pix+gshift8) = color>>surface->format->Gshift;
*(pix+bshift8) = color>>surface->format->Bshift;
*(pix+ashift8) = color>>surface->format->Ashift;
}else{
Uint8 dR, dG, dB, dA=0;
Uint8 sR, sG, sB, sA=0;
pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
dR = *((pix)+rshift8);
dG = *((pix)+gshift8);
dB = *((pix)+bshift8);
dA = *((pix)+ashift8);
sR = (color>>surface->format->Rshift)&0xff;
sG = (color>>surface->format->Gshift)&0xff;
sB = (color>>surface->format->Bshift)&0xff;
sA = (color>>surface->format->Ashift)&0xff;
dR = dR + ((sR-dR)*alpha >> 8);
dG = dG + ((sG-dG)*alpha >> 8);
dB = dB + ((sB-dB)*alpha >> 8);
dA = dA + ((sA-dA)*alpha >> 8);
*((pix)+rshift8) = dR;
*((pix)+gshift8) = dG;
*((pix)+bshift8) = dB;
*((pix)+ashift8) = dA;
}
}
break;
case 4: { /* Probably 32-bpp */
if( alpha == 255 ){
*((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
}else{
Uint32 *pixel = (Uint32 *)surface->pixels + y*surface->pitch/4 + x;
Uint32 dc = *pixel;
R = ((dc & Rmask) + (( (color & Rmask) - (dc & Rmask) ) * alpha >> 8)) & Rmask;
G = ((dc & Gmask) + (( (color & Gmask) - (dc & Gmask) ) * alpha >> 8)) & Gmask;
B = ((dc & Bmask) + (( (color & Bmask) - (dc & Bmask) ) * alpha >> 8)) & Bmask;
if( Amask )
A = ((dc & Amask) + (( (color & Amask) - (dc & Amask) ) * alpha >> 8)) & Amask;
*pixel = R | G | B | A;
}
}
break;
}
}
}
void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
{
if ( SDL_MUSTLOCK(surface) && _sge_lock )
if ( SDL_LockSurface(surface) < 0 )
return;
_PutPixelAlpha(surface,x,y,color,alpha);
/* unlock the display */
if (SDL_MUSTLOCK(surface) && _sge_lock) {
SDL_UnlockSurface(surface);
}
if(_sge_update!=1){return;}
sge_UpdateRect(surface, x, y, 1, 1);
}
void _PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
_PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B),alpha);
}
void sge_PutPixelAlpha(SDL_Surface *surface, Sint16 x, Sint16 y, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha)
{
sge_PutPixelAlpha(surface,x,y, SDL_MapRGB(surface->format, R, G, B), alpha);
}
/**********************************************************************************/
/** Block functions **/
/**********************************************************************************/
//==================================================================================
// The sge_write_block* functions copies the given block (a surface line) directly
// to the surface. This is *much* faster then using the put pixel functions to
// update a line. The block consist of Surface->w (the width of the surface) numbers
// of color values. Note the difference in byte size for the block elements for
// different color dephts. 24 bpp is slow and not included!
//==================================================================================
void sge_write_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
{
memcpy( (Uint8 *)Surface->pixels + y*Surface->pitch, block, sizeof(Uint8)*Surface->w );
}
void sge_write_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
{
memcpy( (Uint16 *)Surface->pixels + y*Surface->pitch/2, block, sizeof(Uint16)*Surface->w );
}
void sge_write_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
{
memcpy( (Uint32 *)Surface->pixels + y*Surface->pitch/4, block, sizeof(Uint32)*Surface->w );
}
//==================================================================================
// ...and get
//==================================================================================
void sge_read_block8(SDL_Surface *Surface, Uint8 *block, Sint16 y)
{
memcpy( block,(Uint8 *)Surface->pixels + y*Surface->pitch, sizeof(Uint8)*Surface->w );
}
void sge_read_block16(SDL_Surface *Surface, Uint16 *block, Sint16 y)
{
memcpy( block,(Uint16 *)Surface->pixels + y*Surface->pitch/2, sizeof(Uint16)*Surface->w );
}
void sge_read_block32(SDL_Surface *Surface, Uint32 *block, Sint16 y)
{
memcpy( block,(Uint32 *)Surface->pixels + y*Surface->pitch/4, sizeof(Uint32)*Surface->w );
}
/**********************************************************************************/
/** Blitting/surface functions **/
/**********************************************************************************/
//==================================================================================
// Clear surface to color
//==================================================================================
void sge_ClearSurface(SDL_Surface *Surface, Uint32 color)
{
SDL_FillRect(Surface,NULL, color);
if(_sge_update!=1){return;}
SDL_UpdateRect(Surface, 0,0,0,0);
}
//==================================================================================
// Clear surface to color (RGB)
//==================================================================================
void sge_ClearSurface(SDL_Surface *Surface, Uint8 R, Uint8 G, Uint8 B)
{
sge_ClearSurface(Surface,SDL_MapRGB(Surface->format, R, G, B));
}
//==================================================================================
// Blit from one surface to another
// Warning! Alpha and color key is lost (=0) on Src surface
//==================================================================================
int sge_BlitTransparent(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H, Uint32 Clear, Uint8 Alpha)
{
SDL_Rect src, dest;
int ret;
/* Dest clipping */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
int flag=0;
if (DestX < Dest->clip_minx){
SrcX += Dest->clip_minx-DestX;
W -= Dest->clip_minx-DestX-1;
DestX=Dest->clip_minx;
}
if (DestY < Dest->clip_miny){
SrcY +=Dest->clip_miny-DestY;
H -= Dest->clip_miny-DestY-1;
DestY=Dest->clip_miny;
}
if ((DestX + W) > Dest->clip_maxx){
W = W - ((DestX + W) - Dest->clip_maxx)+1;
if(W<=0){SDL_SetError("SGE - Blit error");return -1;}
}
if ((DestY + H) > Dest->clip_maxy){
H = H - ((DestY + H) - Dest->clip_maxy)+1;
if(H<=0){SDL_SetError("SGE - Blit error");return -1;}
}
#endif
/* Initialize our rectangles */
src.x = SrcX;
src.y = SrcY;
src.w = W;
src.h = H;
dest.x = DestX;
dest.y = DestY;
dest.w = W;
dest.h = H;
/* We don't care about src clipping, only dest! */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){
Src->flags &= ~SDL_SRCCLIPPING; flag=1;
}
#endif
/* Set the color to be transparent */
SDL_SetColorKey(Src, SDL_SRCCOLORKEY, Clear);
/* Set the alpha value */
SDL_SetAlpha(Src, SDL_SRCALPHA, Alpha);
/* Blit */
ret=SDL_BlitSurface(Src, &src, Dest, &dest);
/* Set the correct flag */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if (flag==1){
Src->flags |= SDL_SRCCLIPPING;
}
#endif
/* Set normal levels */
SDL_SetAlpha(Src,0,0);
SDL_SetColorKey(Src,0,0);
return ret;
}
//==================================================================================
// Blit from one surface to another (not touching alpha or color key -
// use SDL_SetColorKey and SDL_SetAlpha)
//==================================================================================
int sge_Blit(SDL_Surface *Src, SDL_Surface *Dest, Sint16 SrcX, Sint16 SrcY, Sint16 DestX, Sint16 DestY, Sint16 W, Sint16 H)
{
SDL_Rect src, dest;
int ret;
/* Dest clipping */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
int flag=0;
if (DestX < Dest->clip_minx){
SrcX += Dest->clip_minx-DestX;
W -= Dest->clip_minx-DestX -1;
DestX=Dest->clip_minx;
}
if (DestY < Dest->clip_miny){
SrcY +=Dest->clip_miny-DestY;
H -= Dest->clip_miny-DestY -1;
DestY=Dest->clip_miny;
}
if ((DestX + W) > Dest->clip_maxx){
W = W - ((DestX + W) - Dest->clip_maxx)+1;
if(W<=0){SDL_SetError("SGE - Blit error");return -1;}
}
if ((DestY + H) > Dest->clip_maxy){
H = H - ((DestY + H) - Dest->clip_maxy)+1;
if(H<=0){SDL_SetError("SGE - Blit error");return -1;}
}
#endif
/* Initialize our rectangles */
src.x = SrcX;
src.y = SrcY;
src.w = W;
src.h = H;
dest.x = DestX;
dest.y = DestY;
dest.w = W;
dest.h = H;
/* We don't care about src clipping, only dest! */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if ( (Src->flags & SDL_SRCCLIPPING) == SDL_SRCCLIPPING){
Src->flags &= ~SDL_SRCCLIPPING; flag=1;
}
#endif
/* Blit */
ret=SDL_BlitSurface(Src, &src, Dest, &dest);
/* Set the correct flag */
#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) < \
SDL_VERSIONNUM(1, 1, 5)
if (flag==1){
Src->flags |= SDL_SRCCLIPPING;
}
#endif
return ret;
}
//==================================================================================
// Copies a surface to a new...
//==================================================================================
SDL_Surface *sge_copy_surface(SDL_Surface *src)
{
return SDL_ConvertSurface(src, src->format,SDL_SWSURFACE);
}
SDL_Surface *sge_copy_surface(SDL_Surface *a_poSource, Sint16 x, Sint16 y, Sint16 w, Sint16 h)
{
SDL_Surface* poDest;
poDest = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, a_poSource->format->BitsPerPixel,
a_poSource->format->Rmask, a_poSource->format->Gmask, a_poSource->format->Bmask, a_poSource->format->Amask );
if ( a_poSource->format->BitsPerPixel <= 8 )
{
SDL_SetColors( poDest, a_poSource->format->palette->colors, 0, a_poSource->format->palette->ncolors );
}
sge_Blit( a_poSource, poDest, x, y, 0, 0, w, h );
return poDest;
}
/**********************************************************************************/
/** Palette functions **/
/**********************************************************************************/
//==================================================================================
// Fill in a palette entry with R, G, B componenets
//==================================================================================
SDL_Color sge_FillPaletteEntry(Uint8 R, Uint8 G, Uint8 B)
{
SDL_Color color;
color.r = R;
color.g = G;
color.b = B;
return color;
}
//==================================================================================
// Get the RGB of a color value
// Needed in those dark days before SDL 1.0
//==================================================================================
SDL_Color sge_GetRGB(SDL_Surface *Surface, Uint32 Color)
{
SDL_Color rgb;
SDL_GetRGB(Color, Surface->format, &(rgb.r), &(rgb.g), &(rgb.b));
return(rgb);
}
//==================================================================================
// Fades from (sR,sG,sB) to (dR,dG,dB), puts result in ctab[start] to ctab[stop]
//==================================================================================
void sge_Fader(SDL_Surface *Surface, Uint8 sR,Uint8 sG,Uint8 sB, Uint8 dR,Uint8 dG,Uint8 dB,Uint32 *ctab,int start, int stop)
{
// (sR,sG,sB) and (dR,dG,dB) are two points in space (the RGB cube).
/* The vector for the straight line */
int v[3];
v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB;
/* Ref. point */
int x0=sR, y0=sG, z0=sB;
// The line's equation is:
// x= x0 + v[0] * t
// y= y0 + v[1] * t
// z= z0 + v[2] * t
//
// (x,y,z) will travel between the two points when t goes from 0 to 1.
int i=start;
double step=1.0/((stop+1)-start);
for(double t=0.0; t<=1.0 && i<=stop ; t+=step){
ctab[i++]=SDL_MapRGB(Surface->format, (Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t) );
}
}
//==================================================================================
// Fades from (sR,sG,sB,sA) to (dR,dG,dB,dA), puts result in ctab[start] to ctab[stop]
//==================================================================================
void sge_AlphaFader(Uint8 sR,Uint8 sG,Uint8 sB,Uint8 sA, Uint8 dR,Uint8 dG,Uint8 dB,Uint8 dA, Uint32 *ctab,int start, int stop)
{
// (sR,sG,sB,sA) and (dR,dG,dB,dA) are two points in hyperspace (the RGBA hypercube).
/* The vector for the straight line */
int v[4];
v[0]=dR-sR; v[1]=dG-sG; v[2]=dB-sB; v[3]=dA-sA;
/* Ref. point */
int x0=sR, y0=sG, z0=sB, w0=sA;
// The line's equation is:
// x= x0 + v[0] * t
// y= y0 + v[1] * t
// z= z0 + v[2] * t
// w= w0 + v[3] * t
//
// (x,y,z,w) will travel between the two points when t goes from 0 to 1.
int i=start;
double step=1.0/((stop+1)-start);
for(double t=0.0; t<=1.0 && i<=stop ; t+=step)
ctab[i++]=sge_MapAlpha((Uint8)(x0+v[0]*t), (Uint8)(y0+v[1]*t), (Uint8)(z0+v[2]*t), (Uint8)(w0+v[3]*t));
}
//==================================================================================
// Copies a nice rainbow palette to the color table (ctab[start] to ctab[stop]).
// You must also set the intensity of the palette (0-bright 255-dark)
//==================================================================================
void sge_SetupRainbowPalette(SDL_Surface *Surface,Uint32 *ctab,int intensity, int start, int stop)
{
int slice=(int)((stop-start)/6);
/* Red-Yellow */
sge_Fader(Surface, 255,intensity,intensity, 255,255,intensity, ctab, start,slice);
/* Yellow-Green */
sge_Fader(Surface, 255,255,intensity, intensity,255,intensity, ctab, slice+1, 2*slice);
/* Green-Turquoise blue */
sge_Fader(Surface, intensity,255,intensity, intensity,255,255, ctab, 2*slice+1, 3*slice);
/* Turquoise blue-Blue */
sge_Fader(Surface, intensity,255,255, intensity,intensity,255, ctab, 3*slice+1, 4*slice);
/* Blue-Purple */
sge_Fader(Surface, intensity,intensity,255, 255,intensity,255, ctab, 4*slice+1, 5*slice);
/* Purple-Red */
sge_Fader(Surface, 255,intensity,255, 255,intensity,intensity, ctab, 5*slice+1, stop);
}
//==================================================================================
// Copies a B&W palette to the color table (ctab[start] to ctab[stop]).
//==================================================================================
void sge_SetupBWPalette(SDL_Surface *Surface,Uint32 *ctab,int start, int stop)
{
sge_Fader(Surface, 0,0,0, 255,255,255, ctab,start,stop);
}

File Metadata

Mime Type
text/x-c
Expires
Sun, Nov 15, 7:28 AM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
128424
Default Alt Text
sge_surface.cpp (28 KB)

Event Timeline