From bf2391843b679d8919e0a9d054d71e320b9f5afc Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 21 Jul 2013 00:41:15 +0200 Subject: paint_terrain, la suite. Enfait, le parsing des ficheirs ini n'est pas complet. Et il n'y a pas de message d'erreur en cas d'arret du parseur sur une erreur ! --- src/graphic.c | 45 ++++++++++++++++++++++++--------------------- src/include/data_ini.h | 8 ++++---- src/include/parser.h | 1 + src/loader.c | 1 + src/parser.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/test/testrender.c | 13 +++++++++++++ 6 files changed, 86 insertions(+), 25 deletions(-) diff --git a/src/graphic.c b/src/graphic.c index 934e87b..7f25437 100644 --- a/src/graphic.c +++ b/src/graphic.c @@ -82,19 +82,21 @@ void my_SDL_init_or_die(char title[], SDL_Rect win_pos, Uint32 init_flags, Uint3 SDL_RenderGetViewport(*rend, viewport); } +#define PIXEL32(s,x,y) (((Uint32 *)s->pixels)[y*s->w + x]) + //FIXME : to be implmented int paint_terrain(gameIni_t *gIni, gameRess_t *gRess) { int res, res2, bpp; -// int i, modifier; -// int x,y,xmin,xmax,ymin,ymax,y2,xdst,ydst; -// Uint32 dstPixel, dstStencil; - Uint32 format, cc_nothing, rmask, gmask, bmask, amask; -// SDL_Surface *tile; + int i, modifier; + int x,y,xmin,xmax,ymin,ymax,y2,xdst,ydst; + Uint32 srcPixel, dstPixel, dstStencil; + Uint32 cc_nothing, cc_terrain, rmask, gmask, bmask, amask; + SDL_Surface *tile; - format=SDL_PIXELFORMAT_ARGB8888; cc_nothing=0xFF000000; /* Make it portable (big endian) */ + cc_terrain=0xFFFFAAAA; /* Make it portable (big endian) */ - res=SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask); + res=SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB8888, &bpp, &rmask, &gmask, &bmask, &amask); MPL_CHECK( res==SDL_TRUE, { return 1; }, @@ -113,7 +115,7 @@ int paint_terrain(gameIni_t *gIni, gameRess_t *gRess) { /* Fill the entire surfaces with default color */ - res=SDL_FillRect(gRess->terrain, NULL, gIni->style.bgColor); + res =SDL_FillRect(gRess->terrain, NULL, gIni->style.bgColor); res2=SDL_FillRect(gRess->stencil, NULL, cc_nothing); MPL_CHECK( res==0 && res2==0, @@ -122,9 +124,8 @@ int paint_terrain(gameIni_t *gIni, gameRess_t *gRess) { "paintTerrain(), SDL_FillRect() failed" ); -#if 0 - SDL_LockSurface(gRess->terrain); /*XXX Only if RLE encoded. To be removed ? */ - SDL_LockSurface(gRess->stencil); + /* SDL_LockSurface(gRess->terrain); //XXX Only if RLE encoded. To be removed ? + SDL_LockSurface(gRess->stencil); */ for(i=0 ; i < gIni->level.terrainCount ; i++) { int tid=gIni->level.terrains[i].id; MPL_CHECK( @@ -147,7 +148,7 @@ int paint_terrain(gameIni_t *gIni, gameRess_t *gRess) { // 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 + // 8 : NO_OVERRIDE : Don't change pixels that already set on destination // 4 : Upside Down // 2 : REMOVE : oublier (rendre transparent) tous les pixels qu'on a déjà plaqué @@ -164,11 +165,11 @@ int paint_terrain(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, gRess->terrain->clip_rect.h - gIni->level.terrains[i].ypos); + ymax=SDL_min(tile->clip_rect.h, gRess->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, gRess->terrain->clip_rect.w - gIni->level.terrains[i].xpos); + xmax=SDL_min(tile->clip_rect.w, gRess->terrain->clip_rect.w - gIni->level.terrains[i].xpos); - SDL_LockSurface(tile); + //SDL_LockSurface(tile); for (y=ymin; ylevel.terrains[i].ypos+y; xdst=gIni->level.terrains[i].xpos+x; + srcPixel = PIXEL32(tile, x, y2); // Act only if current pixel in tile is not transparent - if ( ! isTransparent(tile, x, y2) ) { + if ( (srcPixel & amask) != 0 ) { // Always paint pixel, except in one case: // If we are in NO_OVERRIDE mode and there is already a terrain on the current (source) pixel if ( !( (modifier & 8) == 8 && - getPixel(gRess->stencil, xdst, ydst) == cc_terrain ) ) { + PIXEL32(gRess->stencil, xdst, ydst) == cc_terrain ) ) { // If we have REMOVE modifier, dstPixel will be rolled back to bgColor, else, it will be identical to the source pixel. We have to update stencil consistenly. if ( (modifier & 2) == 2 ) { dstPixel=gIni->style.bgColor; dstStencil=cc_nothing; } else { - dstPixel=getPixel8BitPalette(tile, x, y2); + dstPixel=srcPixel; dstStencil=cc_terrain; } - putPixel(gRess->terrain,xdst,ydst,dstPixel); - putPixel(gRess->stencil,xdst,ydst,dstStencil); + PIXEL32(gRess->terrain,xdst,ydst)=dstPixel; + PIXEL32(gRess->stencil,xdst,ydst)=dstStencil; } } } } SDL_UnlockSurface(tile); } +/* SDL_UnlockSurface(gRess->stencil); SDL_UnlockSurface(gRess->terrain); -#endif +*/ return 0; } diff --git a/src/include/data_ini.h b/src/include/data_ini.h index 381943a..1f93caf 100644 --- a/src/include/data_ini.h +++ b/src/include/data_ini.h @@ -3,8 +3,8 @@ #include -#define LEVEL_WIDTH 1664 -#define LEVEL_HEIGHT 160 +#define LEVEL_WIDTH (1664*2) +#define LEVEL_HEIGHT (160*2) #define MAX_NAMELEN 64 @@ -37,8 +37,8 @@ struct levelIni { int superLemming; int objectCount, terrainCount, steelCount; struct levelItem objects[MAX_OBJECTS_COUNT]; - struct levelItem terrains[MAX_OBJECTS_COUNT]; - struct levelItem steels[MAX_OBJECTS_COUNT]; + struct levelItem terrains[MAX_TERRAINS_COUNT]; + struct levelItem steels[MAX_STEELS_COUNT]; }; diff --git a/src/include/parser.h b/src/include/parser.h index 9d9c2c7..4b70352 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -18,6 +18,7 @@ #define ERR_KEY_OUT_OF_RANGE 3 #define ERR_VAL_OUT_OF_RANGE 4 #define ERR_STRING_TOO_LONG 5 +#define ERR_BAD_FIELDS 6 enum ini_type { ini_style, ini_levelpack, ini_level }; diff --git a/src/loader.c b/src/loader.c index b2ea9bf..ec34e79 100644 --- a/src/loader.c +++ b/src/loader.c @@ -164,6 +164,7 @@ int loadSurface(SDL_Renderer *rend, char *giffilepath, SDL_Surface **surf) { "loadSurface(rend, \"%s\", frames, sprite) failed : can't decode file", giffilepath ); + *surf = SDL_ConvertSurfaceFormat(*surf, SDL_PIXELFORMAT_ARGB8888, 0); // TODO : conversion en fonction du renderer ou bien systématiquement en ARGB8888, a voir. return 0; } diff --git a/src/parser.c b/src/parser.c index 027d1fc..89f3c55 100644 --- a/src/parser.c +++ b/src/parser.c @@ -206,6 +206,49 @@ int callback_ini_level(const mTCHAR *section, const mTCHAR *key, const mTCHAR *v MATCH_STRING(style,MAX_NAMELEN); MATCH_STRING(name,MAX_NAMELEN); + if (SDL_strncasecmp(key,"object",6)==0 && key[6]=='_') { + return 1; + } + if (SDL_strncasecmp(key,"steel",5)==0 && key[5]=='_') { + return 1; + } + + if (SDL_strncasecmp(key,"terrain",7)==0 && key[7]=='_') { + char *wordBoundary; + int v; + int k = atoi(key+8); + if ( k<0 || k>MAX_TERRAINS_COUNT) { *err=ERR_KEY_OUT_OF_RANGE; return 0; } + if (data->terrainCount < k+1) data->terrainCount = k+1; + + if ( (wordBoundary=SDL_strchr(value,','))==NULL ) { *err=ERR_BAD_FIELDS; return 0; } + *wordBoundary='\0'; + v = atoi(value); + if ( v<0 || v>MAX_OBJECTS_COUNT) { *err=ERR_VAL_OUT_OF_RANGE; return 0; } + data->terrains[k].id = v; + value = wordBoundary+1; + + if ( (wordBoundary=SDL_strchr(value,','))==NULL ) { *err=ERR_BAD_FIELDS; return 0; } + *wordBoundary='\0'; + v = atoi(value); + if ( v<0 || v>LEVEL_WIDTH) { *err=ERR_VAL_OUT_OF_RANGE; return 0; } + data->terrains[k].xpos = v; + value = wordBoundary+1; + + if ( (wordBoundary=SDL_strchr(value,','))==NULL ) { *err=ERR_BAD_FIELDS; return 0; } + *wordBoundary='\0'; + v = atoi(value); + if ( v<0 || v>LEVEL_HEIGHT) { *err=ERR_VAL_OUT_OF_RANGE; return 0; } + data->terrains[k].ypos = v; + value = wordBoundary+1; + + v = atoi(value); + if ( v<0 || v>16) { *err=ERR_VAL_OUT_OF_RANGE; return 0; } + data->terrains[k].modifier = v; + + return 1; + } + //MATCH_INT_ARRAY_QUAD(terrain,MAX_OBJECTS_COUNT,data->terrainCount,data->terrains,id,xpos,ypos,modifier); + //MATCH_INT_ARRAY_QUAD(terrain,MAX_STEELS_COUNT,data->terrainCount,data->terrains,id,xpos,ypos,modifier); // TODO : object/terrain/steel à la main (car struct, et complications) // No match is an error (unkown key) diff --git a/src/test/testrender.c b/src/test/testrender.c index 990efef..c831089 100644 --- a/src/test/testrender.c +++ b/src/test/testrender.c @@ -75,7 +75,19 @@ int main(int argc, char **argv) { res=loadStyleRes(sdl_rend, &gIni, DATA_BASEPATH, &gRess); if (res!=0) exit(res); + res=paint_terrain(&gIni, &gRess); + if (res!=0) exit(res); + + SDL_Texture * terr = SDL_CreateTextureFromSurface(sdl_rend, gRess.terrain); + MPL_CHECK( + terr, + { exit(1); }, + SDL_LOG_PRIORITY_CRITICAL, + "Can't convert terrain to texture" + ); + rlLen=buildTestRL(&gRess, MAX_RENDERLIST_LEN, render_list); + /* Main render loop */ while (!mainloop_end) { int i; @@ -87,6 +99,7 @@ int main(int argc, char **argv) { } } SDL_RenderClear(sdl_rend); + (void) SDL_RenderCopy(sdl_rend, terr, NULL, NULL); render_all(sdl_rend, render_list, rlLen); SDL_RenderPresent(sdl_rend); -- cgit v1.2.3