summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-26 00:12:44 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-26 00:12:44 +0000
commit97a0f629ae5072931f422574320d4d3680c0752e (patch)
treeabed773b2579654b73082d59c2790082b8b4df94
parentb9755814c7f60ec51a6d062610c26dbf4d3e3686 (diff)
download2010-netlemmings-97a0f629ae5072931f422574320d4d3680c0752e.tar.gz
2010-netlemmings-97a0f629ae5072931f422574320d4d3680c0752e.tar.bz2
2010-netlemmings-97a0f629ae5072931f422574320d4d3680c0752e.zip
Code de maleTerrain intégrant les modifiers presque fini d'être codé je pense. Suaf que j'ai la vague impression que le getPixel ne pas grand chose d'utile : le niveau sors tout marron.
git-svn-id: file:///var/svn/2010-netlemmings/trunk@175 077b3477-7977-48bd-8428-443f22f7bfda
-rw-r--r--src/graphic.c91
-rw-r--r--src/include/utils.h3
-rw-r--r--src/utils.c2
3 files changed, 92 insertions, 4 deletions
diff --git a/src/graphic.c b/src/graphic.c
index 10ee0c6..d68c289 100644
--- a/src/graphic.c
+++ b/src/graphic.c
@@ -3,8 +3,27 @@
#include "graphic.h"
#include "utils.h"
+#define ccc_nooverride 0x00cc0000
+#define ccc_terrain 0x0000cc00
+#define ccc_nothing 0x00000000
#define SDLSURF_OPTS SDL_HWSURFACE|SDL_HWACCEL|/*SDL_ASYNCBLIT|*/SDL_RLEACCEL
+Uint32 getPixel(SDL_Surface *s, int x, int y) {
+ 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;
+}
+
+void putPixel(SDL_Surface *s, int x, int y, Uint32 p) {
+ //FIXME : Big Endian
+ ((Uint8 *)s->pixels)[y*s->pitch + x*(s->format->BytesPerPixel+0)] = (p & 0x000000ff) >> 0;
+ ((Uint8 *)s->pixels)[y*s->pitch + x*(s->format->BytesPerPixel+1)] = (p & 0x0000ff00) >> 8;
+ ((Uint8 *)s->pixels)[y*s->pitch + x*(s->format->BytesPerPixel+2)] = (p & 0x00ff0000) >> 16;
+}
+
SDL_Surface * createSurface(int width, int height) {
Uint32 rmask, gmask, bmask, amask;
@@ -28,14 +47,20 @@ SDL_Surface * createSurface(int width, int height) {
SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess) {
int res, i;
- SDL_Rect dstRect;
- SDL_Surface *terrain, *tile;
+ int x,y,xmin,xmax,ymin,ymax,y2,xdst, ydst;
+ Uint32 srcPixel, dstPixel, srcStencil, dstStencil;
+ SDL_Surface *terrain, *stencil, *tile;
terrain=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
if (terrain==NULL) {
logs(LOG_ERROR, "makeTerrain(), SDL_CreateRGBSurface() returns NULL");
return NULL;
}
+ stencil=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
+ if (stencil==NULL) {
+ logs(LOG_ERROR, "makeTerrain(), SDL_CreateRGBSurface() returns NULL");
+ return NULL;
+ }
res=SDL_FillRect(terrain, &(terrain->clip_rect), gIni->style.bgColor);
if (res!=0) {
@@ -43,6 +68,14 @@ SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess) {
return NULL;
}
+ res=SDL_FillRect(stencil, &(stencil->clip_rect), ccc_nothing);
+ if (res!=0) {
+ logs(LOG_WARN, "makeTerrain(), SDL_FillRect() failed");
+ return NULL;
+ }
+
+ SDL_LockSurface(terrain);
+ SDL_LockSurface(stencil);
for(i=0 ; i < gIni->level.terrainCount ; i++) {
//FIXME : check sanity for id value
tile=gRess->style.tiles[gIni->level.terrains[i].id];
@@ -50,15 +83,65 @@ SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess) {
logs(LOG_ERROR, "makeTerrain(), tile==NULL");
return NULL;
}
- dstRect.x=gIni->level.terrains[i].xpos;
- dstRect.y=gIni->level.terrains[i].ypos;
+ // 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)
+
+ // For each tile pixel, without going outside of the terrain
+ 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;
+ 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
+ if ( gIni->level.terrains[i].modifier % 4 ) {
+ y2=tile->clip_rect.h-1-y;
+ } else {
+ y2=y;
+ }
+ 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 ) {
+ dstPixel=gIni->style.bgColor;
+ } else {
+ dstPixel=srcPixel;
+ }
+ putPixel(terrain, xdst, ydst, dstPixel);
+
+ // 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 ) {
+ dstStencil=ccc_nooverride;
+ } else {
+ dstStencil=ccc_terrain;
+ }
+ 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);
return terrain;
}
diff --git a/src/include/utils.h b/src/include/utils.h
index 021816d..085884d 100644
--- a/src/include/utils.h
+++ b/src/include/utils.h
@@ -12,4 +12,7 @@ void logs(int level, char msg[]);
void logs2(int level, char context[], char msg[]);
void logp(int level, char msg[]);
+int min(int a, int b);
+int max(int a, int b);
+
#endif //UTILS_H
diff --git a/src/utils.c b/src/utils.c
index 5d828ab..a470a9f 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -36,3 +36,5 @@ void logp(int level, char msg[]) {
fprintf(fdLog,"%i - %s : %s\n", level, msg, errMsg);
}
+int min(int a, int b) { return (a<b)?a:b; }
+int max(int a, int b) { return (a>b)?a:b; }