From 2dc612b3115e7391582a526be524971e19078425 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Fri, 19 Jul 2013 21:44:09 +0200 Subject: Debut adaptation paint_terrain(). Modif des tiles de texture vers surfaces car blitting custom manuel. --- src/graphic.c | 105 ++++++++++++++++++++++++++++-------------------- src/include/data_ini.h | 28 ++++++------- src/include/data_ress.h | 4 +- src/include/graphic.h | 2 +- src/loader.c | 54 ++++++++++++++++--------- src/test/testparseall.c | 20 ++++----- src/test/testrender.c | 8 ++-- 7 files changed, 128 insertions(+), 93 deletions(-) diff --git a/src/graphic.c b/src/graphic.c index 58d38f1..1a3fa1f 100644 --- a/src/graphic.c +++ b/src/graphic.c @@ -83,45 +83,63 @@ void my_SDL_init_or_die(char title[], SDL_Rect win_pos, Uint32 init_flags, Uint3 } //FIXME : to be implmented -#if 0 -int paint_terrain(gameIni_t *gIni, gameRess_t *gRess, gameGraphics_t *gGraph) { - int res, i, modifier; +int paint_terrain(gameIni_t *gIni, gameRess_t *gRess) { + int res, res2, i, modifier; int x,y,xmin,xmax,ymin,ymax,y2,xdst,ydst; - Uint32 dstPixel, dstStencil; + Uint32 dstPixel, dstStencil, rmask, gmask, bmask, amask; SDL_Surface *tile; - - gGraph->surfaces.terrain=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT); - if (gGraph->surfaces.terrain==NULL) { - logs(LOG_ERROR, "paintTerrain(), SDL_CreateRGBSurface() returns NULL"); - return 1; - } - gGraph->surfaces.stencil=createSurface(LEVEL_WIDTH, LEVEL_HEIGHT); - if (gGraph->surfaces.stencil==NULL) { - logs(LOG_ERROR, "paintTerrain(), SDL_CreateRGBSurface() returns NULL"); - return 2; - } - - res=SDL_FillRect(gGraph->surfaces.terrain, &(gGraph->surfaces.terrain->clip_rect), gIni->style.bgColor); - if (res!=0) { - logs(LOG_WARN, "paintTerrain(), SDL_FillRect() failed"); - return 3; - } - - res=SDL_FillRect(gGraph->surfaces.stencil, &(gGraph->surfaces.stencil->clip_rect), ccc_nothing); - if (res!=0) { - logs(LOG_WARN, "paintTerrain(), SDL_FillRect() failed"); - return 4; - } - - SDL_LockSurface(gGraph->surfaces.terrain); - SDL_LockSurface(gGraph->surfaces.stencil); +/* Is necessary ? +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif +*/ + rmask = gmask = bmask = amask = 0; // Use default masks + gRess->terrain=SDL_CreateRGBSurface(0, LEVEL_WIDTH, LEVEL_HEIGHT, 32, rmask, gmask, bmask, amask); + gRess->stencil=SDL_CreateRGBSurface(0, LEVEL_WIDTH, LEVEL_HEIGHT, 32, rmask, gmask, bmask, amask); + + MPL_CHECK( + gRess->terrain && gRess->stencil, + { return 1; }, + SDL_LOG_PRIORITY_CRITICAL, + "paintTerrain(), SDL_CreateRGBSurface() failed" + ); + + /* Fill the entire surfaces with default color */ + res=SDL_FillRect(gRess->terrain, NULL, gIni->style.bgColor); + res2=SDL_FillRect(gRess->stencil, NULL, ccc_nothing); + MPL_CHECK( + res==0 && res2==0, + { return 2; }, + SDL_LOG_PRIORITY_CRITICAL, + "paintTerrain(), SDL_FillRect() failed" + ); + + SDL_LockSurface(gRess->terrain); + SDL_LockSurface(gRess->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, "paintTerrain(), tile==NULL"); - return 5; - } + int tid=gIni->level.terrains[i].id; + MPL_CHECK( + tid > 0 && tid < MAX_TILES_COUNT, + { return 3; }, + SDL_LOG_PRIORITY_CRITICAL, + "paintTerrain(), gIni->level.terrains[%].id == %i and it's out of range", i, tid + ); + + tile=gRess->tiles[tid]; + MPL_CHECK( + tile, + { return 4; }, + SDL_LOG_PRIORITY_CRITICAL, + "paintTerrain(), tile %i was not loaded", tid + ); // Special modifier values : @@ -145,9 +163,9 @@ int paint_terrain(gameIni_t *gIni, gameRess_t *gRess, gameGraphics_t *gGraph) { // 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, gGraph->surfaces.terrain->clip_rect.h - gIni->level.terrains[i].ypos); + ymax=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, gGraph->surfaces.terrain->clip_rect.w - gIni->level.terrains[i].xpos); + xmax=min(tile->clip_rect.w, gRess->terrain->clip_rect.w - gIni->level.terrains[i].xpos); SDL_LockSurface(tile); for (y=ymin; ysurfaces.stencil, xdst, ydst) == ccc_terrain ) ) { + getPixel(gRess->stencil, xdst, ydst) == ccc_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; @@ -175,20 +193,19 @@ int paint_terrain(gameIni_t *gIni, gameRess_t *gRess, gameGraphics_t *gGraph) { dstPixel=getPixel8BitPalette(tile, x, y2); dstStencil=ccc_terrain; } - putPixel(gGraph->surfaces.terrain,xdst,ydst,dstPixel); - putPixel(gGraph->surfaces.stencil,xdst,ydst,dstStencil); + putPixel(gRess->terrain,xdst,ydst,dstPixel); + putPixel(gRess->stencil,xdst,ydst,dstStencil); } } } } SDL_UnlockSurface(tile); } - SDL_UnlockSurface(gGraph->surfaces.stencil); - SDL_UnlockSurface(gGraph->surfaces.terrain); + SDL_UnlockSurface(gRess->stencil); + SDL_UnlockSurface(gRess->terrain); return 0; } -#endif void render_all(SDL_Renderer *rend, render_item_t render_list[], int list_size) { int i, res; diff --git a/src/include/data_ini.h b/src/include/data_ini.h index 06b1c47..c2c4c11 100644 --- a/src/include/data_ini.h +++ b/src/include/data_ini.h @@ -29,13 +29,13 @@ struct levelItem { }; struct levelIni { - int releaseRate, numLemmings, numToRescue, timeLimit; - int numClimbers, numFloaters, numBlockers, numBombers; - int numBuilders, numBashers, numMiners, numDiggers; - int xPos; // Initial camera position on level + int releaseRate, numLemmings, numToRescue, timeLimit; + int numClimbers, numFloaters, numBlockers, numBombers; + int numBuilders, numBashers, numMiners, numDiggers; + int xPos; // Initial camera position on level char style[MAX_NAMELEN], name[MAX_NAMELEN]; - int superLemming; - int objectCount, terrainCount, steelCount; + int superLemming; + int objectCount, terrainCount, steelCount; struct levelItem objects[MAX_OBJECTS_COUNT]; struct levelItem terrains[MAX_OBJECTS_COUNT]; struct levelItem steels[MAX_OBJECTS_COUNT]; @@ -45,9 +45,9 @@ struct levelIni { //////////////////////// LEVELPACK INI FILES //////////////////////// struct levelPackIni { char name[MAX_NAMELEN]; - int maxFallDistance; + int maxFallDistance; char codeSeed[MAX_NAMELEN]; - int musicCount, levelDifficultyCount; + int musicCount, levelDifficultyCount; char music[MAX_MUSICS_COUNT][MAX_NAMELEN]; char levelDifficulty[MAX_DIFFICULTY_COUNT][MAX_NAMELEN]; }; @@ -55,13 +55,13 @@ struct levelPackIni { //////////////////////// STYLE INI FILES //////////////////////// struct styleIni { uint32_t bgColor, debrisColor; - int tiles, particleColorCount; + int tiles, particleColorCount; uint32_t particleColor[MAX_PARTICLE_COLORS]; - int objectCount; - int frames[MAX_OBJECTS_COUNT]; - int anim[MAX_OBJECTS_COUNT]; - int type[MAX_OBJECTS_COUNT]; - int sound[MAX_OBJECTS_COUNT]; + int objectCount; + int frames[MAX_OBJECTS_COUNT]; + int anim[MAX_OBJECTS_COUNT]; + int type[MAX_OBJECTS_COUNT]; + int sound[MAX_OBJECTS_COUNT]; }; /*////////////////////// MISC/LEMMING.INI FILE //////////////////////// diff --git a/src/include/data_ress.h b/src/include/data_ress.h index 07fbd19..09f1754 100644 --- a/src/include/data_ress.h +++ b/src/include/data_ress.h @@ -13,7 +13,7 @@ typedef struct { typedef struct { /* Style */ - sprite_t tiles[MAX_TILES_COUNT]; + SDL_Surface *tiles[MAX_TILES_COUNT]; sprite_t objects[MAX_OBJECTS_COUNT]; sprite_t objectMasks[MAX_OBJECTS_COUNT]; /* Misc */ @@ -25,6 +25,8 @@ typedef struct { Mix_Music *musics[MAX_MUSICS_COUNT]; /* Sound */ Mix_Chunk *sounds[MAX_SOUNDS_COUNT]; + /* terrain & stencil : generated by paint_terrain() */ + SDL_Surface *terrain, *stencil; } gameRess_t; #endif /*DATA_RESS_H*/ diff --git a/src/include/graphic.h b/src/include/graphic.h index 41cd526..269c283 100644 --- a/src/include/graphic.h +++ b/src/include/graphic.h @@ -14,7 +14,7 @@ typedef struct { void my_SDL_init_or_die(char title[], SDL_Rect win_pos, Uint32 init_flags, Uint32 win_flags, Uint32 rend_flags, SDL_Window **win, SDL_Renderer **rend, SDL_RendererInfo *rend_info, SDL_Rect *viewport); -//int paint_terrain(gameIni_t *gIni, gameRess_t *gRess, gameGraphics_t *gGraph); +int paint_terrain(gameIni_t *gIni, gameRess_t *gRess); void render_all(SDL_Renderer *rend, render_item_t render_list[], int list_size); diff --git a/src/loader.c b/src/loader.c index 0d16c48..b2ea9bf 100644 --- a/src/loader.c +++ b/src/loader.c @@ -4,6 +4,7 @@ #include int loadSprite(SDL_Renderer *rend, char *giffilepath, int frames, sprite_t *sprite); +int loadSurface(SDL_Renderer *rend, char *giffilepath, SDL_Surface **surf); int loadStyleRes(SDL_Renderer *rend, gameIni_t *gIni, char data_basepath[], gameRess_t *gRess) { int i, res; @@ -12,7 +13,7 @@ int loadStyleRes(SDL_Renderer *rend, gameIni_t *gIni, char data_basepath[], game for(i=0; i < gIni->style.tiles; i++) { (void) SDL_snprintf(filepath, MAX_PATH_LEN, "%s/style/%s/%s_%d.gif", data_basepath, stylename, stylename, i); - res=loadSprite(rend,filepath,1,&gRess->tiles[i]); + res=loadSurface(rend,filepath,&gRess->tiles[i]); if (res != 0) return res; } @@ -34,8 +35,11 @@ int loadStyleRes(SDL_Renderer *rend, gameIni_t *gIni, char data_basepath[], game void unloadStyleRes(gameRess_t *gRess) { int i; + + /* Nullpointer checked for surface but not for textures in SDL code */ for(i=0; itiles[i].t); + SDL_FreeSurface(gRess->tiles[i]); + gRess->tiles[i] = NULL; } for(i=0; iobjects[i].t); @@ -106,9 +110,8 @@ void unloadMiscRes(gameRess_t *gRess) { /* frames is for animated sprites and is the number of images. Assumed to be all in a column */ int loadSprite(SDL_Renderer *rend, char *giffilepath, int frames, sprite_t *sprite) { + int res; SDL_Surface *surf; - SDL_RWops *rwop; - //int res; MPL_CHECK( frames > 0, @@ -118,22 +121,8 @@ int loadSprite(SDL_Renderer *rend, char *giffilepath, int frames, sprite_t *spri giffilepath, frames ); - rwop = SDL_RWFromFile(giffilepath,"r"); - MPL_CHECK( - rwop, - {return 2;}, - SDL_LOG_PRIORITY_WARN, - "loadSprite(rend, \"%s\", frames, sprite) failed : problem opening file", giffilepath - ); - surf = IMG_LoadGIF_RW(rwop); - SDL_RWclose(rwop); - - MPL_CHECK( - surf, - {return 3;}, - SDL_LOG_PRIORITY_WARN, - "loadSprite(rend, \"%s\", frames, sprite) failed : can't decode file", giffilepath - ); + res = loadSurface(rend, giffilepath, &surf); + if (res !=0) return res; sprite->t = SDL_CreateTextureFromSurface(rend, surf); MPL_CHECK( @@ -154,3 +143,28 @@ int loadSprite(SDL_Renderer *rend, char *giffilepath, int frames, sprite_t *spri return 0; } +int loadSurface(SDL_Renderer *rend, char *giffilepath, SDL_Surface **surf) { + SDL_RWops *rwop; + //int res; + + rwop = SDL_RWFromFile(giffilepath,"r"); + MPL_CHECK( + rwop, + {return 2;}, + SDL_LOG_PRIORITY_WARN, + "loadSurface(rend, \"%s\", frames, sprite) failed : problem opening file", giffilepath + ); + *surf = IMG_LoadGIF_RW(rwop); + SDL_RWclose(rwop); + + MPL_CHECK( + *surf, + {return 3;}, + SDL_LOG_PRIORITY_WARN, + "loadSurface(rend, \"%s\", frames, sprite) failed : can't decode file", giffilepath + ); + + // TODO : conversion en fonction du renderer ou bien systématiquement en ARGB8888, a voir. + return 0; +} + diff --git a/src/test/testparseall.c b/src/test/testparseall.c index 9528b4e..de456e5 100644 --- a/src/test/testparseall.c +++ b/src/test/testparseall.c @@ -13,16 +13,16 @@ int main() { int i,res; struct test_ini_file ini_list[] = { - { ini_style, "data/styles/brick/brick.ini" }, - { ini_style, "data/styles/bubble/bubble.ini" }, - { ini_style, "data/styles/crystal/crystal.ini" }, - { ini_style, "data/styles/dirt/dirt.ini" }, - { ini_style, "data/styles/fire/fire.ini" }, - { ini_style, "data/styles/marble/marble.ini" }, - { ini_style, "data/styles/pillar/pillar.ini" }, - { ini_style, "data/styles/rock/rock.ini" }, - { ini_style, "data/styles/snow/snow.ini"}, - { ini_style, "data/styles/special/special.ini" }, + { ini_style, "data/style/brick/brick.ini" }, + { ini_style, "data/style/bubble/bubble.ini" }, + { ini_style, "data/style/crystal/crystal.ini" }, + { ini_style, "data/style/dirt/dirt.ini" }, + { ini_style, "data/style/fire/fire.ini" }, + { ini_style, "data/style/marble/marble.ini" }, + { ini_style, "data/style/pillar/pillar.ini" }, + { ini_style, "data/style/rock/rock.ini" }, + { ini_style, "data/style/snow/snow.ini"}, + { ini_style, "data/style/special/special.ini" }, { ini_levelpack, "data/level/1_orig/levelpack.ini" }, { ini_levelpack, "data/level/2_ohno/levelpack.ini" }, { ini_levelpack, "data/level/3_test/levelpack.ini" }, diff --git a/src/test/testrender.c b/src/test/testrender.c index f4c5173..990efef 100644 --- a/src/test/testrender.c +++ b/src/test/testrender.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) { SDL_Event sdl_ev; int rlLen, mainloop_end=0; - SDL_Rect win_pos = { .x=SDL_WINDOWPOS_UNDEFINED, .y=SDL_WINDOWPOS_UNDEFINED, .w=1920, .h=1200 }; + SDL_Rect win_pos = { .x=SDL_WINDOWPOS_UNDEFINED, .y=SDL_WINDOWPOS_UNDEFINED, .w=640, .h=480 }; Uint32 init_flags = SDL_INIT_TIMER|SDL_INIT_VIDEO; Uint32 win_flags = SDL_WINDOW_SHOWN; Uint32 rend_flags = SDL_RENDERER_ACCELERATED; // | SDL_RENDERER_PRESENTVSYNC; @@ -130,8 +130,8 @@ int addRLitem(render_item_t list[], sprite_t *it, int rlMaxLen) { if (tmp_h < it->size.h) tmp_h = it->size.h; cur++; - if (curr_x >= 1920) { - curr_x=0; + if (curr_x >= 640) { + curr_x = 0; curr_y += tmp_h; tmp_h=0; } @@ -172,10 +172,12 @@ int buildTestRL(gameRess_t *gRess, int rlMaxLen, render_item_t render_list[]) { rlLen=addRLitem(render_list, &gRess->countdown, rlMaxLen); rlLen=addRLitem(render_list, &gRess->cursor, rlMaxLen); + /* No more textues but surface (for custom one time blitting) for (i=0; itiles[i], rlMaxLen); } rlLen=addRLitem(render_list, NULL, rlMaxLen); + */ return rlLen; } -- cgit v1.2.3