summaryrefslogtreecommitdiff
path: root/src/graphic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphic.c')
-rw-r--r--src/graphic.c129
1 files changed, 71 insertions, 58 deletions
diff --git a/src/graphic.c b/src/graphic.c
index 35d69c6..edbb799 100644
--- a/src/graphic.c
+++ b/src/graphic.c
@@ -9,14 +9,37 @@
#define SDLSURF_OPTS SDL_HWSURFACE|SDL_HWACCEL|/*SDL_ASYNCBLIT|*/SDL_RLEACCEL
Uint32 getPixel(SDL_Surface *s, int x, int y) {
- Uint32 res=0;
+ Uint32 res=0;
//FIXME : Big Endian
res |= ((Uint8 *)s->pixels)[y*s->pitch + x*s->format->BytesPerPixel+0] << 0;
res |= ((Uint8 *)s->pixels)[y*s->pitch + x*s->format->BytesPerPixel+1] << 8;
res |= ((Uint8 *)s->pixels)[y*s->pitch + x*s->format->BytesPerPixel+2] << 16;
+
+ return res;
+}
+
+Uint32 getPixel8BitPalette(SDL_Surface *s, int x, int y) {
+ Uint8 index;
+ SDL_Color c;
+ Uint32 res=0;
+
+ index=((Uint8 *)s->pixels)[y*s->pitch + x];
+ c=s->format->palette->colors[index];
+
+ //FIXME : Big Endian
+ res |= c.r << 0;
+ res |= c.g << 8;
+ res |= c.b << 16;
return res;
}
+int isTransparent(SDL_Surface *s, int x, int y) {
+ Uint8 index;
+
+ index=((Uint8 *)s->pixels)[y*s->pitch + x];
+ return (index == s->format->colorkey);
+}
+
void putPixel(SDL_Surface *s, int x, int y, Uint32 p) {
//printf("putPixel(s, %i, %i, 0x%x)\n", x, y, p);
//FIXME : Big Endian
@@ -46,51 +69,36 @@ SDL_Surface * createSurface(int width, int height) {
}
-SDL_Surface * loadGifIn24Bpp(char *filePath) {
- int res;
- SDL_Surface *s1, *s2;
- SDL_Rect dstRect = {0,0,0,0};
-
- s1=IMG_Load(filePath);
- if (s1==NULL) { return NULL; }
-
- s2=createSurface(s1->w, s1->h);
- if (s2==NULL) { return NULL; }
- SDL_SetColorKey(s2, SDL_SRCCOLORKEY, s1->format->colorkey);
-
- res=SDL_BlitSurface(s1, NULL, s2, &dstRect);
- if (res!=0) return NULL;
-
- return s2;
+SDL_Surface * loadGif(char *filePath) {
+ return IMG_Load(filePath);
}
-int makeTerrain(gameIni_t *gIni, gameRess_t *gRess, SDL_Surface **terrain, SDL_Surface **stencil) {
+int paintTerrain(gameIni_t *gIni, gameRess_t *gRess, SDL_Surface **terrain, SDL_Surface **stencil) {
int res, i;
- int x,y,xmin,xmax,ymin,ymax,y2,xdst, ydst;
+ int x,y,xmin,xmax,ymin,ymax,y2,xdst, ydst, paint;
Uint32 srcPixel, dstPixel, srcStencil, dstStencil;
SDL_Surface *tile;
- //SDL_Rect dstRect;
*terrain=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
if (*terrain==NULL) {
- logs(LOG_ERROR, "makeTerrain(), SDL_CreateRGBSurface() returns NULL");
+ logs(LOG_ERROR, "paintTerrain(), SDL_CreateRGBSurface() returns NULL");
return 1;
}
*stencil=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
if (*stencil==NULL) {
- logs(LOG_ERROR, "makeTerrain(), SDL_CreateRGBSurface() returns NULL");
+ logs(LOG_ERROR, "paintTerrain(), SDL_CreateRGBSurface() returns NULL");
return 2;
}
res=SDL_FillRect(*terrain, &((*terrain)->clip_rect), gIni->style.bgColor);
if (res!=0) {
- logs(LOG_WARN, "makeTerrain(), SDL_FillRect() failed");
+ logs(LOG_WARN, "paintTerrain(), SDL_FillRect() failed");
return 3;
}
res=SDL_FillRect(*stencil, &((*stencil)->clip_rect), ccc_nothing);
if (res!=0) {
- logs(LOG_WARN, "makeTerrain(), SDL_FillRect() failed");
+ logs(LOG_WARN, "paintTerrain(), SDL_FillRect() failed");
return 4;
}
@@ -100,27 +108,36 @@ int makeTerrain(gameIni_t *gIni, gameRess_t *gRess, SDL_Surface **terrain, SDL_S
//FIXME : check sanity for id value
tile=gRess->style.tiles[gIni->level.terrains[i].id];
if (tile==NULL) {
- logs(LOG_ERROR, "makeTerrain(), tile==NULL");
+ logs(LOG_ERROR, "paintTerrain(), tile==NULL");
return 5;
}
-// dstRect.y=gIni->level.terrains[i].ypos;
-// dstRect.x=gIni->level.terrains[i].xpos;
+
+ // Special modifier values :
+ // 15 : Hidden : Lemini hack. Seems to be the same as NO_OVERRIDE
+ // Combinable modifier :
// 8 : NO_OVERRIDE : marquer les pixels comme indestructibles pour les prochains plaquages
- // 2 : REMOVE : oublier (rendre transparent) tous les pixels qu'on a déjà plaqué
// 4 : Upside Down
- // 0 : Full : écrase tous les pixels (sauf ceux no_override)
+ // 2 : REMOVE : oublier (rendre transparent) tous les pixels qu'on a déjà plaqué
+
+ if (gIni->level.terrains[i].modifier == 15) {
+ gIni->level.terrains[i].modifier=8;
+ }
+ if ((gIni->level.terrains[i].modifier & 10) == 10) {
+ gIni->level.terrains[i].modifier &= ~2;
+ }
// For each tile pixel, without going outside of the terrain
- ymin=(gIni->level.terrains[i].ypos>0)?0:-gIni->level.terrains[i].ypos;
+ ymin=(gIni->level.terrains[i].ypos>=0)?0:-gIni->level.terrains[i].ypos;
ymax=min(tile->clip_rect.h, (*terrain)->clip_rect.h - gIni->level.terrains[i].ypos);
- xmin=(gIni->level.terrains[i].xpos>0)?0:-gIni->level.terrains[i].xpos;
+ xmin=(gIni->level.terrains[i].xpos>=0)?0:-gIni->level.terrains[i].xpos;
xmax=min(tile->clip_rect.w, (*terrain)->clip_rect.w - gIni->level.terrains[i].xpos);
+
SDL_LockSurface(tile);
for (y=ymin; y<ymax; y++) {
- for (x=0; x<xmax; x++) {
- // If we have Upside Down modifier, count lines in reverse order fot dest
+ for (x=xmin; x<xmax; x++) {
+ // If we have Upside Down modifier, count lines in reverse order
if ( (gIni->level.terrains[i].modifier & 4) == 4 ) {
y2=tile->clip_rect.h-1-y;
} else {
@@ -129,39 +146,35 @@ int makeTerrain(gameIni_t *gIni, gameRess_t *gRess, SDL_Surface **terrain, SDL_S
ydst=gIni->level.terrains[i].ypos+y;
xdst=gIni->level.terrains[i].xpos+x;
- // Grab current pixel and stencil state (from previous blits)
- srcPixel=getPixel(tile, x, y2);
- srcStencil=getPixel(*stencil, xdst, ydst);
-
- // Act only if srcPixel is not transparent and srcStentil doesn't says NO_OVERRIDE
- if ( (srcPixel != tile->format->colorkey) && ( srcStencil != ccc_nooverride) ) {
- // If we have REMOVE modifier, dstPixel will be rolled back to bgColor, else, it will be identical to the source pixel
- if ( (gIni->level.terrains[i].modifier & 2) == 2 ) {
- dstPixel=gIni->style.bgColor;
- } else {
- dstPixel=srcPixel;
- }
- putPixel(*terrain, xdst, ydst, dstPixel);
+ // Act only if srcPixel is not transparent
+ if ( ! isTransparent(tile, x, y2) ) {
+ // Grab current pixel and stencil state (from previous blits)
+ srcPixel=getPixel8BitPalette(tile, x, y2);
+ srcStencil=getPixel(*stencil, xdst, ydst);
- // If we have NO_OVERRIDE modifier, put that info on stencil, else, save that there is a (normal) terrain here
if ( (gIni->level.terrains[i].modifier & 8) == 8 ) {
- dstStencil=ccc_nooverride;
+ paint=( getPixel(*stencil, xdst, ydst) != ccc_terrain );
} else {
- dstStencil=ccc_terrain;
+ paint=1;
+ }
+
+ if ( paint == 1 ) {
+ // If we have REMOVE modifier, dstPixel will be rolled back to bgColor, else, it will be identical to the source pixel
+ if ( (gIni->level.terrains[i].modifier & 2) == 2 ) {
+ dstPixel=gIni->style.bgColor;
+ dstStencil=0;
+ } else {
+ dstPixel=srcPixel;
+ dstStencil=ccc_terrain;
+ }
+
+ putPixel(*terrain, xdst, ydst, dstPixel);
+ putPixel(*stencil, xdst, ydst, dstStencil);
}
- putPixel(*stencil, xdst, ydst, dstStencil);
}
-
}
}
SDL_UnlockSurface(tile);
-/*
- res=SDL_BlitSurface(tile, NULL, terrain, &dstRect);
- if (res!=0) {
- logs2(LOG_WARN, "makeTerrain(), SDL_BlitSurface()", SDL_GetError());
- return NULL;
- }
-*/
}
SDL_UnlockSurface(*stencil);
SDL_UnlockSurface(*terrain);