// UTS 2000 - Fichier 'train.cpp' Lecture des variables pour les trains dans le fichier de configuration, et gestion de ces trains.
// V3.7d 23/10/2017
/*****************************************************************************/
/* debut TRAIN                                                               */
/*****************************************************************************/
#include  <windows.h>
#include  <string.h>
#include  <stdlib.h>
#include  <stdio.h>
#include "Train_UTS.h"
#include "train.h"
#include "canton.h"
#include "garage.h"
#include "aigauto.h"
#include "balauto.h"
#include "serial_port.h"

#define _CRT_SECURE_NO_WARNINGS  // Limite les messages de warning dans Visual C++

// Déclaration des fonctions externes
extern int get_line(FILE*, char [][CHAR_CONFIG_NB], int*);
extern int can_to_cons(int, int);
extern void EasyTextOut(int, int, char*);
extern void EasyLine(int, int, int, int);
extern int virtualstep_to_cons(int);
extern int x_mouse,y_mouse, screen_mode_retour;
extern void bmp_SetTextColor(int no_color);


// Déclaration des classes externes
extern cCanton  canton;
extern cGarage  garage;
extern cAigauto aigauto;
extern cBalauto balauto;
extern cSerialPort serialPort;

// Déclaration des variables externes
extern HBRUSH  bmp_pinceau_blanc, bmp_pinceau_gris192, bmp_pinceau_rouge, bmp_pinceau_cyan, bmp_pinceau_vert;
extern HBRUSH  bmp_pinceau_jaune, bmp_pinceau_gris220, bmp_pinceau_noir, bmp_pinceau_magenta;
extern HDC     hMemDC;
extern HFONT   bmp_fonte;
extern HPEN    bmp_stylo_noir, bmp_stylo_gris128, bmp_stylo_gris192, bmp_stylo_blanc, bmp_stylo_rouge, bmp_stylo_magentaf, bmp_stylo_cyanf;
extern void bmp_select_brush(int no_color);
extern void bmp_select_brush(HDC h_dc_,int no_color);
extern int screen_mode;

extern int vio_garage_lock_cmd[NB_GARAGE]; // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
extern int vio_garage_lock_res[NB_GARAGE]; // 0 ou 1, 1 => Garage réservé.
extern int vio_garage_lock_status[NB_GARAGE]; // 0 ou 1, 1 => Le garage est isolé du canton (état réel).

extern int vio_det[NB_CARTE][NB_CANTON];
extern int vio_can[NB_CARTE][NB_CAN];

extern int vio_pot_virtual_step[NB_POT_VIR]; //UU_NEW
extern int vio_pot_virtual_conf[NB_POT_VIR][3];

extern int moins_char_normal;   // 1: '-' est un caractère normal (comme 0)  0: '-' est un séparateur (comme +)
extern int x_mouse,y_mouse,touche,touche_char,x_mouse_move,y_mouse_move;
extern int timer_prg;
extern int color_train[NB_TRAIN];
extern int canton_pb_capt[NB_CARTE][NB_CANTON];

extern int num_cant_a_lib;	// Numéro de canton à libérer dans debug2 uniquement.
extern int debug_tic_nb;
extern int vio_canton_vit[NB_CARTE][NB_CANTON];      //UU: n'en garder qu'un et mettre en debug total
extern int vio_canton_vit_profil[NB_CARTE][NB_CANTON];	// Valeurs envoyées vers la carte pour alimenter les cantons (après calcul du profil d'alimentation de la locomotive).

extern int cfg_aigauto;	                      // (1 par défaut) si=1 On active la configuration de la section "#aigauto", aiguillages automatiques.
extern int cfg_memoire_pos_train;             // (0 par défaut), =1 => UTS sauvegarde et récupére la position des trains sur le réseau, à la fermeture et ouverture du preogramme UTS.
extern int cmd_divers[CMD_DIVERS_TAILLE];     // Tableau pour commander directement les déplacements par clic sur les cases du TCO
extern int balauto_vitmax_train[NB_TRAIN];    // En cas de limitation de vitesse d'un train sur un canton '#balauto' + 'vitmax:' = 1 => Train limité.
extern int balauto_halt_train[NB_TRAIN];      // En cas de halte d'un train sur un canton '#balauto' + 'halt:' = 1 => Train en 'halt:'.
extern int balauto_cant_train[NB_TRAIN];      // =2 => En cas de blocage d'un train sur un canton '#balauto' +'cant:' = 1 => Consigne vitesse du train = 0. =1 => Ralentissement.
extern int balauto_cant_train_dec[NB_TRAIN];  // -1 ou 1 à 28 = décélération du train sur 'cant:'.
extern int balauto_cant_train_ral[NB_TRAIN];  // -64 à +64 = ralenti du train sur 'cant:'.

extern int vio_bal_cant_p[NB_CARTE][NB_CANTON]; // 0-1, 1 = Bloc automatique - Canton bloqué dans le sens Plus
extern int vio_bal_cant_m[NB_CARTE][NB_CANTON]; // 0-1, 1 = Bloc automatique - Canton bloqué dans le sens Moins
extern int cells_tick;

int inertie_tab_ind[VITESSE_INERTIE_MAXI][VITESSE_INERTIE_PAS]={
	{21,21,21,21,21,21,21,21,21,21,21,21},{16,16,16,16,16,16,16,16,16,16,16,16},
	{13,13,13,13,13,13,13,13,13,13,13,13},{10,10,10,10,10,10,10,10,10,10,10,10},
	{8,8,7,8,8,7,8,8,7,8,8,7}, {7,6,6,6,6,6,6,7,6,6,6,6}, {6,5,6,5,6,5,6,5,5,6,5,5}, {4,5,5,5,4,5,5,5,4,5,5,5}, 
	{5,4,4,4,4,4,4,4,4,4,4,4}, {4,4,3,4,3,4,4,3,4,3,4,3}, {3,3,3,3,3,3,3,3,3,3,3,3}, {2,3,3,2,3,3,2,3,3,2,3,3}, 
	{3,3,3,2,2,2,3,2,2,2,2,2}, {2,2,2,2,2,2,2,2,2,2,2,2}, {2,2,2,1,2,2,2,1,2,2,2,1}, {2,1,2,1,2,1,2,1,2,1,2,1}, 
	{2,1,1,1,2,1,1,1,2,1,1,1}, {1,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,0,1,1,1,1,1,0}, {1,1,1,0,1,1,1,0,1,1,1,0},
	{1,1,0,1,1,0,1,1,0,1,1,0}, {1,1,0,1,0,1,1,0,1,0,1,0}, {1,0,1,0,1,0,1,0,1,0,1,0}, {1,0,1,0,1,0,0,1,0,1,0,0}, 
	{1,0,0,1,0,0,1,0,0,1,0,0}, {1,0,0,0,1,0,0,0,1,0,0,0}, {1,0,0,0,0,0,1,0,0,0,0,0}, {1,0,0,0,0,0,0,0,0,0,0,0}};

// Tableau des valeurs 'Accélération' ou 'Décélération" de 1 à 28 donne une inertie de X secondes pour aller de Vmax  0 ou 0 à  vmax.
// Temps d'un pas unitaire = 96 ms = 80 ms + 14 ms de transfert rs232 + 2 msec pour l'éxecution du programme
//  1 =  0,3 sec,    2 = 0,4 sec,   3 =  0,5 sec,   4 =  0,6 sec,   5 =  0,8 sec,   6 =  1 sec, 
//  7 =  1,2 sec,    8 = 1,3 sec,   9 =  1,5 sec,  10 =  1,7 sec,  11 =  2 sec,    12 =  2,3 sec, 
// 13 =  2,7 sec,   14 = 3 sec,    15 =  3,5 sec,  16 =  4 sec,    17 =  5 sec,    18 =  6 sec, 
// 19 =  7 sec,    20 = 8 sec,     21 =  9 sec,    22 = 10 sec,    23 = 12 sec,    24 = 14 sec, 
// 25 = 18 sec,    26 = 24 sec,    27 = 36 sec,    28 = 74 sec, 

extern int acc_progressif[NB_PROGRESSIF]; // Tableau des vitesses pour une accélération progressive.
extern int dec_progressif[NB_PROGRESSIF]; // Tableau des vitesses pour une déccélération progressive.

cTrain   train;

//
int cTrain::get_iti_line(FILE* pf, char ch_tab[][CHAR_CONFIG_NB], int* ch_nb)
{
	int ret;
	moins_char_normal=0;  // '-' est un charactère normal (so it is parsed)
	ret=get_line(pf,ch_tab,ch_nb); 
	moins_char_normal=1;
	return ret;
}

//
cTrain::cTrain(void) { }



// Lecture dans le fichier 'config.txt' des paramètres pour la section 'train'.
// Initialisation au démarrage d'UTS.
//
// Exemple de configuration :
//	train0 : lo_bleue c0  clav0 05-64-xx-xx-xx en_auto
//	train1 : lo_verte c6  clav1 inv 05-64-xx-xx-xx en_auto
//	clav_conf_0  : +a !q -w
//	clav_conf_1  : !s -x +z
//
void cTrain::init(char filename[])
{
	FILE* pf;
	char ch[CHAR_CONFIG_NB],ch_tab[BLOC_CONFIG_NB][CHAR_CONFIG_NB],ch_error[200];
	int  ch_nb, i, j, num_train=0, g, cant, no, train_verif, clavier_verif, reserve_verif=0, progressif_verif=0, nb_reserve;

	for (i=0; i<NB_TRAIN; i++) { // Pour les trains et wagons.
		enable[i]=0; 		strcpy(name[i],""); cmd[i]=-1;
		en_auto[i]=0; 		inv[i]=0; 			vmin[i]=0;
		vmax[i]=64; 		acc[i]=-1;			dec[i]=-1;	
		frein[i]=-1;		cons[i]=0;			vit[i]=0;
		cant_lock[i]=-1;	cons_sans_correction[i];
		strcpy(sz_cant_ind[i],"");				strcpy(mode[i],"SEL"); // modes are SEL or AUTO
	}
	for (i=NB_TRAIN; i<NB_TRAIN+NB_TRAIN_RESERVE; i++) { // Pour les trains en réserve.
		strcpy(name[i],""); inv[i]=0; 			vmin[i]=0;
		vmax[i]=64; 		acc[i]=-1;			dec[i]=-1;	
		frein[i]=-1;
	}

	for (i=0; i<NB_TRAIN_RESERVE; i++) { // Pour les trains en réserve.
		color_train_reserve[i]=-1; // Pas de couleur par défaut.
	}

	for(i=0;i<NB_TRAIN_COULEUR;i++) color_train[i]=-1; // Couleur des trains.

	for (i=0; i<NB_PROGRESSIF; i++){
		acc_progressif[i]=-1;
		dec_progressif[i]=-1;
	}

	if((pf=fopen(filename,"rt"))==NULL){
		MessageBox(NULL,"Impossible d'ouvrir le fichier de configuration des déplacements 'Config.txt'","Erreur",MB_OK|MB_ICONERROR); exit(1);
	}
	moins_char_normal=1; // '-' est un caractère normal (donc dans les chaînes)
	nb_reserve=-1;
	while (fscanf(pf,"%s%*[^\n]\n",ch)!=EOF) {	// " %s" => "%s%*[^\n]\n" = Nouvelle formule au 02/03/2012, lit uniquement le permier mot de chaque ligne.
		if (STR_SAME strcmp(ch,"#train")) {
			fscanf(pf," %s",ch); //remove [
			while (get_line(pf,ch_tab,&ch_nb)) {
				if (ch_nb>=BLOC_CONFIG_NB){
					MessageBox(NULL,"Le fichier config.txt comporte une ligne trop complexe dans la section '#train'","Erreur",MB_OK|MB_ICONERROR);
					MessageBox(NULL,"Section '#train' (ligne>75 blocs) commençant par (taper sur entrée) : ","Erreur",MB_OK|MB_ICONERROR);
					strcpy(ch_error,"Section #train Erreur ligne :");
					for(i=0;i<ch_nb;i++) { strcat(ch_error,"  "); strcat(ch_error,ch_tab[i]); }
					MessageBox(NULL,ch_error,"UTS - Erreur",MB_OK|MB_ICONERROR); exit(1);
				}
				if (ch_tab[0][0]==']') break; // Fin de la section #train
				for(i=0; i<ch_nb; i++) if (ch_tab[i][0]=='@') ch_nb=i; // Supprime les commentaires en fin de ligne.
				i=0;
				train_verif=0;
				clavier_verif=0;
				reserve_verif=0;
				while (i < ch_nb) {
					// train1:Nom_du_train (Nom sur 8 caractères).
					if (ch_nb - i >= 3) {
						if (STR_SAME strncmp(ch_tab[i], "train", 5)) {
							if (cfg_memoire_pos_train == 1) break; // =1 => UTS remet en place la position des trains pour le réseau, à l'ouverture du preogramme UTS.
							// Donc on ne lit pas les caractéristiques des trains, sauf pour les trains en réserve.
							clavier_verif = 0;
							train_verif = 0;
							reserve_verif = 0;
							if (ch_tab[i + 1][0] == ':') {
								num_train = atoi(&ch_tab[i][5]);
								if (num_train >= 0 && num_train < NB_TRAIN) {
									if (strlen(ch_tab[i + 2]) == 8) { // Le nom du train doit faire exactement 8 caractères, complété si besoin par des '_'.
										train_verif = 1;
										strcpy(name[num_train], ch_tab[i + 2]);
										for (j = 0; j < 8; j++) if (name[num_train][j] == '_') name[num_train][j] = ' ';
										for (j = 0; j < 8; j++) {
											if (!(name[num_train][j] == ' ' || name[num_train][j] == '-' || name[num_train][j] == '[' || name[num_train][j] == ']') &&
												((name[num_train][j] < '0' ||
												 (name[num_train][j] > '9' && name[num_train][j] < 'A') ||
												 (name[num_train][j] > 'Z' && name[num_train][j] < 'a') ||
												  name[num_train][j] > 'z'))) name[num_train][j] = '-';
										}
										i = i + 3; continue;
									}
								}
							}
						}
					}
					// reserve : BB660037 10-64-13-13-xx loco_piko_verte
					if (ch_nb - i >= 3) {
						if (STR_SAME strncmp(ch_tab[i], "reserve", 7)) {
							clavier_verif = 0;
							train_verif = 0;
							reserve_verif = 0;
							if (ch_tab[i + 1][0] == ':' && (nb_reserve + 1) < NB_TRAIN_RESERVE) {
								if (strlen(ch_tab[i + 2]) == 8) {		// Le nom du train doit faire exactement 8 caractères, complété si besoin par des '_'.
									nb_reserve++;
									reserve_verif = 1;
									strcpy(name[nb_reserve + NB_TRAIN], ch_tab[i + 2]);
									for (j = 0; j < 8; j++) if (name[nb_reserve + NB_TRAIN][j] == '_') name[nb_reserve + NB_TRAIN][j] = ' ';
									for (j = 0; j < 8; j++) {
										if (!(name[nb_reserve + NB_TRAIN][j] == ' ' || name[nb_reserve + NB_TRAIN][j] == '-' || name[nb_reserve + NB_TRAIN][j] == '[' || name[nb_reserve + NB_TRAIN][j] == ']') &&
											((name[nb_reserve + NB_TRAIN][j] < '0' ||
											(name[nb_reserve + NB_TRAIN][j] > '9' && name[nb_reserve + NB_TRAIN][j] < 'A') ||
											(name[nb_reserve + NB_TRAIN][j] > 'Z' && name[nb_reserve + NB_TRAIN][j] < 'a') ||
											 name[nb_reserve + NB_TRAIN][j] > 'z'))) name[nb_reserve + NB_TRAIN][j] = '-';
									}
								}
								i = i + 3; continue;
							}
						}
					}
// pot3
					if (train_verif==1 && ch_nb-i>=1) {
						if (STR_SAME strncmp(ch_tab[i],"pot",3)) {
							train_verif=0;
							if (atoi(&ch_tab[i][3])>=0 && atoi(&ch_tab[i][3])<(300+NB_CAN) && (atoi(&ch_tab[i][3])%100)<NB_CAN) train_verif=1; // OK
							if (train_verif == 1) {
								cmd[num_train]=atoi(&ch_tab[i][3]);                     // cmd[n° du train] = 0,1,2,3,4,10,11.. = n° du potentiomètre pour conduire le train.
								i++; continue;
							}
						}
					}
// clav_conf_2
					if (ch_nb-i>=6) {
						if (STR_SAME strncmp(ch_tab[i],"clav_conf_",10)) {
							train_verif=0;
							clavier_verif=0;
							reserve_verif=0;
							if (ch_tab[i+1][0]==':') {
								no=atoi(&ch_tab[i][10]);
								if (no>=0 && no<NB_POT_VIR) {
									clavier_verif=1;
									i=i+2;
									while(ch_nb-i>0) {                              // Touches du clavier pour ralentir, arrêter ou accélerer un train.
										if(      ch_nb-i>=1 && ch_tab[i][0]=='-') { vio_pot_virtual_conf[no][2]=ch_tab[i  ][1]; i++;   } // car '-' n'est pas un caractère spécial.
										else if (ch_nb-i>=2 && ch_tab[i][0]=='+') { vio_pot_virtual_conf[no][0]=ch_tab[i+1][0]; i=i+2; }
										else if (ch_nb-i>=2 && ch_tab[i][0]=='!') { vio_pot_virtual_conf[no][1]=ch_tab[i+1][0]; i=i+2; }
										else { i++; break; }
									}
									continue;
								}
							}
						}
					}


// acc_progressif : 1 2 3 4 5 6 7 8
					if (ch_nb-i>=2) {
						if (i==0 && STR_SAME strncmp(ch_tab[i],"acc_progressif",14)) {
							train_verif=0;
							clavier_verif=0;
							reserve_verif=0;
							if (ch_tab[i+1][0]==':' && ch_nb >= 2 && ch_nb-3 < NB_PROGRESSIF) {
								for (i=0 ; i<NB_PROGRESSIF && i+2<ch_nb ; i++) {
									if (atoi(ch_tab[i+2]) < 1) break;
									if (atoi(ch_tab[i+2]) > VITESSE_CANT_MAXI) break;
									acc_progressif[i]=atoi(ch_tab[i+2]);
									if (i>1 && acc_progressif[i] < acc_progressif[i-1]) break;
								}
								if (i+2 == ch_nb) {
									i=ch_nb; // Dans ce cas on a bien fini la ligne.
									continue; // Aller à la ligne suivante.
								}
							}
						}
					}

// decc_progressif : 1 2 3 4 5 6 7 8
					if (ch_nb-i>=2) {
						if (i==0 && STR_SAME strncmp(ch_tab[i],"dec_progressif",14)) {
							train_verif=0;
							clavier_verif=0;
							reserve_verif=0;
							if (ch_tab[i+1][0]==':' && ch_nb >= 2 && ch_nb-3 < NB_PROGRESSIF) {
								for (i=0 ; i<NB_PROGRESSIF && i+2<ch_nb ; i++) {
									if (atoi(ch_tab[i+2]) < 1) break;
									if (atoi(ch_tab[i+2]) > VITESSE_CANT_MAXI) break;
									dec_progressif[i]=atoi(ch_tab[i+2]);
									if (i>1 && dec_progressif[i] < dec_progressif[i-1]) break;
								}
								if (i+2 == ch_nb) {
									i=ch_nb; // Dans ce cas on a bien fini la ligne.
									continue; // Aller à la ligne suivante.
								}
							}
						}
					}


// clav3
					if (train_verif==1 && ch_nb-i>=1) {
						if (STR_SAME strncmp(ch_tab[i],"clav",4)) {
							if (atoi(&ch_tab[i][4])>=0 && atoi(&ch_tab[i][4])<NB_POT_VIR) {
								cmd[num_train]=1000+atoi(&ch_tab[i][4]);	// cmd[n° du train] = 1000,1001,1002,1003,1004 = commande par le clavier pour conduire le train.
								i++; continue;
								//sprintf_s(gszErr,"<clav-cmd[%d]=%d>",t,cmd[num_train]); log(gszErr);
							}
							else train_verif=0;
						}
					}

// color : TESTER "color" avant "c" dans le code !!!
					if ((train_verif== 1 || reserve_verif==1) && ch_nb-i>=3) { // Couleur pour les trains.
						if (!strncmp(ch_tab[i],"color",4) && ch_tab[i+1][0]==':') {
							if(atoi(ch_tab[i+2])>=0 && atoi(ch_tab[i+2])<BMP_CST_COLOR_NB) { // Le numéro de la couleur doit être correct.
								if (train_verif==1)   color_train[num_train]=atoi(ch_tab[i+2]);
								if (reserve_verif==1) color_train_reserve[nb_reserve]=atoi(ch_tab[i+2]);
								i=i+3; continue; // + 3 termes = 'color' ':' 'numéro'
							}
						}
					}

// c1
					if (train_verif==1 && ch_nb-i>=1) {
						if (ch_tab[i][0]=='c') {
							cant=atoi(&ch_tab[i][1]);                        // Renseigne le numéro du canton de départ.
							train_verif=0;
							if (cant>=0 && cant<(300+NB_CANTON) && (cant%100)<NB_CANTON) train_verif=1; // OK
							if (train_verif==1) {
								canton.num_train[cant/100][cant%100]=num_train;
								canton.master_selectif[cant/100][cant%100]=1;
								canton.inv_selectif[cant/100][cant%100]=0;
								canton.update_selectif[cant/100][cant%100]=0;
								enable[num_train]=1;
								i++; continue;
							}
						}
					}
// g1
					if (train_verif==1 && ch_nb-i>=1) {                                  // Renseigne le numéro du garage de départ.
						if (ch_tab[i][0]=='g') {
							g=atoi(&ch_tab[i][1]);
							if (g>=0 && g<NB_GARAGE_REEL) {		  // N° de garage valide ?
								cant_lock[num_train]=g;
								vio_garage_lock_cmd[g]=1;         // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
								vio_garage_lock_status[g]=1;      // 0 ou 1, 1 => Le garage est isolé du canton (état réel).
								garage.numero_train[g]=num_train; // -1 = Garage relié au canton, ou Numéro de train occupant le garage isolé du canton.
								enable[num_train]=1;
								i++; continue;
							}
							else train_verif=0;
						}
					}
// inv
					if (train_verif==1 && ch_nb-i>=1) {
						if (STR_SAME strcmp(ch_tab[i],"inv")) {
							inv[num_train]=1; // (0 par défaut) = 1 si l'alimentation du train est inversée.
							i++; continue;
						}
					}
					if (reserve_verif==1 && ch_nb-i>=1) {
						if (STR_SAME strcmp(ch_tab[i],"inv")) {
							inv[nb_reserve+NB_TRAIN]=1; // (0 par défaut) = 1 si l'alimentation du train est inversée.
							i++; continue;
						}
					}
// en_auto
					if (train_verif==1 && ch_nb-i>=1) {
						if (STR_SAME strcmp(ch_tab[i],"en_auto")) {
							en_auto[num_train]=1; // (0 par défaut) = 1 si le train peut être aussi conduit en mode automatique.
							i++; continue;
						}
					}
					if (train_verif==1 && ch_nb-i>=1) {
						if (strlen(ch_tab[i])==14) {
							if (ch_tab[i][2]=='-' && ch_tab[i][5]=='-' && ch_tab[i][8]=='-' && ch_tab[i][11]=='-') {
								if(ch_tab[i][ 0]>='0' && ch_tab[i][ 0]<='9')  vmin[num_train]=min(VITESSE_MINI,max(1,atoi(&ch_tab[i][ 0]))); else vmin[num_train]=1;
								if(ch_tab[i][ 3]>='0' && ch_tab[i][ 3]<='9')  vmax[num_train]=min(VITESSE_CANT_MAXI,max(5,atoi(&ch_tab[i][ 3]))); // Si 'xx' les autres 
								if(ch_tab[i][ 6]>='0' && ch_tab[i][ 6]<='9')   acc[num_train]=min(VITESSE_INERTIE_MAXI,max(VITESSE_INERTIE_MINI,atoi(&ch_tab[i][ 6]))); // valeurs reste par défaut
								if(ch_tab[i][ 9]>='0' && ch_tab[i][ 9]<='9')   dec[num_train]=min(VITESSE_INERTIE_MAXI,max(VITESSE_INERTIE_MINI,atoi(&ch_tab[i][ 9]))); //
								if(ch_tab[i][12]>='0' && ch_tab[i][12]<='9') frein[num_train]=min(VITESSE_INERTIE_MAXI,max(VITESSE_INERTIE_MINI,atoi(&ch_tab[i][12]))); //
								if (vmax[num_train]>vmin[num_train]) {
									i++; continue;	// Pas d'autre véfification des valeurs qui sont automatiquement bornées.
									}
								else train_verif=0;
							}
							else train_verif=0;
						}
					}
					if (reserve_verif==1 && ch_nb-i>=1) { // Pour les trains en reserve.
						if (strlen(ch_tab[i])==14) {
							if (ch_tab[i][2]=='-' && ch_tab[i][5]=='-' && ch_tab[i][8]=='-' && ch_tab[i][11]=='-') {
								if(ch_tab[i][ 0]>='0' && ch_tab[i][ 0]<='9')  vmin[nb_reserve+NB_TRAIN]=min(VITESSE_MINI,max(1,atoi(&ch_tab[i][ 0]))); else vmin[nb_reserve+NB_TRAIN]=1;
								if(ch_tab[i][ 3]>='0' && ch_tab[i][ 3]<='9')  vmax[nb_reserve+NB_TRAIN]=min(VITESSE_CANT_MAXI,max(5,atoi(&ch_tab[i][ 3]))); // Si 'xx' les autres 
								if(ch_tab[i][ 6]>='0' && ch_tab[i][ 6]<='9')   acc[nb_reserve+NB_TRAIN]=min(VITESSE_INERTIE_MAXI,max(VITESSE_INERTIE_MINI,atoi(&ch_tab[i][ 6]))); // valeurs reste par défaut
								if(ch_tab[i][ 9]>='0' && ch_tab[i][ 9]<='9')   dec[nb_reserve+NB_TRAIN]=min(VITESSE_INERTIE_MAXI,max(VITESSE_INERTIE_MINI,atoi(&ch_tab[i][ 9]))); //
								if(ch_tab[i][12]>='0' && ch_tab[i][12]<='9') frein[nb_reserve+NB_TRAIN]=min(VITESSE_INERTIE_MAXI,max(VITESSE_INERTIE_MINI,atoi(&ch_tab[i][12]))); //
								if (vmax[nb_reserve+NB_TRAIN]>vmin[nb_reserve+NB_TRAIN]) {
									i++; continue;	// Pas d'autre véfification des valeurs qui sont automatiquement bornées.
									}
								else reserve_verif=0;
							}
							else reserve_verif=0;
						}
					}
// name :
					if (reserve_verif==1 && ch_nb-i>=3) { // Commentaires pour les trains en réserve.
						if (!strncmp(ch_tab[i],"name",4) && ch_tab[i+1][0]==':') {
							if(strlen(ch_tab[i+2])<=NB_TRAIN_RESERVE_COM) { // Le commentaire doit être < 40 caractères.
								strcpy(commentaire[nb_reserve],ch_tab[i+2]);
								for( j=0;j<NB_TRAIN_RESERVE_COM;j++) if (commentaire[nb_reserve][j]=='_') commentaire[nb_reserve][j]=' ';
								i=i+3; continue; // + 3 termes = 'name' ':' 'nom'
							}
						}
					}

					strcpy(ch_error,"Fichier 'config.txt',\n\nSection #train,\n\nErreur de description sur la ligne :");
					for(i=0;i<ch_nb;i++){ strcat(ch_error,"  "); strcat(ch_error,ch_tab[i]); }
					MessageBox(NULL,ch_error,"UTS - Erreur",MB_OK|MB_ICONERROR); exit(1);
				}  //fin groupe de mot
			}	// While (get_line) fin de la ligne de texte.
			break; // Pour sortir de la lecture de la suite du fichier.
		}		// if(==#train)   fin description '#train'.
	}			// While (scanf)    fin du fichier 'config.txt'.
	moins_char_normal=1;		// '-' est un caractère normal, comme '+'.
	fclose(pf);
}




// Trace la configuration lue dans le fichier de trace : "debug_train.txt"
//
//
void cTrain::save_conf(void)
{
	FILE* pf;
	int   i,j;
	if((pf=fopen("debug_train.txt","wt"))==NULL){
		MessageBox(NULL,"Impossible de créer le fichier 'Debug_train.txt'","Erreur",MB_OK|MB_ICONERROR); exit(1);
	}
	for(i=0;i<NB_TRAIN;i++){
		fprintf(pf,"\nen=%d name=%8s cmd=%3d en_auto=%d inv=%d vmin=%02d vmax=%02d acc=%02d dec=%02d frein=%02d cons=%03d vit=%03d mode=%4s",enable[i],name[i],cmd[i],en_auto[i],inv[i],vmin[i],vmax[i],acc[i],dec[i],frein[i],cons[i],vit[i],mode[i]);
	}
	for(j=0;j<NB_POT_VIR;j++){
		fprintf(pf,"\nclav_conf_%d",j);
		for(i=0;i<3;i++) fprintf(pf," >%c<",vio_pot_virtual_conf[j][i]);
	}
	fclose(pf);
}

/*	Fonction 'dynamique vit' calcul la nouvelle vitesse du train en fonction de :
	- vit = la vitesse actuelle
	- cons = consigne de vitesse (-64 à +64).
	       = -99 => appui sur le bouton freinage de la manette 
                    si frein[train] = -1 => arrêt immédiat du train, 
                    si frein[train] = (0-64), freinage progressif  0 = rapidement à 64 = lentement
	- les parametres d'accéleration, de decéleration et de freinage =  acc[train], dec[train], frein[train]
	                -1 = Pas d'inertie, on applique directement la consigne.
	                0  = Applique lentement la consigne à  64 = applique rapidement la consigne. 

En V3.3 temps de passage de +0à+64 ou +64à+0 en fonction de 'acc' ou 'dec' =
V 3.4 = inertie_tab_ind[28][12];
Tableau des valeurs 'Accélération' ou 'Décélération" de 1 à 28 donne une inertie de X secondes pour aller de Vmax  0 ou 0 à  vmax.
Temps d'un pas unitaire = 96 ms = 80 ms + 14 ms de transfert rs232 + 2 msec pour l'éxecution du programme
  1 =  0,3 sec,    2 = 0,4 sec,   3 =  0,5 sec,   4 =  0,6 sec,   5 =  0,8 sec,   6 =  1 sec, 
  7 =  1,2 sec,    8 = 1,3 sec,   9 =  1,5 sec,  10 =  1,7 sec,  11 =  2 sec,    12 =  2,3 sec, 
 13 =  2,7 sec,   14 = 3 sec,    15 =  3,5 sec,  16 =  4 sec,    17 =  5 sec,    18 =  6 sec, 
 19 =  7 sec,    20 = 8 sec,     21 =  9 sec,    22 = 10 sec,    23 = 12 sec,    24 = 14 sec, 
 25 = 18 sec,    26 = 24 sec,    27 = 36 sec,    28 = 74 sec, 
 */
//  acc, dec et frein == 1 à 28 !
int cTrain::dynamique_vit(int cons,int vit, int acc, int dec, int frein)
{
	int next_vit, vmin, vmax, i;

	vmin=1;		// Impose  -1, +1 en V3.3 ne pas mettre 0 sinon ça ne démarre pas.
	vmax=64; 	// Impose -64,+64 en V3.3
	next_vit=0;

	if (cons==0 && vit==00) {	next_vit=0; return next_vit; } // Pas la peine d'aller plus loin, Vitesse = 0, même si frein activé.

//1. Si UTS est en mode "STOP", on limite la vitesse des trains lors de la remise en marche.
	if (cmd_divers[CMD_DIVERS_OPT4_ARRET]==1 ) vmax=15; // si cmd_divers[CMD_DIVERS_OPT4_ARRET]=1, Arrêt d'urgence des trains, alimentation des cantons à zéro.

//2. Si freinage demandé quand on appui sur le bouton 'Frein'.
	if (cons==-99) { // Si l'on appuye sur le bouton 'Frein' de la manette alors 'cons' =-99 en entrée de programme.
		if (frein==-1) { next_vit=0; return next_vit; } // Frein et pas d'inertie.
		else{
			#ifdef VERSION_UTS_V3 // Ne pas toucher à cette ligne !!!
			if (frein>=VITESSE_INERTIE_MINI && frein<=VITESSE_INERTIE_MAXI) {
				frein = inertie_tab_ind[frein-1][debug_tic_nb%VITESSE_INERTIE_PAS]; // Le tableau commence à 0 et frein à 1!
			}
			#endif
			if (vit>0) { next_vit=vit-frein; if (next_vit<0) { next_vit=0; return next_vit; } }
			else       { next_vit=vit+frein; if (next_vit>0) { next_vit=0; return next_vit; } }
		}
		return next_vit;
	}
//3. Si pas de freinage demandé, calcul de la valeur d'accélération ou de déceleration.
	#ifdef VERSION_UTS_V3 // Ne pas toucher à cette ligne !!!
	if (acc>=VITESSE_INERTIE_MINI && acc<=VITESSE_INERTIE_MAXI) { // Le tableau commence à 0 et acc à 1!
		// V3.5c, on ajoute un peu plus d'inertie aux faibles vitesses, uniquement en accélération.
		for (i=0; i<NB_PROGRESSIF; i++ ) {
			if (acc_progressif[i]==-1) break;
			else if (abs(vit)<=acc_progressif[i]) acc++;
		}
		if (acc>VITESSE_INERTIE_MAXI) acc=VITESSE_INERTIE_MAXI;
		acc=inertie_tab_ind[acc-1][debug_tic_nb%VITESSE_INERTIE_PAS];
	}
	if (dec>=VITESSE_INERTIE_MINI && dec<=VITESSE_INERTIE_MAXI) { // Le tableau commence à 0 et dec à 1!
		// V3.5c, on ajoute un peu plus d'inertie aux faibles vitesses, uniquement en accélération.
		for (i=0; i<NB_PROGRESSIF; i++ ) {
			if (dec_progressif[i]==-1) break;
			else if (abs(vit)<=dec_progressif[i]) dec++;
		}
		if (dec>VITESSE_INERTIE_MAXI) dec=VITESSE_INERTIE_MAXI;
		dec = inertie_tab_ind[dec-1][debug_tic_nb%VITESSE_INERTIE_PAS];
	}
	#endif

// La vitesse du train est égal à la consigne. On sort.
	if (cons==vit) {  
		next_vit=cons;
		if (next_vit>vmax)  next_vit=vmax;
		if (next_vit<-vmax) next_vit=-vmax;
		return next_vit;
	}

// La vitesse du train est de sens opposée à la consigne. On décélere pour passer par la vitesse nulle.
	if (cons>=0 && vit<0) { if (dec==-1) { next_vit=0; return next_vit; } else { next_vit=vit+dec; if (next_vit>0) { next_vit=0; return next_vit; } } } // Deceleration vers 0 sens -
	if (cons<=0 && vit>0) { if (dec==-1) { next_vit=0; return next_vit; } else { next_vit=vit-dec; if (next_vit<0) { next_vit=0; return next_vit; } } } // Deceleration vers 0 sens +
	
// La vitesse du train est de même sens à la consigne. On accélere ou décélere pour arriver à la consigne.
	if (cons>0 && vit>=0) {
		if      (cons>vit) { if (acc==-1) next_vit=cons; else { next_vit=vit+acc; if (next_vit>cons) next_vit=cons; } } // Acceleration sens +
		else if (cons<vit) { if (dec==-1) next_vit=cons; else { next_vit=vit-dec; if (next_vit<cons) next_vit=cons; } } // Deceleration sens +
	}
	if (cons<0 && vit<=0) {
		if      (cons<vit) { if (acc==-1) next_vit=cons; else { next_vit=vit-acc; if (next_vit<cons) next_vit=cons; } } // Acceleration sens -
		else if (cons>vit) { if (dec==-1) next_vit=cons; else { next_vit=vit+dec; if (next_vit>cons) next_vit=cons; } } // Deceleration sens -
	}
	if (next_vit>vmax)  next_vit=vmax;
	if (next_vit<-vmax) next_vit=-vmax;
	return next_vit;
}


//
void cTrain::maj(void)
{
	int can, cons_tmp, vit_tmp, dec_tmp, enbreak, i, j, t;
// 1. Régulateur
	for(t=0;t<NB_TRAIN;t++){
// 1.1. Pas de commande
		if(cmd[t]==-1 || enable[t]==0 || cant_lock[t]!=-1 || STR_SAME stricmp(mode[t],"AUTO") ) { cons[t]=0; vit[t]=0; }
// 1.2. OK pour commande
		else {
// 1.2.1. Commande potentiometrique
			cons_tmp=0; // Pour inialiser cette variable ?
			if (cmd[t]>=0 && cmd[t]<=305){
				can=vio_can[cmd[t]/100][cmd[t]%100];
				if(inv[t]) can=255-can;
				enbreak=1;
				cons_tmp=can_to_cons(can, enbreak);  // Autorise le bouton frein sur la manette. Si bouton appuyé => cons = -99.
			}
// 1.2.2. Commande clavier
			if (cmd[t]>=1000 && cmd[t]<=1005) cons_tmp=virtualstep_to_cons(vio_pot_virtual_step[cmd[t]%100]); // %100 => à vérifier ?
// V3.4 #balauto + 'vitmax:' ou 'cant:' => On agit sur la consigne de vitesse (Avec inertie). Voir balauto.tick_vitmax() et balauto.tick_cant().
			// En cas de limitation de vitesse sur un canton '#balauto' + 'vitmax:' =1 => Limitation de la consigne de vitesse du train sur le canton.
			// En cas de blocage d'un train sur un canton '#balauto' + 'cant:' =1 => La consigne de vitesse du train =0.
			// Si l'on passe c'est que cmd[t] != -1.
			if (cons_tmp==-99) cons_sans_correction[t]=0;
			else               cons_sans_correction[t]=cons_tmp;
			if (cfg_aigauto==1) aigauto.tick(); // On traitement la commande des aiguillages commandés automatiquesment par un train en mouvement si var =on.
			balauto.tick_vitmax();
			balauto.tick_halt();
			balauto.tick_cant();
			if (cons_tmp==-99) cons_sans_correction[t]=0;
			if (balauto_vitmax_train[t]>0 && cons_tmp>balauto_vitmax_train[t] && cons_tmp!=-99) cons_tmp=balauto_vitmax_train[t];
			if (balauto_vitmax_train[t]<0 && cons_tmp<balauto_vitmax_train[t] && cons_tmp!=-99) cons_tmp=balauto_vitmax_train[t];
			dec_tmp=dec[t];

			if (balauto_cant_train[t]==2 && cmd_divers[CMD_DIVERS_OPT6_BLOCAG]!=1) { // =2 => Train bloqué ? => Fonction '#balauto' + 'cant:' Inhibé par bouton depuis le TCO.
				cons_tmp=0; // Le blocage du train est prioritaire par rapport à la limitation de vitesse.
				if (balauto_cant_train_dec[t]!=-1 && dec[t]!=-1) { 
					// On choisi la valeur de décéleration entre celle du train et celle imposée par la directive '#balauto'+'cant:'+'dec:xx'.
					// pour freiner en cas de blocage de sortie d'un canton, si la valeur est plus faible 
					dec_tmp = min(balauto_cant_train_dec[t],dec_tmp);
				}
			}
			else if  (balauto_cant_train[t]==1) { // =1 => Train ralenti ?
				if (cons_tmp>0 && balauto_cant_train_ral[t]>0) cons_tmp=min(cons_tmp,balauto_cant_train_ral[t]);
				if (cons_tmp<0 && balauto_cant_train_ral[t]<0) cons_tmp=max(cons_tmp,balauto_cant_train_ral[t]);
				if (balauto_cant_train_dec[t]!=-1 && dec[t]!=-1) { 
					// On choisi la valeur de décéleration entre celle du train et celle imposée par la directive '#balauto'+'cant:'+'dec:xx'.
					// pour freiner en cas de blocage de sortie d'un canton, si la valeur est plus faible 
					dec_tmp = min(balauto_cant_train_dec[t],dec_tmp);
				}
			}
			vit_tmp=dynamique_vit(cons_tmp,vit[t],acc[t],dec_tmp,frein[t]); // acc, dec et frein = 1 à 28 !
			cons[t]=cons_tmp;
			vit[t]=vit_tmp;
			// V3.4 #balauto + 'halt:' = > On agit directement sur la vitesse pour stopper le train.  Voir balauto.tick_halt().
			// En cas de halte sur un canton '#balauto' + 'halt:' =1
			// dans cTrain::canton_maj_profil().
//			if (cmd_divers[CMD_DIVERS_OPT5_HALTE]!=1) { // = 1 => Fonction '#balauto' + 'halt:' Inhibé par bouton depuis le TCO.
//				if (balauto_halt_train[t]==1 && vit[t]>0) vit[t]=0;
//				if (balauto_halt_train[t]==1 && vit[t]<0) vit[t]=0;
//			}
			// = 1 => Fonction '#balauto' + 'halt:' Inhibé par bouton depuis le TCO.
			if (cmd_divers[CMD_DIVERS_OPT5_HALTE]!=1 && balauto_halt_train[t]==1) vit[t]=0;
		}
	}


// 2. Indicateur de canton
	for(t=0;t<NB_TRAIN;t++){
		strcpy(sz_cant_ind[t],"");
		for(j=0;j<NB_CARTE;j++) for(i=0;i<NB_CANTON;i++) if(canton.num_train[j][i]==t){
			if(canton.master_selectif[j][i]) sprintf_s(sz_cant_ind[t],"%sc%d ",sz_cant_ind[t],100*j+i);
			if(canton.res_auto[j][i] && vio_det[j][i]) sprintf_s(sz_cant_ind[t],"%sc%d ",sz_cant_ind[t],100*j+i);
		}
		sz_cant_ind[t][20]='\0'; // troncate
	}
// 3. Indicateur de captage
	for(t=0;t<NB_TRAIN;t++){
		capt[t]=0;
		for(j=0;j<NB_CARTE;j++) for(i=0;i<NB_CANTON;i++) if(canton.num_train[j][i]==t){
			if(canton.master_selectif[j][i] && vio_det[j][i]) capt[t]=1;
			if(canton.res_auto[j][i] && vio_det[j][i]) capt[t]=1;
		}
		if( cant_lock[t]!=-1 ) capt[t]=2;
	}
}

// Sous programme pour, à partir des valeurs brutes d'alimentation des cantons (-64 +64) élaborer les valeurs d'alimentation envoyée aux cantons.
//   calcul ces valeurs en fonction des profils des trains (Vmin Vmax).
//   Ceci permet d'avoir une valeur brute comprise entre -64 et +64.
//   Quand on donne une consigne de +32 que ce soit avec un potentiométre ou un la consigne d'un déplacement, le train ira à la moitié de sa vitesse.


void cTrain::canton_maj_profil(void)
{
	int i,j,trpro;
	for(j=0;j<NB_CARTE;j++) {
		for(i=0;i<NB_CANTON;i++) {
			if (vio_canton_vit[j][i]==0) vio_canton_vit_profil[j][i]=0;
			else {
				trpro=canton.num_train[j][i];
				if (trpro!=-1) {
					if (vio_canton_vit[j][i] > 0) vio_canton_vit_profil[j][i]=+vmin[trpro]+((vmax[trpro]-vmin[trpro])*vio_canton_vit[j][i])/64;
					else                          vio_canton_vit_profil[j][i]=-vmin[trpro]+((vmax[trpro]-vmin[trpro])*vio_canton_vit[j][i])/64;
				}
			}
		}
	}
}


// Affiche le tableau avec des états des trains. Appel de cet écran depuis le menu : 'Tables >Trains'.
// Cette fenêtre est interactive.
// selected_entry =
// TRAIN_SAISIE_CMDE, TRAIN_SAISIE_CMDE_N_TRAIN, TRAIN_SAISIE_CANTON, TRAIN_SAISIE_NOM, TRAIN_SAISIE_PROFILE, TRAIN_SAISIE_GARAGE_ISOLE, TRAIN_SAISIE_NOUVEAU_TRAIN
//
void cTrain::debug(int action)
{
	int  i,j,c,g;
	int  x,y;
	char ch[200], ch2[10];
	static int dimx=50; // Dimension horizontale d'une colonne simple.
	static int dimy=20; // Dimension verticale d'une ligne
	static int dimyr=29; // Dimension verticale d'une ligne pour les noms des trains de réserve.
	static int nblignes=16; // Nombre de ligne du tableau (sans le titre)	
	static int decaly=80; // Décalage vers le bas de la premiére ligne du tableau.
	static int selected_train=-1;
	static int selected_entry=-1;
	int train_debug_deb=0;
	int val;
	static char szEntryName[10];
	int len;

	if (action==DEBUG_MOUSE) { // ACTION = CLIC GAUCHE DE LA SOURIS.
		if ((x_mouse > 800-15 && x_mouse < 800-2) && (y_mouse > 2 && y_mouse < 15)) {
			screen_mode= screen_mode_retour; 
			return;	// On ferme la fenêtre.
		}
		if (x_mouse>=12*dimx && x_mouse<=16*dimx && y_mouse>=((3*dimy)/2) && y_mouse<=((7*dimy)/2) && selected_entry==-1) {
			if (screen_mode==MD_ECRAN_TRAIN1) screen_mode=MD_ECRAN_TRAIN2;
			else if (screen_mode==MD_ECRAN_TRAIN2) screen_mode=MD_ECRAN_TRAIN1; // MD_ECRAN_TRAIN1=1 -> Affiche la page des trains, MD_ECRAN_TRAIN2=1 -> Affiche la page des wagons.
		}
		if (screen_mode==MD_ECRAN_TRAIN1) train_debug_deb=0; // Valeur du premier déplacement à afficher.
		else train_debug_deb=nblignes;
		j=(y_mouse-dimy-decaly)/dimy;
		if (y_mouse>=dimy+decaly && selected_entry==-1 && j>=0 && j<nblignes) {
			  selected_train=j+train_debug_deb;
			  if (x_mouse>0 && x_mouse<dimx ) {
				  if(enable[selected_train]==0) { // enable train
					enable[selected_train]=1;
					selected_entry=TRAIN_SAISIE_NOUVEAU_TRAIN; // Avant = selected_entry=TRAIN_SAISIE_CANTON;
					SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
					Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
					if (screen_mode==MD_ECRAN_TRAIN1) {
						sprintf_s(name[selected_train],"TRAIN %2d",selected_train); // Nom du train = 8 caractères.
						en_auto[selected_train]=1; // Par défaut un nouveau train peut être en conduite automatique.
					}
					else {
						sprintf_s(name[selected_train],"WGON[%2d]",selected_train); // Nom des wagons = 8 caractères.
						en_auto[selected_train]=0; // Par défaut les nouveaux wagons ne peuvent pas être en conduite automatique.
					}
				}
				else { // disable train
					if( STR_SAME stricmp(mode[selected_train],"AUTO") ) { EasyTextOut(100,400,"Err: Cannot Deactivate an AUTO train"); }
					else {
						enable[selected_train]=0;               // liberation train
						cmd[selected_train]=-1;
						en_auto[selected_train]=0;
						inv[selected_train]=0;
						vmin[selected_train]=0;
						vmax[selected_train]=64;
						acc[selected_train]=-1;
						dec[selected_train]=-1;
						frein[selected_train]=-1;
						cons[selected_train]=0;
						vit[selected_train]=0;
						strcpy(mode[selected_train],"SEL");
						for (j=0; j<NB_CARTE; j++) for (i=0; i<NB_CANTON; i++) { // liberation canton (et donc selectif)
							if(canton.num_train[j][i]==selected_train){
								canton.master_selectif[j][i]=0;
								canton.inv_selectif[j][i]=0;
								canton.update_selectif[j][i]=0;
							}
						}
						g=cant_lock[selected_train];     // Libération garage
						if(g!=-1){
							vio_garage_lock_cmd[g]=0;    // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
							vio_garage_lock_status[g]=0; // 0 ou 1, 1 => Le garage est isolé du canton (état réel).
							vio_garage_lock_res[g]=0;    // 0 ou 1, 1 => Garage réservé.
							garage.numero_train[g]=-1;   // -1 = Garage relié au canton, ou Numéro de train occupant le garage isolé du canton.
							cant_lock[selected_train]=-1;
						}
					}
				}
			}
			if(enable[selected_train]) {
				if(x_mouse>   dimx && x_mouse< 3*dimx) {
					selected_entry=TRAIN_SAISIE_NOM; strcpy(szEntryName,"");
					SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
					Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
				}
				if(x_mouse> 3*dimx && x_mouse< 4*dimx) {
					selected_entry=TRAIN_SAISIE_CMDE;
					SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
					Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
				}
				if(x_mouse> 4*dimx && x_mouse< 5*dimx) en_auto[selected_train]^=1;
				if(x_mouse> 5*dimx && x_mouse< 6*dimx) inv[selected_train]^=1;
				if(x_mouse> 6*dimx && x_mouse< 9*dimx) { 
					selected_entry=TRAIN_SAISIE_PROFILE; 
					SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
					Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
				}
				if(x_mouse>14*dimx && x_mouse<15*dimx){
					g=cant_lock[selected_train];
					if(g!=-1) { 
						if(vio_garage_lock_res[g]==0) vio_garage_lock_cmd[g]=0;  // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
					}
					else { 
						selected_entry=TRAIN_SAISIE_GARAGE_ISOLE; 
						SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
						Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
					}
				}
			}
		}
		if(selected_entry==TRAIN_SAISIE_GARAGE_ISOLE){
			j=((y_mouse-decaly)/dimy)-1-nblignes-2 ;
			i=(x_mouse/dimx);
			if (j>=0 && j<=4 && i>=0 && i<=15){
				g=16*j+i;
				c=garage.ass_canton[g];
				if(c!=-1)  if(canton.num_train[c/100][c%100]==selected_train) vio_garage_lock_cmd[g]=1;  // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
				selected_train=-1;
				selected_entry=-1;
			}
		}
		if (selected_entry==TRAIN_SAISIE_CMDE || selected_entry==TRAIN_SAISIE_CMDE_N_TRAIN) {
			j=((y_mouse-decaly)/dimy)-1-nblignes-2;
			i=(x_mouse/(2*dimx))-1;
			if (j>=0 && j<=4 && i>=0 && i<=4) {
				if(j==4) val=1000+i;
				else     val=100*j+i;
				if (selected_train>=0) cmd[selected_train]=val;
				selected_train=-1;
				selected_entry=-1;
			}
			else if (j>=4 && j<=5 && i>=0 && i<=4) {
				if (selected_train>=0) cmd[selected_train]=-1;
				selected_train=-1;
				selected_entry=-1;
			}
		}
		if (selected_entry==TRAIN_SAISIE_CANTON){
			j=((y_mouse-decaly)/dimy)-1-nblignes-2;
			i=(x_mouse/dimx);
			if (j>=0 && j<4 && i>=0 && i<16) {
				val=100*j+i;
				canton.num_train[val/100][val%100]=selected_train;
				canton.master_selectif[val/100][val%100]=1;
				canton.inv_selectif[val/100][val%100]=0;
				canton.update_selectif[val/100][val%100]=0;
				//selected_train=-1;
				//selected_entry=-1;
				selected_entry=TRAIN_SAISIE_CMDE_N_TRAIN;
				SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
				Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
			}
			j=((y_mouse-decaly)/dimy)-1-nblignes-2-5;
			i=(x_mouse/dimx);
			if ( j>=0 && j<NB_GARAGE_REEL/16 && i>=0 && i<16) {
				g=16*j+i;
				cant_lock[selected_train]=g;
				vio_garage_lock_cmd[g]=1;              // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
				vio_garage_lock_status[g]=1;           // 0 ou 1, 1 => Le garage est isolé du canton (état réel).
				garage.numero_train[g]=selected_train; // -1 = Garage relié au canton, ou Numéro de train occupant le garage isolé du canton.
				//selected_train=-1;
				//selected_entry=-1;
				selected_entry=TRAIN_SAISIE_CMDE_N_TRAIN;
				SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
				Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
			}
		}
		if (selected_entry==TRAIN_SAISIE_PROFILE) {
			j=((y_mouse-decaly)/dimy)-1-nblignes-2;
			i=(x_mouse/dimx);
			if(j==0 && i==2) { vmin[selected_train]-=10; if(vmin[selected_train]<1) vmin[selected_train]=1; }
			if(j==0 && i==3) { vmin[selected_train]--;   if(vmin[selected_train]<1) vmin[selected_train]=1; }
			if(j==0 && i==4)   vmin[selected_train]=1;
			if(j==0 && i==5) { vmin[selected_train]++;   if(vmin[selected_train]>VITESSE_MINI) vmin[selected_train]=VITESSE_MINI; }
			if(j==0 && i==6) { vmin[selected_train]+=10; if(vmin[selected_train]>VITESSE_MINI) vmin[selected_train]=VITESSE_MINI; }

			if(j==1 && i==2) { vmax[selected_train]-=10; if(vmax[selected_train]<6) vmax[selected_train]=6; }
			if(j==1 && i==3) { vmax[selected_train]--;   if(vmax[selected_train]<6) vmax[selected_train]=6; }
			if(j==1 && i==4)   vmax[selected_train]=64;
			if(j==1 && i==5) { vmax[selected_train]++;   if(vmax[selected_train]>VITESSE_CANT_MAXI) vmax[selected_train]=VITESSE_CANT_MAXI; }
			if(j==1 && i==6) { vmax[selected_train]+=10; if(vmax[selected_train]>VITESSE_CANT_MAXI) vmax[selected_train]=VITESSE_CANT_MAXI; }

			if(j==2 && i==2) { acc[selected_train]-=10;  if(acc[selected_train]<1) acc[selected_train]=VITESSE_INERTIE_MINI; }
			if(j==2 && i==3) { acc[selected_train]--;    if(acc[selected_train]<1) acc[selected_train]=VITESSE_INERTIE_MINI; }
			if(j==2 && i==4)   acc[selected_train]=-1;
			if(j==2 && i==5) { acc[selected_train]++;    if(acc[selected_train]>VITESSE_INERTIE_MAXI) acc[selected_train]=VITESSE_INERTIE_MAXI; }
			if(j==2 && i==5) {                           if(acc[selected_train]==0) acc[selected_train]=VITESSE_INERTIE_MINI;  }
			if(j==2 && i==6) { acc[selected_train]+=10;  if(acc[selected_train]>VITESSE_INERTIE_MAXI) acc[selected_train]=VITESSE_INERTIE_MAXI; }

			if(j==3 && i==2) { dec[selected_train]-=10;  if(dec[selected_train]<1) dec[selected_train]=VITESSE_INERTIE_MINI; }
			if(j==3 && i==3) { dec[selected_train]--;    if(dec[selected_train]<1) dec[selected_train]=VITESSE_INERTIE_MINI; }
			if(j==3 && i==4)   dec[selected_train]=-1;
			if(j==3 && i==5) { dec[selected_train]++;    if(dec[selected_train]>VITESSE_INERTIE_MAXI) dec[selected_train]=VITESSE_INERTIE_MAXI; }
			if(j==3 && i==5) {                           if(dec[selected_train]==0) dec[selected_train]=VITESSE_INERTIE_MINI;  }
			if(j==3 && i==6) { dec[selected_train]+=10;  if(dec[selected_train]>VITESSE_INERTIE_MAXI) dec[selected_train]=VITESSE_INERTIE_MAXI; }

			if(j==4 && i==2) { frein[selected_train]-=10;if(frein[selected_train]<1) frein[selected_train]=VITESSE_INERTIE_MINI; }
			if(j==4 && i==3) { frein[selected_train]--;  if(frein[selected_train]<1) frein[selected_train]=VITESSE_INERTIE_MINI; }
			if(j==4 && i==4)   frein[selected_train]=-1;
			if(j==4 && i==5) { frein[selected_train]++;  if(frein[selected_train]>VITESSE_INERTIE_MAXI) frein[selected_train]=VITESSE_INERTIE_MAXI; }
			if(j==4 && i==5) {                           if(frein[selected_train]==0) frein[selected_train]=VITESSE_INERTIE_MINI;  }
			if(j==4 && i==6) { frein[selected_train]+=10;if(frein[selected_train]>VITESSE_INERTIE_MAXI) frein[selected_train]=VITESSE_INERTIE_MAXI; }
			// valeurs par défaut et case 'OK'.
			if(j==3 && (i==7 || i==8)) { vmin[selected_train]=VITESSE_CANT_MIN;  vmax[selected_train]=VITESSE_CANT_MAXI;  acc[selected_train]=dec[selected_train]=frein[selected_train]=-1; }
			if(j==4 && (i==7 || i==8)) { selected_train=-1; selected_entry=-1; }
			if (vmax[selected_train]!=-1) vmax[selected_train]=max(6,vmax[selected_train]);
			if (vmin[selected_train]>=vmax[selected_train]) {
				vmin[selected_train]=vmax[selected_train]-1;
				if (vmin[selected_train]==0 ) {vmin[selected_train]=2; vmin[selected_train]=1;}
			}
		}
// Clic sur le tableau de sélection d'un nouveau train, par défaut ou en réserve.
		if (x_mouse>=(dimx/2) &&  x_mouse<=(dimx*5*3+(dimx/2)) && y_mouse>=dimy*(nblignes+3)+decaly && y_mouse<=dimy*(nblignes+3)+(dimyr*8)+decaly && selected_entry==TRAIN_SAISIE_NOUVEAU_TRAIN) {
			i=(x_mouse-(dimx/2))/(dimx*5);
			j=(y_mouse-(dimy*(nblignes+3)+decaly))/dimyr;
			i=i+(3*j)-1;
			if (i>=0 && i<NB_TRAIN_RESERVE && strlen(name[NB_TRAIN+i])>=1) {
				strcpy(name[selected_train],name[NB_TRAIN+i]);
				inv[selected_train]=  inv[NB_TRAIN+i];
				vmin[selected_train]= vmin[NB_TRAIN+i];
				vmax[selected_train]= vmax[NB_TRAIN+i];
				acc[selected_train]=  acc[NB_TRAIN+i];
				dec[selected_train]=  dec[NB_TRAIN+i];
				frein[selected_train]=frein[NB_TRAIN+i];
				if(color_train_reserve[i]!=-1) color_train[selected_train]=color_train_reserve[i];  // La couleur du train est dans une table propre aux trains en réserve.
			}
			else if (selected_train>=NB_TRAIN_COULEUR) color_train[selected_train]=BMP_CST_COLOR_MAGENTA; // Couleurs des wagons par défaut.

			SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
			Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
			selected_entry=TRAIN_SAISIE_CANTON;
		}
		if (selected_entry==-1) {
			SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
			Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
		}
	}

	if (action==DEBUG_KEY) { // ACTION = TOUCHE ENFONCEE
		if (selected_entry==TRAIN_SAISIE_NOM) {		// Saisie du nouveau nom du train (8 caractères maximum).
			if (touche_char!=0xd) {			// On a tapé un caractère # 'Entrée'.
				len=strlen(szEntryName);
				if(len<8) { szEntryName[len]=touche_char; szEntryName[len+1]='\0'; }  // Conversion de 'int' en 'char'.
			}
			else{ // = Touche Entrée, '\n'==0x10 !!!!.
				if (szEntryName[0] != 0) {	// On change le nom du train seulement si l'on a tapé au moins un caractère.
					for (i = 0; i < 8; i++) {		// On complète le nom du train saisie manuellement par des ' '.
						if (szEntryName[i] == 0) {
							szEntryName[i] = 0x20;
							szEntryName[i + 1] = 0;
						}
					}
					for (i = 0; i < 8; i++) if (szEntryName[i] == '_') szEntryName[i]= ' ';
					for (i = 0; i < 8; i++) {
						if (!(szEntryName[i] == ' ' || szEntryName[i] == '-' || szEntryName[i] == '[' || szEntryName[i] == ']' ) &&
						   ((szEntryName[i] < '0' ||
						    (szEntryName[i] > '9' && szEntryName[i] < 'A') ||
						    (szEntryName[i] > 'Z' && szEntryName[i] < 'a') ||
							 szEntryName[i] > 'z'))) szEntryName[i] = '-';
					}
					strcpy(name[selected_train],szEntryName);
				}
				selected_entry=-1;
				selected_train=-1;
				SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
				Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
			}
		}
	}

	if(action==DEBUG_MOUSE_RIGHT) {} // ACTION = CLIC DROIT DE LA SOURIS..

	SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192); 
	SelectObject(hMemDC,bmp_fonte); SetBkMode(hMemDC,TRANSPARENT);

	if(action==DEBUG_TOTAL_PAINT) {		// ACTION = REDESSINE TOUTE LA FENETRE.
		Rectangle(hMemDC,0,0,800,700);		// Efface tout
		SelectObject(hMemDC,bmp_pinceau_gris192); SelectObject(hMemDC,bmp_stylo_gris192); Rectangle(hMemDC,800-15,15,800-2,2); // Rectangle gris pour fermer la fenêtre.
		SelectObject(hMemDC,bmp_stylo_noir); EasyLine(800-14,3,800-3,14 ); EasyLine(800-14,13,800-3,2); // Croix noire.
		SelectObject(hMemDC,bmp_stylo_noir);  EasyLine(800-2,1,800-2,16); EasyLine(800-16,15,800-1,15); // Trait noir.
		SelectObject(hMemDC,bmp_stylo_gris128); EasyLine(800-3,2,800-3,15); EasyLine(800-15,14,800-2,14); // Trait gris foncé.
		SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);

		EasyLine(0,decaly,16*dimx,decaly);

		SetTextColor(hMemDC,RGB(0,0,0)); // Texte en noir
		EasyTextOut(2,2,"AFFICHE LES CARACTÉRISTIQUES DES TRAINS"); EasyTextOut(800-140,2,"(QUITTER = ESC)");
		EasyTextOut(2,2+1*dimy," Pour ajouter ou enlever un train, cliquez dans la colonne : 'n°TR'.");
		EasyTextOut(2,2+2*dimy," Les modifications ne sont pas sauvegardées dans 'config.txt'.");

		SetTextColor(hMemDC,RGB(255,0,0)); // Texte en rouge
		x=0;y=0;
		EasyTextOut(x+7,4+decaly,"n°TR"     ); x+=  dimx;  EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'TR' marquée '/' = valeurs modifiables
		EasyTextOut(x+3,4+decaly,"Nom  Couleur"); x+=2*dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Nom' marquée '/' = valeurs modifiables
		EasyTextOut(x+13,4+decaly,"Cmd"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Cmd' marquée '/' = valeurs modifiables
		EasyTextOut(x+7,4+decaly,"Auto"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Auto' marquée '/' = valeurs modifiables
		EasyTextOut(x+5,4+decaly,"Invrs"	 ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Inv' marquée '/' = valeurs modifiables
		EasyTextOut(x+6,4+decaly,"Profile:Vmin,Vmax"); x+=3*dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Profile' marquée '/' = valeurs modifiables
		EasyTextOut(x+8,4+decaly,"Cons"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyTextOut(x+5,4+decaly,"Vites"     ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyTextOut(x+9,4+decaly,"Mode"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyTextOut(x+22,4+decaly,"Cantons" ); x+=2*dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyTextOut(x+5,4+decaly,"Garag"     ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,dimy+decaly-10);  // Colonne 'Garag' marquée '/' = valeurs modifiables
		EasyTextOut(x+9,4+decaly,"Capt"      ); x+=  dimx-1; EasyLine(x,y+decaly,x,y+dimy+decaly);
	}
	SetTextColor(hMemDC,RGB(0,0,0)); // Texte en noir
	SelectObject(hMemDC,bmp_stylo_noir);
	if (screen_mode==MD_ECRAN_TRAIN1) {
		SelectObject(hMemDC,bmp_pinceau_cyan);
		Rectangle(hMemDC, 12*dimx, (3*dimy)/2, 16*dimx, (7*dimy)/2);
		SelectObject(hMemDC,bmp_stylo_cyanf);
		EasyLine(12*dimx+1, (7*dimy)/2-2, 16*dimx-1, (7*dimy)/2-2); // Relief rectangle.
		EasyLine(16*dimx-2, (3*dimy)/2+1, 16*dimx-2, (7*dimy)/2-2);	// Relief rectangle.
		SelectObject(hMemDC,bmp_stylo_noir);
		EasyTextOut(13*dimx+20, 5+2*dimy, "TRAINS");
	}
	else {
		SelectObject(hMemDC,bmp_pinceau_magenta);
		Rectangle(hMemDC, 12*dimx, (3*dimy)/2, 16*dimx, (7*dimy)/2);
		SelectObject(hMemDC,bmp_stylo_magentaf);
		EasyLine(12*dimx+1, (7*dimy)/2-2, 16*dimx-1, (7*dimy)/2-2); // Relief rectangle.
		EasyLine(16*dimx-2, (3*dimy)/2+1, 16*dimx-2, (7*dimy)/2-2);	// Relief rectangle.
		SelectObject(hMemDC,bmp_stylo_noir);
		EasyTextOut(13*dimx+20, 5+2*dimy, "WAGONS");
	}
	EasyLine(16*dimx-1, (7*dimy)/2-11, 16*dimx-11, (7*dimy)/2-1); // Trait en diagonal.
	SelectObject(hMemDC,bmp_stylo_gris192);

	if (screen_mode==MD_ECRAN_TRAIN1) train_debug_deb=0; // Valeur du premier déplacement à afficher.
	else train_debug_deb=nblignes;

	SetTextColor(hMemDC,RGB(0,0,255));	// Texte en bleu.
	for (i=0; i<nblignes; i++) {
		if (train_debug_deb+i<NB_TRAIN) {
			y=(dimy*i)+decaly+dimy ;
			SelectObject(hMemDC,bmp_pinceau_blanc);
			//if((iti_deb+i)>=ITI_TAB_NB) break;
			//if(iti_tab[iti_deb+i][ITI_TAB_IND_WAIT]) SelectObject(hMemDC,bmp_pinceau_jaune);
			//if(iti_tab[iti_deb+i][ITI_TAB_IND_OK])   SelectObject(hMemDC,bmp_pinceau_vert);
			Rectangle(hMemDC,0,y,16*dimx,y+dimy+1);
			x=0;
			x+=  dimx; EasyLine(x,y,x,y+dimy);  // Trace les traits verticaux.
			x+=2*dimx; EasyLine(x,y,x,y+dimy);	// Une colonne double.
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=3*dimx; EasyLine(x,y,x,y+dimy);	// Une colonne triple.
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=2*dimx; EasyLine(x,y,x,y+dimy);	// Une colonne double.
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx;
			x=0; 
			sprintf_s(ch,"%2d",train_debug_deb+i);
			EasyTextOut(x+15,y+4,ch); x+=dimx;
	 		SelectObject(hMemDC,bmp_stylo_noir);
			bmp_select_brush(color_train[train_debug_deb+i]); // Affiche un rectangle de la couleur du train.
			Rectangle(hMemDC,x-15,y+6,x+12-15,y+8+6);
			SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
			if (enable[train_debug_deb+i]==1) {
				sprintf_s(ch," %s",name[train_debug_deb+i]);
				EasyTextOut(x+3,y+4,ch); x+=2*dimx;
		 		SelectObject(hMemDC,bmp_stylo_noir);
				bmp_select_brush(color_train[train_debug_deb+i]); // Affiche un rectangle de la couleur du train.
				Rectangle(hMemDC,x-15,y+6,x+12-15,y+8+6);
				SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
				if(cmd[train_debug_deb+i]==-1) sprintf_s(ch,"",cmd[train_debug_deb+i]);
				else if(cmd[train_debug_deb+i]<1000) sprintf_s(ch,"P_%d",cmd[train_debug_deb+i]);
				else sprintf_s(ch,"CLA_%d",cmd[train_debug_deb+i]-1000);                 EasyTextOut(x+5,y+4,ch); x+=dimx;
				if(en_auto[train_debug_deb+i]) strcpy(ch,"  Y"); else strcpy(ch,"  N");  EasyTextOut(x+5,y+4,ch); x+=dimx;
				if(inv[train_debug_deb+i]) strcpy(ch," Inv"); else strcpy(ch,"");        EasyTextOut(x+5,y+4,ch); x+=dimx;
				sprintf_s(ch,"%02d-%02d-%02d-%02d-%02d",vmin[train_debug_deb+i],vmax[train_debug_deb+i],acc[ train_debug_deb+i],dec[train_debug_deb+i],frein[train_debug_deb+i]);
				if(  acc[train_debug_deb+i]==-1) strncpy(&ch[6] ,"xx",2);
				if(  dec[train_debug_deb+i]==-1) strncpy(&ch[9] ,"xx",2);
				if(frein[train_debug_deb+i]==-1) strncpy(&ch[12],"xx",2); EasyTextOut(x+15,y+4,ch); x+=3*dimx;
				sprintf_s(ch," %3d",cons[train_debug_deb+i]);             EasyTextOut(x+5,y+4,ch);  x+=dimx;
				sprintf_s(ch," %3d",vit[train_debug_deb+i]);              EasyTextOut(x+5,y+4,ch);  x+=dimx;
				if (STR_SAME strcmp(mode[train_debug_deb + i], "SEL")) { EasyTextOut(x+1 , y + 4, "Manuel");  x += dimx; }
				else { EasyTextOut(x+1 , y + 4, " Auto ");  x += dimx; }
				strcpy(ch,sz_cant_ind[train_debug_deb+i]);                EasyTextOut(x+5,y+4,ch);  x+=2*dimx;  // Affiche le n° du canton en cours (max = 'Cx-Cy-Cz').
				if(cant_lock[train_debug_deb+i]!=-1) {sprintf_s(ch," g%d",cant_lock[train_debug_deb+i]); EasyTextOut(x+5,y+4,ch);}x+=dimx;
				strcpy(ch,""); 
				if (capt[train_debug_deb+i]==1) {
					SelectObject(hMemDC,bmp_pinceau_blanc);
					strcpy(ch,"OK"); 
				}
				else if(capt[train_debug_deb+i]==0) {
					SelectObject(hMemDC,bmp_pinceau_rouge);
					strcpy(ch,"PB"); 
				}
				Rectangle(hMemDC,x,y,x+dimx,y+dimy+1);
				EasyTextOut(x
					,y+4,ch);  x+=dimx;
			}
		}
	}

	x=0; y=(dimy*nblignes)+dimy+decaly;

	SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_blanc); 
//	Rectangle(hMemDC, 1, y + 1, 800 - 1, y + 12 * 20);		// Efface le bas
	Rectangle(hMemDC, 1, y + 1, 800 - 1, 700);		// Efface le bas en V3.6d
	SelectObject(hMemDC, bmp_stylo_gris192);


	if (selected_entry==-1) {
		// Affiche l'état des commandes  = Potentiométres + Clavier.
		SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192); SetTextColor(hMemDC,RGB(0,0,0));
		sprintf_s(ch,"Affichage non désignable de l'état des commandes des trains : Manettes + Clavier");
		EasyTextOut(x+65+5,y+2+dimy,ch);

		for(j=0;j<7;j++) for(i=0;i<5;i++){
			x=3*dimx*i+dimx/2;
			y=dimy*(nblignes+3+j)+decaly;
			if (j!=4) Rectangle(hMemDC,x,y,x+3*dimx+1,y+dimy+1);
			if (j==0 || (j==1 && serialPort.card1_ok) || (j==2 && serialPort.card2_ok) || (j==3 && serialPort.card3_ok) || j>=5) {
				SetTextColor(hMemDC,RGB(0,0,0)); // En bleu si carte n°0 ou si connectée.
				if (j<4) {
					sprintf_s(ch,"%4d",can_to_cons(vio_can[j][i],1));
					if (can_to_cons(vio_can[j][i],1)==-99 ) {
						sprintf_s(ch,"frein");
						SetTextColor(hMemDC,RGB(160,160,160));
						EasyTextOut(x+5+97,y+4,ch);
					}
					else EasyTextOut(x+5+105,y+4,ch);
				SetTextColor(hMemDC,RGB(0,0,0)); // En bleu si carte n°0 ou si connectée.
				}
			}
			else  { SetTextColor(hMemDC,RGB(160,160,160)); } // En gris si carte <> n°0 et absente.

			if(j==5) {
				if (vio_pot_virtual_conf[i][1]==0) SetTextColor(hMemDC,RGB(160,160,160));
				else { sprintf_s(ch,"%4d",virtualstep_to_cons(vio_pot_virtual_step[i])); EasyTextOut(x+5+105,y+4,ch); }
				sprintf_s(ch,"CLAVIER_%d :",i); EasyTextOut(x+5,y+4,ch);
			}
			else if (j<4) {
				sprintf_s(ch,"  POT_%03d :",2*dimx*j+i); EasyTextOut(x+5,y+4,ch);
			}
			if(j==6) {
				sprintf_s(ch,"Touches   :-%c %c %c+",vio_pot_virtual_conf[i][2],vio_pot_virtual_conf[i][1],vio_pot_virtual_conf[i][0]);
				if (vio_pot_virtual_conf[i][1]==0) SetTextColor(hMemDC,RGB(160,160,160));
				EasyTextOut(x+5,y+4,ch);
			}
		}

		SetTextColor(hMemDC,RGB(0,0,0));
		strcpy(ch,"Paramètres accélération progressive (Vitesses) : "); 
		EasyTextOut(30, dimy*(nblignes + 11) + decaly, ch);

		SetTextColor(hMemDC, RGB(0, 0, 255));
		strcpy(ch, ""); strcpy(ch2, "");
		for (i = 0; i<NB_PROGRESSIF; i++) {
			if (acc_progressif[i] != -1 ) {
				sprintf_s(ch2,"%2d, ",acc_progressif[i]);
				strcat(ch,ch2);
			}
		}
		EasyTextOut(420,dimy*(nblignes+11)+decaly,ch);

		SetTextColor(hMemDC, RGB(0, 0, 0));
		strcpy(ch, "           décélération progressive (Vitesses) : ");
		EasyTextOut(30, dimy*(nblignes + 12) + decaly, ch);

		SetTextColor(hMemDC, RGB(0, 0, 255));
		strcpy(ch, ""); strcpy(ch2, "");
		for (i = 0; i<NB_PROGRESSIF; i++) {
			if (dec_progressif[i] != -1 ) {
				sprintf_s(ch2,"%2d, ",dec_progressif[i]);
				strcat(ch,ch2);
			}
		}
		EasyTextOut(420,dimy*(nblignes+12)+decaly,ch);

		SetTextColor(hMemDC, RGB(0, 0, 0));
		strcpy(ch, "          Mémorisation position des trains est :");
		EasyTextOut(30, dimy*(nblignes + 13) + decaly, ch);

		SetTextColor(hMemDC, RGB(0, 0, 255));
		if (cfg_memoire_pos_train == 1) { EasyTextOut(420, dimy*(nblignes + 13) + decaly, " ACTIF"); }
		else { EasyTextOut(420, dimy*(nblignes + 13) + decaly, " PAS ACTIF"); }
	}

	if (selected_entry==TRAIN_SAISIE_CMDE || selected_entry==TRAIN_SAISIE_CMDE_N_TRAIN){ // Saisie du type de commande pour un train donné
		SelectObject(hMemDC,bmp_stylo_gris192);
		SetTextColor(hMemDC,RGB(0,0,0));
		SelectObject(hMemDC,bmp_stylo_noir);
		bmp_select_brush(color_train[selected_train]); // Affiche un rectangle de la couleur du train.
		if (selected_entry==TRAIN_SAISIE_CMDE_N_TRAIN ) {
			sprintf_s(ch,"3 / Choisir le type de commande pour le train n° %2d : '%s'",selected_train,name[selected_train]);
			EasyTextOut(x+20+5,y+2+dimy,ch);
			Rectangle(hMemDC,x+130+410,y+2+2+dimy,x+142+410,y+10+2+dimy);
		}
		else {
			sprintf_s(ch,"Choisir le type de commande pour le train n° %2d : '%s'",selected_train,name[selected_train]);
			EasyTextOut(x+100+5,y+2+dimy,ch);
			Rectangle(hMemDC,x+130+460,y+2+2+dimy,x+142+460,y+10+2+dimy);
		}
		SelectObject(hMemDC,bmp_pinceau_blanc);
		SelectObject(hMemDC,bmp_stylo_gris192);

		SetTextColor(hMemDC,RGB(0,0,255));
		for(j=0;j<5;j++) for(i=0;i<5;i++){
			x=2*dimx*i+2*dimx;
			y=dimy*(nblignes+3+j)+decaly;
			Rectangle(hMemDC,x,y,x+2*dimx+1,y+dimy+1);
			if (j==0 || (j==1 && serialPort.card1_ok) || (j==2 && serialPort.card2_ok) || (j==3 && serialPort.card3_ok) || j==4) {
				SetTextColor(hMemDC,RGB(0,0,255)); // En bleu si carte n°0 ou si connectée.
			}
			else  { SetTextColor(hMemDC,RGB(160,160,160)); } // En gris si carte <> n°0 et absente.
			if(j==4) {
				if (vio_pot_virtual_conf[i][1]==0) SetTextColor(hMemDC,RGB(160,160,160));
				sprintf_s(ch,"CLAVIER_%d",i); 
			}
			else {
				sprintf_s(ch," POT_%03d",2*dimx*j+i);
			}
			EasyTextOut(x+15,y+4,ch);
		}
		SetTextColor(hMemDC,RGB(0,0,255)); // En bleu.
		i=0; j=5;  // Ligne supplémentaire.
		Rectangle(hMemDC,2*dimx*i+2*dimx, dimy*(nblignes+3+j)+decaly, 2*dimx*(i+4)+2*dimx+2*dimx+1, dimy*(nblignes+3+j)+decaly+dimy+1 );
		sprintf_s(ch,"TRAIN ou WAGONS SANS COMMANDES"); EasyTextOut(2*dimx*(i+2)+2*dimx+15-85, dimy*(nblignes+3+j)+decaly+4, ch);
	}

	if (selected_entry==TRAIN_SAISIE_CANTON){
		SelectObject(hMemDC,bmp_stylo_gris192);
		SetTextColor(hMemDC,RGB(0,0,0));
		sprintf_s(ch,"2 / Choisir l'emplacement actuel du train n° %2d : '%s'",selected_train,name[selected_train]);
		EasyTextOut(x+100+5,y+2+dimy,ch);

		SelectObject(hMemDC,bmp_stylo_noir);
		bmp_select_brush(color_train[selected_train]); // Affiche un rectangle de la couleur du train.
		Rectangle(hMemDC,x+130+463,y+2+2+dimy,x+142+463,y+10+2+dimy);
		SelectObject(hMemDC,bmp_pinceau_blanc);
		SelectObject(hMemDC,bmp_stylo_gris192);

		SetTextColor(hMemDC,RGB(0,0,255));	// Texte en bleu.
		for (j=0; j<NB_CARTE; j++) {
			for (i=0; i<NB_CANTON; i++) {
				x=dimx*i;
				y=dimy*(nblignes+3+j)+decaly;
				SelectObject(hMemDC,bmp_pinceau_blanc);
				// Le canton à choisir est normalement de couleur jaune = Train devant être sur ce canton, mais pas de train detecté.
				if (canton_pb_capt[j][i]==1 )                       SelectObject(hMemDC,bmp_pinceau_rouge); // Rouge = Problème de captage sur le canton ='PB'.
				if (canton.num_train[j][i]!=-1 && vio_det[j][i]==1) SelectObject(hMemDC,bmp_pinceau_vert);  // Vert  = Canton occupé et detécté   ='Normal'.
				if (canton.num_train[j][i]==-1 && vio_det[j][i]==1) SelectObject(hMemDC,bmp_pinceau_jaune); // Jaune = Canton inoccupé et detécté ='Manque un train ici'.
				Rectangle(hMemDC,x,y,min(800,x+dimx+1),y+dimy+1);
				if (j==0 || (j==1 && serialPort.card1_ok) || (j==2 && serialPort.card2_ok) || (j==3 && serialPort.card3_ok)) {
					SetTextColor(hMemDC,RGB(0,0,255)); // En bleu si carte n°0 ou si connectée.
				}
				else  { SetTextColor(hMemDC,RGB(160,160,160)); } // En gris si carte <> n°0 et absente.
				sprintf_s(ch,"C%d",2*dimx*j+i);
				EasyTextOut(x+5,y+2,ch);
			}
		}
		for(j=0;j<4;j++) {
			for(i=0;i<16;i++){		// Affichage limité à 16 garages pour le  moment (mais * 16 gararages possibles si évolution).
				if (i+16*j >= NB_GARAGE_REEL) break;  // Pour le moment, limité à 16 garages = 1 lignes x 16 garages.
				x=dimx*i;
				y=dimy*(nblignes+3+5+j)+decaly;
				if(vio_garage_lock_status[i+16*j]) SelectObject(hMemDC,bmp_pinceau_vert); else SelectObject(hMemDC,bmp_pinceau_blanc); // 0 ou 1, 1 => Le garage est isolé du canton (état réel).
				Rectangle(hMemDC,x,y,min(800,x+dimx+1),y+dimy+1);

				if (garage.ass_canton[16*j+i]!=-1) {SetTextColor(hMemDC,RGB(0,0,255)); } // Texte bleu = garage valide
				else { SetTextColor(hMemDC,RGB(192,192,192)); }// Texte gris

				sprintf_s(ch,"g%d",NB_CANTON*j+i);
				EasyTextOut(x+5,y+2,ch);
			}
		}
	}

	if (selected_entry==TRAIN_SAISIE_NOUVEAU_TRAIN) { // Affichage du tableau pour choisir un train de réserve ou un train par défaut.
		SelectObject(hMemDC,bmp_stylo_gris192);
		SetTextColor(hMemDC,RGB(0,0,0));
		sprintf_s(ch," 1 / Choisir un train en réserve ou le train par défaut pour le n° %2d",selected_train);
		EasyTextOut(x+100+5,y+2+dimy,ch);
		SelectObject(hMemDC,bmp_stylo_noir);
		bmp_select_brush(color_train[selected_train]); // Affiche un rectangle de la couleur du train.
		Rectangle(hMemDC,x+130+535,y+2+2+dimy,x+142+535,y+10+2+dimy);
		SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);

		SetTextColor(hMemDC,RGB(0,0,255));	// Texte en bleu.
		for (j=0; j<8; j++) {
			for (i=0; i<3; i++) {
				x=dimx*5*i+(dimx/2);
				y=dimy*(nblignes+3)+(dimyr*j)+decaly;
				SelectObject(hMemDC,bmp_pinceau_blanc);
				// 
				Rectangle(hMemDC,x,y,min(800,x+5*dimx+1),y+dimyr+1); 
				if (-1+i+(3*j)==-1) {
					sprintf(ch,"Nom par défaut = ");
					strcat(ch,name[selected_train]);
					SetTextColor(hMemDC,RGB(0,0,192));	// Texte en bleu foncé.
					EasyTextOut(x+25,y+(dimyr/3),ch);
					SetTextColor(hMemDC,RGB(0,0,255));	// Texte en bleu.
					if (screen_mode==MD_ECRAN_TRAIN2) { // Wagon = rectange magenta.
						SelectObject(hMemDC,bmp_pinceau_magenta);
						SelectObject(hMemDC,bmp_stylo_noir);
						Rectangle(hMemDC,x+92+138,y+13,x+92+12+138,y+13+8);
						SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
					}
				}
				if ((-1+i+(3*j))>=0 && (-1+i+(3*j))<NB_TRAIN_RESERVE) {
					sprintf_s(ch,"%s",name[-1+i+(3*j)+NB_TRAIN]);
					SetTextColor(hMemDC,RGB(0,0,192));	// Texte en bleu foncé.
					EasyTextOut(x+92,y+2,ch);
					SetTextColor(hMemDC,RGB(0,0,255));	// Texte en bleu.
					strncpy(ch,commentaire[-1+i+(3*j)],30); ch[30]='\0';
					EasyTextOut(x+12+(8*14-4*(strlen(ch))),y+(dimyr/2),ch);
					if (color_train_reserve[-1+i+(3*j)]!=-1) {
						bmp_select_brush(color_train_reserve[-1+i+(3*j)]); // Affiche un rectangle de la couleur du train en reserve.
						SelectObject(hMemDC,bmp_stylo_noir);
						Rectangle(hMemDC,x+92+90,y+5,x+92+12+90,y+5+8);
						SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
					}
				}
			}
		}
	}

	if(selected_entry==TRAIN_SAISIE_GARAGE_ISOLE){
		SelectObject(hMemDC,bmp_stylo_gris192);
		SetTextColor(hMemDC,RGB(0,0,0));
		sprintf_s(ch,"Choisir le garage actuel pour le train n° %2d : '%s'",selected_train,name[selected_train]);
		EasyTextOut(x+100+5,y+2+dimy,ch);

		SelectObject(hMemDC,bmp_stylo_noir);
		bmp_select_brush(color_train[selected_train]); // Affiche un rectangle de la couleur du train.
		Rectangle(hMemDC,x+130+440,y+2+2+dimy,x+142+440,y+10+2+dimy);
		SelectObject(hMemDC,bmp_pinceau_blanc);
		SelectObject(hMemDC,bmp_stylo_gris192);

		SetTextColor(hMemDC,RGB(0,0,255));
		for(j=0;j<4;j++) for(i=0;i<16;i++){
			if (i+16*j >= NB_GARAGE_REEL) break;			// Affichage limité à 16 garages pour le  moment (mais * 16 gararages possibles si évolution).
			x=dimx*i;
			y=dimy*(nblignes+3+j)+decaly;
			Rectangle(hMemDC,x,y,min(800,x+dimx+1),y+dimy+1);
			if (garage.ass_canton[16*j+i]!=-1) {SetTextColor(hMemDC,RGB(0,0,255)); } // Texte bleu = garage valide
			else { SetTextColor(hMemDC,RGB(192,192,192)); }// Texte gris
			sprintf_s(ch,"g%d",16*j+i);
			EasyTextOut(x+5,y+2,ch);
		}
	}

	if(selected_entry==TRAIN_SAISIE_NOM){
		SelectObject(hMemDC,bmp_stylo_gris192); SetTextColor(hMemDC,RGB(0,0,0)); Rectangle(hMemDC,0,y,800,700);
		sprintf_s(ch,"Saisir le nom du train n° %2d   (8 car. maxi (Espace et '-][' autorisé') + valider par [Entrée]): ",selected_train);
		EasyTextOut(x+40+5,y+2+dimy,ch);

		SelectObject(hMemDC,bmp_stylo_noir);
		bmp_select_brush(color_train[selected_train]); // Affiche un rectangle de la couleur du train.
		Rectangle(hMemDC,x+68+210,y+2+2+dimy,x+80+210,y+10+2+dimy);
		SelectObject(hMemDC,bmp_pinceau_blanc);
		SelectObject(hMemDC,bmp_stylo_gris192);

		SetTextColor(hMemDC,RGB(0,0,255));
		sprintf_s(ch,"%s",szEntryName);
		EasyTextOut(x+100+5,y+2+2*dimy,ch);
	}

	if(selected_entry==TRAIN_SAISIE_PROFILE){
		SelectObject(hMemDC,bmp_stylo_gris192);
		SetTextColor(hMemDC,RGB(0,0,0));
		sprintf_s(ch,"Ajuster le profil (Vmin-Vmax-Acc-Dec-Frein) pour le train n° %2d : '%s'",selected_train,name[selected_train]);
		EasyTextOut(x+50+5,y+2+dimy,ch);

		SelectObject(hMemDC,bmp_stylo_noir);
		bmp_select_brush(color_train[selected_train]); // Affiche un rectangle de la couleur du train.
		Rectangle(hMemDC,x+130+542,y+2+2+dimy,x+142+542,y+10+2+dimy);
		SelectObject(hMemDC,bmp_pinceau_blanc);
		SelectObject(hMemDC,bmp_stylo_gris192);

		SetTextColor(hMemDC,RGB(0,0,255));
// Ajustement
		for(j=0;j<5;j++) for(i=0;i<7;i++){ //  5 lignes * 7 colonnes
			x=dimx*i;
			y=decaly+dimy*(nblignes+3+j);
			Rectangle(hMemDC,x,y,x+dimx+1,y+dimy+1);
			if(i==0){
				if(j==0) { sprintf_s(ch,"VMIN");  EasyTextOut(x+5,y+2,ch); }
				if(j==1) { sprintf_s(ch,"VMAX");  EasyTextOut(x+5,y+2,ch); }
				if(j==2) { sprintf_s(ch,"ACC");   EasyTextOut(x+5,y+2,ch); }
				if(j==3) { sprintf_s(ch,"DEC");   EasyTextOut(x+5,y+2,ch); }
				if(j==4) { sprintf_s(ch,"FREIN"); EasyTextOut(x+5,y+2,ch); }
			}
			if(i==1){
				if(j==0) { sprintf_s(ch," %2d",vmin[selected_train]); EasyTextOut(x+5,y+2,ch); }
				if(j==1) { sprintf_s(ch," %2d",vmax[selected_train]); EasyTextOut(x+5,y+2,ch); }
				if(j==2) { if(acc[selected_train]==-1)   sprintf_s(ch," xx"); else sprintf_s(ch," %2d",  acc[selected_train]); EasyTextOut(x+5,y+2,ch); }
				if(j==3) { if(dec[selected_train]==-1)   sprintf_s(ch," xx"); else sprintf_s(ch," %2d",  dec[selected_train]); EasyTextOut(x+5,y+2,ch); }
				if(j==4) { if(frein[selected_train]==-1) sprintf_s(ch," xx"); else sprintf_s(ch," %2d",frein[selected_train]); EasyTextOut(x+5,y+2,ch); }
			}
			if(i==2) { sprintf_s(ch," --"); EasyTextOut(x+5,y+2,ch); }
			if(i==3) { sprintf_s(ch," -" ); EasyTextOut(x+5,y+2,ch); }
			if(i==4){
				if(j==0) sprintf_s(ch,"  1");
				if(j==1) sprintf_s(ch," 64");
				if(j>=2) sprintf_s(ch," xx");
				EasyTextOut(x+5,y+2,ch);
			}
			if(i==5) { sprintf_s(ch," +" ); EasyTextOut(x+5,y+2,ch); }
			if(i==6) { sprintf_s(ch," ++"); EasyTextOut(x+5,y+2,ch); }
			if (i>=2 ) EasyLine(x+dimx-10,y+dimy,x+dimx,y+dimy-10); // Indicateur cases sensibles
		}
// profiles
		
			Rectangle(hMemDC,7*dimx,decaly+dimy*(nblignes+3+3),9*dimx,decaly+1+dimy*(nblignes+3+4));
			sprintf_s(ch,"DÉFAUT");  EasyTextOut(7*dimx+20,decaly+3+dimy*(nblignes+3+3),ch); 
			EasyLine(9*dimx-10,decaly+dimy*(nblignes+3+4),9*dimx,decaly+dimy*(nblignes+3+4)-10); // Indicateur case sensible.

			Rectangle(hMemDC,7*dimx,decaly+dimy*(nblignes+3+4),9*dimx,decaly+1+dimy*(nblignes+3+5));
			sprintf_s(ch,"OK");      EasyTextOut(7*dimx+35,decaly+3+dimy*(nblignes+3+4),ch); 
			EasyLine(9*dimx-10,decaly+dimy*(nblignes+3+5),9*dimx,decaly+dimy*(nblignes+3+5)-10); // Indicateur case sensible.

			// Affiche 9 lignes d'aide.
			SetTextColor(hMemDC,RGB(0,0,0)); // texte noir
			sprintf_s(ch,"Valeurs pour 'ACC', 'DEC' ou 'FREIN':");  EasyTextOut(480,decaly+dimy*(nblignes+3+0)+2,ch);
			sprintf_s(ch," 1=0,3s Temps de passage de 0 à VMAX");   EasyTextOut(480,decaly+dimy*(nblignes+3+1)+2,ch);
			sprintf_s(ch," 2=0,4s en secondes.");                   EasyTextOut(480,decaly+dimy*(nblignes+3+2)+2,ch);
			sprintf_s(ch," 3= 0,5s|  4= 0,6s|  5= 0,8s|  6= 1s  "); EasyTextOut(480,decaly+dimy*(nblignes+3+3)+2,ch);
			sprintf_s(ch," 7= 1,2s|  8= 1,3s|  9= 1,5s| 10= 1,7s"); EasyTextOut(480,decaly+dimy*(nblignes+3+4)+2,ch);
			sprintf_s(ch,"11= 2s  | 12= 2,3s| 13= 2,7s| 14= 3s  "); EasyTextOut(480,decaly+dimy*(nblignes+3+5)+2,ch);
			sprintf_s(ch,"15= 3,5s| 16= 4s  | 17= 5s  | 18= 6s  "); EasyTextOut(480,decaly+dimy*(nblignes+3+6)+2,ch);
			sprintf_s(ch,"19= 7s| 20= 8s| 21= 9s| 22=10s| 23=12s");  EasyTextOut(480,decaly+dimy*(nblignes+3+7)+2,ch);
			sprintf_s(ch,"24=14s| 25=18s| 26=24s| 27=36s| 28=74s");  EasyTextOut(480,decaly+dimy*(nblignes+3+8)+2,ch);

			sprintf_s(ch,"64>=VMAX>=6    28>=ACC>=1     xx=Pas d'inertie"); EasyTextOut(10,decaly+dimy*(nblignes+3+6)+2,ch);
			sprintf_s(ch,"50>=VMIN>=1    28>=DEC>=1");   EasyTextOut(10,decaly+dimy*(nblignes+3+7)+2,ch);
			sprintf_s(ch,"VMAX > VMIN    28>=FREIN>=1"); EasyTextOut(10,decaly+dimy*(nblignes+3+8)+2,ch);

  		/*for(j=0;j<5;j++) for(i=0;i<4;i++){
			x=8*dimx+2*dimx*i;
			y=dimy*(NB_TRAIN+3+j)+decaly;
			Rectangle(hMemDC,x,y,x+2*dimx,y+dimy);
			if((5*i+j)==18) {
				sprintf_s(ch,"DEFAUT");  EasyTextOut(x+5,y+2,ch); 
				EasyLine(x,y+dimy-10,x+10,y+dimy); // Indicateur case sensible.
			}
			if((5*i+j)==19) {
				sprintf_s(ch,"OK");      EasyTextOut(x+5,y+2,ch); 
				EasyLine(x,y+dimy-10,x+10,y+dimy); // Indicateur case sensible.
				}
		}*/
	}
	entry=selected_entry;
}


// Affiche une page avec les locomotives. 
// Permet de placer manuellement une locomotive sur un canton quand UTS a raté un déplacement de train.
// Les cantons occupés ou en erreur sont en couleurs.
// 
void cTrain::debug2(int action)
{
	int  i,j,g,k,l;
	int  x,y;
	char ch[200];
	static int dimx=50; // Dimension horizontal d'une colonne simple.
	static int dimy=20; // Dimension vertical d'une ligne du tableau.
	static int nblignes=16; // Nombre de ligne du tableau (sans le titre)	
	static int decaly=80; //Décalage en pixel vers le bas de la premiére ligne du tableau.
	static int selected_train=-1;
	static int selected_entry=-1;
	int train_debug_deb=0;
	int val;
	
	if(action==DEBUG_MOUSE) {        // ACTION = CLIC GAUCHE DE LA SOURIS.
		if ((x_mouse > 800-15 && x_mouse < 800-2) && (y_mouse > 2 && y_mouse < 15)) {
			screen_mode= screen_mode_retour; 
			return;	// On ferme la fenêtre.
		}
		if (x_mouse>=12*dimx && x_mouse<=16*dimx && y_mouse>=((3*dimy)/2) && y_mouse<=((7*dimy)/2) && selected_entry==-1 ) {
			if (screen_mode==MD_ECRAN_POSLOC1) screen_mode=MD_ECRAN_POSLOC2;
			else if (screen_mode==MD_ECRAN_POSLOC2) screen_mode=MD_ECRAN_POSLOC1;
		}
		if (screen_mode==MD_ECRAN_POSLOC1) train_debug_deb=0; // Valeur du premier déplacement à afficher.
		else train_debug_deb=nblignes;
		j=(y_mouse-dimy-decaly)/dimy;
		if(y_mouse>=dimy+decaly && selected_entry==-1) if(j>=0 && j<nblignes){
			  selected_train=j+train_debug_deb;
			  if (x_mouse>0 && x_mouse<800) {
				  if(enable[selected_train]==1) { // enable train
					// cons[selected_train]=0; On ne remet pas la vitesse à 0
					// vit[selected_train]=0;
					//enable[selected_train]=1;
					selected_entry=TRAIN_SAISIE_CANTON;
					//sprintf_s(name[selected_train],"train_%d",selected_train);
					num_cant_a_lib = selected_train;
				}
			}
		}
		if(selected_entry==TRAIN_SAISIE_CANTON){
			j=((y_mouse-decaly)/dimy)-1-nblignes-2;
			i=(x_mouse/dimx);
			if(j>=0 && j<4) if(i>=0 && i<16){	
	
				for(l=0;l<NB_CARTE;l++) for(k=0;k<NB_CANTON;k++) {        // libération de l'ancien canton ou le train était attendu (et donc selectif)
					if(canton.num_train[l][k]==num_cant_a_lib){           // après avoir choisi un garage ou un canton.
						canton.master_selectif[l][k]=0;
						canton.inv_selectif[l][k]=0;
						canton.update_selectif[l][k]=0;
					}
				}
				g=cant_lock[num_cant_a_lib];            // Libération garage
				if(g!=-1){
					vio_garage_lock_cmd[g]=0;    // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
					vio_garage_lock_status[g]=0; // 0 ou 1, 1 => Le garage est isolé du canton (état réel).
					vio_garage_lock_res[g]=0;    // 0 ou 1, 1 => Garage réservé.
					garage.numero_train[g]=-1;   // -1 = Garage relié au canton, ou Numéro de train occupant le garage isolé du canton.
					cant_lock[num_cant_a_lib]=-1;
				}

				val=100*j+i;
				canton.num_train[val/100][val%100]=selected_train;
				canton.master_selectif[val/100][val%100]=1;
				canton.inv_selectif[val/100][val%100]=0;
				canton.update_selectif[val/100][val%100]=0;
				selected_train=-1; 
				selected_entry=-1;
			}

			j=((y_mouse-decaly)/dimy)-1-nblignes-2-5;
			i=(x_mouse/dimx);
			if(j>=0 && j<NB_GARAGE_REEL/16) if(i>=0 && i<16){

				for(l=0;l<NB_CARTE;l++) for(k=0;k<NB_CANTON;k++) {     // libération de l'ancien canton ou le train était attendu (et donc selectif)
					if(canton.num_train[l][k]==num_cant_a_lib){				// après avoir choisi un garage ou un canton.
						canton.master_selectif[l][k]=0;
						canton.inv_selectif[l][k]=0;
						canton.update_selectif[l][k]=0;
					}
				}
				g=cant_lock[num_cant_a_lib];            // Libération garage
				if(g!=-1){
					vio_garage_lock_cmd[g]=0;    // 0 ou 1, 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
					vio_garage_lock_status[g]=0; // 0 ou 1, 1 => Le garage est isolé du canton (état réel).
					vio_garage_lock_res[g]=0;    // 0 ou 1, 1 => Garage réservé.
					garage.numero_train[g]=-1;   // -1 = Garage relié au canton
					cant_lock[num_cant_a_lib]=-1;
				}

				g=16*j+i;
				cant_lock[selected_train]=g;
				vio_garage_lock_cmd[g]=1;              // 1 => Demande d'isolation du garage (Sera réalisée si il a un train sur le canton).
				vio_garage_lock_status[g]=1;           // 1 => Le garage est isolé du canton (état réel).
				garage.numero_train[g]=selected_train; // Numéro de train occupant le garage isolé du canton.
				selected_train=-1;
				selected_entry=-1;
			}
		}
	}

	SelectObject(hMemDC,bmp_fonte); SetBkMode(hMemDC,TRANSPARENT);
	SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);

	if(action==DEBUG_TOTAL_PAINT) {     // ACTION = REDESSINE TOUTE LA FENETRE.
		Rectangle(hMemDC,0,0,800,700);	// Efface tout
		SelectObject(hMemDC,bmp_pinceau_gris192); SelectObject(hMemDC,bmp_stylo_gris192); Rectangle(hMemDC,800-15,15,800-2,2); // Rectangle gris pour fermer la fenêtre.
		SelectObject(hMemDC,bmp_stylo_noir); EasyLine(800-14,3,800-3,14 ); EasyLine(800-14,13,800-3,2); // Croix noire.
		SelectObject(hMemDC,bmp_stylo_noir);  EasyLine(800-2,1,800-2,16); EasyLine(800-16,15,800-1,15); // Trait noir.
		SelectObject(hMemDC,bmp_stylo_gris128); EasyLine(800-3,2,800-3,15); EasyLine(800-15,14,800-2,14); // Trait gris foncé.
		SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
		EasyLine(0,decaly,16*dimx,decaly);
		SetTextColor(hMemDC,RGB(0,0,0)); // Noir
		SelectObject(hMemDC,bmp_pinceau_noir);
		Rectangle(hMemDC, 0, decaly, 800, decaly+dimy+1);
		SelectObject(hMemDC,bmp_pinceau_gris192);

		EasyTextOut(2,2,"AFFECTATION DES TRAINS SUR LES CANTONS"); EasyTextOut(800-140,2,"(QUITTER = ESC)");
		EasyTextOut(2,2+1*dimy," UTS NE SAIT PLUS OU SE TROUVE LES TRAINS si 'Capt' est en rouge.");
		EasyTextOut(2,2+2*dimy," Pour indiquer où se trouve actuellement un train, cliquez sur sa ligne.");

		SetTextColor(hMemDC,RGB(255,0,0)); // Rouge
		x=0;y=0;
		SelectObject(hMemDC,bmp_stylo_blanc);
		EasyTextOut(x+7,4+decaly,"n°TR"      ); x+=  dimx;  EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'TR' marquée '/' = valeurs modifiables
		EasyTextOut(x+3,4+decaly,"Nom  Couleur"); x+=2*dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Nom' marquée '/' = valeurs modifiables
		EasyTextOut(x+13,4+decaly,"Cmd"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Cmd' marquée '/' = valeurs modifiables
		EasyTextOut(x+7,4+decaly,"Auto"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Auto' marquée '/' = valeurs modifiables
		EasyTextOut(x+5,4+decaly,"Invrs"	 ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);       // =1 si l'alimentation du train est inversée.
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Inv' marquée '/' = valeurs modifiables
		EasyTextOut(x+6,4+decaly,"Profile:Vmin,Vmax"); x+=3*dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne 'Profile' marquée '/' = valeurs modifiables
		EasyTextOut(x+8,4+decaly,"Cons"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne marquée '/' = valeurs modifiables
		EasyTextOut(x+5,4+decaly,"Vites"     ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne marquée '/' = valeurs modifiables
		EasyTextOut(x+9,4+decaly,"Mode"      ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne marquée '/' = valeurs modifiables
		EasyTextOut(x+22,4+decaly,"Cantons"  ); x+=2*dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne marquée '/' = valeurs modifiables
		EasyTextOut(x+5,4+decaly,"Garag"     ); x+=  dimx; EasyLine(x,y+decaly,x,y+dimy+decaly);
		EasyLine(x-10,dimy+decaly,x,dimy+decaly-10);  // Colonne 'Garag' marquée '/' = valeurs modifiables
		EasyTextOut(x+9,4+decaly,"Capt"      ); x+=dimx;
		EasyLine(x-10,dimy+decaly,x,decaly+dimy-10);  // Colonne marquée '/' = valeurs modifiables
		SelectObject(hMemDC,bmp_stylo_gris192);
	}

	k=0; // Indicateur erreur d'occupation.
	for (j=0; j<NB_CARTE && k==0; j++) {
		for (i=0; i<NB_CANTON && k==0; i++) {
			if (canton_pb_capt[j][i]==1 || (canton.num_train[j][i]==-1 && vio_det[j][i]==1)) k=1;
		}
	}
	SetTextColor(hMemDC,RGB(0,0,0)); // Texte en noir
	if (k==0) SelectObject(hMemDC,bmp_pinceau_vert);
	else  SelectObject(hMemDC,bmp_pinceau_rouge);
	Rectangle(hMemDC, 3*dimx-3, 3*dimy, 9*dimx, 4*dimy-3);
	EasyTextOut(3*dimx+25,2+3*dimy,"OCCUPATION : TRAINS => CANTONS");

	SelectObject(hMemDC,bmp_stylo_noir);
	if (screen_mode==MD_ECRAN_POSLOC1) {
		SelectObject(hMemDC,bmp_pinceau_cyan);
		Rectangle(hMemDC, 12*dimx, (3*dimy)/2, 16*dimx, (7*dimy)/2);
		SelectObject(hMemDC,bmp_stylo_cyanf);
		EasyLine(12*dimx+1, (7*dimy)/2-2, 16*dimx-1, (7*dimy)/2-2); // Relief rectangle.
		EasyLine(16*dimx-2, (3*dimy)/2+1, 16*dimx-2, (7*dimy)/2-2);	// Relief rectangle.
		SelectObject(hMemDC,bmp_stylo_noir);
		EasyTextOut(13*dimx+20, 5+2*dimy, "TRAINS");
	}
	else {
		SelectObject(hMemDC,bmp_pinceau_magenta);
		Rectangle(hMemDC, 12*dimx, (3*dimy)/2, 16*dimx, (7*dimy)/2);
		SelectObject(hMemDC,bmp_stylo_magentaf);
		EasyLine(12*dimx+1, (7*dimy)/2-2, 16*dimx-1, (7*dimy)/2-2); // Relief rectangle.
		EasyLine(16*dimx-2, (3*dimy)/2+1, 16*dimx-2, (7*dimy)/2-2);	// Relief rectangle.
		SelectObject(hMemDC,bmp_stylo_noir);
		EasyTextOut(13*dimx+20, 5+2*dimy, "WAGONS");
	}
	EasyLine(16*dimx-1, (7*dimy)/2-11, 16*dimx-11, (7*dimy)/2-1); // Trait en diagonal.
	SelectObject(hMemDC,bmp_stylo_gris192);

	if (screen_mode==MD_ECRAN_POSLOC1) train_debug_deb=0; // Valeur du premier déplacement à afficher.
	else train_debug_deb=nblignes;

	SetTextColor(hMemDC,RGB(0,0,255));	// Texte en bleu.
	SelectObject(hMemDC,bmp_stylo_gris192);
	for (i=0; i<nblignes; i++) {
		if (train_debug_deb+i<NB_TRAIN) {
			y=(dimy*i)+decaly+dimy ;
			SelectObject(hMemDC,bmp_pinceau_blanc);
			//if((iti_deb+i)>=ITI_TAB_NB) break;
			//if(iti_tab[iti_deb+i][ITI_TAB_IND_WAIT]) SelectObject(hMemDC,bmp_pinceau_jaune);
			//if(iti_tab[iti_deb+i][ITI_TAB_IND_OK])   SelectObject(hMemDC,bmp_pinceau_vert);
			Rectangle(hMemDC,0,y,16*dimx,y+dimy+1);
			x=0;
			x+=  dimx; EasyLine(x,y,x,y+dimy);  // Trace les traits verticaux.
			x+=2*dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=3*dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=2*dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx; EasyLine(x,y,x,y+dimy);
			x+=  dimx;
			x=0; 
			if(enable[train_debug_deb+i]==0) SetTextColor(hMemDC,RGB(192,192,192)); // Gris
			sprintf_s(ch,"%2d",train_debug_deb+i); EasyTextOut(x+15,y+4,ch); x+=dimx;
			SetTextColor(hMemDC,RGB(0,0,0)); // Noir
			if(enable[train_debug_deb+i]==0) continue;
			sprintf_s(ch," %s",name[train_debug_deb+i]); EasyTextOut(x+3,y+4,ch); x+=2*dimx;
 			SelectObject(hMemDC,bmp_stylo_noir); bmp_select_brush(color_train[train_debug_deb+i]); // Affiche un rectangle de la couleur du train.
			Rectangle(hMemDC,x-15,y+6,x+12-15,y+8+6);
			SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);
			if (cmd[train_debug_deb+i]==-1) sprintf_s(ch,"",cmd[train_debug_deb+i]);
			else if (cmd[train_debug_deb+i]<1000) sprintf_s(ch,"P_%d",cmd[train_debug_deb+i]);
			else sprintf_s(ch,"CLA_%d",cmd[train_debug_deb+i]-1000);                 EasyTextOut(x+5,y+4,ch); x+=dimx;
			if (en_auto[train_debug_deb+i]) strcpy(ch,"  Y"); else strcpy(ch,"  N"); EasyTextOut(x+5,y+4,ch); x+=dimx;
			if (inv[train_debug_deb+i]) strcpy(ch," Inv"); else strcpy(ch,"");       EasyTextOut(x+5,y+4,ch); x+=dimx;
			sprintf_s(ch,"%02d-%02d-%02d-%02d-%02d",vmin[train_debug_deb+i],vmax[train_debug_deb+i],acc[ train_debug_deb+i],dec[train_debug_deb+i],frein[train_debug_deb+i]);
			if (acc[train_debug_deb+i]==-1) strncpy(&ch[6] ,"xx",2);
			if (dec[train_debug_deb+i]==-1) strncpy(&ch[9] ,"xx",2);
			if (frein[train_debug_deb+i]==-1) strncpy(&ch[12],"xx",2); EasyTextOut(x+15,y+4,ch); x+=3*dimx;
			sprintf_s(ch," %3d",cons[train_debug_deb+i]);              EasyTextOut(x+5,y+4,ch);  x+=dimx;
			sprintf_s(ch," %3d",vit[train_debug_deb+i]);               EasyTextOut(x+5,y+4,ch);  x+=dimx;
//			strcpy(ch,mode[train_debug_deb+i]);                        EasyTextOut(x+9,y+4,ch);  x+=dimx;
			if (STR_SAME strcmp(mode[train_debug_deb + i], "SEL")) { EasyTextOut(x+1 , y + 4, "Manuel");  x += dimx; }
			else { EasyTextOut(x+1 , y + 4, " Auto ");  x += dimx; }

			strcpy(ch,sz_cant_ind[train_debug_deb+i]);                 EasyTextOut(x+5,y+4,ch);  x+=2*dimx;  // Affiche le n° du canton en cours (max = 'Cx-Cy-Cz').
			if (cant_lock[train_debug_deb+i]!=-1) {sprintf_s(ch," g%d",cant_lock[train_debug_deb+i]); EasyTextOut(x+5,y+4,ch);}x+=dimx;
			strcpy(ch,""); 
			if (capt[train_debug_deb+i]==1) {
				SelectObject(hMemDC,bmp_pinceau_blanc);
				strcpy(ch,"OK"); 
			}
			else if(capt[train_debug_deb+i]==0) {
				SelectObject(hMemDC,bmp_pinceau_rouge);
				strcpy(ch,"PB"); 
			}
			Rectangle(hMemDC,x,y,x+dimx,y+dimy+1);
			EasyTextOut(x+15,y+4,ch);  x+=dimx;
		}
	}
	x=0; y=(dimy*nblignes)+dimy+decaly;


	SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_blanc); 
	Rectangle(hMemDC,1,y+1,800-1,y+12*20);		// Efface le bas
	SelectObject(hMemDC,bmp_stylo_gris192); 


	if(selected_entry==-1){
		SelectObject(hMemDC,bmp_stylo_blanc); SelectObject(hMemDC,bmp_pinceau_blanc);
		Rectangle(hMemDC,0,decaly+1+(nblignes+1)*dimy,800,700); // Efface la zone de saisie en dessous du tableau.
	}
	if(selected_entry==TRAIN_SAISIE_CANTON){

		SelectObject(hMemDC,bmp_pinceau_jaune); // Rectangle jaune.
		Rectangle(hMemDC,727+x+10+5, y+2, 770+x+10+5, -2+y+2+15);
		SelectObject(hMemDC,bmp_pinceau_blanc);


		SelectObject(hMemDC,bmp_stylo_gris192);
		SetTextColor(hMemDC,RGB(0,0,0));
		sprintf_s(ch,"Indiquer où se trouve actuellement le train n° %2d : '%s'       (Cliquez sur une case JAUNE)",selected_train,name[selected_train]);
		EasyTextOut(x+10+5,y+2,ch);

		SelectObject(hMemDC,bmp_stylo_noir);
		bmp_select_brush(color_train[selected_train]); // Affiche un rectangle de la couleur du train.
		Rectangle(hMemDC,x+130+398,y+2+2,x+142+398,y+10+2);
		SelectObject(hMemDC,bmp_pinceau_blanc);
		SelectObject(hMemDC,bmp_stylo_gris192);

		EasyTextOut(x+10+5,y+2+dimy,"JAUNE = Il devrait y avoir un train sur ce canton,    VERT = OK,    ROUGE  = Canton occupé à tord");

		SetTextColor(hMemDC,RGB(0,0,255));
		for(j=0;j<NB_CARTE;j++) {
			for(i=0;i<NB_CANTON;i++){
				x=dimx*i;
				y=dimy*(nblignes+3+j)+decaly;
				SelectObject(hMemDC,bmp_pinceau_blanc);
				// Le canton à choisir est normalement de couleur jaune = Train devant être sur ce canton, mais pas de train detecté.
				if (canton_pb_capt[j][i]==1 )                       SelectObject(hMemDC,bmp_pinceau_rouge); // Rouge = Problème de captage sur le canton ='PB'.
				if (canton.num_train[j][i]!=-1 && vio_det[j][i]==1) SelectObject(hMemDC,bmp_pinceau_vert);  // Vert  = Canton occupé et detécté   ='Normal'.
				if (canton.num_train[j][i]==-1 && vio_det[j][i]==1) SelectObject(hMemDC,bmp_pinceau_jaune); // Jaune = Canton inoccupé et detécté ='Manque un train ici'.
				Rectangle(hMemDC,x,y,min(800,x+dimx+1),y+dimy+1);
				if (j==0 || (j==1 && serialPort.card1_ok) || (j==2 && serialPort.card2_ok) || (j==3 && serialPort.card3_ok)) {
					SetTextColor(hMemDC,RGB(0,0,255)); // En bleu si carte n°0 ou si connectée.
				}
				else  { SetTextColor(hMemDC,RGB(160,160,160)); } // En gris si carte <> n°0 et absente.
				sprintf_s(ch,"C%d",2*dimx*j+i);
				EasyTextOut(x+5,y+2,ch);
			}
		}
		for(j=0;j<4;j++) {
			for(i=0;i<16;i++){		// Affichage limité à 16 garages pour le  moment (mais * 16 gararages possibles si évolution).
				if (i+16*j >= NB_GARAGE_REEL) break;  // Pour le moment, limité à 16 garages = 1 lignes x 16 garages.
				x=dimx*i;
				y=dimy*(nblignes+3+5+j)+decaly;
				if(vio_garage_lock_status[i+16*j]) SelectObject(hMemDC,bmp_pinceau_vert); else SelectObject(hMemDC,bmp_pinceau_blanc); // 0 ou 1, 1 => Le garage est isolé du canton (état réel).
				Rectangle(hMemDC,x,y,min(800,x+dimx+1),y+dimy+1);
				if (garage.ass_canton[i+16*j]!=-1) {SetTextColor(hMemDC,RGB(0,0,255)); } // Texte bleu = garage valide
				else { SetTextColor(hMemDC,RGB(192,192,192)); }// Texte gris
				sprintf_s(ch,"g%d",NB_CANTON*j+i);
				EasyTextOut(x+5,y+2,ch);
			}
		}
	}
	entry=selected_entry;
}

