summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-26 23:03:13 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-26 23:03:13 +0000
commit691bca5a1f70f96ceb4c5510fc73c147883f69ab (patch)
tree2bb6c6718405c6be69cddebeec54cbf7bbd6a9f6
parentba92534d9e92f4611eea65dbecc8ce1cde298f4d (diff)
download2010-netlemmings-691bca5a1f70f96ceb4c5510fc73c147883f69ab.tar.gz
2010-netlemmings-691bca5a1f70f96ceb4c5510fc73c147883f69ab.tar.bz2
2010-netlemmings-691bca5a1f70f96ceb4c5510fc73c147883f69ab.zip
Première version du blitting refactorisé qui s'exécute. En revanche la définition de NO_OVERWRITE considérée est fausse !
git-svn-id: file:///var/svn/2010-netlemmings/trunk@178 077b3477-7977-48bd-8428-443f22f7bfda
-rw-r--r--level/3_test/levelpack.ini19
-rw-r--r--level/3_test/lvl2000.ini31
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/graphic.c87
-rw-r--r--src/include/graphic.h6
-rw-r--r--src/loader.c13
-rw-r--r--src/test/CMakeLists.txt2
-rw-r--r--src/test/testfunc_004_buildterrain.c22
8 files changed, 128 insertions, 54 deletions
diff --git a/level/3_test/levelpack.ini b/level/3_test/levelpack.ini
index 6be7eee..64be0ec 100644
--- a/level/3_test/levelpack.ini
+++ b/level/3_test/levelpack.ini
@@ -24,12 +24,13 @@ level_0 = Pixels
# Level 0 - Pixels
-pixels_0 = lvl2001.ini,5
-pixels_1 = lvl2002.ini,4
-pixels_2 = lvl2003.ini,3
-pixels_3 = lvl2004.ini,2
-pixels_4 = lvl2005.ini,1
-pixels_5 = lvl2006.ini,0
-pixels_6 = lvl2007.ini,1
-pixels_7 = lvl2008.ini,2
-pixels_8 = lvl2009.ini,3
+pixels_0 = lvl2000.ini,5
+pixels_1 = lvl2001.ini,4
+pixels_2 = lvl2002.ini,3
+pixels_3 = lvl2003.ini,2
+pixels_4 = lvl2004.ini,1
+pixels_5 = lvl2005.ini,0
+pixels_6 = lvl2006.ini,1
+pixels_7 = lvl2007.ini,2
+pixels_8 = lvl2008.ini,3
+pixels_9 = lvl2009.ini,3
diff --git a/level/3_test/lvl2000.ini b/level/3_test/lvl2000.ini
new file mode 100644
index 0000000..296bf2c
--- /dev/null
+++ b/level/3_test/lvl2000.ini
@@ -0,0 +1,31 @@
+# LVL extracted by Lemmini #LVL0041.LVL
+releaseRate = 1
+numLemmings = 99
+numToRescue = 1
+timeLimit = 20
+numClimbers = 99
+numFloaters = 99
+numBombers = 99
+numBlockers = 99
+numBuilders = 99
+numBashers = 99
+numMiners = 99
+numDiggers = 99
+xPos = 200
+style = brick
+
+# 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
+
+name = test modifiers
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 23b652e..5d919b9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -12,7 +12,7 @@ configure_file (
"${PROJECT_BINARY_DIR}/netlem_ds.h"
)
-add_executable(netlem WIN32 netlem.c ${SRC_COMMON} game.c loader.c parser/lex.yy.c parser/y.tab.c )
+add_executable(netlem WIN32 netlem.c ${SRC_COMMON} game.c loader.c graphic.c parser/lex.yy.c parser/y.tab.c )
target_link_libraries(netlem SDL SDL_net SDL_image)
add_executable(netlem_ds WIN32 netlem_ds.c ${SRC_COMMON} )
diff --git a/src/graphic.c b/src/graphic.c
index d68c289..35d69c6 100644
--- a/src/graphic.c
+++ b/src/graphic.c
@@ -11,17 +11,18 @@
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;
+ 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) {
+ //printf("putPixel(s, %i, %i, 0x%x)\n", x, y, 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;
+ ((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) {
@@ -45,45 +46,67 @@ SDL_Surface * createSurface(int width, int height) {
}
-SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess) {
+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;
+}
+
+int makeTerrain(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;
Uint32 srcPixel, dstPixel, srcStencil, dstStencil;
- SDL_Surface *terrain, *stencil, *tile;
+ SDL_Surface *tile;
+ //SDL_Rect dstRect;
- terrain=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
- if (terrain==NULL) {
+ *terrain=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
+ if (*terrain==NULL) {
logs(LOG_ERROR, "makeTerrain(), SDL_CreateRGBSurface() returns NULL");
- return NULL;
+ return 1;
}
- stencil=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
- if (stencil==NULL) {
+ *stencil=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT);
+ if (*stencil==NULL) {
logs(LOG_ERROR, "makeTerrain(), SDL_CreateRGBSurface() returns NULL");
- return NULL;
+ return 2;
}
- res=SDL_FillRect(terrain, &(terrain->clip_rect), gIni->style.bgColor);
+ res=SDL_FillRect(*terrain, &((*terrain)->clip_rect), gIni->style.bgColor);
if (res!=0) {
logs(LOG_WARN, "makeTerrain(), SDL_FillRect() failed");
- return NULL;
+ return 3;
}
- res=SDL_FillRect(stencil, &(stencil->clip_rect), ccc_nothing);
+ res=SDL_FillRect(*stencil, &((*stencil)->clip_rect), ccc_nothing);
if (res!=0) {
logs(LOG_WARN, "makeTerrain(), SDL_FillRect() failed");
- return NULL;
+ return 4;
}
- SDL_LockSurface(terrain);
- SDL_LockSurface(stencil);
+ 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];
if (tile==NULL) {
logs(LOG_ERROR, "makeTerrain(), tile==NULL");
- return NULL;
+ return 5;
}
+// dstRect.y=gIni->level.terrains[i].ypos;
+// dstRect.x=gIni->level.terrains[i].xpos;
+
// 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
@@ -91,14 +114,14 @@ SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess) {
// 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);
+ 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);
+ 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 ) {
+ if ( (gIni->level.terrains[i].modifier & 4) == 4 ) {
y2=tile->clip_rect.h-1-y;
} else {
y2=y;
@@ -108,25 +131,25 @@ SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess) {
// Grab current pixel and stencil state (from previous blits)
srcPixel=getPixel(tile, x, y2);
- srcStencil=getPixel(stencil, xdst, ydst);
+ 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 ) {
+ if ( (gIni->level.terrains[i].modifier & 2) == 2 ) {
dstPixel=gIni->style.bgColor;
} else {
dstPixel=srcPixel;
}
- putPixel(terrain, xdst, ydst, dstPixel);
+ 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 ) {
+ if ( (gIni->level.terrains[i].modifier & 8) == 8 ) {
dstStencil=ccc_nooverride;
} else {
dstStencil=ccc_terrain;
}
- putPixel(stencil, xdst, ydst, dstStencil);
+ putPixel(*stencil, xdst, ydst, dstStencil);
}
}
@@ -140,8 +163,8 @@ SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess) {
}
*/
}
- SDL_UnlockSurface(stencil);
- SDL_UnlockSurface(terrain);
+ SDL_UnlockSurface(*stencil);
+ SDL_UnlockSurface(*terrain);
- return terrain;
+ return 0;
}
diff --git a/src/include/graphic.h b/src/include/graphic.h
index 697ff99..7941210 100644
--- a/src/include/graphic.h
+++ b/src/include/graphic.h
@@ -5,6 +5,10 @@
#include "data_ini.h"
#include "data_ress.h"
-SDL_Surface * makeTerrain(gameIni_t *gIni, gameRess_t *gRess);
+Uint32 getPixel(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);
#endif /*GRAPHIC_H*/
diff --git a/src/loader.c b/src/loader.c
index bd8d8c4..d83087c 100644
--- a/src/loader.c
+++ b/src/loader.c
@@ -1,6 +1,7 @@
#include "SDL/SDL_stdinc.h"
#include "SDL/SDL_image.h"
#include "loader.h"
+#include "graphic.h"
#include "utils.h"
#define PATH_STYLE "../styles"
@@ -19,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] = IMG_Load(filepath);
+ gRess->style.tiles[i] = loadGifIn24Bpp(filepath);
if(gRess->style.tiles[i]==NULL) {
- logs2(LOG_WARN, "loadRessources(), IMG_Load() error for ", filepath);
+ logs2(LOG_WARN, "loadRessources(), loadGifIn24Bpp() error for ", filepath);
return 2;
}
}
@@ -41,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] = IMG_Load(filepath);
+ gRess->style.objects[i] = loadGifIn24Bpp(filepath);
if (gRess->style.objects[i]==NULL) {
- logs2(LOG_WARN, "loadRessources(), IMG_Load() error for ", filepath);
+ logs2(LOG_WARN, "loadRessources(), loadGifIn24Bpp() error for ", filepath);
return 2;
}
@@ -53,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] = IMG_Load(filepath);
+ gRess->style.objectMasks[i] = loadGifIn24Bpp(filepath);
if (gRess->style.objectMasks[i]==NULL) {
- logs2(LOG_WARN, "loadRessources(), IMG_Load() error for ", filepath);
+ logs2(LOG_WARN, "loadRessources(), loadGifIn24Bpp() error for ", filepath);
return 2;
}
break;
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 0618958..0d903be 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -5,7 +5,7 @@ set(PARSER_FILES ../parser/lex.yy.c ../parser/y.tab.c)
add_executable(testfunc_001_lex WIN32 testfunc_001_lex.c ${PARSER_FILES} )
add_executable(testfunc_002_parse WIN32 testfunc_002_parse.c ${PARSER_FILES} )
-add_executable(testfunc_003_loadress WIN32 testfunc_003_loadress.c ${PARSER_FILES} ../loader.c ../utils.c )
+add_executable(testfunc_003_loadress WIN32 testfunc_003_loadress.c ${PARSER_FILES} ../loader.c ../utils.c ../graphic.c )
target_link_libraries(testfunc_003_loadress SDL_image)
add_executable(testfunc_004_buildterrain WIN32 testfunc_004_buildterrain.c ${PARSER_FILES} ../loader.c ../graphic.c ../utils.c )
target_link_libraries(testfunc_004_buildterrain SDL_image)
diff --git a/src/test/testfunc_004_buildterrain.c b/src/test/testfunc_004_buildterrain.c
index b230e5c..d802542 100644
--- a/src/test/testfunc_004_buildterrain.c
+++ b/src/test/testfunc_004_buildterrain.c
@@ -30,7 +30,7 @@ int main(int argc, char **argv) {
char filepath[MAX_PATH_LEN];
gameIni_t gIni;
gameRess_t gRess;
- SDL_Surface *terrain;
+ SDL_Surface *terrain=NULL, *stencil=NULL;
if (argc != 3) {
fprintf(stderr, "Usage %s <levelpack_name> <ini_file>\n", argv[0]);
@@ -66,9 +66,17 @@ int main(int argc, char **argv) {
SDL_Init(SDL_INIT_VIDEO);
atexit(SDL_Quit);
-
- terrain=makeTerrain(&gIni, &gRess);
- if (terrain==NULL) {
+/*
+ SDL_Surface *tile;
+ tile=gRess.style.tiles[gIni.level.terrains[0].id];
+ SDL_LockSurface(tile);
+ for(int i=0;i<1000000;i++) {
+ printf("%02i ", ((Uint8*)tile->pixels)[i]);
+ }
+ SDL_UnlockSurface(tile);
+*/
+ res=makeTerrain(&gIni, &gRess, &terrain, &stencil);
+ if (res!=0) {
fprintf(stderr, "Cannot makeTerrain\n");
exit(3);
}
@@ -78,6 +86,12 @@ int main(int argc, char **argv) {
fprintf(stderr, "Cannot SaveBMP\n");
exit(4);
}
+ snprintf(filepath, MAX_PATH_LEN, "%s/%s_%s-stencil.bmp", PATH_TMP, argv[1], argv[2]);
+ res=SDL_SaveBMP(stencil, filepath);
+ if (res!=0) {
+ fprintf(stderr, "Cannot SaveBMP\n");
+ exit(4);
+ }
closeLog(NULL);