SDLGameEngine

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# src/sgegfx.c

    00001 /*
    00002  * Copyright (c) 2007 Heiko Irrgang
    00003  *
    00004  * The license and distribution terms for this file may be
    00005  * found in the file COPYING in this distribution or at
    00006  * http://93-interactive.com/cms/products/software/sdl-game-engine/license/
    00007  */
    00008
    00009 #include <sge.h>
    00010
    00011 SGEPOSITION *sgePositionNew(int x, int y) {
    00012         SGEPOSITION *ret;
    00013
    00014         sgeNew(ret, SGEPOSITION);
    00015         ret->x=x;
    00016         ret->y=y;
    00017         return ret;
    00018 }
    00019
    00020 void sgePositionDestroy(SGEPOSITION *p) {
    00021         sgeFree(p);
    00022 }
    00023
    00024 SGEPIXELINFO *sgePixelInfoNew(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
    00025         SGEPIXELINFO *ret;
    00026
    00027         sgeNew(ret, SGEPIXELINFO);
    00028         ret->r=r;
    00029         ret->g=g;
    00030         ret->b=b;
    00031         ret->a=a;
    00032
    00033         return ret;
    00034 }
    00035
    00036 void sgePixelInfoDestroy(SGEPIXELINFO *i) {
    00037         sgeFree(i);
    00038 }
    00039
    00040 inline Uint32 sgeMakeColor(SDL_Surface *surface, int r, int g, int b, int a) {
    00041         Uint32 color;
    00042         if (a<0) {
    00043                 color=SDL_MapRGB(surface->format,r,g,b);
    00044         } else {
    00045                 color=SDL_MapRGBA(surface->format,r,g,b,a);
    00046         }
    00047         return color;
    00048 }
    00049
    00050 inline void sgeFillRect(SDL_Surface *dest, int x, int y, int w, int h, Uint32 color) {
    00051         SDL_Rect rect;
    00052         rect.x=x;
    00053         rect.y=y;
    00054         rect.w=w;
    00055         rect.h=h;
    00056         SDL_FillRect(dest, &rect, color);
    00057 }
    00058
    00059 inline void sgeDrawRect(SDL_Surface *dest, int x, int y, int w, int h, int linewidth, Uint32 color) {
    00060         sgeFillRect(dest, x, y, w, linewidth, color);
    00061         sgeFillRect(dest, x, y, linewidth, h, color);
    00062         sgeFillRect(dest, x+w-linewidth, y, linewidth, h, color);
    00063         sgeFillRect(dest, x, y+h-linewidth, w, linewidth, color);
    00064 }
    00065
    00066 inline void sgeDrawPixel(SDL_Surface *dest, int x, int y, Uint32 color) {
    00067         Uint8 *buf8=NULL;
    00068         Uint16 *buf16=NULL;
    00069         Uint32 *buf32=NULL;
    00070
    00071         if (x<0 || y<0) return;
    00072         if (x>=dest->w || y>=dest->h) return;
    00073
    00074         switch (dest->format->BitsPerPixel) {
    00075                 case 8:
    00076                         buf8=(Uint8 *)dest->pixels+y*dest->w+x;
    00077                         *buf8=(Uint8)color;
    00078                         break;
    00079                 case 16:
    00080                         buf16=(Uint16 *)dest->pixels+y*dest->w+x;
    00081                         *buf16=(Uint16)color;
    00082                         break;
    00083                 default:
    00084                         buf32=(Uint32 *)dest->pixels+y*dest->w+x;
    00085                         *buf32=color;
    00086                         break;
    00087         }
    00088 }
    00089
    00090 inline SGEPIXELINFO *sgeGetPixel(SDL_Surface *dest, int x, int y) {
    00091         Uint8 p8, *buf8;
    00092         Uint16 p16, *buf16;
    00093         Uint32 p32, *buf32;
    00094         SGEPIXELINFO *ret;
    00095
    00096         switch (dest->format->BitsPerPixel) {
    00097                 case 8:
    00098                         buf8=(Uint8 *)dest->pixels;
    00099                         p8=buf8[y*dest->w+x];
    00100                         p32=p8;
    00101                         break;
    00102                 case 16:
    00103                         buf16=(Uint16 *)dest->pixels;
    00104                         p16=buf16[y*dest->w+x];
    00105                         p32=p16;
    00106                         break;
    00107                 default:
    00108                         buf32=(Uint32 *)dest->pixels;
    00109                         p32=buf32[y*dest->w+x];
    00110                         break;
    00111         }
    00112         sgeNew(ret, SGEPIXELINFO);
    00113         SDL_GetRGBA(p32, dest->format, &ret->r, &ret->g, &ret->b, &ret->a);
    00114         return ret;
    00115 }
    00116
    00117 inline void sgeDrawLine(SDL_Surface *dest, int x, int y, int x2, int y2, Uint32 color) {
    00118         int steep=0;
    00119         int tmp=0;
    00120         int dx=0;
    00121         int dy=0;
    00122         int err=0;
    00123         int ystep=1;
    00124         int yy=0;
    00125         int xx=0;
    00126
    00127         if (abs(y2-y)>abs(x2-x)) steep=1;
    00128         if (steep) {
    00129                 tmp=x;
    00130                 x=y;
    00131                 y=tmp;
    00132                 tmp=x2;
    00133                 x2=y2;
    00134                 y2=tmp;
    00135         }
    00136         if (x>x2) {
    00137                 tmp=x;
    00138                 x=x2;
    00139                 x2=tmp;
    00140                 tmp=y;
    00141                 y=y2;
    00142                 y2=tmp;
    00143         }
    00144
    00145         if (y>y2) {
    00146                 ystep=-1;
    00147         }
    00148
    00149         dx=x2-x;
    00150         dy=abs(y2-y);
    00151         err=-dx>>1;
    00152         yy=y;
    00153
    00154         for (xx=x;xx<=x2;xx++) {
    00155                 if (!steep) {
    00156                         sgeDrawPixel(dest, xx, yy, color);
    00157                 } else {
    00158                         sgeDrawPixel(dest, yy, xx, color);
    00159                 }
    00160                 err+=dy;
    00161                 if (err>0) {
    00162                         yy+=ystep;
    00163                         err-=dx;
    00164                 }
    00165         }
    00166 }
    00167
    00168 inline void sgeDrawImage(SDL_Surface *dest, SDL_Surface *image, int x, int y) {
    00169         SDL_Rect r;
    00170         r.w=image->w;
    00171         r.h=image->h;
    00172         r.x=x;
    00173         r.y=y;
    00174         SDL_BlitSurface(image, NULL, dest, &r);
    00175 }
    00176
    00177 void sgeIgnoreAlpha(SDL_Surface *s) {
    00178         SDL_SetAlpha(s, s->flags^SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
    00179 }
    00180
    00181 void sgeUseAlpha(SDL_Surface *s) {
    00182         SDL_SetAlpha(s, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
    00183 }
    00184
    00185 SDL_Surface *sgeRotoZoom(SDL_Surface *source, float rotation, float zoom) {
    00186         Uint32 *src32=(Uint32*)source->pixels;
    00187         Uint16 *src16=(Uint16*)source->pixels;
    00188         Uint8 *src8=(Uint8*)source->pixels;
    00189         SDL_Surface *ret;
    00190         SDL_Surface *target=SDL_CreateRGBSurface(
    00191                         source->flags,
    00192                         (int)((float)source->w*zoom)*3,
    00193                         (int)((float)source->h*zoom)<<1,
    00194                         source->format->BitsPerPixel,
    00195                         source->format->Rmask,
    00196                         source->format->Gmask,
    00197                         source->format->Bmask,
    00198                         source->format->Amask
    00199         );
    00200         SDL_Rect r;
    00201         Uint32 *dst32=(Uint32*)target->pixels;
    00202         Uint16 *dst16=(Uint16*)target->pixels;
    00203         Uint8 *dst8=(Uint8*)target->pixels;
    00204
    00205         int sinfp=(int)((sin(rotation)*65536.0)/zoom);
    00206         int cosfp=(int)((cos(rotation)*65536.0)/zoom);
    00207
    00208         int xc;
    00209         int yc;
    00210
    00211         int tx,ty;
    00212         int x,y;
    00213         int tempx,tempy;
    00214
    00215         int targetpitch;
    00216         int sourcepitch;
    00217         int divider;
    00218
    00219         int minx=target->w;
    00220         int miny=target->h;
    00221         int maxx=0;
    00222         int maxy=0;
    00223
    00224         switch (source->format->BitsPerPixel) {
    00225                 case 8:
    00226                         divider=0;
    00227                         break;
    00228                 case 16:
    00229                         divider=1;
    00230                         break;
    00231                 default:
    00232                         divider=2;
    00233                         break;
    00234         }
    00235
    00236         targetpitch=target->pitch>>divider;
    00237         sourcepitch=source->pitch>>divider;
    00238         xc=(source->w<<15) - ((target->w>>1)*(cosfp+sinfp));
    00239         yc=(source->h<<15) - ((target->h>>1)*(cosfp-sinfp));
    00240
    00241         sgeLock(target);
    00242         for ( y=0; y<target->h; y++ ) {
    00243
    00244                 tx=xc;
    00245                 ty=yc;
    00246
    00247                 for( x=0; x<target->w; x++ ) {
    00248
    00249
    00250                         tempx=(tx>>16);
    00251                         tempy=(ty>>16);
    00252
    00253                         if( (tempx>=0) && (tempx<source->w) && (tempy>=0) && (tempy<source->h) ) {
    00254                                 if (x>maxx) {
    00255                                         maxx=x;
    00256                                 }
    00257                                 if (y>maxy) {
    00258                                         maxy=y;
    00259                                 }
    00260                                 if (x<minx) {
    00261                                         minx=x;
    00262                                 }
    00263                                 if (y<miny) {
    00264                                         miny=y;
    00265                                 }
    00266                                 switch (source->format->BitsPerPixel) {
    00267                                         case 8:
    00268                                                 *(dst8+x+y*targetpitch) = *(src8+tempx+tempy*sourcepitch);
    00269                                                 break;
    00270                                         case 16:
    00271                                                 *(dst16+x+y*targetpitch) = *(src16+tempx+tempy*sourcepitch);
    00272                                                 break;
    00273                                         default:
    00274                                                 *(dst32+x+y*targetpitch) = *(src32+tempx+tempy*sourcepitch);
    00275                                                 break;
    00276                                 }
    00277                         }
    00278
    00279                         tx+=cosfp;
    00280                         ty-=sinfp;
    00281                 }
    00282                 xc+=sinfp;
    00283                 yc+=cosfp;
    00284         }
    00285         sgeUnlock(target);
    00286
    00287         r.x=minx;
    00288         r.y=miny;
    00289         r.w=maxx-minx;
    00290         r.h=maxy-miny;
    00291
    00292         ret=SDL_CreateRGBSurface(
    00293                         source->flags,
    00294                         r.w,
    00295                         r.h,
    00296                         source->format->BitsPerPixel,
    00297                         source->format->Rmask,
    00298                         source->format->Gmask,
    00299                         source->format->Bmask,
    00300                         source->format->Amask
    00301         );
    00302
    00303         SDL_SetAlpha(target, 0, 0);
    00304
    00305         SDL_BlitSurface(target, &r, ret, NULL);
    00306         SDL_FreeSurface(target);
    00307
    00308         return ret;
    00309 }
    00310
    00311 SDL_Surface *sgeChangeSDLSurfaceAlpha(SDL_Surface *s, Uint8 alpha) {
    00312         int x,y;
    00313         SDL_Surface *ret=sgeDuplicateSDLSurface(s);
    00314         SGEPIXELINFO *pi;
    00315
    00316         sgeLock(ret);
    00317         for (y=0;y<ret->h;y++) {
    00318                 for (x=0;x<ret->w;x++) {
    00319                         pi=sgeGetPixel(ret,x,y);
    00320                         pi->a=pi->a*alpha/256;
    00321                         sgeDrawPixel(ret,x,y,sgeMakeColor(ret,pi->r,pi->g,pi->b,pi->a));
    00322                         sgePixelInfoDestroy(pi);
    00323                 }
    00324         }
    00325         sgeUnlock(ret);
    00326         return ret;
    00327 }
    00328
    00329 SDL_Surface *sgeCreateSDLSurface(int width, int height, int depth, Uint32 sdlflags) {
    00330         SDL_Surface *ret;
    00331         Uint32 rmask,gmask,bmask,amask;
    00332
    00333 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
    00334         rmask = 0xff000000;
    00335         gmask = 0x00ff0000;
    00336         bmask = 0x0000ff00;
    00337         amask = 0x000000ff;
    00338 #else
    00339         rmask = 0x000000ff;
    00340         gmask = 0x0000ff00;
    00341         bmask = 0x00ff0000;
    00342         amask = 0xff000000;
    00343 #endif
    00344
    00345         if (sdlflags==0) {
    00346                 sdlflags=SDL_SWSURFACE;
    00347         }
    00348
    00349         ret=SDL_CreateRGBSurface(sdlflags, width, height, depth, rmask, gmask, bmask, amask);
    00350         if (ret==NULL) {
    00351                 sgeBailOut("cannot create new surface: %s\n", SDL_GetError ());
    00352         }
    00353         return ret;
    00354 }
    00355
    00356 SDL_Surface *sgeCreateVideoSurface(int width, int height, int depth, Uint32 sdlflags) {
    00357         SDL_Surface *s=sgeCreateSDLSurface(width, height, depth, sdlflags);
    00358         SDL_Surface *ret;
    00359
    00360         ret=SDL_DisplayFormatAlpha(s);
    00361         if (ret!=NULL) {
    00362                 SDL_FreeSurface(s);
    00363                 return ret;
    00364         }
    00365
    00366         return s;
    00367 }
    00368
    00369 SDL_Surface *sgeConvertToGrey(SDL_Surface *src) {
    00370         SGEPIXELINFO *info;
    00371         SDL_Surface *ret=sgeDuplicateSDLSurface(src);
    00372         int x,y;
    00373         int grey;
    00374
    00375         sgeLock(ret);
    00376         for (y=0;y<src->h;y++) {
    00377                 for (x=0;x<src->w;x++) {
    00378                         info=sgeGetPixel(src, x, y);
    00379                         grey=(int)(0.3*(float)info->r+0.59*(float)info->g+0.11*(float)info->b);
    00380                         sgeDrawPixel(ret, x, y, sgeMakeColor(ret, grey, grey, grey, info->a));
    00381                         sgeFree(info);
    00382                 }
    00383         }
    00384         sgeUnlock(ret);
    00385         return ret;
    00386 }

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines