//Ne pas traduire

/*char *declaration="//%file%\n//Converti avec GBA Graphics par Brünni\n//Bitmap 16 bits\n//Taille: %sizex%*%sizey%\n//Mémoire: %memory% octets\n\nconst unsigned short %name%_bitmap16[%size%]=	{\n";
int nbChaqueX=8;
char *chaque_x="\b\n";
char *chaque_valeur="0x%04x, ";
char *fin_ligne="\b\n";
char *fin_declaration="\b\b\n};\n\n\n";*/

//bitmap16
char *b16_declaration="//%file%\r\n//Converti avec %user2% par Brünni\r\n//Bitmap 16 bits\r\n//Taille: %sizex%*%sizey%\r\n//Mémoire: %memory% octets\r\n\r\nconst unsigned short %name%_bitmap16[%sizey%][%sizex%]=	{\r\n";
int b16_nbChaqueX=8;
char *b16_chaque_x="\b\r\n";
char *b16_chaque_valeur="0x%04x, ";
char *b16_fin_ligne="\b\r\n";
char *b16_fin_declaration="\b\b};\r\n";
char *b16_def_ext=".b16.c";

//bitmap8
char *b8_declaration="//%file%\r\n//Converti avec GBA Graphics par Brünni\r\n//Bitmap 8 bits (\"%link%\")\r\n//Taille: %sizex%*%sizey%\r\n//Mémoire: %memory% octets\r\n\r\nconst unsigned char %name%_bitmap8[%sizey%][%sizex%]=	{\r\n";
int b8_nbChaqueX=12;
char *b8_chaque_x="\b\r\n";
char *b8_chaque_valeur="0x%02x, ";
char *b8_fin_ligne="";
char *b8_fin_declaration="\b\b};\r\n";
char *b8_def_ext=".b8.c";

/*//palette
char *pal_declaration="//%file%\n//Palette (%memory% octets)\n\nconst unsigned short %name%_palette[%size%]=	{\n";
int pal_nbChaqueX=8;
char *pal_chaque_x="\b\n";
char *pal_chaque_valeur="0x%04x, ";
char *pal_fin_ligne="\b\n";
char *pal_fin_declaration="\b\b\n};\n\n\n";*/

//palette
char *pal_declaration="//%file%\r\n//Converti avec GBA Graphics par Brünni\r\n//Palette\r\n//Taille: %size%\r\n//Mémoire: %memory% octets\r\n\r\nconst unsigned short %name%_palette[%size%]=	{\r\n";
int pal_nbChaqueX=8;
char *pal_chaque_x="\b\r\n";
char *pal_chaque_valeur="0x%04x, ";
char *pal_fin_ligne="\b\r\n";
char *pal_fin_declaration="\b\b};\r\n";
char *pal_def_ext=".pal.c";


//tileset
//char *til_declaration="//%file%\r\n//Converti avec GBA Graphics par Brünni\r\n//Tileset %+if=(%(\"%link%\")%+else%%depth% bits (\"%link%\")%+end%\r\n//Taille: %tilex%*%tiley%*%size%\r\n//Mémoire: %memory% octets\r\n\r\nconst unsigned %type% %name%_tiles[%memory%]=	{\r\n";
char *til_declaration="//%file%\r\n//Converti avec GBA Graphics par Brünni\r\n//Tileset %+if<>(%%depth% bits (\"%link%\")%+else%(\"%link%\")%+end%\r\n//Taille: %tilex%*%tiley%*%size%\r\n//Mémoire: %memory% octets\r\n\r\nconst unsigned %type%%user[2]% %name%_tiles[%memory%]=	{\r\n";
int til_nbChaqueX=12;
char *til_chaque_x="\b\r\n";
char *til_chaque_valeur_1="0x%02x, ";
char *til_chaque_valeur_2="0x%02x, ";
char *til_chaque_valeur_3="0x%04x, ";
char *til_fin_ligne="";
char *til_fin_declaration="\b\b};\r\n";
char *til_def_ext=".til.c";


//map
//char *map_declaration="//%file%\r\n//Converti avec GBA Graphics par Brünni\r\n//Map (\"%null%\",\"%link%\"%+if=,%,%tilebase%%+if=,%,%$gfxmask%)%+else%)%+end%\r\n//Taille: %tilex%*%tiley% * %sizex%*%sizey%\r\n//Mémoire: %memory% octets\r\n%+if<>c%\r\nc%+else%c%+endif%onst unsigned %type% %name%_map[%sizey%][%sizex%]=	{\r\n	{";
char *map_declaration="//%file%\r\n//Converti avec GBA Graphics par Brünni\r\n//Map (\"%null%\",\"%link%\"%+if=,%,%tilebase%,%$gfxmask%)%+else%)%+end%\r\n//Taille: %tilex%*%tiley% * %sizex%*%sizey%\r\n//Mémoire: %memory% octets\r\n%+if<>c%\r\nc%+else%c%+endif%onst unsigned %type% %name%_map[%sizey%][%sizex%]=	{\r\n	{";
int map_nbChaqueX=8;
char *map_chaque_x="\b\r\n";
char *map_chaque_valeur_1="0x%04x, ";
char *map_chaque_valeur_2="0x%02x, ";
char *map_chaque_valeur_3="0x%08x, ";
char *map_fin_ligne="\b\b},\r\n	{";
char *map_fin_declaration="\b\b\b\b\b\r\n};\r\n";
char *map_def_ext=".map.c";

//Liste
char *lst_declaration="//%file%\r\n//Converti avec GBA Graphics par Brünni\r\n//Liste (\"%link%\"%+if=,%, \"%model%\")%+else%)%+end%\r\n//Taille: %tilex%*%tiley%\r\n//Mémoire: %memory% octets\r\n\r\n%user[1]%\r\n\r\nconst unsigned int %name%_liste_nbEle=%size%;\r\n\r\nconst %type% %name%_liste[]=	{";
int lst_nbChaqueX=0;
char *lst_chaque_x="";
char lst_chaque_valeur_ok[1000];
//ATTENTION: Modifié ailleurs dans le cas par défaut. #+param:"texte_avant":"texte_après"#
char *lst_chaque_valeur="\r\n	{#type#,#x#,#y##+param:\",\":\"\"#},";
//char *lst_chaque_valeur="\r\n	{#type#,#x#,#y#,#\"<test>\"#},";
char *lst_fin_ligne="";
char *lst_fin_declaration="\r\n};\r\n";
char *lst_def_ext=".lst.c";

//divers
char *type8="char";
char *type16="short";
char *type32="long";
/*char *tileset4="4 bits ";
char *tileset8="";
char *tileset16="16 bits ";*/
char *typesd="SPRITE_LISTE";
char *defUserData[NB_MAX_USERDATA]=		{
	"#include \"def.h\"",
	"",
	"",
	"",
	//4
	"",
	"",
	"",
	"",
};

//Pour le recouvrement des données, essaie de retrouver son chemin si au moins 4 caractères sont identiques
int comparemin=4;
int bLectureNoError=0;


//1 Mo pour les définitions de format, je pense que ce sera suffisant ;)
#define MAX_DONNEES_FORMAT (1<<20)


int nb_sections=0;

typedef struct			{
	char 	nom[100];
	char *	donnees;

	char *	ptrs[NBRE_PTRS_FORMATS][9];

	char *	plus[6];

	char *	user[NB_MAX_USERDATA];
} FORMAT_SORTIE;

#define MAX_SECTIONS 100
FORMAT_SORTIE formats[MAX_SECTIONS];
void DefFormat(FORMAT_SORTIE *f);
void myprintf(FILE *f, char *format, int valeur);
int ProchaineBalise(char *chaine, int i, char *balise, int longeur);
void LitFormat(FORMAT_SORTIE *f);
FORMAT_SORTIE *ptr_formatActuel=NULL;

typedef struct			{
	char *nom;
	void *donnees;
	int type;
} SYMBOLE;

SYMBOLE symboles[]=		{
	//0
	{"file",NULL,TYPE_CHAINE},
	{"sizex",&tailleX,TYPE_ENTIER},
	{"sizey",&tailleY,TYPE_ENTIER},
	//3
	{"size",NULL,TYPE_ENTIERDIRECT},
	{"memory",NULL,TYPE_ENTIERDIRECT},
	{"name",NULL,TYPE_CHAINE},
	//6
	{"link",NULL,TYPE_CHAINE},
	{"tilex",&tileX,TYPE_ENTIER},
	{"tiley",&tileY,TYPE_ENTIER},
	//9
	{"depth",NULL,TYPE_ENTIERDIRECT},
	{"type",NULL,TYPE_CHAINE},
	{"null",NULL,TYPE_CHAINE},
	//12
	{"bits",NULL,TYPE_CHAINE},
	{"gfxmask",&gfxmask,TYPE_ENTIER},
	{"tilebase",&blocBase,TYPE_ENTIER},
	//15
	{"model",NULL,TYPE_CHAINE},
};

//Traduction possible

SYMBOLE *symcopie;

void CopieSymTable()		{
	symcopie=(SYMBOLE*)malloc(sizeof(symboles));

	memcpy(symcopie,symboles,sizeof(symboles));
}

void ReinitSymTable()			{
	memcpy(symboles,symcopie,sizeof(symboles));
}

//1=lecture, 0=écriture, 2=écriture à partir de rien
void PrepareSymTable(int lecture)			{
	int i;
	if (lecture)		{
		for (i=0;i<NB_MAX_USERDATA;i++)
			strcpy(gblUserData[i], defUserData[i]);
	}
}

#define InitSymbole(nSym,valeur)			symboles[nSym].donnees=(void*)(valeur)

void FEcritBinaire(FILE *dest, void *source, int nombre)			{
	int val;

	if (nombre==1)
		val=(int)(*(char*)source);
	else if (nombre==2)
		val=(int)(*(short*)source);
	else if (nombre==4)
		val=(int)(*(long*)source);
	else		{
		Debug("Erreur de typage binaire (%i)",nombre);
		return;
	}

	val=fwrite(&val,nombre,1,dest);
}

void LitSymbole(FILE *f, char *symbole)			{
	int i, mode=0, nb=0;

	if (*symbole=='$')		{
		mode=1;
		symbole++;
	}
	else if (*(symbole+1)>='0' && *(symbole+1)<='9' && *symbole=='#')		{
		mode=2;
		nb=*(symbole+1)-'0';
		symbole+=2;
	}
	if (!strncmp(symbole, "user[", 5))		{
		symbole+=5;
		i=*symbole-'1';
		if (i<NB_MAX_USERDATA)
			fputs(gblUserData[i],f);
	}

	for (i=0;i<sizeof(symboles)/sizeof(symboles[0]);i++)
		if (!strcmp(symbole,symboles[i].nom) && (symboles[i].donnees!=NULL || symboles[i].type==TYPE_ENTIER || symboles[i].type==TYPE_ENTIERDIRECT))			{
			if (symboles[i].type==TYPE_CHAINE)			{
				fputs((char*)symboles[i].donnees,f);
				break;
			}
			else if (symboles[i].type==TYPE_ENTIER)			{
				if (mode==0)
					sprintf(str,"%i",*(int*)symboles[i].donnees);
				else if (mode==1)
					sprintf(str,"%x",*(int*)symboles[i].donnees);
				else		{
					FEcritBinaire(f,(int*)symboles[i].donnees,nb);
					break;
				}
				fputs(str,f);
				break;
			}
			else if (symboles[i].type==TYPE_ENTIERDIRECT)			{
				if (mode==0)
					sprintf(str,"%i",(int)symboles[i].donnees);
				else if (mode==1)
					sprintf(str,"%x",(int)symboles[i].donnees);
				else		{
					FEcritBinaire(f,(int*)&symboles[i].donnees,nb);
					break;
				}
				fputs(str,f);
				break;
			}
		}

	return;
}

void EcritBinaire(void *source, int *dest, int nombre)			{
	if (nombre==1)
		*dest=(int)(*(char*)source);
	else if (nombre==2)
		*dest=(int)(*(short*)source);
	else if (nombre==4)
		*dest=(int)(*(long*)source);
	else
		Debug("Erreur de typage binaire");
}

char *EcritSymbole(char *symbole, char *valeur)			{
	int i;
	int mode=0, nb;

	if (*symbole=='$')		{
		mode=1;
		symbole++;
	}
	else if (*(symbole+1)>='0' && *(symbole+1)<='9' && *symbole=='#')		{
		mode=2;
		nb=*(symbole+1)-'0';
		symbole+=2;
	}

	if (!strncmp(symbole, "user[", 5))		{
		symbole+=5;
		i=*symbole-'1';
		if (i<NB_MAX_USERDATA)
			strcpy(gblUserData[i],valeur);
	}

	for (i=0;i<sizeof(symboles)/sizeof(symboles[0]);i++)		{
		if (!strcmp(symbole,symboles[i].nom) && !(symboles[i].donnees==NULL && symboles[i].type!=TYPE_ENTIERDIRECT && symboles[i].type!=TYPE_ENTIER))			{
			if (symboles[i].type==TYPE_CHAINE)
				strcpy((char*)symboles[i].donnees,valeur);
			else if (symboles[i].type==TYPE_ENTIER)			{
				if (mode==0)
					*(int*)symboles[i].donnees=atoi(valeur);
				else if (mode==1)
					*(int*)symboles[i].donnees=atox(valeur);
				else
					EcritBinaire((void*)valeur,(int*)symboles[i].donnees,nb);
			}
			else if (symboles[i].type==TYPE_ENTIERDIRECT)			{
				if (mode==0)
					symboles[i].donnees=(void*)atoi(valeur);
				else if (mode==1)
					symboles[i].donnees=(void*)atox(valeur);
				else
					EcritBinaire((void*)valeur,(int*)&symboles[i].donnees,nb);
			}
		}
	}

	return NULL;
}


void EcritChaineFiltree(char *chaine, FILE *f)			{
	char *ptr=chaine;
	char variable[1000];
	int i;

	while(*ptr)			{
		if (*ptr=='\b')
			fseek(f,-1,SEEK_CUR);
		else if (*ptr=='%')		{
			i=0;
			ptr++;
			while(*ptr && *ptr!='%' && i<sizeof(variable)-1)
				variable[i++]=*ptr++;
			variable[i]=0;

			if (variable[0]=='+')			{			//Directive
				if (!strcmp(variable,"+else"))
					ptr+=ProchaineBalise(ptr,0,"end",3)-1;
			}
			else
				LitSymbole(f,variable);
		}
		else									//Caractère normal
			fputc(*ptr,f);
		ptr++;
	}
}


//Taille du tampon temporaire pour les fichiers = 4 Mo
#define TAILLE_MAXIMUM (8<<20)

int taille_totale;

/*int mymemcmp(char *buf1, char *buf2, int taille)		{
	for(*buf2!='%' && *buf2;buf1++, buf2++)
		if (*buf1!=*buf2)
			return 1;

	return 0;
}*/

int GereIf(char *bloc, int j, char *variable)			{
	char chaine[100];
	int i, op;

	if (*variable=='=')				{
		op='=';
		variable++;
egalite:
		i=0;
		while(*variable && i<sizeof(chaine)-1)
			chaine[i++]=*variable++;
		chaine[i]=0;
		if (op=='=')
			return !(strncmp(bloc+j,chaine,i));
		else
			return strncmp(bloc+j,chaine,i);
	}
	else if (*variable=='<' && *(variable+1)=='>')			{
		op='/';
		variable+=2;
		goto egalite;
	}

	return 0;
}

int ProchaineBalise(char *chaine, int i, char *balise, int longeur)			{
	int niveau=1;

	while(niveau>0 && chaine[i])			{
		if (chaine[i]=='%' && chaine[i+1]=='+')			{
			if (!strncmp(chaine+i+2,balise,longeur))
				niveau--;
//			else
//				niveau++;
			i+=2;
			while(chaine[i]!='%' && chaine[i])
				i++;
			i++;
		}
		else
			i++;
	}

	return i;
}

int LitChaineFiltree(int j, char *bloc, char *chaine, FILE *f)			{
	char *ptr=chaine;
	int taille_chaine=strlen(chaine);
	char variable[1000], chne[1000];
	int i,temp,temp2,nb, niveau=0;

	i=0;
	while(chaine[i]!='%' && chaine[i])
		i++;

	temp=0;
	while(chaine[temp]=='\b')
		i--, temp++;

	while(memcmp(bloc+j,chaine+temp,i) && j+i<taille_totale)
		j++;

	i=temp;

	while(1)			{

		temp=i, temp2=j;
		while(chaine[i]!='%' && chaine[i])
			i++, j++;

		if (!chaine[i])
			break;

		if (!memcmp(bloc+temp2,chaine+temp,i-temp))			{
			i++;
			temp=0;
			while(chaine[i]!='%' && chaine[i] && j<taille_totale && temp<sizeof(variable)-1)
				variable[temp++]=chaine[i++];
			variable[temp]=0;
			i++;

			if (variable[0]=='+')		{
				niveau=1;
				if (!strncmp(variable+1,"noerror",7))			{
					bLectureNoError = 1;
				}
				else if (!strncmp(variable+1,"endnoerror",10))			{
					bLectureNoError = 0;
				}
				else if (!strncmp(variable+1,"if",2))			{
					if (GereIf(bloc,j,variable+3))			{
						continue;
					}
					else	{
						niveau--;
						i=ProchaineBalise(chaine,i,"else",4);
					}
				}
				else if (!strncmp(variable+1,"else",4))			{
					i=ProchaineBalise(chaine,i,"end",3);
				}
			}

			temp=i;
			while(chaine[i]!='%' && chaine[i] && i<taille_chaine)
				i++;

			//Ce cas signifie que deux variables sont collées (%sizex%%sizey% par exemple). Il va falloir tenter
			//de déterminer la fin de la variable dans la chaîne, sachant si c'est un entier ou autre.
/*			if (i-temp==0)
				Debug("ICI");*/

			temp2=j;

			while(memcmp(bloc+j,chaine+temp,i-temp) && j+(i-temp)<taille_totale)
				j++;

			if (j+(i-temp)>=taille_totale)			{
				if (!bLectureNoError)
					Debug("Tente de recouvrer d'une erreur fatale de lecture...");
				for(;*(chaine+temp);temp++)		{
					j=temp2;
					if (*(chaine+temp)=='%')		{
						temp++;
						while(*(chaine+temp)!='%' && *(chaine+temp))
							temp++;
						if (*(chaine+temp))
							temp++;
						i=temp;
						while(chaine[i]!='%' && chaine[i] && i<taille_chaine)
							i++;
						i-=1;
					}
					//Comparer avec au moins comparemin caractères
					while(memcmp(bloc+j,chaine+temp,i-temp) && j+(i-temp)<taille_totale && i-temp>=comparemin)
						j++;
					if (j+(i-temp)<taille_totale && i-temp>=comparemin)
						break;
				}
				i=temp;
//				goto ici;
//				Debug("Erreur de format de fichier");
//				return taille_totale+1;
			}

			//Impossible de trouver le nombre
			if (j-temp2==0)		{
				if (variable[0]=='#')		{
					nb=variable[1]-'0';						//Taille des données (octets)
					EcritSymbole(variable,bloc+temp2);
					j+=nb;
				}
				if (chaine[i]==0)		{
					j+=i-temp;
					break;
				}
/*				else	{
					Debug("Mis à part dans le cas des fichiers binaires, les spécifications de format ne peuvent se terminer par une variable seule...");
				}*/
			}
			else	{
				if (chaine==lst_declaration)		{
					j=j+1;
					j=j-1;
				}
				memcpy(chne,bloc+temp2,j-temp2);
				chne[j-temp2]=0;
				EcritSymbole(variable,chne);
			}

//			Debug("%s=%s",variable,chne);

			i=temp;
		}
		else		{
			Debug("Le format du fichier ne correspond pas avec celui attendu.");
			return taille_totale+1;
		}
	}
	return j;
}


int myscanf(char *base, char *format, int *valeur)			{
	char *basesauv;
	int nbre=0, temp, complete, nombre;

	while(1)			{
		if (*format=='%')		{
			basesauv=base;

			format++;

			complete=0;

			if (*format=='0')			{
				complete=*format++;
				nombre=(*format++)-'0';
			}
			else if (*format>='1' && *format<='9')
				nombre=(*format++)-'0';


			if (*format=='i' || *format=='x' || *format=='X')			{
				while((*base>='0' && *base<='9') || (*base>='a' && *base<='f' && *format=='x') || (*base>='A' && *base<='F' && *format=='X'))
					base++, nbre++;

				temp=*base;
				*base=0;
				
				if (*format=='i')
					*valeur=atoi(basesauv);
				else if (*format=='x')
					*valeur=atox(basesauv);
				else
					Debug("Erreur de conversion");

				*base=temp;
			}
			else if (*format=='b')		{
				if (nombre==1)
					*valeur=(int)(*(char*)base);
				else if (nombre==2)
					*valeur=(int)(*(short*)base);
				else if (nombre==4)
					*valeur=(int)(*(long*)base);
				else
					Debug("Erreur de typage binaire");

				base+=nombre;
				nbre+=nombre;
			}


			format++;
		}
		else if (*base==*format && *base)
			base++, format++, nbre++;
		else
			break;
	}

	return nbre;
}


void EcritValeurBinaire(FILE *f, void *valeur, int nbreOctets)			{
	if (nbreOctets==1)
		fwrite((char*)valeur,sizeof(char),1,f);
	else if (nbreOctets==2)
		fwrite((short*)valeur,sizeof(short),1,f);
	else if (nbreOctets==4)
		fwrite((long*)valeur,sizeof(long),1,f);
	else
		Debug("Erreur de type binaire (%%1b, %%2b, %%4b seulement)");
}



void myprintf(FILE *f, char *format, int valeur)			{
//	return sprintf(base,format,valeur);
	int complete, nombre;
	char *formatbase, tmpchne[100], str[100];

	while(*format)			{
		if (*format=='%')		{
			formatbase=format;

			format++;

			complete=0;

			if (*format=='0')			{
				complete=*format++;
				nombre=(*format++)-'0';
			}
			else if (*format>='1' && *format<='9')
				nombre=(*format++)-'0';

			if (*format=='i' || *format=='x' || *format=='X')			{
				memcpy(tmpchne,formatbase,format-formatbase+1);
				tmpchne[format-formatbase+1]=0;
				sprintf(str,tmpchne,valeur);
				fputs(str,f);
			}
			else if (*format=='b')
				EcritValeurBinaire(f,&valeur,nombre);

			format++;
		}
		else
			fputc(*format++,f);
	}

	return;
}

int LitValeur(int j, char *bloc, char *chaine, FILE *f, int *valeur)			{
	int i,k;

	k=myscanf(bloc+j,chaine,&i);

	if (k==0)
		return taille_totale+1;

	j+=k;
	*valeur=i;

	return j;
}


#define SAUTE_ESPACES(ptr)	 { while(*ptr==' ' || *ptr=='	') ptr++; }

int section=0;
char *flux;

char *InscritFlux(char *chne)			{
	char *fluxbase=flux;
	while(*chne)
		*flux++=*chne++;
	*flux++=0;
	return fluxbase;
}


char *InscritChaineFlux(char *chne)			{
	char *fluxbase = flux, *fin;
	fin = GetCopieChaine(flux, chne, MAX_S32);
	flux = flux + (fin-chne);
	return fluxbase;
}


void DefSection(char *nom)			{
	int i;
	char *sections_en[]={"bitmap16","bitmap8","palette","tileset","map","list"};
	char *sections_fr[]={"bitmap16","bitmap8","palette","tileset","map","liste"};

	for (i=0;i<sizeof(sections_en)/sizeof(sections_en[0]);i++)			{
		if (!strcmp(nom,sections_en[i]) || !strcmp(nom,sections_fr[i]))
			section=i;
	}
}

void DefChamp(char *champ, char *texte)			{
	int i, valeur=-1;
	//Ne pas traduire
	char *lookup_numero_en[]={"declaration","n_every","every_x","element","element2","element3","line","end","ext",
							"type8","type16","type32","bits4","bits8","typesd"};
	char *lookup_numero_fr[]={"declaration","n_chaque","chaque_x","element","element2","element3","ligne","fin","ext",
							"type8","type16","type32","bits4","bits8","typesd"};
	//Traduction possible

	if (!strncmp(champ, "user[", 5))			{
		champ+=5;
		i=*champ-'1';
		if (i<NB_MAX_USERDATA)
			formats[gblCurSection].user[i]=InscritChaineFlux(texte);
	}
	else	{
		for (i=0;i<sizeof(lookup_numero_en)/sizeof(lookup_numero_en[0]);i++)			{
			if (!strcmp(lookup_numero_en[i],champ) || !strcmp(lookup_numero_fr[i],champ))
				valeur=i;
		}
	}

	if (valeur==-1)
		return;

	if (valeur>=0 && valeur<9)			{
		if (section==-1)			{
			Debug("Définition de champ rencontrée hors de toute section (%s=%s)",champ,texte);
			return;
		}
		if (valeur==1)
			formats[gblCurSection].ptrs[section][valeur]=(char*)atoi(texte);
		else
			formats[gblCurSection].ptrs[section][valeur]=InscritChaineFlux(texte);
	}
	else if (valeur>=9 && valeur<15)
		formats[gblCurSection].plus[valeur-9]=InscritChaineFlux(texte);
}


void LitFiltre(FILE *f, char *nom_format)			{
	char str[4096], nom[100], *ptr;
	int i, commande;

	for (i=0;i<nb_sections;i++)
		if (!strcmp(formats[i].nom, nom_format))
			break;
	if (i>=nb_sections)		{

		gblCurSection=nb_sections;
		LitFormat(&formats[gblCurSection]);
		strcpy(formats[gblCurSection].nom,nom_format);
	}
	else	{
		gblCurSection = i;
	}
	//Le flux n'existe pas encore
	if (!formats[gblCurSection].donnees)			{
		flux=(char*)malloc(MAX_DONNEES_FORMAT);
		formats[gblCurSection].donnees=flux;
	}
	section=-1;

	while(1)			{
		fgets(str,sizeof(str),f);

		//Pré-analyse de la chaîne
		for (ptr=str;*ptr;ptr++)			{
			//Conversion en minuscules (lettres majuscules & accentuées).
			if ((*ptr>='A' && *ptr<='Z') || (*ptr>=192 && *ptr<=221))
				*ptr|=32;

			if (*ptr=='	')									//Tab -> espace, pour éviter des embêtements inutiles
				*ptr=' ';
			else if (*ptr=='#' || *ptr=='\n')		{		//Commentaire ou fin de ligne
				*ptr=0;										//=Fin de la chaîne
				break;
			}
			else if (*ptr=='\"')			{				//Ne pas toucher aux chaînes!
				ptr++;
				while(*ptr && (*ptr!='\"' || (*ptr=='\"' && *(ptr-1)=='\\')))					//Jusqu'à la fin de celle-ci
					ptr++;
				ptr++;
			}
			else if (*ptr=='\'')			{				//Ne pas toucher aux chaînes!
				ptr++;
				while(*ptr && (*ptr!='\'' || (*ptr=='\'' && *(ptr-1)=='\\')))					//Jusqu'à la fin de celle-ci
					ptr++;
				ptr++;
			}
		}

		ptr=str;
		SAUTE_ESPACES(ptr);									//Pour sauter l'indentation

		i=0;
		//Normalement, au début de la ligne devrait se trouver le nom de champ, comme par exemple dans "i=0" et "i {".
		while(((*ptr>='a' && *ptr<='z') || (*ptr>='0' && *ptr<='9') || *ptr=='_' || *ptr=='[' || *ptr==']') && i<sizeof(nom)-1)
			nom[i++]=*ptr++;

		nom[i]=0;												//Termine la chaîne

		SAUTE_ESPACES(ptr);

		if (*ptr=='=')										//Assignement demandé
			commande=1;
		else if (*ptr=='{')									//Définition d'un champ
			commande=2;
		else if (*ptr=='}')				{					//Fin de section
			if (section>=0)									//Fermeture de la section
				section=-1;
			else											//Fin de la définition
				break;
			commande=0;
		}
		else if (*ptr==0)
			continue;
		else
			Debug("Caractère inattendu: %c",*ptr);

		ptr++;
		SAUTE_ESPACES(ptr);									//On devrait pointer sur la chaîne définie.

		if (commande==1)		{
			DefChamp(nom,ptr);
		}
		else if (commande==2)		{
			DefSection(nom);
		}

	}
	
//	DefFormat(&formats[nb_sections]);
	if (gblCurSection>=nb_sections)
		nb_sections++;
}

#define SetFormat(dst,src)		(dst=src)
#define GetFormat(src,dst)		(dst=src)

void DefFormat(FORMAT_SORTIE *f)			{
	int i;
	//Il faudra contrôler s'il y en a des NULL

	//Assignement pour les bitmaps 16 bits
	SetFormat(b16_declaration,f->ptrs[0][0]);
	SetFormat(b16_nbChaqueX,(int)f->ptrs[0][1]);
	SetFormat(b16_chaque_x,f->ptrs[0][2]);
	SetFormat(b16_chaque_valeur,f->ptrs[0][3]);
	SetFormat(b16_fin_ligne,f->ptrs[0][6]);
	SetFormat(b16_fin_declaration,f->ptrs[0][7]);
	SetFormat(b16_def_ext,f->ptrs[0][8]);

	//Assignement pour les bitmaps 8 bits
	SetFormat(b8_declaration,f->ptrs[1][0]);
	SetFormat(b8_nbChaqueX,(int)f->ptrs[1][1]);
	SetFormat(b8_chaque_x,f->ptrs[1][2]);
	SetFormat(b8_chaque_valeur,f->ptrs[1][3]);
	SetFormat(b8_fin_ligne,f->ptrs[1][6]);
	SetFormat(b8_fin_declaration,f->ptrs[1][7]);
	SetFormat(b8_def_ext,f->ptrs[1][8]);

	//Assignement pour les palettes
	SetFormat(pal_declaration,f->ptrs[2][0]);
	SetFormat(pal_nbChaqueX,(int)f->ptrs[2][1]);
	SetFormat(pal_chaque_x,f->ptrs[2][2]);
	SetFormat(pal_chaque_valeur,f->ptrs[2][3]);
	SetFormat(pal_fin_ligne,f->ptrs[2][6]);
	SetFormat(pal_fin_declaration,f->ptrs[2][7]);
	SetFormat(pal_def_ext,f->ptrs[2][8]);

	//Assignement pour les tilesets
	SetFormat(til_declaration,f->ptrs[3][0]);
	SetFormat(til_nbChaqueX,(int)f->ptrs[3][1]);
	SetFormat(til_chaque_x,f->ptrs[3][2]);
	SetFormat(til_chaque_valeur_1,f->ptrs[3][3]);
	SetFormat(til_chaque_valeur_2,f->ptrs[3][4]);
	SetFormat(til_chaque_valeur_3,f->ptrs[3][5]);
	SetFormat(til_fin_ligne,f->ptrs[3][6]);
	SetFormat(til_fin_declaration,f->ptrs[3][7]);
	SetFormat(til_def_ext,f->ptrs[3][8]);

	//Assignement pour les maps
	SetFormat(map_declaration,f->ptrs[4][0]);
	SetFormat(map_nbChaqueX,(int)f->ptrs[4][1]);
	SetFormat(map_chaque_x,f->ptrs[4][2]);
	SetFormat(map_chaque_valeur_1,f->ptrs[4][3]);
	SetFormat(map_chaque_valeur_2,f->ptrs[4][4]);
	SetFormat(map_chaque_valeur_3,f->ptrs[4][5]);
	SetFormat(map_fin_ligne,f->ptrs[4][6]);
	SetFormat(map_fin_declaration,f->ptrs[4][7]);
	SetFormat(map_def_ext,f->ptrs[4][8]);

	//Listes
	SetFormat(lst_declaration,f->ptrs[5][0]);
	SetFormat(lst_nbChaqueX,(int)f->ptrs[5][1]);
	SetFormat(lst_chaque_x,f->ptrs[5][2]);
	SetFormat(lst_chaque_valeur,f->ptrs[5][3]);
	SetFormat(lst_fin_ligne,f->ptrs[5][6]);
	SetFormat(lst_fin_declaration,f->ptrs[5][7]);
	SetFormat(lst_def_ext,f->ptrs[5][8]);

	SetFormat(type8,f->plus[0]);
	SetFormat(type16,f->plus[1]);
	SetFormat(type32,f->plus[2]);
//	SetFormat(tileset4,f->plus[3]);
//	SetFormat(tileset8,f->plus[4]);
	SetFormat(typesd,f->plus[5]);

	for (i=0;i<NB_MAX_USERDATA;i++)		{
		SetFormat(defUserData[i],f->user[i]);
	}
	nom_format=f->nom;
	ptr_formatActuel=f;
}

FORMAT_SORTIE *GetNomFormat(char *nom)			{
	int i;
	for (i=0;i<nb_sections;i++)
		if (!strcmp(nom,formats[i].nom))
			break;
	if (i==nb_sections)
		return NULL;
	else
		return formats+i;
}

void LitFormat(FORMAT_SORTIE *f)			{
	int i;
	//Il faudra contrôler s'il y en a des NULL

	//Assignement pour les bitmaps 16 bits
	GetFormat(b16_declaration,f->ptrs[0][0]);
	GetFormat((char*)b16_nbChaqueX,f->ptrs[0][1]);
	GetFormat(b16_chaque_x,f->ptrs[0][2]);
	GetFormat(b16_chaque_valeur,f->ptrs[0][3]);
	GetFormat(b16_fin_ligne,f->ptrs[0][6]);
	GetFormat(b16_fin_declaration,f->ptrs[0][7]);
	GetFormat(b16_def_ext,f->ptrs[0][8]);

	//Assignement pour les bitmaps 8 bits
	GetFormat(b8_declaration,f->ptrs[1][0]);
	GetFormat((char*)b8_nbChaqueX,f->ptrs[1][1]);
	GetFormat(b8_chaque_x,f->ptrs[1][2]);
	GetFormat(b8_chaque_valeur,f->ptrs[1][3]);
	GetFormat(b8_fin_ligne,f->ptrs[1][6]);
	GetFormat(b8_fin_declaration,f->ptrs[1][7]);
	GetFormat(b8_def_ext,f->ptrs[1][8]);

	//Assignement pour les palettes
	GetFormat(pal_declaration,f->ptrs[2][0]);
	GetFormat((char*)pal_nbChaqueX,f->ptrs[2][1]);
	GetFormat(pal_chaque_x,f->ptrs[2][2]);
	GetFormat(pal_chaque_valeur,f->ptrs[2][3]);
	GetFormat(pal_fin_ligne,f->ptrs[2][6]);
	GetFormat(pal_fin_declaration,f->ptrs[2][7]);
	GetFormat(pal_def_ext,f->ptrs[2][8]);

	//Assignement pour les tilesets
	GetFormat(til_declaration,f->ptrs[3][0]);
	GetFormat((char*)til_nbChaqueX,f->ptrs[3][1]);
	GetFormat(til_chaque_x,f->ptrs[3][2]);
	GetFormat(til_chaque_valeur_1,f->ptrs[3][3]);
	GetFormat(til_chaque_valeur_2,f->ptrs[3][4]);
	GetFormat(til_chaque_valeur_3,f->ptrs[3][5]);
	GetFormat(til_fin_ligne,f->ptrs[3][6]);
	GetFormat(til_fin_declaration,f->ptrs[3][7]);
	GetFormat(til_def_ext,f->ptrs[3][8]);

	//Assignement pour les maps
	GetFormat(map_declaration,f->ptrs[4][0]);
	GetFormat((char*)map_nbChaqueX,f->ptrs[4][1]);
	GetFormat(map_chaque_x,f->ptrs[4][2]);
	GetFormat(map_chaque_valeur_1,f->ptrs[4][3]);
	GetFormat(map_chaque_valeur_2,f->ptrs[4][4]);
	GetFormat(map_chaque_valeur_3,f->ptrs[4][5]);
	GetFormat(map_fin_ligne,f->ptrs[4][6]);
	GetFormat(map_fin_declaration,f->ptrs[4][7]);
	GetFormat(map_def_ext,f->ptrs[4][8]);

	//Listes
	GetFormat(lst_declaration,f->ptrs[5][0]);
	GetFormat((char*)lst_nbChaqueX,f->ptrs[5][1]);
	GetFormat(lst_chaque_x,f->ptrs[5][2]);
	GetFormat(lst_chaque_valeur,f->ptrs[5][3]);
	GetFormat(lst_fin_ligne,f->ptrs[5][6]);
	GetFormat(lst_fin_declaration,f->ptrs[5][7]);
	GetFormat(lst_def_ext,f->ptrs[5][8]);

	GetFormat(type8,f->plus[0]);
	GetFormat(type16,f->plus[1]);
	GetFormat(type32,f->plus[2]);
//	GetFormat(tileset4,f->plus[3]);
//	GetFormat(tileset8,f->plus[4]);
	GetFormat(typesd,f->plus[5]);

	for (i=0;i<NB_MAX_USERDATA;i++)		{
		GetFormat(defUserData[i],f->user[i]);
	}
}


