summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <lpouzenc@gmail.com>2013-07-21 00:41:15 +0200
committerLudovic Pouzenc <lpouzenc@gmail.com>2013-07-21 00:41:15 +0200
commitbf2391843b679d8919e0a9d054d71e320b9f5afc (patch)
treef22c3ab55e71f2e0d9f0c9f2032053db10a7bea7
parent5d0b6e197f11004753484ad383d66fe0c3588857 (diff)
downloadmplemmings-bf2391843b679d8919e0a9d054d71e320b9f5afc.tar.gz
mplemmings-bf2391843b679d8919e0a9d054d71e320b9f5afc.tar.bz2
mplemmings-bf2391843b679d8919e0a9d054d71e320b9f5afc.zip
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 !
-rw-r--r--src/graphic.c45
-rw-r--r--src/include/data_ini.h8
-rw-r--r--src/include/parser.h1
-rw-r--r--src/loader.c1
-rw-r--r--src/parser.c43
-rw-r--r--src/test/testrender.c13
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; y<ymax; y++) {
for (x=xmin; x<xmax; x++) {
// If we have Upside Down modifier, count lines in reverse order
@@ -180,31 +181,33 @@ int paint_terrain(gameIni_t *gIni, gameRess_t *gRess) {
ydst=gIni->level.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 <SDL_stdinc.h>
-#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);