diff options
author | Ludovic Pouzenc <lpouzenc@gmail.com> | 2013-07-14 20:00:29 +0200 |
---|---|---|
committer | Ludovic Pouzenc <lpouzenc@gmail.com> | 2013-07-14 20:00:29 +0200 |
commit | aebfa9ac4b9eea848ec40f62819ecf743a807b73 (patch) | |
tree | 9d3b74ce189ff13b99c19489ec73d44529fae840 /src/parser.c | |
parent | 893b33145439f68990b29a3aad3f628aede78711 (diff) | |
download | mplemmings-aebfa9ac4b9eea848ec40f62819ecf743a807b73.tar.gz mplemmings-aebfa9ac4b9eea848ec40f62819ecf743a807b73.tar.bz2 mplemmings-aebfa9ac4b9eea848ec40f62819ecf743a807b73.zip |
Ajout de macros pour reduire la redondance.Parsing des fichiers level*.ini commencé.
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 172 |
1 files changed, 137 insertions, 35 deletions
diff --git a/src/parser.c b/src/parser.c index 18924b6..d139436 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,29 +1,65 @@ #include "parser.h" - #include "minIni.h" -/* -long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename); -int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); - -int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); -int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename); +#define MATCH_INT(keysymbol) \ + do { \ + if (SDL_strcasecmp(key,#keysymbol)==0) { \ + data->keysymbol = SDL_atoi(value); \ + return 1; \ + } \ + } while(0) + +#define MATCH_HEXCOLOR(keysymbol) \ + do { \ + if (SDL_strcasecmp(key,#keysymbol)==0) { \ + data->keysymbol = hextext2rgb(value); \ + return 1; \ + } \ + } while(0) + + +#define MATCH_STRING(keysymbol) \ + do { \ + if (SDL_strcasecmp(key,#keysymbol)==0) { \ + data->keysymbol = SDL_strdup(value); \ + return 1; \ + } \ + } while(0) + +#define MATCH_STRING_ARRAY(keysymbol,keysymlen,keyidxmax,outofrangeerrnum) \ + do { \ + if (SDL_strncasecmp(key,#keysymbol,keysymlen)==0 && key[keysymlen]=='_') { \ + int k = atoi(value+keysymlen+1); \ + if (k<0 || k>keyidxmax) { *err=outofrangeerrnum; return 0; } \ + if (data->keysymbol##Count < k) data->keysymbol##Count = k+1; \ + data->keysymbol##s[k] = SDL_strdup(value); \ + return 0; \ + } \ + } while(0) + +#define MATCH_INT_ARRAY_MALLOC(keysymbol,keysymlen,outofrangeerrnum,minval,maxval,valoutofrangeerrnum) \ + do { \ + if (SDL_strncasecmp(key,#keysymbol,keysymlen)==0 && key[keysymlen]=='_') { \ + int k = atoi(value+keysymlen+1); \ + if ( k<0 || k > data->objectCount) { *err=outofrangeerrnum; return 0; } \ + int v = atoi(value); \ + if ( v<minval || v>maxval) { *err=valoutofrangeerrnum; return 0; } \ + data->objects[k].keysymbol = v; \ + } \ + return 0; \ + } while(0) -typedef int (*INI_CALLBACK)(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const void *UserData); -int ini_browse(INI_CALLBACK Callback, const void *UserData, const mTCHAR *Filename); -*/ +int callback_ini_style (const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData); +int callback_ini_levelpack (const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData); +int callback_ini_level_pass1(const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData); +int callback_ini_level_pass2(const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData); +// struct for void *UserData pointer (app context passed to each callback func) typedef struct { int error_code; gameIni_t *ini; } parserState_t; -int callback_ini_style (const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData); -int callback_ini_levelpack (const mTCHAR *Section, const mTCHAR *key, const mTCHAR *value, const void *userData); -int callback_ini_level_pass1(const mTCHAR *Section, const mTCHAR *key, const mTCHAR *value, const void *userData); -int callback_ini_level_pass2(const mTCHAR *Section, const mTCHAR *key, const mTCHAR *value, const void *userData); - - int loadIni(enum ini_type type, const char *filepath, gameIni_t *ini) { int res; parserState_t state; @@ -46,33 +82,37 @@ int loadIni(enum ini_type type, const char *filepath, gameIni_t *ini) { res=ini_browse(callback_ini_level_pass2, UserData, filepath); return state.error_code; } - return -1; // Unreachable + return -1; // should be unreachable } uint32_t hextext2rgb(const char str[]) { int res; unsigned int val; res=SDL_sscanf(str,"0x%x",&val); - // Default value to opaque white. Should be visible on screen if problem here + // Default value to opaque white. Should be visible on screen if problem with that return (res!=1)?0xffffffff:(uint32_t)val; } int callback_ini_style(const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData) { gameIni_t *ini = ((parserState_t*) userData)->ini; + struct styleIni *data = &( ((parserState_t*) userData)->ini->style ); int *err= &(((parserState_t*) userData)->error_code); - // styles/*.ini + MATCH_HEXCOLOR(bgColor); + MATCH_HEXCOLOR(debrisColor); +/* if (SDL_strcasecmp(key,"bgColor")==0) {ini->style.bgColor = hextext2rgb(value); return 1;} if (SDL_strcasecmp(key,"debrisColor")==0) {ini->style.debrisColor = hextext2rgb(value); return 1;} +*/ if (SDL_strcasecmp(key,"particleColor")==0) { char *wordBoundary; int i=0; //((parserState_t*) userData)->need_2pass=1; - while ( strlen(value)>0 && (wordBoundary=strchr(value,',')) != NULL && (i<MAX_PARTICLE_COLORS) ) { + while ( SDL_strlen(value)>0 && (wordBoundary=SDL_strchr(value,','))!=NULL && i<MAX_PARTICLE_COLORS ) { *wordBoundary='\0'; ini->style.particleColor[i++]=hextext2rgb(value); value = wordBoundary+1; @@ -90,6 +130,8 @@ int callback_ini_style(const mTCHAR *section, const mTCHAR *key, const mTCHAR *v return 0; } + MATCH_INT_ARRAY_MALLOC(frames,6,4,0,MAX_OBJECT_FRAMES,5); +/* if (SDL_strncasecmp(key,"frames_", 7) == 0) { int i = atoi(value+7); if ( i<0 || i>=ini->style.objectCount) { *err=4; return 0; } @@ -100,7 +142,9 @@ int callback_ini_style(const mTCHAR *section, const mTCHAR *key, const mTCHAR *v ini->style.objects[i].frames = v; return 0; } - +*/ + MATCH_INT_ARRAY_MALLOC(anim,5,6,0,3,7); +/* if (SDL_strncasecmp(key,"anim_", 5) == 0) { int i = atoi(value+5); if ( i<0 || i>=ini->style.objectCount) { *err=6; return 0; } @@ -111,7 +155,10 @@ int callback_ini_style(const mTCHAR *section, const mTCHAR *key, const mTCHAR *v ini->style.objects[i].anim = v; return 0; } - +*/ + MATCH_INT_ARRAY_MALLOC(type,4,8,0,32,9); + // TODO : TEST outof range : if (! (v==0 || v==32 || (v>=3 && v<=8))) +/* if (SDL_strncasecmp(key,"type_", 5) == 0) { int i = atoi(value+5); if ( i<0 || i>=ini->style.objectCount) { *err=8; return 0; } @@ -122,7 +169,10 @@ int callback_ini_style(const mTCHAR *section, const mTCHAR *key, const mTCHAR *v ini->style.objects[i].type = v; return 0; } +*/ + MATCH_INT_ARRAY_MALLOC(sound,5,10,0,MAX_SOUNDS_COUNT,11); + /* if (SDL_strncasecmp(key,"sound_", 6) == 0) { int i = atoi(value+6); if ( i<0 || i>=ini->style.objectCount) { *err=10; return 0; } @@ -132,34 +182,86 @@ int callback_ini_style(const mTCHAR *section, const mTCHAR *key, const mTCHAR *v ini->style.objects[i].frames = v; return 0; - } - - if (SDL_strncasecmp(key,"frames_", 7) == 0) { - int i = atoi(value+7); - if ( i<0 || i>=ini->style.objectCount) { *err=12; return 0; } - - int v = atoi(value); - if ( v<0 || v>MAX_OBJECT_FRAMES) { *err=13; return 0; } - - ini->style.objects[i].frames = v; - return 0; - } + } + */ // No match is an error (unkown key) *err=1; return -1; } int callback_ini_levelpack(const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData) { - //gameIni_t *ini = ((parserState_t*) userData)->ini; + struct levelPackIni *data = &(((parserState_t*) userData)->ini->levelPack); + int *err= &(((parserState_t*) userData)->error_code); + int i; + + MATCH_STRING(name); + MATCH_INT(maxFallDistance); + MATCH_STRING(codeSeed); + + /* + if (SDL_strcasecmp(key,"name")==0) + { ini->levelPack.name = SDL_strdup(value); return 1;} + if (SDL_strcasecmp(key,"maxFallDistance")==0) + { ini->levelPack.maxFallDistance = SDL_atoi(value); return 1;} + if (SDL_strcasecmp(key,"codeSeed")==0) + { ini->levelPack.codeSeed = SDL_strdup(value); return 1;} + */ + + MATCH_STRING_ARRAY(music,5,MAX_MUSIC_COUNT,22); +/* + if (SDL_strncasecmp(key,"music_", 6) == 0) { + int k = atoi(value+6); + if (k<0 || k>MAX_MUSIC_COUNT) { *err=22; return 0; } + if (ini->levelPack.musicCount < k) ini->levelPack.musicCount=k+1; + ini->levelPack.musics[k] = SDL_strdup(value); + return 0; + } +*/ + if (SDL_strncasecmp(key,"level_", 6) == 0) { + int k = atoi(value+6); + if (k<0 || k>MAX_DIFFICULTY_COUNT) { *err=23; return 0; } + if (data->levelDifficultyCount < k) data->levelDifficultyCount=k+1; + data->levelDifficulty[k] = SDL_strdup(value); + return 0; + } + + // Parse all entries like <difficultyname>_<levelnumber> (ex: tame_0, havoc_5) + for (i=0;i < data->levelDifficultyCount; i++ ) { + char *diffname = data->levelDifficulty[i]; + int len=SDL_strlen(diffname); + if ( (len > 0) && (SDL_strncasecmp(key,diffname,len) == 0) && (key[len] == '_') ) { + //FIXME : checher position de .ini : copier la chaine avant + 4 + //FIXME : chercher , et sscandf de la suite + *err=1; return -1; + } + } // No match is an error (unkown key) *err=1; return -1; } int callback_ini_level_pass1(const mTCHAR *section, const mTCHAR *key, const mTCHAR *value, const void *userData) { //gameIni_t *ini = ((parserState_t*) userData)->ini; + struct levelIni *data = &(((parserState_t*) userData)->ini->level); + int *err= &(((parserState_t*) userData)->error_code); + MATCH_INT(releaseRate); + MATCH_INT(numLemmings); + MATCH_INT(numToRescue); + MATCH_INT(timeLimit); + MATCH_INT(numClimbers); + MATCH_INT(numFloaters); + MATCH_INT(numBombers); + MATCH_INT(numBlockers); + MATCH_INT(numBuilders); + MATCH_INT(numBashers); + MATCH_INT(numMiners); + MATCH_INT(numDiggers); + MATCH_INT(xPos); + MATCH_STRING(style); + MATCH_STRING(name); + // TODO : object/terrain/steel à la main (car struct, et complications) // No match is an error (unkown key) *err=1; return -1; |