int gblIndice;
FILE *gblFichierConfig;
int bModeWideCrLf=1;

char *GetChaine(char **dest)		{
	char *retour, *chne;
	chne=*dest;
	if (*chne=='\"')		{
		chne++;
		retour=chne;
		while(*chne!='\"' && *chne)
			chne++;
	}
	else if (*chne=='\'')		{
		chne++;
		retour=chne;
		while(*chne!='\'' && *chne)
			chne++;
	}
	else if (*chne=='*')		{
		chne++;
		retour=chne;
		while(*chne!='*' && *chne)
			chne++;
	}
	else
		return NULL;
	if (!(*chne))
		return NULL;
	*chne=0;
	*dest=chne+1;
	return retour;
}

void AnalyseCar(char **dest, char **car, char *max)		{
	char *src, *dst;
	src = *car;
	dst = *dest;

	if (*src=='\\')		{
		src++;
		if (*src=='n')		{
			src++;
			if (dst < max)		{
				if (bModeWideCrLf)
					*dst++ = '\r';
			}
			if (dst < max)
				*dst++ = '\n';
		}
		else if (*src=='b')			{
			src++;
			if (dst < max)
				*dst++ = '\b';
		}
		else	{
			if (dst < max)
				*dst++ = *src++;
		}
	}
	else		{
		if (dst < max)
			*dst++ = *src++;
	}
	*dest = dst;
	*car = src;
}

char *GetCopieChaine(char *dst, char *chne, unsigned long tailleMax)			{
	char *base = chne, *ptrmax = dst+tailleMax;
	if (*chne=='\"')		{
		chne++;
		while(*chne!='\"' && *chne && dst<ptrmax)			{
			AnalyseCar(&dst, &chne, ptrmax);
		}
	}
	else if (*chne=='\'')		{
		chne++;
		while(*chne!='\'' && *chne && dst<ptrmax)			{
			AnalyseCar(&dst, &chne, ptrmax);
		}
	}
	else if (*chne=='*')		{
		chne++;
		while(*chne!='*' && *chne && dst<ptrmax)			{
			AnalyseCar(&dst, &chne, ptrmax);
		}
	}
	else
		return base;
	if (dst>=ptrmax)
		dst--;
	*dst++ = 0;
	if (!(*chne))
		return base;
	return chne+1;
}

void CreeChaineScript(char *dst, char *src, char carspecial, int taillemax)			{
	int i=0;
	dst[i++]=carspecial;
	while (*src && i<taillemax-2)			{
		if (*src == '\\')			{
			dst[i++] = '\\';
			dst[i++] = '\\';
		}
		else if (*src == '\n')			{
			dst[i++] = '\\';
			dst[i++] = 'n';
		}
		else if (*src == carspecial)			{
			dst[i++] = '\\';
			dst[i++] = carspecial;
		}
		else
			dst[i++]=*src;
		src++;
	}
	dst[i++]=carspecial;
	dst[i++]=0;
}

void GetNomFichierConfigMap(char *nom_fichier, char *nom_base)		{
	int i, j;

	strcpy(nom_fichier, nom_base);
	j=0;
	for (i=strlen(nom_fichier)-1; i>0; i--)		{		//Ne pas prendre le premier '.'
		if (nom_fichier[i]=='.')			{
			j++;
			if (j>=2)
				break;
		}
	}

	//On a trouvé le deuxième point en partant de la droite
	if (j>=2)		{
		i++;
		while(nom_fichier[i] && nom_fichier[i]!='.')
			i++;
		nom_fichier[i]=0;
		strcat(nom_fichier, ".spt");
	}
	else		{
		//Qu'un seul point -> on rajoute à la suite
		strcat(nom_fichier, ".spt");
	}

	//Efface le fichier .spt de config de l'éditeur de maps
/*	strcpy(nom_fichier, nom_base);
	if (strstr(nom_fichier, map_def_ext))
		*strstr(nom_fichier, map_def_ext)=0;
	longueur = strlen(nom_fichier);
	strcat(nom_fichier, map_def_ext);
	for (i=strlen(map_def_ext)-1; i>0; i--)				//Ne pas prendre le premier '.'
		if (map_def_ext[i]=='.')
			break;
	if (i>0)
		nom_fichier[longueur+i]=0;
	strcat(nom_fichier, ".spt");*/
}


void FctResetParams(char *ptr)		{
	SD_PARAMS *sdp=&sdParams[gblSdModele];
	sdp->sdNumParams=0;
}

void MajFichierParams()		{
	char *ptr, *adr_avant;
	char texte_avant[1000], texte_apres[1000], temp_texte[1000], str[1000];
	int i;
	SD_PARAMS *sdp=&sdParams[gblSdModele];
	char variable[100];
	int v, signe_ok, incrementDiff;

	memset(lst_chaque_valeur_ok, 0, sizeof(lst_chaque_valeur_ok));
	strcpy(lst_chaque_valeur_ok, lst_chaque_valeur);
	if (ptr_formatActuel==&formats[0])				{
		ptr=lst_chaque_valeur_ok;
		while(1)		{
			while(*ptr && *ptr!='#')
				ptr++;
			if (*ptr==0)
				return;
			if (!strncmp(ptr, "#+param:", 8))			{
				adr_avant = ptr;
				ptr+=8;
				//Prochain guillemet
				while((*ptr!='\"' && *ptr!='\'') && *ptr)
					ptr++;
				if (*ptr==0)
					return;
				ptr++;
				//Jusqu'à la fin du guillemet -> texte_avant
				i=0;
				while(*ptr && (*ptr!='\"' && *ptr!='\''))
					texte_avant[i++]=*ptr++;
				texte_avant[i++]=0;
				if (*ptr==0)
					return;
				ptr++;
				//Prochain guillemet
				while((*ptr!='\"' && *ptr!='\'') && *ptr)
					ptr++;
				if (*ptr==0)
					return;
				ptr++;
				//Jusqu'à la fin du guillemet -> texte_apres
				i=0;
				while(*ptr && (*ptr!='\"' && *ptr!='\''))
					texte_apres[i++]=*ptr++;
				texte_apres[i++]=0;
				if (*ptr==0)
					return;
				ptr++;
				//Fin (#)
				while(*ptr!='#' && *ptr)
					ptr++;
				if (*ptr==0)
					return;
				ptr++;
				strcpy(adr_avant, ptr);

//				for (i=0;i<sdp->sdNumParams;i++)			{
				//A l'envers
				for (i=sdp->sdNumParams-1;i>=0;i--)			{
					strcpy(temp_texte, texte_avant);
						//ECRIT LE DEBUT DE LA CHAINE
						//#"<param>"# par exemple
						strcpy(variable, sdp->sdNomsParams[i]);
						strcpy(str, "");
						v=0;
						incrementDiff=-1;
						signe_ok=0;
						while(variable[v]!='>' && variable[v])			{
							if (variable[v]=='<')
								signe_ok=v;
							v++;
						}
						if (variable[signe_ok]=='<' && v>=0)			{
							if (variable[v]=='>')			{
								variable[signe_ok]=0;
								strcat(str, variable);
							}
						}
						//ECRIT LE PARAMETRE DE LA CHAINE
						strcat(str, "#");
						strcat(str, sdp->sdNomsParams[i]);
						strcat(str, "#");
						//ECRIT LA FIN DE LA CHAINE
						if (variable[v]=='>')			{
							v++;
							strcat(str, variable+v);
						}
//					sprintf(str, "#%s#", sdp->sdNomsParams[i]);
					strcat(temp_texte, str);
					strcat(temp_texte, texte_apres);
					memmove(adr_avant+strlen(temp_texte), adr_avant, strlen(adr_avant)+1);
					memset(adr_avant, 32, strlen(temp_texte));
					memmove(adr_avant, temp_texte, strlen(temp_texte));
				}
			}
			else
				ptr++;
		}
	}
}

void FctDefParamList(char *ptr)		{
	FILE *f=gblFichierConfig;
	char str[1024], nom[100], defaut[1024], nomparam[1024];
	int i, commande, type, taille, modele;
	char *ptrDebut=ptr;
	SD_PARAMS *sdp;

	if (*ptr=='\"')				{
		ptr++;
		while(*ptr && *ptr!='\"')
			ptr++;
		*ptr=0;
		ptrDebut++;
	}
	else		{
		while(*ptr!='{' && *ptr)
			ptr++;
		if (!(*ptr))		{
			MessageBox(gblHDlg,"Vous avez oublié le { d'ouverture du format (sur la même ligne).","Erreur d'exécution de macro",MB_ICONERROR);
			return;
		}
		ptr--;
		while(*ptr==' ' || *ptr=='	')
			ptr--;
		*(ptr+1)=0;
	}

	for (i=0;i<sdNbreModeles;i++)		{
		if (!strcmp(ptrDebut, sdParams[i].sdNomModele))
			break;
	}
	modele=i;
	sdp=&sdParams[modele];
	sdp->sdNumParams=0;

/*	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);
		if (feof(f))
			break;
		for (ptr=str;*ptr;ptr++)			{
			if (*ptr=='\n')
				*ptr=0;
		}

		//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!='\"')					//Jusqu'à la fin de celle-ci
					ptr++;
				ptr++;
			}
		}*/

		ptr=str;
		SAUTE_ESPACES(ptr);									//Pour sauter l'indentation
		commande=1;
		if (*ptr=='{')									//Définition d'un champ
			commande=2;
		else if (*ptr=='}')				{					//Fin de section
			if (section>=0)									//Fermeture de la section
				section--;
			else											//Fin de la définition
				break;
			commande=0;
		}
		else if (*ptr==0)
			continue;

		i=0;
		while((*ptr>='0' && *ptr<='9') && i<sizeof(nom)-1)
			nom[i++]=*ptr++;
		nom[i++]=0;
		type=GetEntier(nom);
		while((*ptr<'0' || *ptr>'9') && i<sizeof(nom)-1 && *ptr)
			ptr++;
		i=0;
		while((*ptr>='0' && *ptr<='9') && i<sizeof(nom)-1)
			nom[i++]=*ptr++;
		nom[i++]=0;
		taille=GetEntier(nom);
		if (*ptr==',')
			ptr++;
		if (*ptr==' ')
			ptr++;
		ptr = GetCopieChaine(nomparam, ptr, sizeof(nom));
		if (*ptr==',')
			ptr++;
		if (*ptr==' ')
			ptr++;
		ptr = GetCopieChaine(defaut, ptr, sizeof(defaut));

//		if (*ptr=='=')										//Assignement demandé
//		else
//			Debug("Caractère inattendu: %c",*ptr);

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

		if (commande==1)		{
			strcpy(sdp->sdNomsParams[sdp->sdNumParams], nomparam);
			sdp->sdTypeParam[sdp->sdNumParams] = type;
			sdp->sdTaillesParam[sdp->sdNumParams] = taille;
			if (defaut==NULL)
				strcpy(sdp->sdTexteDefaut[sdp->sdNumParams], "");
			else
				strcpy(sdp->sdTexteDefaut[sdp->sdNumParams], defaut);
			sdp->sdNumParams++;
//			DefChamp(nom,ptr);
		}
/*		else if (commande==2)		{
			DefSection(nom);
		}*/

	}
	
	strcpy(sdp->sdNomModele, ptrDebut);
	sdp->sizeofSD=CalcSdSize(sdp);
	if (modele>=sdNbreModeles)
		sdNbreModeles++;

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

void FctEmulGBAAncien(char *ptr)			{
	MessageBox(gblHDlg, "System.emulGBA n'est plus disponible. Veuillez utiliser Fonds[x].emulGBA à la place", "Erreur", MB_ICONEXCLAMATION);
}

void FctMaxObjets(char *ptr)		{
	int val;
	val=GetEntier(ptr);
	if (val<3)
		val=3;
	NB_MAX_ELE_LISTE = val;
}

void FctAjParam(char *ptr)		{
	char *paramName;
	int paramType, taille;

	paramName=GetChaine(&ptr);
	while(*ptr==',' || *ptr==' ' || *ptr=='	')
		ptr++;
	paramType=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	taille=GetEntier(ptr);
	if (taille==0)
		taille=4;
	AjTypePerso(&sdParams[gblSdModele], paramName,paramType,taille, "");
//	AjTypePerso("Paramètre 2",SDT_ENTIER,4);
//	AjTypePerso("Paramètre 3",SDT_ENTIER,4);
}

int arretdurgence=0;
char *trouveLabel=NULL, chneLabel[1000];

void FctInclure(char *ptr)			{
	char *nom;
	nom=GetChaine(&ptr);
	if (nom)			{
		if (!OuvreFichierConfig(nom,NULL))
			MessageBox(gblHDlg,ptr,"Impossible d'inclure le fichier",MB_ICONERROR);
	}
	else
		MessageBox(gblHDlg,"Fonction: inclure\nNom de fichier pas défini correctement (n'oubliez pas les guillemets)","Erreur d'exécution de macro",MB_ICONERROR);
}

void FctMemoireMax(char *ptr)			{
	DIMENSION_MAX = (int)Memory_StringToInt32(ptr);
}

void FctOk(char *ptr)		{
	GereBoutonInconnu(gblHDlg,hBoutonOk);
}

void FctMsgBox(char *ptr)		{
	char *chne, *label, *tmp, *titre;

	chne=GetChaine(&ptr);
	if (!chne)
		chne="Point d'arrêt défini ici (MsgBox sans argument).";

	titre="Message utilisateur";

prochArg:
	if (*ptr==',')
		ptr++;
	while(*ptr==' ' || *ptr=='	')		ptr++;

	tmp=GetChaine(&ptr);

	label=NULL;

	if (!tmp)		{
		if (!strncmp(ptr,"sinon goto ",11))
			label=ptr+11;
	}
	else		{
		titre=tmp;
		goto prochArg;
	}

	if (MessageBox(gblHDlg,chne,titre,MB_ICONINFORMATION|MB_OKCANCEL)==IDCANCEL)		{
		if (label)		{
			strcpy(chneLabel,label);
			trouveLabel=chneLabel;
		}
		else
			arretdurgence=1;
	}
}

void FctShowWindow(char *ptr)		{
	int val;
	val=GetEntier(ptr);
	if (val)
		ShowWindow(gblHDlg,SW_SHOW);
	else
		ShowWindow(gblHDlg,SW_HIDE);
}

void FctQuitte(char *ptr)		{
	arretdurgence=2;
}

void FctFin(char *ptr)		{
	arretdurgence=1;
}

void FctExec(char *ptr)		{
	char *cmd;
	cmd=GetChaine(&ptr);
	WinExec(cmd,1);
}

void FctCoulTrans(char *ptr)		{
	int couleur;
	unsigned char *ptrcouleur;

	couleur=GetEntier(ptr);
	ptrcouleur=(unsigned char *)&couleur;
	rougeMasque=*ptrcouleur++;
	vertMasque=*ptrcouleur++;
	bleuMasque=*ptrcouleur++;
}

void FctPalZero(char *ptr)		{
	int couleur;
	unsigned char *ptrcouleur;

	couleur=GetEntier(ptr);
	ptrcouleur=(unsigned char *)&couleur;
	rougeZero=*ptrcouleur++;
	vertZero=*ptrcouleur++;
	bleuZero=*ptrcouleur++;
	rougeZero/=8;
	vertZero/=8;
	bleuZero/=8;
}

void FctRetour(char *ptr)		{
	retourScript=GetEntier(ptr);
	arretdurgence=1;
}

void FctAjouteFond(char *ptr)		{
	int i, emplacement=0, old;
	char *nom;
	nom=GetChaine(&ptr);
	for (i=0;i<nbreElements;i++)		{
		if (((elements[i].type)&MASQUE_TYPE)==TYPE_CARTE || ((elements[i].type)&MASQUE_TYPE)==TYPE_LISTE)
			if (!strcmp(elements[i].nom_court,nom))
				break;
	}
	if (i>=nbreElements)
		return;
	
	ptr=ProchArgEntier(ptr);
	if (*ptr)		{
		emplacement=GetEntier(ptr);
	}
	if (*ptr && emplacement>=1 && emplacement<=MAX_FONDS)		{
		emplacement--;
		if ((ele_fond[emplacement]) == (&elements[i]))		{			//Le même fond est déjà chargé, au même endroit?
			return;
		}
		else		{
			if (ele_fond[emplacement] != NULL)		{
				old = nMaps;
				nMaps = emplacement;
				AjouteFond(i);
				nMaps = old;
			}
			else			{
//				Debug("AV %i %i", emplacement, nMaps);
				AjouteFond(i);
//				Debug("AP %i %i", emplacement, nMaps);
			}
		}
	}
	else
		AjouteFond(i);
}

void FctReinitFonds(char *ptr)		{
	int i;
	for (i=0;i<nMaps;i++)			{
		free(params[i].gblMap);
		free(params[i].gblPal);
		free(params[i].gblMotifs);
		free(undos[i].undoBuffer);
	}
	nMaps=0;
}

void FctGoto(char *ptr)		{
	strcpy(chneLabel,ptr);
	trouveLabel=chneLabel;
}

void FctZoom(char *ptr)		{
	double nvZoom;
	nvZoom=atof(ptr);
	if (nvZoom>0)
		zoom=nvZoom;
}

double GetIntensiteCouleur(char *ptr)		{
	int pourcentage;
	char *ptrsauv=ptr;
	double valeur;

	ptrsauv=ptr;
	pourcentage=0;

	while(*ptr!=' ' && *ptr!='	' && *ptr!=',' && *ptr)		{
		if (*ptr=='%')			{
			pourcentage=1;
			break;
		}
		ptr++;
	}

	valeur=atof(ptrsauv);

	if (pourcentage)
		return (valeur*255.0)/100.0;
	else
		return valeur;
}


char *AnalyseCouleur(char *ptr, double *r, double *v, double *b)		{
	double temp;
	char str[1000];

	if (*ptr>='0' && *ptr<='9')		{
		temp=GetIntensiteCouleur(ptr);
		*r=temp;
		*v=temp;
		*b=temp;
		while(*ptr!=' ' && *ptr!='	' && *ptr)
			ptr++;
		if (*ptr)		{
			while(*ptr==' ' || *ptr=='	')
				ptr++;
		}
	}
	else if (!strncmp(ptr,"rgb",3))		{
		ptr+=3;
		while(*ptr==' ')
			ptr++;
		if (*ptr=='(')
			ptr++;
		while(*ptr==' ')
			ptr++;
		*r=GetIntensiteCouleur(ptr);
		ptr=ProchArgEntier(ptr);
		*v=GetIntensiteCouleur(ptr);
		ptr=ProchArgEntier(ptr);
		*b=GetIntensiteCouleur(ptr);
		ptr=ProchArgEntier(ptr);
	}
	else		{
		sprintf(str,"Erreur du système de couleurs, analysant: %s",ptr);
		MessageBox(gblHDlg,str,"Erreur d'exécution de macro",MB_ICONERROR);
		return NULL;
	}
	return ptr;
}

void CreeCouleurs()		{
	int x, y, couleur;
	double divi, mult, valR, valV, valB, absR, absV, absB, arrondi;

	divi=256.0/(nuances+1);
	mult=31.0/(nuances);


	valR=AlphaR>=0?AlphaR:0;
	valV=AlphaV>=0?AlphaV:0;
	valB=AlphaB>=0?AlphaB:0;

	absR=(AlphaR>=0)?(AlphaR):(-AlphaR);
	absV=(AlphaV>=0)?(AlphaV):(-AlphaV);
	absB=(AlphaB>=0)?(AlphaB):(-AlphaB);

	//Tronc entier ne sert plus à rien /*si nuancesAvant n'est pas activé*/
//	if (troncEntier || !nuancesAvant)
		arrondi=0;
//	else
//		arrondi=0.5;

	for (y=0;y<256;y++)		{
		if (nuancesAvant)		{
			//Pour appliquer l'effet de nuances avant le traitement de la couleur
			x=(int)((int)((y/divi)+arrondi)*mult*MULT);
			couleur=(int)(((valR)+(255-absR)*((255.0*pow((x/255.0),GammaR))+AdditionR)/255+0.5)/MULT+arrondi);
			if (couleur<0)		couleur=0;
			if (couleur>31)		couleur=31;
			tblCoulR[y]=couleur;
			couleur=(int)(((valV)+(255-absV)*((255.0*pow((x/255.0),GammaV))+AdditionV)/255+0.5)/MULT+arrondi);
			if (couleur<0)		couleur=0;
			if (couleur>31)		couleur=31;
			tblCoulV[y]=couleur;
			couleur=(int)(((valB)+(255-absB)*((255.0*pow((x/255.0),GammaB))+AdditionB)/255+0.5)/MULT+arrondi);
//			couleur=(int)(((valB)+(255-AlphaB)*((255.0*pow((x/255.0),GammaB))+AdditionB)/255)/divi);
			if (couleur<0)		couleur=0;
			if (couleur>31)		couleur=31;
			tblCoulB[y]=couleur;
		}
		else	{
			//Pour appliquer l'effet de nuances à la fin (après correction gamma)
			couleur=(int)(((valR)+(255-absR)*((255.0*pow((y/255.0),GammaR))+AdditionR)/255+0.5)/divi+arrondi);
			couleur=(int)(couleur*mult);
			if (couleur<0)		couleur=0;
			if (couleur>31)		couleur=31;
			tblCoulR[y]=couleur;
			couleur=(int)(((valV)+(255-absV)*((255.0*pow((y/255.0),GammaV))+AdditionV)/255+0.5)/divi+arrondi);
			couleur=(int)(couleur*mult);
			if (couleur<0)		couleur=0;
			if (couleur>31)		couleur=31;
			tblCoulV[y]=couleur;
			couleur=(int)(((valB)+(255-absB)*((255.0*pow((y/255.0),GammaB))+AdditionB)/255+0.5)/divi+arrondi);
	//		couleur=(int)(((valB)+(255-AlphaB)*((255.0*pow((y/255.0),GammaB))+AdditionB)/255)/divi);
			couleur=(int)(couleur*mult);
			if (couleur<0)		couleur=0;
			if (couleur>31)		couleur=31;
			tblCoulB[y]=couleur;
		}
	}
}

void FctNuances(char *ptr)		{
	nuances=GetEntier(ptr)-1;
	CreeCouleurs();
}

void FctModeReduc(char *ptr)		{
	int i;
	char str[1000];
	//Ne pas traduire
	char *modes_en[]=	{
		"initial","halftone","optimal"
	};
	char *modes_fr[]=	{
		"normal","tramé","meilleur"
	};
	//Traduction possible

	if (*ptr>='0' && *ptr<='2')
		modeConversion=*ptr-'0';
	else	{
		for (i=0;i<sizeof(modes_fr)/sizeof(modes_fr[0]);i++)		{
			if (!strcmp(ptr,modes_en[i]) || !strcmp(ptr,modes_fr[i]))
				goto trouve;
		}
		sprintf(str,"Le nom de la méthode de réduction suivante n'a pas été trouvé: %s",ptr);
		MessageBox(gblHDlg,str,"Erreur d'exécution de macro",MB_ICONERROR);
		return;

trouve:
		modeConversion=i;
	}
}

//Ne pas traduire
void FctLumiere(char *ptr)		{
	double r,v,b;

	while(*ptr)		{
		if (!strncmp(ptr,"gamma",5))		{
			ptr+=5;
			while(*ptr==' ')
				ptr++;
			if (*ptr=='=')
				ptr++;
			while(*ptr==' ')
				ptr++;
			ptr=AnalyseCouleur(ptr,&r,&v,&b);
			if (ptr)
				GammaR=1.0/r, GammaV=1.0/v, GammaB=1.0/b;
		}
		else if (!strncmp(ptr,"add",3))		{
			ptr+=3;
			while(*ptr==' ')
				ptr++;
			if (*ptr=='=')
				ptr++;
			while(*ptr==' ')
				ptr++;
			ptr=AnalyseCouleur(ptr,&r,&v,&b);
			if (ptr)
				AdditionR=r, AdditionV=v, AdditionB=b;
		}
		else if (!strncmp(ptr,"alpha",5))		{
			ptr+=5;
			while(*ptr==' ')
				ptr++;
			if (*ptr=='=')
				ptr++;
			while(*ptr==' ')
				ptr++;
			ptr=AnalyseCouleur(ptr,&r,&v,&b);
			if (ptr)
				AlphaR=r, AlphaV=v, AlphaB=b;
		}
		else	{
			MessageBox(gblHDlg,"Dans la fonction de convert.luminosite: le paramètre à régler n'est pas connu.\nExemple: convert.luminosite GAMMA=RGB(1.0,1.3,1.0)","Erreur d'exécution de macro",MB_ICONERROR);
			break;
		}
	}
	CreeCouleurs();
}
//Traduction possible

void FctTronquer(char *ptr)		{
	troncEntier=GetEntier(ptr);
	CreeCouleurs();
}

void FctNuancesAvant(char *ptr)		{
	nuancesAvant=GetEntier(ptr);
	CreeCouleurs();
}

void FctBougeSpecimen(char *ptr)		{
	int posX, posY, tailleX, tailleY;

	tailleX=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	if (!(*ptr))
		return;
	tailleY=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	if (*ptr)		{
		posX=GetEntier(ptr);
		ptr=ProchArgEntier(ptr);
		if (!(*ptr))
			return;
		posY=GetEntier(ptr);
		ptr=ProchArgEntier(ptr);
		SetWindowPos(gblHSpec,HWND_TOP,posX,posY,tailleX,tailleY,SWP_NOZORDER);
	}
	else
		SetWindowPos(gblHSpec,HWND_TOP,0,0,tailleX,tailleY,SWP_NOZORDER|SWP_NOMOVE);
}

void FctBougeBits(char *ptr)		{
	int tailleX, tailleY;

	tailleX=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	if (!(*ptr))
		return;
	tailleY=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	SetWindowPos(hDlgBits,HWND_TOP,tailleX,tailleY,0,0,SWP_NOZORDER|SWP_NOSIZE);
}

void FctBougeEditeur(char *ptr)		{
	int posX, posY, tailleX, tailleY, max;
	WINDOWPLACEMENT wp;
//	RECT rect;
//	HWND hTmpWnd;

	tailleX=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	if (!(*ptr))
		return;
	tailleY=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	if (*ptr)		{
		posX=GetEntier(ptr);
		ptr=ProchArgEntier(ptr);
		if (!(*ptr))
			return;
		posY=GetEntier(ptr);
		ptr=ProchArgEntier(ptr);
		if (*ptr)		{
			max=GetEntier(ptr);
			if (!max)
				goto apres;
			GetWindowPlacement(gblHEdit, &wp);
			wp.showCmd=SW_SHOWMAXIMIZED;
			SetWindowPlacement(gblHEdit, &wp); 
		}
		else		{
apres:
/*			hTmpWnd=GetDesktopWindow();
			GetWindowRect(hTmpWnd,&rect);
			if (posX > rect.right-256)
				posX = rect.right-256;
			if (posY > rect.bottom-256)
				posY = rect.bottom-256;
			if (posX<0) posX=0;
			if (posY<0) posY=0;*/
/*			if (posX+tailleX >= rect.right)
				tailleX=rect.right-posX;
			if (posY+tailleY >= rect.bottom)
				tailleY=rect.bottom-posY;*/
			SetWindowPos(gblHEdit,HWND_TOP,posX,posY,tailleX,tailleY,SWP_NOZORDER);
		}
	}
	else
		SetWindowPos(gblHEdit,HWND_TOP,0,0,tailleX,tailleY,SWP_NOZORDER|SWP_NOMOVE);
}

void AjoutePlanSpecimen(int i)			{
	int j;
	if (!(i>=0 && i<nMaps))				//Pas bon
		return;
	for (j=0;j<nPlansLies;j++)
		if (plans[j]==i)
			return;
	plans[nPlansLies]=i;
//	ptr=ProchArgEntier(ptr);
//	fond_editable[i]=0;
	fond_actif[i]=0;
	taillePlanX=params[i].tailleX;
	taillePlanY=params[i].tailleY;
	tailleTilesX=params[i].tileX;
	tailleTilesY=params[i].tileY;
	nPlansLies++;
}

void FctAssoc(char *ptr)		{
	int i;
	i=GetEntier(ptr)-1;
	AjoutePlanSpecimen(i);
}

void FctLieMap(char *ptr)		{
	int vars[20], nVars, i, j, condition;
	UNDO_BUFFER *ub;

	nVars=0;
	while(*ptr)		{
		i=GetEntier(ptr);
		if (i && i<=nMaps)		{
			condition=TRUE;
			for (j=0;j<nVars;j++)		{
				if ((i-1)==vars[j])
					condition=FALSE;
			}
			if (condition)
				vars[nVars++]=i-1;
		}
		ptr=ProchArgEntier(ptr);
	}
	vars[nVars]=LIEN_INVALIDE;

	for (i=0;i<nVars;i++)		{
		ub=&undos[vars[i]];
		condition=(ub->nOperations!=ub->dernierEnreg || ub->modifie);
		VideUndoBufferFond(vars[i]);
		ub->modifie=condition;
		for (j=0;j<=nVars;j++)
			liens[vars[i]][j]=vars[j];
	}
}

void FctParallax(char *ptr)		{
	double temp;
	temp=atof(ptr);
	if (temp>0)
		params[gblIndice].parallaxeX=temp;
	ptr=ProchArgEntier(ptr);
	temp=atof(ptr);
	if (temp>0)
		params[gblIndice].parallaxeY=temp;
	majRequise=1;
	CreeBarresDefil(gblHEdit);
}

void FctEmulGBA(char *ptr)		{
	params[gblIndice].emul_gba = GetEntier(ptr);
}


void FctGrille(char *ptr)		{
	int temp;
	temp=atoi(ptr);
	if (temp>0)
		params[gblIndice].grilleX=temp;
	ptr=ProchArgEntier(ptr);
	temp=atoi(ptr);
	if (temp>0)
		params[gblIndice].grilleY=temp;
	else
		params[gblIndice].grilleY=params[gblIndice].grilleX;
}

void FctAfficheBits(char *ptr)		{
	if (!fenBits)
		CreateDialog(hInst,(LPCTSTR)IDD_BITS,gblHEdit,(DLGPROC)DlgBits);
}

void FctAfficheSpecimen(char *ptr)		{
	bSpecimenAffiche = GetEntier(ptr);
}

void FctTexteBit(char *ptr)		{
	char *nom;
	int numero_bit;

	Alloc_Bits();
	numero_bit=15-GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	nom=GetChaine(&ptr);
	if (numero_bit>=0 && numero_bit<=7)
		strcpy(nomsBits[gblIndice][numero_bit],nom);
	else
		MessageBox(gblHDlg,"Renommage des bits: le numéro de bit spécifié n\'est pas dans la gamme prévue (8 à 15).","Erreur d'exécution de macro",MB_ICONERROR);
}

void FctBitActif(char *ptr)		{
	int numero_bit, valeur;

	Alloc_Bits();
	numero_bit=15-GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	valeur=GetEntier(ptr);
	if (numero_bit>=0 && numero_bit<=7)		{
		bitsActives[gblIndice][numero_bit]=valeur;
/*		if (valeur==0)
			strcpy(nomsBits[gblIndice][numero_bit],"(inutile)");*/
	}
	else
		MessageBox(gblHDlg,"Renommage des bits: le numéro de bit spécifié n\'est pas dans la gamme prévue (8 à 15).","Erreur d'exécution de macro",MB_ICONERROR);
}

void FctAjCondition(char *ptr)		{
	int debut, fin, nouvelle, i, j;
	S_CONDITION cd;

	debut=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	fin=GetEntier(ptr);
	ptr=ProchArgEntier(ptr);
	nouvelle=GetEntier(ptr);

	i=n_conditions[gblIndice];

	if (i<MAX_COND)			{
		cd.debut=debut;
		cd.fin=fin;
		cd.difference=debut-nouvelle;
		while(*ptr)	ptr++;
		if (*(ptr-1)=='=')
			cd.exact=1;
		else
			cd.exact=0;
		//Vérifie qu'elle n'existe pas déjà
		for (j=0;j<n_conditions[gblIndice];j++)		{
			if (!memcmp(&s_conditions[gblIndice][j], &cd, sizeof(cd)))
				break;
		}
		if (j>=n_conditions[gblIndice])		{
			memcpy(&s_conditions[gblIndice][i], &cd, sizeof(cd));
			n_conditions[gblIndice]++;
		}
	}
}

void FctNvFormat(char *ptr)			{
	char *ptrDebut=ptr;
	if (*ptr=='\"')				{
		ptr++;
		while(*ptr && *ptr!='\"')
			ptr++;
		*ptr=0;
		LitFiltre(gblFichierConfig,ptrDebut+1);
	}
	else		{
		while(*ptr!='{' && *ptr)
			ptr++;
		if (!(*ptr))		{
			MessageBox(gblHDlg,"Vous avez oublié le { d'ouverture du format (sur la même ligne).","Erreur d'exécution de macro",MB_ICONERROR);
			return;
		}
		ptr--;
		while(*ptr==' ' || *ptr=='	')
			ptr--;
		*(ptr+1)=0;
		LitFiltre(gblFichierConfig,ptrDebut);
	}

}

void ChoisitFormat(char *nom)			{
	int i;
	for (i=0;i<nb_sections;i++)
		if (!strcmp(nom,formats[i].nom))			{
			DefFormat(&formats[i]);
			return;
		}
	sprintf(str,"Format %s non-trouvé",nom);
	MessageBox(gblHDlg,str,"Erreur ChoisitFormat",MB_ICONERROR);
}

void FctFormat(char *ptr)			{
	strcpy(format_appliquer,GetChaine(&ptr));
}

void FctSetFormat(char *ptr)			{
	char *arg;
	arg=GetChaine(&ptr);

	if (arg)
		ChoisitFormat(arg);
}

void ChoisitModele(char *nom)			{
	int i;
	for (i=0;i<sdNbreModeles;i++)
		if (!strcmp(nom, sdParams[i].sdNomModele))			{
			gblSdModele=i;
			return;
		}
	sprintf(str,"Modèle %s non-trouvé",nom);
	MessageBox(gblHDlg,str,"Erreur ChoisitModele",MB_ICONERROR);
}

void ChoisitFormatFichierExtension(const char *nom)			{
	const char *extension;
	int i, j;
	if (!bChoisitAutoFormat)
		return;
	extension = GetWideExtension((char*)nom);
	for (i=0;i<nb_sections;i++)			{
		//Pour chaque type de fichier, compare si l'extension est la même que le fichier en cours
		for (j=0;j<NBRE_PTRS_FORMATS;j++)		{
			//+1 pour supprimer le point
			if (!strcmp(extension, formats[i].ptrs[j][8]+1))			{
				DefFormat(&formats[i]);
				return;
			}
		}
	}
}

void FctModele(char *ptr)			{
	strcpy(modele_appliquer,GetChaine(&ptr));
}

void FctSetModele(char *ptr)			{
	char *arg;
	arg=GetChaine(&ptr);

	if (arg)
		ChoisitModele(arg);
}


//Tableau de test
int tabTest[10];

typedef struct		{
	int taille;
	int type;
	void *tableau;
} INFOS_TABLEAU;

//Infos sur le tableau de test
INFOS_TABLEAU infoTabTest[]={10,TYPE_ENTIER,tabTest};
INFOS_TABLEAU infoTabFondVisible[]={MAX_FONDS,TYPE_ENTIER,fond_actif};
INFOS_TABLEAU infoTabDoss[]={10,TYPE_CHAINE,dossierParDefaut};

typedef struct		{
	char *nom;
	void *handle;
	int type;
} IDENTIFICATEUR;

typedef struct		{
	char *nom;
	void *handle;
	int type;
	void *valeur;
} IDENTIFICATEUR_ETENDU;

int typeDeConversion=0, maxCoul;
char convBmp[TAILLE_MAX_CHAINES], convMap[TAILLE_MAX_CHAINES], convDst[TAILLE_MAX_CHAINES], convPal[TAILLE_MAX_CHAINES];
char chneUPal[TAILLE_MAX_CHAINES], chneUTil[TAILLE_MAX_CHAINES], chneTVoulue[TAILLE_MAX_CHAINES], chneTileXY[TAILLE_MAX_CHAINES];
char chneColorMode[TAILLE_MAX_CHAINES], chneMapMode[TAILLE_MAX_CHAINES];

//Ne pas traduire
IDENTIFICATEUR_ETENDU idConv[]=		{
	//Conversion rapide
	{"tset",				&typeDeConversion,		TYPE_ENTIERDIRECT,			(void*)1},
	{"b8",					&typeDeConversion,		TYPE_ENTIERDIRECT,			(void*)2},
	{"b16",					&typeDeConversion,		TYPE_ENTIERDIRECT,			(void*)3},

	{"bmp",					&convBmp,				TYPE_CHAINE,				NULL},
	{"src",					&convBmp,				TYPE_CHAINE,				NULL},
	{"dst",					&convDst,				TYPE_CHAINE,				NULL},
	{"til",					&convDst,				TYPE_CHAINE,				NULL},
	{"map",					&convMap,				TYPE_CHAINE,				NULL},
	{"pal",					&convPal,				TYPE_CHAINE,				NULL},
	
	{"name",				(void*)1,				TYPE_SPECIAL,				NULL},
	{"nametil",				&chneNomVarTil,			TYPE_CHAINE,				NULL},
	{"nameb8",				&chneNomVarB8,			TYPE_CHAINE,				NULL},
	{"nameb16",				&chneNomVarB16,			TYPE_CHAINE,				NULL},
	{"namepal",				&chneNomVarPal,			TYPE_CHAINE,				NULL},
	{"namemap",				&chneNomVarMap,			TYPE_CHAINE,				NULL},

	{"col",					&maxCoul,				TYPE_ENTIER,				NULL},
	{"upal",				&chneUPal,				TYPE_CHAINE,				NULL},
	{"util",				&chneUTil,				TYPE_CHAINE,				NULL},

	{"txt",					&ModeTexte,				TYPE_BOOLEEN,				NULL},
	{"16c",					&b16coul,				TYPE_BOOLEEN,				NULL},
	{"cmode",				&chneColorMode,			TYPE_CHAINE,				NULL},
	{"gmap",				&bGenereMap,			TYPE_BOOLEEN,				NULL},
	{"opt",					&bOptimiseTileset,		TYPE_BOOLEEN,				NULL},
	{"mapmode",				&chneMapMode,			TYPE_CHAINE,				NULL},

	{"mdim",				&chneTVoulue,			TYPE_CHAINE,				NULL},
	{"tdim",				&chneTileXY,			TYPE_CHAINE,				NULL},

};
//Traduction possible

void FctConv(char *ptr)			{
	char cmd[100], chaine[500], *chn;
	int i, valeur;
	ELEMENT els[10];					//Eléments à passer aux fonctions de conversion
	char nom_court[MAX_PATH], temp[MAX_PATH], *temp_ptr;

	//Initialisations
	typeDeConversion=0;
	convBmp[0]=0;
	convDst[0]=0;
	convPal[0]=0;
	convMap[0]=0;
	chneUPal[0]=0;
	chneUTil[0]=0;
	AnnuleNomVar();
	maxCoul=255;
	utilPalette=-1;
	optimisePal=TRUE;
	ModeTexte=1;
	bGenereMap=1;
	bOptimiseTileset=TRUE;
	optimiseTil=TRUE;
	chneTVoulue[0]=0;
	chneTileXY[0]=0;
	b16coul=FALSE;
	bTil32Bits=FALSE;
	chneColorMode[0]=0;
	chneMapMode[0]=0;

	//Saut des espaces
	while (*ptr=='	')
		ptr++;

	while(*ptr)		{
		while (*ptr==' ')
			ptr++;

		i=0;
		if (*ptr=='+')		{
			valeur=1;
			ptr++;
		}
		else if (*ptr=='-')		{
			valeur=0;
			ptr++;
		}
		else if (*ptr=='!')		{
			valeur=2;
			ptr++;
		}
		else
			valeur=-1;

		for (i=0;*ptr && *ptr!=' ' && *ptr!='=' && i<100;)
			cmd[i++]=*ptr++;
		cmd[i]=0;
		chaine[0]=0;

		if (*ptr=='=')			{
			ptr++;
			if (*ptr=='\"')			{
				ptr++;
				for (i=0;*ptr && *ptr!='\"' && i<500;)
					chaine[i++]=*ptr++;
				ptr++;
			}
			else	{
				for (i=0;*ptr && *ptr!=' ' && i<500;)
					chaine[i++]=*ptr++;
			}
			chaine[i]=0;
		}

		for (i=sizeof(idConv)/sizeof(idConv[0])-1;i>=0;i--)			{
			if (!strcmp(idConv[i].nom,cmd))
				break;
		}

		if (i<0)		{
			Debug("Identificateur de conversion non-reconnu: %s",cmd);
			continue;
		}

		if (idConv[i].type==TYPE_SPECIAL)		{
			//name="" à recopier sur tous les noms
			if ((int)idConv[i].handle==1)			{
				ChangeTousNomVar(chaine);
			}
		}

		if (idConv[i].type==TYPE_ENTIERDIRECT)
			*(int*)idConv[i].handle=(int)idConv[i].valeur;
		else if (idConv[i].type==TYPE_BOOLEEN)			{
			if (valeur!=-1)			{
				*(int*)idConv[i].handle=valeur;
				if (idConv[i].handle==&b16coul)			{
					if (valeur==0)
						maxCoul=255;
					else
						maxCoul=15;
				}
			}
		}
		else if (idConv[i].type==TYPE_ENTIER)
			*(int*)idConv[i].handle=atoi(chaine);
		else if (idConv[i].type==TYPE_CHAINE)		{
			int j;
			chn=(char*)idConv[i].handle;
			j=0;
			while(j<TAILLE_MAX_CHAINES && i)			{
				chn[j]=chaine[j];
				j++;
			}

			if (idConv[i].handle==chneUPal)			{
				if (valeur==2)
					optimisePal=FALSE;
			}
			else if (idConv[i].handle==chneUTil)			{
				if (valeur==2)
					optimiseTil=FALSE;
			}
			else if (idConv[i].handle==convBmp)			{
				strcpy(temp, convBmp);
				temp_ptr = GetExtension(temp);
				if (*temp_ptr)
					*(temp_ptr-1)=0;
				if (typeDeConversion==3)			{
					strcpy(convDst,temp);
					strcat(convDst,b16_def_ext);
				}
				else if (typeDeConversion==2)			{
					strcpy(convDst,temp);
					strcat(convDst,b8_def_ext);
					strcpy(convPal,temp);
					strcat(convPal,pal_def_ext);
				}
				else if (typeDeConversion==1)			{
					strcpy(convDst,temp);
					strcat(convDst,til_def_ext);
					strcpy(convPal,temp);
					strcat(convPal,pal_def_ext);
					strcpy(convMap,temp);
					strcat(convMap,map_def_ext);
				}
				strcpy(chaine, convBmp);
				//Pas trouvé d'extension?
				if (*GetExtension(chaine)==0)	{
					//Si le fichier.bmp existe, on le prend, sinon on essaie avec .png
					strcat(convBmp,".bmp");
					if (!FichierExiste(convBmp))			{
						strcpy(convBmp, chaine);
						strcat(convBmp,".png");
						//Si le PNG ça ne va pas, on prend le JPG
						if (!FichierExiste(convBmp))			{
							strcpy(convBmp, chaine);
							strcat(convBmp,".jpg");
							//Si le JPG ça ne va pas, on prend le GIF
							if (!FichierExiste(convBmp))			{
								strcpy(convBmp, chaine);
								strcat(convBmp,".gif");
								if (!FichierExiste(convBmp))			{
									//Décidément ce n'est pas notre jour, il reste encore le TIF
									strcpy(convBmp, chaine);
									strcat(convBmp,".tif");
									if (!FichierExiste(convBmp))			{
										//Il n'existe vraiment pas, alors on reprend le BMP par défaut
										strcpy(convBmp, chaine);
										strcat(convBmp,".bmp");
									}
								}
							}
						}
					}
				}
			}
			else if (idConv[i].handle==convDst)			{
				if (typeDeConversion==3)			{
					strcat(convDst,b16_def_ext);
				}
				else if (typeDeConversion==2)			{
					strcpy(convPal,convDst);
					strcat(convPal,pal_def_ext);
					strcat(convDst,b8_def_ext);
				}
				else if (typeDeConversion==1)			{
					strcpy(convPal,convDst);
					strcat(convPal,pal_def_ext);
					strcpy(convMap,convDst);
					strcat(convMap,map_def_ext);
					strcat(convDst,til_def_ext);
				}
			}
			else if (idConv[i].handle==convMap && typeDeConversion==1)
				strcat(convMap,map_def_ext);
			else if (idConv[i].handle==convPal && typeDeConversion<=2)
				strcat(convPal,pal_def_ext);
		}
	}

	if (chneUPal[0])			{
		i=TrouveElement(TYPE_PALETTE,chneUPal);
		if (i==-1)			{
			Debug("Erreur -> TrouveElement(TYPE_PALETTE,chneUPal)");
			return;
		}
		utilPalette=i;
	}
	else
		utilPalette=-1;

	if (chneUTil[0])			{
		i=TrouveElement(TYPE_MOSAIQUE,chneUTil);
		if (i==-1)			{
			Debug("Erreur -> TrouveElement(TYPE_MOSAIQUE,chneUTil)");
			return;
		}
		bUtilTileset=i;
	}
	else
		bUtilTileset=-1;

	if (typeDeConversion==3)		{
		strcpy(els[0].nom_base,convBmp);
		strcpy(els[0].nom_fichier,convDst);

		faitNomCourt(convDst,nom_court);
		strcpy(els[0].nom_court,nom_court);

		els[0].type=TYPE_BITMAP16;

		if (PasteImage(els[0].nom_base,&tailleX,&tailleY,0))		{
			if (ConvertitBmp16(els))		{					//Si la conversion a réussi
				AjouteAuProjet(els[0]);
			}
		}
	}
	else if (typeDeConversion==2 && maxCoul>=1 && maxCoul<=255)			{
		strcpy(els[0].nom_base,convBmp);
		strcpy(els[0].nom_fichier,convDst);

		faitNomCourt(convDst,nom_court);
		strcpy(els[0].nom_court,nom_court);

		els[0].type=TYPE_BITMAP8;
	
		if (PasteImage(els[0].nom_base,&tailleX,&tailleY,1))		{
			strcpy(els[1].nom_base,convBmp);

			if (utilPalette>=0)
				strcpy(els[1].nom_fichier,elements[utilPalette].nom_fichier);
			else
				strcpy(els[1].nom_fichier,convPal);

			faitNomCourt(els[1].nom_fichier,nom_court);
			strcpy(els[1].nom_court,nom_court);

			els[1].type=TYPE_PALETTE;

			if (ConvertitBmp8(els,maxCoul))			{
/*				if (utilPalette>=0)
					EffaceElement(utilPalette);*/

				AjouteAuProjet(els[0]);
				AjouteAuProjet(els[1]);
			}
		}
	}
	else if (typeDeConversion==1 && maxCoul>=1 && maxCoul<=255)			{
		//Récupération des arguments spéciaux (mdim et tdim)
		tailleVoulueX=tailleVoulueY=0;
		if (chneTVoulue[0])			{
			tailleVoulueX=atoi(chneTVoulue);
			i=0;
			while(chneTVoulue[i]!='x' && chneTVoulue[i])
				i++;
			if (chneTVoulue[i])
				tailleVoulueY=atoi(chneTVoulue+i+1);
			else
				tailleVoulueY=0;
		}

		if (tailleVoulueX<0 || tailleVoulueY<0)			{
			Debug("Dimensions de la map négatives");
			return;
		}

		tileX=tileY=8;
		if (chneTileXY[0])			{
			tileX=atoi(chneTileXY);
			i=0;
			while(chneTileXY[i]!='x' && chneTileXY[i])
				i++;
			if (chneTileXY[i])
				tileY=atoi(chneTileXY+i+1);
		}

		//Définit le mode de couleurs
		if (chneMapMode[0])			{
			if (!strncmp(chneMapMode, "32", 2))
				ModeTexte=2;
			else if (!strncmp(chneMapMode, "16", 2))
				ModeTexte=1;
			else if (!strncmp(chneMapMode, "8", 1))
				ModeTexte=0;
		}

		//Définit le mode de couleurs
		if (chneColorMode[0])			{
			if (!strncmp(chneColorMode, "4", 1))			{
				b16coul=1;
				if (maxCoul>=16)
					maxCoul=15;
			}
			else if (!strncmp(chneColorMode, "15", 2))
				bTil32Bits=1;
		}


		if (tileX%8 || tileY%8 || tileX>128 || tileY>128 || tileX<0 || tileY<0)			{
			Debug("Erreur sur les dimensions du tileset (multiple de 8 et inférieur à 128)");
			return;
		}

		//Début
		strcpy(els[0].nom_base,convBmp);

		if (bUtilTileset>=0)
			strcpy(els[0].nom_fichier,elements[bUtilTileset].nom_fichier);
		else
			strcpy(els[0].nom_fichier,convDst);

		faitNomCourt(els[0].nom_fichier,nom_court);
		strcpy(els[0].nom_court,nom_court);

		EffaceEcran(Bits2);

		if (PasteImage(els[0].nom_base,&tailleX,&tailleY,1))		{
			strcpy(els[1].nom_base,convBmp);

			if (utilPalette>=0)
				strcpy(els[1].nom_fichier,elements[utilPalette].nom_fichier);
			else
				strcpy(els[1].nom_fichier,convPal);

			faitNomCourt(els[1].nom_fichier,nom_court);
			strcpy(els[1].nom_court,nom_court);

			strcpy(els[2].nom_base,convBmp);
			strcpy(els[2].nom_fichier,convMap);

			faitNomCourt(convMap,nom_court);
			strcpy(els[2].nom_court,nom_court);

			els[0].type=TYPE_MOSAIQUE;
			els[1].type=TYPE_PALETTE;
			els[2].type=TYPE_CARTE;

			if (ConvertitTiles(els,maxCoul))			{
/*				if (utilPalette>=0)
					EffaceElement(utilPalette);

				if (bUtilTileset>=0)
					EffaceElement(bUtilTileset);*/

				AjouteAuProjet(els[0]);
				if (!bTil32Bits)
					AjouteAuProjet(els[1]);
				if (bGenereMap)
					AjouteAuProjet(els[2]);
			}
		}				//Fin if image collée
	}


}

//Ne pas traduire

IDENTIFICATEUR objFonds[]=	{
	//Français
	{"alphapremplan",		&AlphaPremPlan,		TYPE_ENTIER},
	{"proprepalette",		&proprePalette,		TYPE_ENTIER},
	{"transparence",		&fondTransparent,	TYPE_ENTIER},
	{"ajoute",				FctAjouteFond,		TYPE_FONCTION},
	{"reinit",				FctReinitFonds,		TYPE_FONCTION},
	{"liemap",				FctLieMap,			TYPE_FONCTION},
	{"vitessedefil",		FctParallax,		TYPE_FONCTION},
	{"ajcondition",			FctAjCondition,		TYPE_FONCTION},
	{"grille",				FctGrille,			TYPE_FONCTION},

	//Anglais
	{"alphaforeground",		&AlphaPremPlan,		TYPE_ENTIER},
	{"multipalettes",		&proprePalette,		TYPE_ENTIER},
	{"transparency",		&fondTransparent,	TYPE_ENTIER},
	{"add",					FctAjouteFond,		TYPE_FONCTION},
	{"reset",				FctReinitFonds,		TYPE_FONCTION},
	{"link",				FctLieMap,			TYPE_FONCTION},
	{"scrollrate",			FctParallax,		TYPE_FONCTION},
	{"addcondition",		FctAjCondition,		TYPE_FONCTION},
	{"stepping",			FctGrille,			TYPE_FONCTION},
	{"grid",				FctGrille,			TYPE_FONCTION},

	//Les deux
	{"alphahex",			&hexAlphaFonds,		TYPE_ENTIER},
	{"alphagfx",			&gfxAlphaFonds,		TYPE_ENTIER},
	{"visible",				infoTabFondVisible, TYPE_TABLEAU},
	{"emulgba",				FctEmulGBA,			TYPE_FONCTION},
};

IDENTIFICATEUR objHexa[]=	{
	//Français
	{"actif",				&MODE_TEXTE,		TYPE_ENTIER},
	{"comblezeros",			&combleZeros,		TYPE_ENTIER},
	{"fondactif",			&fondHexa,			TYPE_ENTIER},

	//Anglais
	{"enabled",				&MODE_TEXTE,		TYPE_ENTIER},
	{"fillzeros",			&combleZeros,		TYPE_ENTIER},
	{"activemap",			&fondHexa,			TYPE_ENTIER},
};

IDENTIFICATEUR objSystem[]=	{
	//Français
	{"répertoire",			repertoire,			TYPE_CHAINE},
	{"objetsmax",			FctMaxObjets,		TYPE_FONCTION},
	{"sauverparamsmaps",	&sauverParamsMaps,	TYPE_ENTIER},
	{"sauverparamsmapsauto",&sauverParamsMapsAutomatiquement,TYPE_ENTIER},
	{"memoiremax",			FctMemoireMax,		TYPE_FONCTION},
	{"selectionformatauto",	&bChoisitAutoFormat,TYPE_ENTIER},

	//Anglais
	{"directory",			repertoire,			TYPE_CHAINE},
	{"maxobjects",			FctMaxObjets,		TYPE_FONCTION},
	{"savemapsparams",		&sauverParamsMaps,	TYPE_ENTIER},
	{"savemapsparamsauto",	&sauverParamsMapsAutomatiquement,TYPE_ENTIER},
	{"maxmemory",			FctMemoireMax,		TYPE_FONCTION},
	{"autoformatselection",	&bChoisitAutoFormat,TYPE_ENTIER},

	//Les deux
	{"emulgba",				FctEmulGBAAncien,	TYPE_FONCTION},
};

IDENTIFICATEUR objConvert[]=	{
	//Français
	{"couleurmasque",		FctCoulTrans,		TYPE_FONCTION},
	{"couleurzero",			FctPalZero,			TYPE_FONCTION},
	{"utilmaxcoul",			&utilMaxCoul,		TYPE_ENTIER},
	{"luminosite",			FctLumiere,			TYPE_FONCTION},
	{"nuances",				FctNuances,			TYPE_FONCTION},
	{"nuancesavant",		FctNuancesAvant,	TYPE_FONCTION},
	{"mode",				FctModeReduc,		TYPE_FONCTION},
	{"tronquer",			FctTronquer,		TYPE_FONCTION},
	{"precisionmax",		&precisionMax,		TYPE_ENTIER},

	//Anglais
	{"maskcolor",			FctCoulTrans,		TYPE_FONCTION},
	{"zerocolor",			FctPalZero,			TYPE_FONCTION},
	{"usemaxcolors",		&utilMaxCoul,		TYPE_ENTIER},
	{"lighting",			FctLumiere,			TYPE_FONCTION},
	{"shades",				FctNuances,			TYPE_FONCTION},
	{"shadesbefore",		FctNuancesAvant,	TYPE_FONCTION},
	{"quantization",		FctModeReduc,		TYPE_FONCTION},
	{"truncate",			FctTronquer,		TYPE_FONCTION},
	{"maxprecision",		&precisionMax,		TYPE_ENTIER},

	//Les deux
	{"tilex",				&tileX,				TYPE_ENTIER},
	{"tiley",				&tileY,				TYPE_ENTIER},
};

IDENTIFICATEUR objEdit[]=	{
	//Français
	{"popupinfos",			&popUpInfos,		TYPE_ENTIER},
	{"tempspopup",			&tempsPopUp,		TYPE_ENTIER},
	{"blocinvisible",		&masqueInvisible,	TYPE_ENTIER},
	{"zoomprecis",			&zoomPrecis,		TYPE_ENTIER},
	{"grille",				&grille,			TYPE_ENTIER},
	{"couleurgrille",		&couleurGrille,		TYPE_ENTIER},
	{"alphagrille",			&transGrille,		TYPE_ENTIER},
	{"masquezero",			&masqueZero,		TYPE_ENTIER},
	{"timing",				&editTiming,		TYPE_ENTIER},
	{"deplace",				FctBougeEditeur,	TYPE_FONCTION},

	//Anglais
	{"popupinfos",			&popUpInfos,		TYPE_ENTIER},
	{"popuptime",			&tempsPopUp,		TYPE_ENTIER},
	{"invisibleblock",		&masqueInvisible,	TYPE_ENTIER},
	{"precisezoom",			&zoomPrecis,		TYPE_ENTIER},
	{"grid",				&grille,			TYPE_ENTIER},
	{"gridcolor",			&couleurGrille,		TYPE_ENTIER},
	{"alphagrid",			&transGrille,		TYPE_ENTIER},
	{"zeromask",			&masqueZero,		TYPE_ENTIER},
	{"move",				FctBougeEditeur,	TYPE_FONCTION},

	{"zoom",				FctZoom,			TYPE_FONCTION},
};

IDENTIFICATEUR objDossier[]=	{
	//Français
	{"cartes",			dossierParDefaut[0],	TYPE_CHAINE},
	{"mosaiques",		dossierParDefaut[2],	TYPE_CHAINE},
	{"listes",			dossierParDefaut[6],	TYPE_CHAINE},
	{"dossier",			infoTabDoss,			TYPE_TABLEAU},

	//Anglais
	{"maps",			dossierParDefaut[0],	TYPE_CHAINE},
	{"tilesets",		dossierParDefaut[2],	TYPE_CHAINE},
	{"lists",			dossierParDefaut[6],	TYPE_CHAINE},
	{"folder",			infoTabDoss,			TYPE_TABLEAU},

	//Les deux
	{"bitmaps8",		dossierParDefaut[3],	TYPE_CHAINE},
	{"bitmaps16",		dossierParDefaut[4],	TYPE_CHAINE},
	{"palettes",		dossierParDefaut[5],	TYPE_CHAINE},
};

IDENTIFICATEUR objSpecimen[]=	{
	//Français
	{"affiche",				FctAfficheSpecimen,	TYPE_FONCTION},
	{"ajoutemap",			FctAssoc,			TYPE_FONCTION},
	{"deplace",				FctBougeSpecimen,	TYPE_FONCTION},
	
	//Anglais
	{"show",				FctAfficheSpecimen,	TYPE_FONCTION},
	{"addmap",				FctAssoc,			TYPE_FONCTION},
	{"move",				FctBougeSpecimen,	TYPE_FONCTION},
};

IDENTIFICATEUR objBits[]=	{
	//Français
	{"affiche",				FctAfficheBits,		TYPE_FONCTION},
	{"textebit",			FctTexteBit,		TYPE_FONCTION},
	{"bitactif",			FctBitActif,		TYPE_FONCTION},
	{"masquezero",			&bitsMasqueZero,	TYPE_ENTIER},
	{"deplace",				FctBougeBits,		TYPE_FONCTION},

	//Anglais
	{"show",				FctAfficheBits,		TYPE_FONCTION},
	{"bittext",				FctTexteBit,		TYPE_FONCTION},
	{"bitenabled",			FctBitActif,		TYPE_FONCTION},
	{"zeromask",			&bitsMasqueZero,	TYPE_ENTIER},
	{"move",				FctBougeBits,		TYPE_FONCTION},
};

IDENTIFICATEUR objListe[]=	{
	//Français
	{"reinitparams",		FctResetParams,		TYPE_FONCTION},
	{"ajparam",				FctAjParam,			TYPE_FONCTION},
	//Anglais
	{"resetparams",			FctResetParams,		TYPE_FONCTION},
	{"addparam",			FctAjParam,			TYPE_FONCTION},
	//Commun
};

typedef struct		{
	int taille;
	IDENTIFICATEUR *objet;
} INFOS_OBJET;

INFOS_OBJET infoObjFonds[]={sizeof(objFonds)/sizeof(objFonds[0]),objFonds};
INFOS_OBJET infoObjHexa[]={sizeof(objHexa)/sizeof(objHexa[0]),objHexa};
INFOS_OBJET infoObjSystem[]={sizeof(objSystem)/sizeof(objSystem[0]),objSystem};
INFOS_OBJET infoObjConvert[]={sizeof(objConvert)/sizeof(objConvert[0]),objConvert};
INFOS_OBJET infoObjEdit[]={sizeof(objEdit)/sizeof(objEdit[0]),objEdit};
INFOS_OBJET infoObjDoss[]={sizeof(objDossier)/sizeof(objDossier[0]),objDossier};
INFOS_OBJET infoObjSpec[]={sizeof(objSpecimen)/sizeof(objSpecimen[0]),objSpecimen};
INFOS_OBJET infoObjBits[]={sizeof(objBits)/sizeof(objBits[0]),objBits};
INFOS_OBJET infoObjListe[]={sizeof(objListe)/sizeof(objListe[0]),objListe};


//Types d'objets: voir types_objets dans le fichier "definitions.h"

/*HWND hBoutonOk=0, hTexte01=0, hBoutonParcourir=0, hStatic01=0, hRadioTexte=0,
	hRadioRotation=0, hStatic02=0, hTexte02=0, hBoutonParcourir2=0,
	hBoutonParcourir3=0, hTexte03=0, hStatic03=0, hBoutonParcourir4=0, hTexte04=0,
	hStatic04=0, hComboPalette=0, hCheckPal=0, hComboTileset=0, hCheckTileset=0,
	hCheckMap=0, hTexte05=0, hStatic05=0, hStatic06=0, hComboTaille=0, hCheckOptimise=0,
	hComboTiles=0, hComboMap=0, hCheck16=0;*/

IDENTIFICATEUR objets[]=		{
	//Français
	{"arbre-mosaiques",		&htvMosaiques,			TYPE_TREEVIEW},
	{"arbre-cartes",		&htvCartes,				TYPE_TREEVIEW},
	{"arbre-bitmaps8",		&htvBitmaps8,			TYPE_TREEVIEW},
	{"arbre-bitmaps16",		&htvBitmaps16,			TYPE_TREEVIEW},
	{"texte-01",			&hTexte01,				TYPE_EDIT},
	{"texte-02",			&hTexte02,				TYPE_EDIT},
	{"texte-03",			&hTexte03,				TYPE_EDIT},
	{"texte-04",			&hTexte04,				TYPE_EDIT},
	{"texte-05",			&hTexte05,				TYPE_EDIT},
	{"texte-source",		&hTexte01,				TYPE_EDIT},
	{"texte-dest",			&hTexte02,				TYPE_EDIT},
	{"texte-palette",		&hTexte03,				TYPE_EDIT},
	{"texte-map",			&hTexte04,				TYPE_EDIT},
	{"texte-couleurs",		&hTexte05,				TYPE_EDIT},
	{"texte-tileset",		&hTexte02,				TYPE_EDIT},
	{"texte-taillex",		&hTexte02,				TYPE_EDIT},
	{"texte-tailley",		&hTexte03,				TYPE_EDIT},
	{"check-palette",		&hCheckPal,				TYPE_CHECKBOX},
	{"check-map",			&hCheckMap,				TYPE_CHECKBOX},
	{"check-tileset",		&hCheckTileset,			TYPE_CHECKBOX},
	{"check-optimise",		&hCheckOptimise,		TYPE_CHECKBOX},
	{"check-16",			&hCheck16,				TYPE_CHECKBOX},
	{"radio-texte",			&hRadioTexte,			TYPE_RADIO},
	{"radio-rotation",		&hRadioRotation,		TYPE_RADIO},
	{"combo-palette",		&hComboPalette,			TYPE_COMBOBOX},
	{"combo-tileset",		&hComboTileset,			TYPE_COMBOBOX},
	{"combo-taille",		&hComboTaille,			TYPE_COMBOBOX},
	{"combo-tiles",			&hComboTiles,			TYPE_COMBOBOX},
	{"combo-map",			&hComboMap,				TYPE_COMBOBOX},
	{"ok",					FctOk,					TYPE_FONCTION},
	{"msgbox",				FctMsgBox,				TYPE_FONCTION},
	{"visible",				FctShowWindow,			TYPE_FONCTION},
	{"quitte",				FctQuitte,				TYPE_FONCTION},
	{"fin",					FctFin,					TYPE_FONCTION},
	{"exec",				FctExec,				TYPE_FONCTION},
	{"goto",				FctGoto,				TYPE_FONCTION},
	{"messages",			&messages,				TYPE_ENTIER},
	{"répertoire",			repertoire,				TYPE_CHAINE},
//	{"test",				infoTabTest,			TYPE_TABLEAU},
	{"script",				fichierConfigAOuvrir,	TYPE_CHAINE},
	{"aideperso",			fichierAide,			TYPE_CHAINE},
	{"retour",				FctRetour,				TYPE_FONCTION},
	{"dossiers",			infoObjDoss,			TYPE_OBJET},
	{"dossierdéf",			infoTabDoss,			TYPE_TABLEAU},
	{"effets",				FctLumiere,				TYPE_FONCTION},
	{"defformat",			FctNvFormat,			TYPE_FONCTION},
	{"defmodele",			FctDefParamList,		TYPE_FONCTION},
	{"format",				FctFormat,				TYPE_FONCTION},
	{"modele",				FctModele,				TYPE_FONCTION},
	{"selmodele",			FctSetModele,			TYPE_FONCTION},
	{"selformat",			FctSetFormat,			TYPE_FONCTION},
	{"inclure",				FctInclure,				TYPE_FONCTION},

	//Anglais
	{"tree-tilesets",		&htvMosaiques,			TYPE_TREEVIEW},
	{"tree-maps",			&htvCartes,				TYPE_TREEVIEW},
	{"tree-bitmaps8",		&htvBitmaps8,			TYPE_TREEVIEW},
	{"tree-bitmaps16",		&htvBitmaps16,			TYPE_TREEVIEW},
	{"text-01",				&hTexte01,				TYPE_EDIT},
	{"text-02",				&hTexte02,				TYPE_EDIT},
	{"text-03",				&hTexte03,				TYPE_EDIT},
	{"text-04",				&hTexte04,				TYPE_EDIT},
	{"text-05",				&hTexte05,				TYPE_EDIT},
	{"text-source",			&hTexte01,				TYPE_EDIT},
	{"text-dest",			&hTexte02,				TYPE_EDIT},
	{"text-palette",		&hTexte03,				TYPE_EDIT},
	{"text-map",			&hTexte04,				TYPE_EDIT},
	{"text-colors",			&hTexte05,				TYPE_EDIT},
	{"text-tileset",		&hTexte02,				TYPE_EDIT},
	{"text-sizex",			&hTexte02,				TYPE_EDIT},
	{"text-sizey",			&hTexte03,				TYPE_EDIT},
	{"check-palette",		&hCheckPal,				TYPE_CHECKBOX},
	{"check-map",			&hCheckMap,				TYPE_CHECKBOX},
	{"check-tileset",		&hCheckTileset,			TYPE_CHECKBOX},
	{"check-optimize",		&hCheckOptimise,		TYPE_CHECKBOX},
	{"check-16",			&hCheck16,				TYPE_CHECKBOX},
	{"radio-text",			&hRadioTexte,			TYPE_RADIO},
	{"radio-rotation",		&hRadioRotation,		TYPE_RADIO},
	{"combo-palette",		&hComboPalette,			TYPE_COMBOBOX},
	{"combo-tileset",		&hComboTileset,			TYPE_COMBOBOX},
	{"combo-size",			&hComboTaille,			TYPE_COMBOBOX},
	{"combo-tiles",			&hComboTiles,			TYPE_COMBOBOX},
	{"combo-map",			&hComboMap,				TYPE_COMBOBOX},
	{"ok",					FctOk,					TYPE_FONCTION},
	{"msgbox",				FctMsgBox,				TYPE_FONCTION},
	{"visible",				FctShowWindow,			TYPE_FONCTION},
	{"quit",				FctQuitte,				TYPE_FONCTION},
	{"end",					FctFin,					TYPE_FONCTION},
	{"exec",				FctExec,				TYPE_FONCTION},
	{"goto",				FctGoto,				TYPE_FONCTION},
	{"messages",			&messages,				TYPE_ENTIER},
	{"directory",			repertoire,				TYPE_CHAINE},
	{"script",				fichierConfigAOuvrir,	TYPE_CHAINE},
	{"userhelp",			fichierAide,			TYPE_CHAINE},
	{"return",				FctRetour,				TYPE_FONCTION},
	{"folders",				infoObjDoss,			TYPE_OBJET},
	{"deffolder",			infoTabDoss,			TYPE_TABLEAU},
	{"effects",				FctLumiere,				TYPE_FONCTION},
	{"definefmt",			FctNvFormat,			TYPE_FONCTION},
	{"definemodel",			FctDefParamList,		TYPE_FONCTION},
	{"format",				FctFormat,				TYPE_FONCTION},
	{"model",				FctModele,				TYPE_FONCTION},
	{"setmodel",			FctSetModele,			TYPE_FONCTION},
	{"setformat",			FctSetFormat,			TYPE_FONCTION},
	{"include",				FctInclure,				TYPE_FONCTION},

	//Conversion rapide
	{"conv",				FctConv,				TYPE_FONCTION},

	//Les objets. Voir leur déclaration plus haut
	{"fonds",				infoObjFonds,			TYPE_OBJET},
	{"modehexa",			infoObjHexa,			TYPE_OBJET},
	{"system",				infoObjSystem,			TYPE_OBJET},
	{"convert",				infoObjConvert,			TYPE_OBJET},
	{"editeur",				infoObjEdit,			TYPE_OBJET},
	{"specimen",			infoObjSpec,			TYPE_OBJET},
	{"bits",				infoObjBits,			TYPE_OBJET},
	{"liste",				infoObjListe,			TYPE_OBJET},

	//En anglais
	{"maps",				infoObjFonds,			TYPE_OBJET},
	{"editor",				infoObjEdit,			TYPE_OBJET},
};

//Traduction possible

int OuvreFichierConfig(char *nom_fichier, char *fonction)		{
	FILE *f;

	retourScript=1;

	if (!(*nom_fichier))
		return 0;

	f=fopen(nom_fichier,"rt");
	if (!f)
		return 0;

	ExecScript(f,fonction);
	return 1;
}

void ExecScript(FILE *f, char *fonction)		{
	char str[1000], objet[1000], commande[1000], *arg, *ptr, tmp[4096];
	int i,j, type, val;
	void *handle;
	void (*laFonction)(char*);
	INFOS_OBJET *infos;
	int indice;

	arretdurgence=0;

	notification=messages=0;
	retourScript=1;

	if (fonction)		{				//Une fonction sur laquelle se brancher?
		//Pas case sensitive, bien entendu :p
		for (ptr=fonction;*ptr;ptr++)
			if (*ptr>='A' && *ptr<='Z')
				*ptr+=32;
	}

	trouveLabel=fonction;
	while(!feof(f))		{
		fgets(str,sizeof(str),f);
		if (!str[0])
			continue;

		//Tout d'abord: ne pas être "case sensitive"...
		for (i=0;str[i];i++)	{
			if (str[i]>='A' && str[i]<='Z')
				str[i]+=32;

			if (str[i]=='\"')	{
				i++;
				while(str[i] && (str[i]!='\"' || (str[i-1]=='\\' && str[i]=='\"')))
					i++;
				if (!str[i])
					break;
			}
			else if (str[i]=='\'')	{
				i++;
				while(str[i] && (str[i]!='\'' || (str[i-1]=='\\' && str[i]=='\'')))
					i++;
				if (!str[i])
					break;
			}
			else if (str[i]=='*')	{
				i++;
				while(str[i] && (str[i]!='*' || (str[i-1]=='\\' && str[i]=='*')))
					i++;
				if (!str[i])
					break;
			}
			else if (str[i]=='#' || str[i]==';'/* || str[i]=='\'' || str[i]=='/'*/)		{
				str[i]=0;
				if (i>0)	{
					i--;
					while(str[i]==' ' || str[i]=='	' && i>=0)
						str[i--]=0;
				}
				goto parsingTermine;
			}
		}
		str[i-1]=0;
		i-=2;

parsingTermine:

		if (str[i]==':' && !trouveLabel)		//Label trouvé!
			continue;

		//Sauter les espaces/tabs éventuels
		i=j=indice=0;
		while(str[i]==' ' || str[i]=='	')
			i++;

		//Bon, c'est pas le tout, mais on a un label à trouver nous!
		if (trouveLabel)		{
			if (str[i]=='_')
				i++;
			j=i;
			while(!(str[i]==':' && str[i+1]==0) && str[i])
				i++;
			if (!str[i])									//Pas un label
				continue;
			str[i]=0;
			if (strcmp(trouveLabel,str+j))					//Pas le bon label
				continue;
			trouveLabel=NULL;								//Label trouvé -> plus à rechercher.
			continue;
		}

		//Après, récupérer l'objet de la commande (opérande gauche)
		while(str[i] && str[i]!=' ' && str[i]!='	' && str[i]!='.' && str[i]!='=' && str[i]!='[')
			objet[j++]=str[i++];

		//Si ça n'a pas été terminé par un point
		while(str[i]!='[' && str[i]!='.' && str[i]!='=' && str[i] && str[i]!=' ')		i++;

		//Termine la chaîne
		objet[j]=0;

		//L'objet est faux?
		if (!objet[0])
			continue;

		//Permet ensuite de savoir si aucune commande n'a été donnée
		commande[0]=0;

		if (str[i]=='=' || str[i]==' ')				//Pas de méthode
			goto sauteEspaces;

		//Fin de chaîne -> seul un objet est spécifié
		if (!str[i])
			goto sauteEspaces;

		//Prochain caractère
		if (str[i]!='[')
			i++;
		//Saute les espaces
		while(str[i]==' ' || str[i]=='	')	i++;

commande:
		//Après, récupérer la commande à exécuter (opérande droite)
		j=0;
		while(str[i] && str[i]!=' ' && str[i]!='	' && str[i]!='=' && str[i]!='[')
			commande[j++]=str[i++];

		//Termine la chaîne
		commande[j]=0;

		//Sauter les espaces/tabulations qui viennent ensuite
sauteEspaces:
		if (str[i]==' ' || str[i]=='	')		{
			while(str[i]==' ' || str[i]=='	')
				i++;
		}

		if (str[i]=='.')	{
			i++;
			goto commande;
		}
		if (str[i]=='=')	{
			i++;
			goto sauteEspaces;
		}
		if (str[i]=='[')	{
			i++;
			indice=GetEntier(str+i)-1;
			while(str[i] && str[i]!=']')
				i++;
			if (str[i])		{
				i++;
				goto sauteEspaces;
			}
		}

		//On est prêt pour exécuter une commande!
		ptr=str+i;

		handle=NULL;
		gblFichierConfig=f;

		//Trouve la référence d'objet dans la table
		for (i=0;i<sizeof(objets)/sizeof(objets[0]);i++)		{
			if (!strcmp(objet,(char*)objets[i].nom))		{
				handle=objets[i].handle, type=objets[i].type;
				break;
			}
		}

		//Aucun résultat
		if (!handle)		{
			sprintf(tmp,"L'objet %s n'existe pas.",objet);
			MessageBox(gblHDlg,tmp,"Erreur d'exécution de macro",MB_ICONERROR);
			continue;
		}

		gblIndice=indice;

		if (type==TYPE_OBJET)		{
			IDENTIFICATEUR *id;
			infos=(INFOS_OBJET*)handle;

			id=infos->objet;

			handle=NULL;
			//Trouve la référence d'objet dans la table
			for (i=0;i<infos->taille;i++)		{
				if (!strcmp(commande,(char*)id[i].nom))		{
					handle=id[i].handle, type=id[i].type;
					break;
				}
			}
			//Aucun résultat
			if (!handle)		{
				sprintf(tmp,"La méthode %s de l'objet %s n'existe pas.",commande,objet);
				MessageBox(gblHDlg,tmp,"Erreur d'exécution de macro",MB_ICONERROR);
				continue;
			}
		}

		if (type==TYPE_TABLEAU)		{
			INFOS_TABLEAU *it;
			it=(INFOS_TABLEAU*)handle;
			if (indice<0 || indice>=it->taille)		{
				sprintf(tmp,"Tableau %s de l'objet %s.\nL'indice (%i) est en dehors de la plage.",commande,objet,indice+1);
				MessageBox(gblHDlg,tmp,"Erreur d'exécution de macro",MB_ICONERROR);
				continue;
			}
			type=it->type;
			if (type==TYPE_ENTIER)
				handle=(int*)it->tableau+indice;
			else if (type==TYPE_CHAINE)
				handle=(char (*)[TAILLE_MAX_CHAINES])it->tableau+indice;
			else if (type==TYPE_REEL)
				handle=(double*)it->tableau+indice;
			//Vous devriez pouvoir adapter pour d'autres types sans trop de problèmes ;)
			else		{
				sprintf(tmp,"Le tableau %s de l'objet %s a un type incalculable.",commande,objet);
				MessageBox(gblHDlg,tmp,"Erreur d'exécution de macro",MB_ICONERROR);
				continue;
			}
		}

		if (type==TYPE_FONCTION)		{
			//Depuis que je m'amuse sur GBA avec ce genre de trucs, ça me semble déjà plus sûr comme méthode. Ne vous inquiétez pas si vous trouvez ça sale :p
			laFonction=(void (*)(char*))handle;
			laFonction(ptr);
			if (arretdurgence)
				break;
			continue;
		}
		else if (type==TYPE_ENTIER)		{
			val=GetEntier(ptr);
			*(int*)handle=val;
			continue;
		}
		else if (type==TYPE_REEL)		{
			*(double*)handle=atof(ptr);
			continue;
		}
		else if (type==TYPE_CHAINE)		{
			arg=GetChaine(&ptr);
			ptr=(char*)handle;
			for (i=0;i<TAILLE_MAX_CHAINES-1 && *arg;i++)
				*ptr++=*arg++;
			(*ptr)=0;
			continue;
		}
		else if (type==TYPE_TREEVIEW)		{
			TreeView_SelectItem(hArbre,*(HANDLE*)handle);
			DessFenetre(gblHDlg,*(HANDLE*)handle);
		}
		else if (type==TYPE_EDIT)		{
			arg=GetChaine(&ptr);
			if (!arg)		{
argumentsManquants:
				sprintf(tmp,"Objet %s.\nIl manque des arguments et/ou leur type est incorrect.",objet);
				MessageBox(gblHDlg,tmp,"Erreur d'exécution de macro",MB_ICONERROR);
				continue;
			}
			SetWindowText(*(HWND*)handle,arg);
		}
		else if (type==TYPE_COMBOBOX)		{
			arg=GetChaine(&ptr);
			if (!arg)
				goto argumentsManquants;
			val=SendMessage(*(HWND*)handle,CB_FINDSTRINGEXACT,-1,(LPARAM)arg);
			if (val==CB_ERR)		{
				sprintf(tmp,"Objet: %s.\nLe texte recherché dans la zone de liste déroulante n'y figure pas (%s).",objet,arg);
				MessageBox(gblHDlg,tmp,"Erreur d'exécution de macro",MB_ICONERROR);
				continue;
			}
			SendMessage(*(HWND*)handle,CB_SETCURSEL,val,0);
		}
		else if (type==TYPE_CHECKBOX || type==TYPE_RADIO)		{
			val=GetEntier(ptr);
			SendMessage(*(HWND*)handle,BM_SETCHECK,val,0);
			MajBoutons(*(HWND*)handle);
		}
	}

	notification=messages=1;
	fclose(f);
	ShowWindow(gblHDlg,SW_SHOW);
}



void AjouteProcedures(char *nom_fichier, HMENU hMenu)		{
	FILE *f;
	char str[1000];
	int i,j;

	nbreProcedures=0;

	if (!(*nom_fichier))		{
		AppendMenu(hMenu,MF_STRING|MF_DISABLED,BASEMENU-1,"(Aucun script spécifié)");
		return;
	}

	f=fopen(nom_fichier,"rt");
	if (!f)		{
		AppendMenu(hMenu,MF_STRING|MF_DISABLED,BASEMENU-1,"(Pas de script)");
		return;
	}

	while(!feof(f))		{
		fgets(str,sizeof(str),f);
		if (!str[0])
			continue;

		//Tout d'abord: ne pas être "case sensitive"...
		for (i=0;str[i];i++)	{
//			if (str[i]>='A' && str[i]<='Z')
//				str[i]+=32;

			if (str[i]=='#' || str[i]==';'/* || str[i]=='\'' || str[i]=='/'*/)		{
				str[i]=0;
				if (i>0)	{
					i--;
					while(str[i]==' ' || str[i]=='	' && i>=0)
						str[i--]=0;
				}
				goto parsingTermine;
			}
		}
		str[i-1]=0;

parsingTermine:

		//Sauter les espaces/tabs éventuels
		i=j=0;
		while(str[i]==' ' || str[i]=='	')
			i++;

		//Bon, c'est pas le tout, mais on a un label à trouver nous!
		j=i;
		while(!(str[i]==':' && str[i+1]==0) && str[i])
			i++;
		if (!str[i])									//Pas un label
			continue;
		str[i]=0;
		if (str[j]!='_')								//Pas un label exporté (_label:)
			continue;
		AppendMenu(hMenu,MF_STRING,BASEMENU+nbreProcedures,str+j+1);
		nbreProcedures++;
	}

	if (nbreProcedures==0)
		AppendMenu(hMenu,MF_STRING|MF_DISABLED,BASEMENU-1,"(Aucune)");

	notification=1;
	fclose(f);
}




