summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-17 23:17:30 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2010-11-17 23:17:30 +0000
commit3d1b9d1dce722e9aa7a77ebaf84b19ffc682924c (patch)
tree4574d7a328f3a389157430aa9bcbe629c8632e99 /src
parent61ff7a1b6736109ea1b555f74455a28f38d58cb3 (diff)
download2010-netlemmings-3d1b9d1dce722e9aa7a77ebaf84b19ffc682924c.tar.gz
2010-netlemmings-3d1b9d1dce722e9aa7a77ebaf84b19ffc682924c.tar.bz2
2010-netlemmings-3d1b9d1dce722e9aa7a77ebaf84b19ffc682924c.zip
Modification du parser : 2 passes. 1 pour compter les objets puis malloc, puis 2ème passe pour remplir. Inachevé mais compilable et runnable.
git-svn-id: file:///var/svn/2010-netlemmings/trunk@154 077b3477-7977-48bd-8428-443f22f7bfda
Diffstat (limited to 'src')
-rw-r--r--src/parser/ginit.h66
-rw-r--r--src/parser/parse_ini.yy155
-rw-r--r--src/test/test_parse.c3
3 files changed, 155 insertions, 69 deletions
diff --git a/src/parser/ginit.h b/src/parser/ginit.h
index a769851..1a2661c 100644
--- a/src/parser/ginit.h
+++ b/src/parser/ginit.h
@@ -3,6 +3,53 @@
#include "SDL/SDL.h"
+#define LEVEL_WIDTH (1664*2)
+
+struct styleObjects {
+ int frames, anim, type, sound;
+};
+
+struct style {
+ uint32_t bgColor, debrisColor;
+ int tiles, particleColorCount, objectCount;
+ uint32_t *particleColor;
+ struct styleObjects *objects;
+};
+
+struct skills {
+ int releaseRate, numLemmings, numToRescue, timeLimit;
+ int numClimbers, numFloaters, numBlockers, numBombers, numBuilders, numBashers, numMiners, numDiggers;
+};
+
+// Item should be an object, terrain or steel
+struct levelItem {
+ int id, xpos, ypos; // Common to all types
+ int paintMode, ud; // Specific to objects
+ int modifier; // Specific to terrain
+ int width, height; // Specific to steels
+};
+
+struct level {
+ struct skills initSkills;
+ int xPos;
+ char *style, *name;
+ int superLemming;
+ int objectCount, terrainCount, steelCount;
+ struct levelItem *objects, *terrain, *steel;
+};
+
+struct levelPack {
+ int maxFallDistance;
+ char *codeSeed;
+};
+
+struct gameInit {
+ struct style style;
+ struct level level;
+ struct levelPack levelPack;
+ int firstPass;
+};
+/*
struct colorMap {
Uint32 bgColor;// background color present in "style".ini
Uint32 debrisColor;// debris color present in "style".ini
@@ -58,9 +105,9 @@
#define FLOATER_TO_FALLER 32
#define MAX_LEM_FLOATER 2
- /** a jumper moves up two pixels per frame */
+ // a jumper moves up two pixels per frame
#define MAX_JUMPER_STEP 2
- /** if a walker jumps up 6 pixels, it becomes a jumper */
+ // if a walker jumps up 6 pixels, it becomes a jumper
#define MAX_JUMPER_JUMP 4
#define MAX_BUILD_BRICK 9
#define MAX_BUILD_END 3
@@ -112,14 +159,14 @@
builder , builder_end , digger , basher , miner , jumper ,
died , enter , safe , nuke , bomber_stopper , floater_start
};
-/*
+
char tabString_eLemmingJob[TOTAL_LEM_JOB][20] = {
"walker" , "faller" , "climber" , "climber_to_walker" , "floater" ,
"splat" , "stopper" , "drowning" , "trap_death" , "exIt" , "bomber",
"builder" , "builder_end , digger" , "basher" , "miner" , "jumper",
"died" , "enter" , "safe" , "nuke", "bomber_stopper", "floater_start"
};
-*/
+
struct lemmingMask {
// ID == lemming.ID;
int stateM; // number of state in mask_XX.gif;
@@ -159,13 +206,13 @@
numClimbers,numFloaters,numBombers,numBlockers,numBuilders,
numBashers,numMiners,numDiggers
};
-/*
+
char tabString_eParaMap[IDENT_COUNT][32] = {
"releaseRate","numLemmings","numToRescue","timeLimit",
"numClimbers","numFloaters","numBombers","numBlockers",
"numBuilders","numBashers","numMiners","numDiggers"
};
-*/
+
struct skills {
int releaseRate,numLemmings,numToRescue,timeLimit;
int numClimbers,numFloaters,numBombers,numBlockers,numBuilders,numBashers,numMiners,numDiggers;
@@ -262,14 +309,15 @@
struct steel s; // all DATA of steel on this map;
struct lemming l; // all DATA of lemming on this map;
int parseError;
-/*
+
// 0-13 : BUTTON_LEMMING state button 0: off; 1: on;
// 14 : CURSOR STATE
// 15 : FREE CPT: for all need it ...; default=0;
// 16 : NBR_ENTRY OPEN; default=0;
// 17 : clic on mouse on lemning skill; default=-1;
// 18 : clic on mouse on lemning;default=0;
- int cptGame[NBR_CPT]; // default=0;
-*/
+// int cptGame[NBR_CPT]; // default=0;
};
+
+*/
#endif /*GINIT_H*/
diff --git a/src/parser/parse_ini.yy b/src/parser/parse_ini.yy
index 6045024..5888582 100644
--- a/src/parser/parse_ini.yy
+++ b/src/parser/parse_ini.yy
@@ -1,21 +1,48 @@
%{
-//#include <stdio.h>
+#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <stdint.h>
-//#include <sys/types.h>
-//#include <dirent.h>
#include "ginit.h"
+#define OUT_OF_BOUNDS "out of bounds"
+#define CANNOT_BE_NEGATIVE "cannot be negative"
+#define BAD_VALUE "bad value"
+
+#define MAX_OBJECT_TYPES 32
+#define MAX_OBJECT_FRAMES 64
+#define MAX_SOUNDS_COUNT 32
+#define MAX_NUMLEMMINGS 100
+
extern FILE *yyin;
extern int yylineno;
extern char *yytext;
-
-int yylex();
+extern int yyparse(struct gameInit *gInit);
+
void yyerror(struct gameInit *gInit, char *s);
-void yyassert(int condition, int what, int why);
+void yyassert(int condition, char what[], char why[]);
+int yylex();
+void callocIfNull(void **ptr, size_t nmemb, size_t size) {
+ if (*ptr==NULL && nmemb>0) {
+ *ptr=calloc(nmemb, size);
+ }
+}
+
+void parse(struct gameInit *gInit) {
+ gInit->firstPass=1;
+ yyparse(gInit);
+
+ callocIfNull(&gInit->style.objects, gInit->style.objectCount, sizeof(struct styleObjects));
+ callocIfNull(&gInit->level.objects, gInit->level.objectCount, sizeof(struct levelItem));
+ callocIfNull(&gInit->level.terrain, gInit->level.terrainCount, sizeof(struct levelItem));
+ callocIfNull(&gInit->level.steel, gInit->level.steelCount, sizeof(struct levelItem));
+
+ rewind(yyin);
+ gInit->firstPass=0;
+ yyparse(gInit);
+}
%}
%parse-param { struct gameInit *gInit }
@@ -34,7 +61,6 @@ void yyassert(int condition, int what, int why);
%token AFF
%token VIR
-%token <str> IDENT
%token <str> STR
%token <num> INT
%token <uint32> INTHEX
@@ -49,111 +75,124 @@ ini: /*epsilon*/
| EOL ini
/* styles/...ini */
-decl: BGCOLOR AFF INTHEX { gInit->style.bgColor = $3; }
+decl: BGCOLOR AFF INTHEX { gInit->style.bgColor = $3; }
| DEBRISCOLOR AFF INTHEX { gInit->style.debrisColor = $3; }
-| PARTICLECOLOR AFF particles { gInit->style.particleColor = $3; }
+| PARTICLECOLOR AFF particles {
+ gInit->style.particleColorCount=16;
+ gInit->style.particleColor = $3;
+ }
| TILES AFF INT {
- yyassert($3>0,TILES, CANNOT_BE_NEGATIVE);
+ yyassert($3>0,"tiles", CANNOT_BE_NEGATIVE);
gInit->style.tiles = $3;
- /* check coherence par rapport aux fichiers trouvés */
+ //TODO check coherence par rapport aux fichiers trouvés
}
| FRAMES INT AFF INT {
- yyassert($2>0 && $2<MAX_OBJECT_TYPES, OBJECT_INDEX, OUT_OF_BOUNDS);
- yyassert($4>0 && $4<MAX_OBJECT_FRAMES, FRAMES, OUT_OF_BOUNDS);
- gInit->style.objects[$2].frames = $4;
+ if ( gInit->firstPass==1 ) {
+ yyassert($2>=0 && $2<MAX_OBJECT_TYPES, "frame_ index", OUT_OF_BOUNDS);
+ yyassert($4>0 && $4<MAX_OBJECT_FRAMES, "frame_ value", OUT_OF_BOUNDS);
+ gInit->style.objectCount++;
+ } else {
+ yyassert($2<gInit->style.objectCount, "frame_ index", OUT_OF_BOUNDS);
+ gInit->style.objects[$2].frames = $4;
+ }
}
| ANIM INT AFF INT {
- yyassert($2>0 && $2<MAX_OBJECT_TYPES, OBJECT_INDEX, OUT_OF_BOUNDS);
- yyassert($4>0 && $4<=3, ANIM, BAD_VALUE);
- gInit->style.objects[$2].anim = $4;
+ if ( gInit->firstPass==1 ) {
+ yyassert($2>=0 && $2<MAX_OBJECT_TYPES, "anim_ index", OUT_OF_BOUNDS);
+ yyassert($4>=0 && $4<=3, "anim_ value", BAD_VALUE);
+ } else {
+ yyassert($2<gInit->style.objectCount, "anim_ index", OUT_OF_BOUNDS);
+ gInit->style.objects[$2].anim = $4;
+ }
}
| TYPE INT AFF INT {
- yyassert($2>0 && $2<MAX_OBJECT_TYPES, OBJECT_INDEX, OUT_OF_BOUNDS);
- yyassert($4==0|$4==32|($4>=3 && $4<=8), TYPE; BAD_VALUE);
- gInit->style.objects[$2].type = $4;
+ yyassert($2>=0 && $2<MAX_OBJECT_TYPES, "type_ index", OUT_OF_BOUNDS);
+ yyassert($4==0 || $4==32 || ($4>=3 && $4<=8), "type_ value", BAD_VALUE);
+// gInit->style.objects[$2].type = $4;
}
| SOUND INT AFF INT {
- yyassert($2>0 && $2<MAX_OBJECT_TYPES, OBJECT_INDEX, OUT_OF_BOUNDS);
- yyassert($4>=-1 && $4<=MAX_SOUNDS_COUNT, SOUND, OUT_OF_BOUNDS);
- gInit->style.objects[$2].sound = $4;
+ yyassert($2>=0 && $2<MAX_OBJECT_TYPES, "sound_ index", OUT_OF_BOUNDS);
+ yyassert($4>=-1 && $4<=MAX_SOUNDS_COUNT, "sound value", OUT_OF_BOUNDS);
+// gInit->style.objects[$2].sound = $4;
}
/*lvl_xxxx.ini*/
| RELEASERATE AFF INT {
- yyasert($3>=0 && $3<=99, RELEASERATE, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.releaseRate = $3;
+ yyassert($3>=0 && $3<=99, "releaseRate", OUT_OF_BOUNDS);
+ gInit->level.initSkills.releaseRate = $3;
}
| NUMLEMMINGS AFF INT {
- yyasert($3>=0 && $3<=99, NUMLEMMINGS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numLemmings = $3; }
+ yyassert($3>=0 && $3<=MAX_NUMLEMMINGS, "numLemmings", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numLemmings = $3; }
| NUMTORESCUE AFF INT {
- yyasert($3>=0 && $3<=99, NUMTORESCUE, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numToRescue = $3;
+ yyassert($3>=0 && $3<=99, "numToRescue", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numToRescue = $3;
}
| TIMELIMIT AFF INT {
- yyasert($3>=0 && $3<=99, TIMELIMIT, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.timeLimit = $3;
+ yyassert($3>=0 && $3<=99, "timeLimit", OUT_OF_BOUNDS);
+ gInit->level.initSkills.timeLimit = $3;
}
| NUMCLIMBERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMCLIMBERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numClimbers = $3;
+ yyassert($3>=0 && $3<=99, "numClimbers", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numClimbers = $3;
}
| NUMFLOATERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMFLOATERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numFloaters = $3;
+ yyassert($3>=0 && $3<=99, "numFloaters", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numFloaters = $3;
}
| NUMBOMBERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMBOMBERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numBombers = $3;
+ yyassert($3>=0 && $3<=99, "numBombers", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numBombers = $3;
}
| NUMBLOCKERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMBLOCKERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numBlockers = $3;
+ yyassert($3>=0 && $3<=99, "numBlockers", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numBlockers = $3;
}
| NUMBUILDERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMBUILDERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numBuilders = $3;
+ yyassert($3>=0 && $3<=99, "numBuilders", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numBuilders = $3;
}
| NUMBASHERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMBASHERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numBashers = $3;
+ yyassert($3>=0 && $3<=99, "numBashers", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numBashers = $3;
}
| NUMMINERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMMINERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numMiners = $3;
+ yyassert($3>=0 && $3<=99, "numMiners", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numMiners = $3;
}
| NUMDIGGERS AFF INT {
- yyasert($3>=0 && $3<=99, NUMDIGGERS, OUT_OF_BOUNDS);
- gInit->mapI.initSkills.numDiggers = $3;
+ yyassert($3>=0 && $3<=99, "numDiggers", OUT_OF_BOUNDS);
+ gInit->level.initSkills.numDiggers = $3;
}
| XPOS AFF INT {
- yyasert($3>=0 && $3<=LEVEL_WITDH, XPOS, OUT_OF_BOUNDS);
- gInit->mapI.xPos = $3;
+ yyassert($3>=0 && $3<=LEVEL_WIDTH, "xPos", OUT_OF_BOUNDS);
+ gInit->level.xPos = $3;
}
-| STYLE AFF STR { gInit->mapI.map.style = $3; }
-| SLEM AFF STR { gInit->mapI.map.superLemming = strcasecmp("true", $3)==0; }
+| STYLE AFF STR { gInit->level.style = $3; }
+| SLEM AFF STR { gInit->level.superLemming = strcasecmp("true", $3)==0; }
| OBJECT INT AFF INT VIR INT VIR INT VIR INT VIR INT {}
| TERRAIN INT AFF INT VIR INT VIR INT VIR INT {}
| STEEL INT AFF INT VIR INT VIR INT VIR INT {}
-| NAME AFF STR { gInit->mapI.name = $3; } /* TODO : attention, si fichier levelpack, name n'est pas le nom d'unniveau */
+| NAME AFF STR { gInit->level.name = $3; } /* TODO : attention, si fichier levelpack, name n'est pas le nom d'unniveau */
/* levelpack.ini */
| MAXFALLDISTANCE AFF INT {
- gInit->mapI.maxFallDistance = $3;
+ yyassert($3>=0, "maxFallDistance", OUT_OF_BOUNDS);
+ gInit->levelPack.maxFallDistance = $3;
}
-| CODESEED AFF STR {}
-| MUSIC INT AFF STR {}
+| CODESEED AFF STR { gInit->levelPack.codeSeed = $3; }
+| MUSIC INT AFF STR { }
| LEVEL INT AFF STR {}
-| IDENT INT AFF STR VIR INT {}
+| DIFFICULTY INT AFF STR VIR INT {}
particles: INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX VIR INTHEX {
$$=malloc(16*sizeof(uint32_t));
$$[0]=$1; $$[1]=$3; $$[2]=$5; $$[3]=$7; $$[4]=$9; $$[5]=$11; $$[6]=$13; $$[7]=$15 ;$$[8]=$17; $$[9]=$19; $$[10]=$21; $$[11]=$23; $$[12]=$25; $$[13]=$27; $$[14]=$29; $$[15]=$31;
}
%%
-void yyassert(int condition, int what, int why) {
+void yyassert(int condition, char what[], char why[]){
char msg[256];
if (!condition) {
- sprintf(msg, "%s for %s", errors[why], items[what]);
+ sprintf(msg, "%s for %s", why, what);
yyerror(NULL, msg);
}
}
diff --git a/src/test/test_parse.c b/src/test/test_parse.c
index 50ee80d..62c71bd 100644
--- a/src/test/test_parse.c
+++ b/src/test/test_parse.c
@@ -5,7 +5,6 @@
#include "../parser/ginit.h"
extern FILE *yyin;
-extern int yyparse(struct gameInit *gInit);
int main(int argc, char **argv) {
char *filepath=NULL;
@@ -28,7 +27,7 @@ int main(int argc, char **argv) {
}
memset(&gInit,0,sizeof(gInit));
printf("Parsing '%s'\n", filepath);
- yyparse(&gInit);
+ parse(&gInit);
// printf("End of parse ('%s')\n", filepath);
fclose(yyin);