From 691bca5a1f70f96ceb4c5510fc73c147883f69ab Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Fri, 26 Nov 2010 23:03:13 +0000 Subject: Première version du blitting refactorisé qui s'exécute. En revanche la définition de NO_OVERWRITE considérée est fausse ! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2010-netlemmings/trunk@178 077b3477-7977-48bd-8428-443f22f7bfda --- level/3_test/levelpack.ini | 19 ++++---- level/3_test/lvl2000.ini | 31 +++++++++++++ src/CMakeLists.txt | 2 +- src/graphic.c | 87 +++++++++++++++++++++++------------- src/include/graphic.h | 6 ++- src/loader.c | 13 +++--- src/test/CMakeLists.txt | 2 +- src/test/testfunc_004_buildterrain.c | 22 +++++++-- 8 files changed, 128 insertions(+), 54 deletions(-) create mode 100644 level/3_test/lvl2000.ini 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; ylevel.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 \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); -- cgit v1.2.3