summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-28 16:55:46 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-28 16:55:46 +0000
commit2952c4a61eb1838a8d7ada77ecc3b7c2ae3829df (patch)
tree4a73f112c37f89dbcd76ce7582bb1bde9e7bbfcd
parent9e6906386b67cdce2b9cbafbd7fc11342fd20e71 (diff)
download2010-netlemmings-2952c4a61eb1838a8d7ada77ecc3b7c2ae3829df.tar.gz
2010-netlemmings-2952c4a61eb1838a8d7ada77ecc3b7c2ae3829df.tar.bz2
2010-netlemmings-2952c4a61eb1838a8d7ada77ecc3b7c2ae3829df.zip
Amélioration de l'algo de plaquage graphique. Le fichier level2000 est rendu de la même façon sous Lemini et avec mes sources. Les 10 et 14 sont ramenés à 8 et 12 (no_override prime sur remove)
git-svn-id: file:///var/svn/2010-netlemmings/trunk@180 077b3477-7977-48bd-8428-443f22f7bfda
-rw-r--r--level/3_test/lvl2000.ini43
-rw-r--r--src/graphic.c129
-rw-r--r--src/include/graphic.h7
-rw-r--r--src/loader.c12
-rw-r--r--src/parser/parse_ini.yy1
-rw-r--r--src/test/testfunc_004_buildterrain.c4
6 files changed, 119 insertions, 77 deletions
diff --git a/level/3_test/lvl2000.ini b/level/3_test/lvl2000.ini
index 296bf2c..b5a1311 100644
--- a/level/3_test/lvl2000.ini
+++ b/level/3_test/lvl2000.ini
@@ -12,20 +12,45 @@ numBashers = 99
numMiners = 99
numDiggers = 99
xPos = 200
-style = brick
+style = crystal
# Terrain
# id, xpos, ypos, modifier
# modifier: 8=NO_OVERWRITE, 4=UPSIDE_DOWN, 2=REMOVE (combining allowed, 0=FULL)
-terrain_0 = 19, 0, 0, 0
-terrain_1 = 19, 100, 0, 0
-terrain_2 = 19, 110, 10, 2
-terrain_3 = 19, 200, 0, 4
-terrain_4 = 19, 210, 10, 6
-terrain_5 = 19, 300, 0, 0
-terrain_6 = 19, 310, 10, 8
-terrain_7 = 19, 320, 10, 0
+terrain_0 = 8, -20, -20, 12
+terrain_1 = 8, 3275, 300, 12
+terrain_2 = 8, -20, 300, 0
+terrain_3 = 8, 3275, -20, 0
+
+# un gros gems
+terrain_4 = 8, 1000, 210, 0
+
+# une grile percee en forme de gros gems
+terrain_5 = 9, 1100, 200, 0
+terrain_6 = 8, 1110, 210, 2
+
+# une grille percee en forme de gros gems à l'envers
+terrain_7 = 9, 1300, 200, 4
+terrain_8 = 8, 1310, 210, 6
+
+# un gems, une grille par dessus en no override, puis encore un gems
+terrain_9 = 8, 1500, 200, 0
+terrain_10 = 9, 1510, 210, 8
+terrain_11 = 8, 1520, 210, 0
+
+terrain_12 = 8, 1700, 200, 0
+terrain_13 = 9, 1710, 210, 8
+terrain_14 = 8, 1720, 210, 0
+
+terrain_15 = 28, 1900, 200, 0
+terrain_16 = 8, 1900, 210, 10
+terrain_17 = 9, 1910, 220, 0
+
+terrain_18 = 28, 2100, 200, 0
+terrain_19 = 8, 2100, 210, 0
+terrain_20 = 9, 2110, 220, 10
+
name = test modifiers
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);
diff --git a/src/include/graphic.h b/src/include/graphic.h
index 7941210..e8ce669 100644
--- a/src/include/graphic.h
+++ b/src/include/graphic.h
@@ -6,9 +6,12 @@
#include "data_ress.h"
Uint32 getPixel(SDL_Surface *s, int x, int y);
+Uint32 getPixel8BitPalette(SDL_Surface *s, int x, int y);
+int isTransparent(SDL_Surface *s, int x, int y);
+
void putPixel(SDL_Surface *s, int x, int y, Uint32 p);
SDL_Surface * createSurface(int width, int height);
-SDL_Surface * loadGifIn24Bpp(char *filePath);
-int makeTerrain(gameIni_t *gIni, gameRess_t *gRess, SDL_Surface **terrain, SDL_Surface **stencil);
+SDL_Surface * loadGif(char *filePath);
+int paintTerrain(gameIni_t *gIni, gameRess_t *gRess, SDL_Surface **terrain, SDL_Surface **stencil);
#endif /*GRAPHIC_H*/
diff --git a/src/loader.c b/src/loader.c
index d83087c..de28df9 100644
--- a/src/loader.c
+++ b/src/loader.c
@@ -20,9 +20,9 @@ int loadRessources(gameIni_t *gIni, gameRess_t *gRess) {
}
for(i=0; i < gIni->style.tiles ; ++i) {
snprintf(filepath, filenamelen, "%s/%s/%s_%d.gif", PATH_STYLE, gIni->style.name, gIni->style.name, i);
- gRess->style.tiles[i] = loadGifIn24Bpp(filepath);
+ gRess->style.tiles[i] = loadGif(filepath);
if(gRess->style.tiles[i]==NULL) {
- logs2(LOG_WARN, "loadRessources(), loadGifIn24Bpp() error for ", filepath);
+ logs2(LOG_WARN, "loadRessources(), loadGif() error for ", filepath);
return 2;
}
}
@@ -42,9 +42,9 @@ int loadRessources(gameIni_t *gIni, gameRess_t *gRess) {
for(i=0; i < gIni->style.objectCount ; ++i) {
snprintf(filepath, filenamelen, "%s/%s/%so_%d.gif", PATH_STYLE, gIni->style.name, gIni->style.name, i);
- gRess->style.objects[i] = loadGifIn24Bpp(filepath);
+ gRess->style.objects[i] = loadGif(filepath);
if (gRess->style.objects[i]==NULL) {
- logs2(LOG_WARN, "loadRessources(), loadGifIn24Bpp() error for ", filepath);
+ logs2(LOG_WARN, "loadRessources(), loadGif() error for ", filepath);
return 2;
}
@@ -54,9 +54,9 @@ int loadRessources(gameIni_t *gIni, gameRess_t *gRess) {
case 7:
case 8:
snprintf(filepath, filenamelen, "%s/%s/%som_%d.gif", PATH_STYLE, gIni->style.name, gIni->style.name, i);
- gRess->style.objectMasks[i] = loadGifIn24Bpp(filepath);
+ gRess->style.objectMasks[i] = loadGif(filepath);
if (gRess->style.objectMasks[i]==NULL) {
- logs2(LOG_WARN, "loadRessources(), loadGifIn24Bpp() error for ", filepath);
+ logs2(LOG_WARN, "loadRessources(), loadGif() error for ", filepath);
return 2;
}
break;
diff --git a/src/parser/parse_ini.yy b/src/parser/parse_ini.yy
index 39e0fcb..7d0a160 100644
--- a/src/parser/parse_ini.yy
+++ b/src/parser/parse_ini.yy
@@ -181,6 +181,7 @@ decl: BGCOLOR AFF INTHEX { gIni->style.bgColor = $3; }
gIni->level.terrains[$2].xpos = $6;
gIni->level.terrains[$2].ypos = $8;
gIni->level.terrains[$2].modifier = $10;
+if ($10!=0 && $10!=2 && $10!=4 && $10!=6 &&$10!=8 && $10!=10 &&$10!=12 && $10 != 15 ) printf("modifier==%i\n", $10);
}
}
| STEEL INT AFF INT VIR INT VIR INT VIR INT {
diff --git a/src/test/testfunc_004_buildterrain.c b/src/test/testfunc_004_buildterrain.c
index d802542..882f499 100644
--- a/src/test/testfunc_004_buildterrain.c
+++ b/src/test/testfunc_004_buildterrain.c
@@ -75,9 +75,9 @@ int main(int argc, char **argv) {
}
SDL_UnlockSurface(tile);
*/
- res=makeTerrain(&gIni, &gRess, &terrain, &stencil);
+ res=paintTerrain(&gIni, &gRess, &terrain, &stencil);
if (res!=0) {
- fprintf(stderr, "Cannot makeTerrain\n");
+ fprintf(stderr, "Cannot paintTerrain\n");
exit(3);
}
snprintf(filepath, MAX_PATH_LEN, "%s/%s_%s.bmp", PATH_TMP, argv[1], argv[2]);