// UTS 2000 - fichier 'vib.cpp' Lecture des variables pour le vibreur dans le fichier de configuration, et gestion de ce vibreur - 
// V3.7c - Le 01/10/2016
// Le vibreur est activé quand on pert le signbal d'occupation de voie sur un canton où un train devrait être présent.
// L'action du vibreur doit permettre de rétablir le contact électrique.
/*****************************************************************************/
/* VIBRATOR                                                                   */
/*****************************************************************************/
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h> 
#include "Train_UTS.h"
#include  "serial_port.h"

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


// Déclaration des fonctions externes
extern void EasyTextOut(int, int, char*);
extern void EasyLine(int, int, int, int); 
extern int get_line(FILE*, char [][CHAR_CONFIG_NB], int*);
extern int pio_set_val(int ,int );
extern int pio_var_ch2int(char []);
extern void bmp_select_brush(int no_color);
extern cSerialPort serialPort;

// Déclaration des variables externes
extern HBRUSH  bmp_pinceau_blanc, bmp_pinceau_gris192, bmp_pinceau_gris240,bmp_pinceau_rouge, bmp_pinceau_vert, bmp_pinceau_magenta, bmp_pinceau_orange;
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_rougef, bmp_stylo_vertfonce;
extern int vib_on;      //dans pio
extern int vib_state;   //dans pio
extern int vib_var;
extern int vib_var_inv;
extern int vib_pwm_no;
extern int vib_pwm_vit;
extern int vib_time_before;
extern int vib_time_after;
extern int vib_dec_before;
extern int vib_dec_after;
extern int canton_pb_capt[NB_CARTE][NB_CANTON];
extern int x_mouse, y_mouse, touche, touche_char, x_mouse_move, y_mouse_move, screen_mode, screen_mode_retour;
extern int vio_canton_vit[NB_CARTE][NB_CANTON];      //UU: n'en garder qu'un et mettre en debug total
extern int train_pb_capt[NB_TRAIN];  // 0 ou 1, 1 => Le train n'est pas détecté sur les cantons.
extern int timer_prg;
extern int color_train[NB_TRAIN];


void vib_init_file(char filename[])
{
    FILE* pf;
    char ch[CHAR_CONFIG_NB],ch_tab[BLOC_CONFIG_NB][CHAR_CONFIG_NB],ch_error[200];
    int  ch_nb,i,var;
    if((pf=fopen(filename,"rt"))==NULL) {
        MessageBox(NULL,"Impossible d'ouvrir le fichier de configuration du vibreur 'config.txt'","Erreur",MB_OK|MB_ICONERROR); exit(1);
    }
    vib_on=0;
    vib_state=0;
    vib_var=-1;
    vib_var_inv=0;
    vib_pwm_no=-1;
    vib_pwm_vit=32;
    vib_time_before=0;
    vib_time_after=0;
    vib_dec_before=0;
    vib_dec_after=0;
    // on
    // nb_det_dep:2
    // out:io_out_3
    // out_pwm:0,-35
    // time_before:3
    // time_after:8
	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,"#vibrator") || !strcmp(ch,"#vib") ) {
            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 '#vib'","Erreur",MB_OK|MB_ICONERROR);
					MessageBox(NULL,"Section '#vib' (ligne>75 blocs) commençant par (taper sur entrée) : ","Erreur",MB_OK|MB_ICONERROR);
					strcpy(ch_error,"Section #vib 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 #aigauto
                for(i=0;i<ch_nb;i++) if (ch_tab[i][0]=='@') ch_nb=i;  //remove comments
                i=0;
                while(i<ch_nb) {
					if (ch_nb-i>=3) {
						if ((!strcmp(ch_tab[i],"time_before")) && ch_tab[i+1][0]==':') {
							vib_time_before=atoi(ch_tab[i+2]);
							i=i+3; continue;
						}
                    }
					if (ch_nb-i>=3) {
						if ((!strcmp(ch_tab[i],"time_after")) && ch_tab[i+1][0]==':' ) {
							vib_time_after=atoi(ch_tab[i+2]);
							i=i+3; continue;
						}
                    }
					if (ch_nb-i>=5) {
						if ((!strcmp(ch_tab[i],"out_pwm")) && ch_tab[i+1][0]==':' && ch_tab[i+3][0]==',') {
						    vib_pwm_no =atoi(ch_tab[i+2]);
	                        vib_pwm_vit=atoi(ch_tab[i+4]);
		                    i=i+5; continue;
						}
                    }
					if (ch_nb-i>=4) {
						if ((!strncmp(ch_tab[i],"out",3)) && ch_tab[i+1][0]==':' && ch_tab[i+2][0]=='!')  {
							if ((var=pio_var_ch2int(ch_tab[i+3]))!=-1) {
								vib_var=var;
								vib_var_inv=1;
								i=i+4; continue;
							}
						}
                    }
					if (ch_nb-i>=3) {
						if ((!strncmp(ch_tab[i],"out",3)) && ch_tab[i+1][0]==':') {
							if((var=pio_var_ch2int(ch_tab[i+2]))!=-1) {
						        vib_var=var;
							    vib_var_inv=0;
								i=i+3; continue;
							}
						}
					}
					if (ch_nb-i>=1) {
						if (!strcmp(ch_tab[i],"on")) { // Fonction vibreur en marche.
							vib_on=1;
							i++; continue;
						}
					}
					if (ch_nb-i>=1) {
						if (!strcmp(ch_tab[i],"off")) { // Fonction vibreur à l'arrêt.
							vib_on=0;
							i++; continue;
						}
					}
					strcpy(ch_error,"Fichier 'config.txt',\n\nSection #Vib,\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(==#vibrator)   fin description '#vibrator'.
	}			// While (scanf)    fin du fichier 'config.txt'.
//	moins_char_normal=1;		// '-' est un caractère normal, comme '+'.
	fclose(pf);
}


void vib_maj(void)
{
    int j,i,pb;
    pb=0;

	if (vib_on==1) { // Si vibreur en fonction.
		for (j=0; j<NB_CARTE && pb==0; j++) {
			for (i=0; i<NB_CANTON && pb==0; i++) { // On teste 'pb' pour sortir plus vite si pb==1;
				if (canton_pb_capt[j][i]==1) pb=1;
			}
		}
	    if (vib_state==0 && pb==0) { // Ca ne vibre pas et pas de problème.
			vib_dec_before=vib_time_before; // Réinitialise le temps avant déclenchement.
			vib_dec_after=vib_time_after;   // Réinitialise le temps après déclenchement.
		}
		if (vib_state==0 && pb==1 && vib_on) {// Ca ne vibre pas et problème !!!
	        if (vib_dec_before==0) vib_state=1;
			if (vib_dec_before>0)  vib_dec_before--;
		}
		if (vib_state==1 && pb==1) { // Ca vibre et le problème est encore là.
				vib_dec_after=vib_time_after;
		}
		if (vib_state==1 && pb==0) { // Ca vibre et le problème n'est plus là.
			if (vib_dec_after>0) vib_dec_after--;
			if (vib_dec_after==0) vib_state=0;
		}
	
		if (vib_state==0) { // Ca ne doit pas vibrer.
			if (vib_var!=-1) pio_set_val(vib_var,vib_var_inv);
			if (vib_pwm_no!=-1) vio_canton_vit[vib_pwm_no/100][vib_pwm_no%100]=0;
		}
		else { // Ca doit vibrer. 
	        if (vib_var!=-1) pio_set_val(vib_var,vib_var_inv^1);
			if (vib_pwm_no!=-1) vio_canton_vit[vib_pwm_no/100][vib_pwm_no%100]=vib_pwm_vit;
		}
	}
	else { // Si vibreur hors fonction.
		vib_state=0;
		if (vib_var!=-1) pio_set_val(vib_var,vib_var_inv);
		if (vib_pwm_no!=-1) vio_canton_vit[vib_pwm_no/100][vib_pwm_no%100]=0;
		vib_dec_before=vib_time_before; // Réinitialise le temps avant déclenchement.
		vib_dec_after=vib_time_after;   // Réinitialise le temps après déclenchement.
	}
}

// Affiche le tableau d'état du vibreur.
//
//
void vib_debug(int action)
{
    int i,j,t,y;
    char ch[200];

	int decalx, decaly, dimx, dimy, nb_colonnes;  // Décalage de la premiere case et dimmension d'une case 
	float nb_secondes;
	dimx   = 180;
	dimy   = 20;
	decalx = 180;
	decaly = 7*dimy;
	nb_colonnes=16;

    if(action==DEBUG_TOTAL_PAINT) {     // ACTION = REDESSINE TOUTE LA FENETRE.
		SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192); Rectangle(hMemDC,0,0,800,700);
		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);
		SelectObject(hMemDC,bmp_fonte); SetBkMode(hMemDC,TRANSPARENT); SetTextColor(hMemDC,RGB(0,0,0)); // Texte noir

// Affiche le texte en haut et le tableau de saisie du milieu .

		EasyTextOut(2,2+0*dimy,"AFFICHE LES VALEURS DU VIBREUR"); EasyTextOut(800-140,2,"(QUITTER = ESC)");
		EasyTextOut(2,2+1*dimy," Le vibreur fait vibrer le plateau en cas de faux contact prolongé");
		EasyTextOut(2,2+2*dimy," Il existe une temporisation entre la détection d'un faux contact et la mise en marche du vibreur");
		EasyTextOut(2,2+3*dimy," et une temporisation entre l'arrêt du faux contact et l'arrêt du vibreur");
		EasyTextOut(2,2+4*dimy," La configuration du vibreur se fait dans 'config.txt' section '#vib'");
		EasyTextOut(2,2+5*dimy," La variable 'vib_on' permet d'activer ou de désactiver le vibreur'");
		EasyTextOut(2,2+6*dimy," La variable 'vib_state' indique l'état du vibreur'");

		decalx=decalx+15; // Pour centrer le tableau. Reporter aussi ce décalage dans '(action==DEBUG_MOUSE)'.
 		y=decaly+10*dimy; // 1ere ligne du tableau
        Rectangle(hMemDC,decalx,y,decalx+2*dimx,y+dimy+1);
        SelectObject(hMemDC,bmp_fonte); SetBkMode(hMemDC,TRANSPARENT); SetTextColor(hMemDC,RGB(255,0,0)); // Texte rouge
		EasyTextOut(10+decalx,4+y," Réglages (temporisations et surveillance)");

        y=decaly+11*dimy;  // 2eme ligne du tableau
		SetTextColor(hMemDC,RGB(0,0,255)); // Texte bleu
		Rectangle(hMemDC,decalx,y,decalx+2*dimx,y+dimy+1);
		EasyLine(decalx+1*dimx,y,decalx+1*dimx,y+dimy); 
        EasyTextOut(decalx+40,4+y,"Tic avant -"); EasyTextOut(decalx+1*dimx+40,4+y,"Tic avant +"); 
        y=decaly+12*dimy;
		Rectangle(hMemDC,decalx,y,decalx+2*dimx,y+dimy+1);
		EasyLine(decalx+1*dimx,y,decalx+1*dimx,y+dimy); 
        EasyTextOut(decalx+40,4+y,"Tic après -"); EasyTextOut(decalx+1*dimx+40,4+y,"Tic après +"); 

        y=decaly+13*dimy;
        Rectangle(hMemDC,decalx,y,decalx+2*dimx,y+dimy+1);
		EasyLine(decalx+1*dimx,y,decalx+1*dimx,y+dimy); 
		EasyTextOut(decalx+50,4+y,"DÉMARRER"); EasyTextOut(decalx+1*dimx+50,4+y,"ARRÊTER");

        y=decaly+14*dimy;
		for (i=0;i<3;i++) { // Trace un trait en diagonal sur les cases sensibles
			EasyLine(decalx+1*dimx-10,y-i*dimy, decalx+1*dimx,y-i*dimy-10); 
			EasyLine(decalx+2*dimx-10,y-i*dimy, decalx+2*dimx,y-i*dimy-10); }

		decalx=decalx-15; // Pour remettre la valeur originale.
	}

	SelectObject(hMemDC,bmp_pinceau_blanc);
	SelectObject(hMemDC,bmp_fonte); SetBkMode(hMemDC,TRANSPARENT); SetTextColor(hMemDC,RGB(0,0,0)); // Texte noir

	decalx = decalx-140;
	y=decaly+1*dimy; 

// Affiche le tableau d'information du dessus

	Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1); // Placée au dessus du tableau
	sprintf_s(ch,"Durée du Timer 'tic'                              : %3d msec",(timer_prg+15)); EasyTextOut(decalx+15,4+y,ch);

	y=y+dimy; Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1);
	nb_secondes=(timer_prg+15)*vib_time_before;
	nb_secondes=nb_secondes/1000;
	sprintf_s(ch,"Temps d'attente configuré avant déclenchement     : %3d (tics) = %4.1f sec",vib_time_before,nb_secondes);
	EasyTextOut(decalx+15,4+y,ch);

	y=y+dimy; Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1);
	nb_secondes=(timer_prg+15)*vib_dec_before;
	nb_secondes=nb_secondes/1000;
	sprintf_s(ch,"Temps restant actuellement avant un déclenchement : %3d (tics) = %4.1f sec",vib_dec_before,nb_secondes);
	EasyTextOut(decalx+15,4+y,ch);

	y=y+dimy; Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1);
	nb_secondes=(timer_prg+15)*vib_time_after;
	nb_secondes=nb_secondes/1000;
	sprintf_s(ch,"Temps d'attente configuré après rétablissement    : %3d (tics) = %4.1f sec",vib_time_after,nb_secondes);
	EasyTextOut(decalx+15,4+y,ch);

	y=y+dimy; Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1); 
	nb_secondes=(timer_prg+15)*vib_dec_after;
	nb_secondes=nb_secondes/1000;
	sprintf_s(ch,"Temps restant actuellement après rétablissement   : %3d (tics) = %4.1f sec",vib_dec_after,nb_secondes);
	EasyTextOut(decalx+15,4+y,ch);

	y=y+dimy; Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1);  // Case pour le moment vide.

	y=y+dimy; Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1);
	sprintf_s(ch,"Surveillance des faux contacts                    :");
    if(vib_on==1)  strcat(ch," En marche"); else strcat(ch," A l'arrêt"); EasyTextOut(decalx+15,4+y,ch);

	y=y+dimy; Rectangle(hMemDC,decalx,y,decalx+4*dimx,y+dimy+1);
	sprintf_s(ch,"Etat du vibreur                                   :");
    if(vib_state==1)  strcat(ch," En marche"); else strcat(ch," A l'arrêt"); EasyTextOut(decalx+15,4+y,ch);

//	Affiche le tableau 'Cantons' et 'Trains' du dessous. Case en rouge si état = on

    SelectObject(hMemDC,bmp_pinceau_blanc);    SelectObject(hMemDC,bmp_stylo_blanc);
	Rectangle(hMemDC, decalx+140, decaly+16*dimy, decalx+140+25*16-5, decaly+16*dimy+4*25-5);
	Rectangle(hMemDC, decalx+140, decaly+22*dimy, decalx+140+25*16-5, decaly+22*dimy+2*25-5);

	decalx = decalx+140;
    SelectObject(hMemDC,bmp_stylo_gris192);

    y=decaly+15*dimy;
	for (t=0; t<nb_colonnes; t++) { sprintf_s(ch,"%2d",t); EasyTextOut(decalx+25*t,y,ch); } // Affiche 1,2,3,4...15
    EasyTextOut(decalx+16*25+10,y,"N° de Cantons / Trains");

	y=decaly+16*dimy;
	for(j=0;j<NB_CARTE ;j++) { sprintf_s(ch,"Carte n° %d",j); EasyTextOut(decalx-90,y+25*j+2,ch); } 
    EasyTextOut(decalx+16*25+10,y+2+25,     "Indication des cantons");
    EasyTextOut(decalx+16*25+10,y+2+25+dimy,"en défaut (case en rouge)");

	for(j=0;j<NB_CARTE;j++) for(i=0;i<NB_CANTON;i++) {
		if (j == 0 || (j == 1 && serialPort.card1_ok) || (j == 2 && serialPort.card2_ok) || (j == 3 && serialPort.card3_ok)) {
			SelectObject(hMemDC, bmp_stylo_noir); }
		else SelectObject(hMemDC, bmp_stylo_gris192);
		if(canton_pb_capt[j][i]) SelectObject(hMemDC,bmp_pinceau_rouge); else SelectObject(hMemDC,bmp_pinceau_blanc);
        Rectangle(hMemDC,decalx+25*i,25*j+y,decalx+25*i+20,25*j+20+y);
    }

	y=decaly+22*dimy;
    EasyTextOut(decalx-90,y+2,"Trains");
    EasyTextOut(decalx-90,y+2+25,"Wagons");
    EasyTextOut(decalx+16*25+10,y+2,     "Indication des trains");
    EasyTextOut(decalx+16*25+10,y+2+dimy,"en défaut (case en rouge)");
	EasyTextOut(decalx+16*25+10,y+2+2*dimy,"+ couleur du train");

    for (t=0; t<nb_colonnes; t++) { 
		if (train_pb_capt[t]) { bmp_select_brush(color_train[t]);   SelectObject(hMemDC,bmp_stylo_rouge); }
		else { SelectObject(hMemDC,bmp_pinceau_blanc);  SelectObject(hMemDC,bmp_stylo_gris192);}
        Rectangle(hMemDC,decalx+25*t,y,decalx+25*t+20,y+20);
    }
    for (t=0; t<nb_colonnes; t++) { 
		if (train_pb_capt[t+16]) { SelectObject(hMemDC,bmp_pinceau_magenta);   SelectObject(hMemDC,bmp_stylo_rouge); }
		else { SelectObject(hMemDC,bmp_pinceau_blanc); SelectObject(hMemDC,bmp_stylo_gris192);}
        Rectangle(hMemDC,decalx+25*t,y+25,decalx+25*t+20,y+20+25);
    }
	for (t=0; t<nb_colonnes; t++) { 
		sprintf_s(ch,"%2d",t);    EasyTextOut(decalx+25*t,y-17,ch);      // Affiche 1,2,3,4...15 = n° de trains.
		sprintf_s(ch,"%2d",t+16); EasyTextOut(decalx+25*t,y+20+25+5,ch); // Affiche 16,17,...31  = n° wagons
	}

	SetTextColor(hMemDC,RGB(0,0,0)); // Texte noir.
	SelectObject(hMemDC,bmp_stylo_noir);
	if (vib_on==1) { // Vibreur on.
		SelectObject(hMemDC,bmp_pinceau_vert);
		Rectangle(hMemDC, 600, decaly+12*dimy, 730, decaly+13*dimy+1); 
		SelectObject(hMemDC,bmp_stylo_vertfonce);
		EasyLine(601, decaly+13*dimy+1-2, 729, decaly+13*dimy+1-2); // Relief rectangle.
		EasyLine(728, decaly+12*dimy+1,   728, decaly+13*dimy+1-2);	// Relief rectangle.
		EasyTextOut(630, decaly+12*dimy+4, "EN MARCHE");
	}
	else { // Vibreur off.
		SelectObject(hMemDC,bmp_pinceau_rouge);
		Rectangle(hMemDC, 600, decaly+12*dimy, 730, decaly+13*dimy+1); 
		SelectObject(hMemDC,bmp_stylo_rougef);
		EasyLine(601, decaly+13*dimy+1-2, 729, decaly+13*dimy+1-2); // Relief rectangle.
		EasyLine(728, decaly+12*dimy+1,   728, decaly+13*dimy+1-2);	// Relief rectangle.
		EasyTextOut(630, decaly+12*dimy+4, "A L'ARRÊT");
	}
	SelectObject(hMemDC,bmp_stylo_noir);
	EasyLine(730-1, decaly+13*dimy+1-10, 730-11, decaly+13*dimy+1); // Lignes diagonales
	SelectObject(hMemDC,bmp_stylo_gris192);

	SetTextColor(hMemDC,RGB(0,0,0)); // Texte noir.
	SelectObject(hMemDC,bmp_stylo_gris192);
	if (vib_state==1) { // Vibre.
		SelectObject(hMemDC,bmp_pinceau_orange);
		Rectangle(hMemDC, 600, decaly+10*dimy, 730, decaly+11*dimy+1); 
		EasyTextOut(645, decaly+10*dimy+4, "VIBRE");
	}
	else { // Ne vibre pas.
		SelectObject(hMemDC,bmp_pinceau_vert);
		Rectangle(hMemDC, 600, decaly+10*dimy, 730, decaly+11*dimy+1); 
		EasyTextOut(615, decaly+10*dimy+4, "NE VIBRE PAS");
	}

										 
    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>=600 && x_mouse<=730 && y_mouse>=decaly+12*dimy && y_mouse<=decaly+13*dimy) vib_on^=1;

        i=(y_mouse-decaly-11*dimy)/dimy;
        if(i==0 && x_mouse>decalx+15        && x_mouse<decalx+15+1*dimx) if(vib_time_before>0) vib_time_before--;
        if(i==0 && x_mouse>decalx+15+1*dimx && x_mouse<decalx+15+2*dimx) vib_time_before++;

        if(i==1 && x_mouse>decalx+15        && x_mouse<decalx+15+1*dimx) if(vib_time_after>0 ) vib_time_after--;
        if(i==1 && x_mouse>decalx+15+1*dimx && x_mouse<decalx+15+2*dimx) vib_time_after++;

        if(i==2 && x_mouse>decalx+15        && x_mouse<decalx+15+1*dimx) vib_on=1;
        if(i==2 && x_mouse>decalx+15+1*dimx && x_mouse<decalx+15+2*dimx) vib_on=0;
    }
}