Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

/*
 * Project: S.Ha.R.K.
 *
 * Coordinators:
 *   Giorgio Buttazzo    <giorgio@sssup.it>
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *
 * Authors     :
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *   (see the web pages for full authors list)
 *
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
 *
 * http://www.sssup.it
 * http://retis.sssup.it
 * http://shark.sssup.it
 */


/*
 ------------
 CVS :        $Id: soccer.c,v 1.1.1.1 2002-09-02 09:37:44 pj Exp $

 File:        $File$
 Revision:    $Revision: 1.1.1.1 $
 Last update: $Date: 2002-09-02 09:37:44 $
 ------------
*/


/*
 * Copyright (C) 2000 Merli Andrea and Zucchetti Alessandro
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */



/*--------------------------------------------------------------*/
/*                                                                                  */
/*              S.Ha.R.K. SOCCER SIMULATOR 2001                 */
/*                                                                                  */
/*                                                                                  */
/*Autori: Merli Andrea                                                      */
/*        Zucchetti Alessandro                                      */
/*--------------------------------------------------------------*/

#include <kernel/kern.h>
#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <semaphore.h>
#include <stdlib.h>
#include <math.h>
#include <modules/cabs.h>
#include <ll/sys/types.h>
#include "images.h"
#include "position.h"
#include "iniziali.h"
#include "calc.h"
#include "calc2.h"
#include "stadio.h"

struct target{
int x;
int y;
};

void    draw_calc(int x, int y, int c,int f);    /*disegna i calciatori*/
void    draw_ball(int c);                        /*disegna la palla*/
void    draw_port(int c,int p,int yp,int xp);    /*disegna i portieri*/
void    init_calc();       /*carica i task calc*/
void    init_position(int num,int *ox,int *oy); /*inizializza la posizione dei calciatori*/
void    init_calc_area(int i,int *x_min,int *x_max,int *y_min,int *y_max); /*inizializza la zona di campo die calciatori*/
void    get_target(int modo,int i,struct target * obj,int x_max,int x_min,int y_max,int y_min);/*seleziona l'obietivo dei calciatori*/
void    collision_detection(int i);/*gestisce le collisioni tra i calciatori*/
int     get_direction(int x,int y,int x2, int y2);
void    init_portiere();   /*carica i task portiere*/
void    init_ball();       /*carica il task ball*/
void    act_goal();        /*carica il task gol*/
void    draw_goal();       /*gestisce il tabellone facendo apparire la scritta GOAL!!*/
void    disegna_campo();   /*disegna il campo di gioco*/
int     yportiere(int y1, int y2);
int     xportiere(int x1, int x2);
int     goal_behaviour(int f); /*gestisce gli eventi in occasione di un gol*/
int     rigore=0;
float   t;
double  tick = 1.0;             /* system tick = 1 ms            */
int     xb=300,yb=300,xob=300,yob=300;          /* coordinate globali della palla*/
struct  position pos_calc[MAX_P+2];
PID     pid_calc,pid_calc2,pid_ball,pid_port,pid_gol;
sem_t   mutex,mutex2;
CAB     cbi[4];


/*--------------------------------------------------------------*/
TASK    ball(void *arg)
{
float   dx=0, dy=0;//,df=0,dg=0;
float   acc =0.0;         /*accelerazione*/
float   x;                /*spostamento*/
int     g=10;           /*accelerazione di gravit…*/
float   cattr=0.05;     /*coeff di attrito tra palla e campo*/
int     col=1000;
int     ij=0;
int     r1=0,r2=0;      /*gol segnati*/
char    tetaa[15];
double  r;              /*angolo in radianti*/
int     flag =0;        /*variabile generatrice di eventi*/
int     outy,outx;      /*variabile per rilevare il rimbalzo della palla*/
float   vel1=0.0,vel2=0.0;          /*variabili di velocita*/
float   tau = 1.0;                  /*tempo base*/
char    *m;                         /*modo*/
char    *a;                         /*angolo*/
char    *s;                         /*speed*/
char    modo;
char    *o;                         /*azione*/
char    azione;
int     teta=0;
char    velocita;
char    mode;
    ij=0;
    m = cab_getmes(cbi[0]);
    mode = *m;
    cab_unget(cbi[0],m);
    if(mode==NO_BALL_MODE){
    xb = xob =(XMIN+XMAX)/2;
    yb = yob =(YMIN+YMAX)/2;
    }
    if(mode ==PENALTY_MODE_BLUE){

            xb=700;    
            yb=(YMIN+YMAX)/2;
    }
    if(mode == PENALTY_MODE_WHITE){
            xb=100;
            yb=(YMIN+YMAX)/2;
            }

    sprintf(tetaa,"BLUE FC %3d        AC WHITE %3d",(r1),(r2));
    grx_text(tetaa,XMIN+270 ,YMENU+60, rgb16(255,255,255), rgb16(0,0,0));
/***************************************************************************/
    while (1) {                                                 //WHILE(1);
        m = cab_getmes(cbi[0]);
        mode = *m;
        cab_unget(cbi[0],m);
        /*posiziono la palla sul dischetto del rigore*/
        if(mode ==PENALTY_MODE_BLUE){
            xb=700;    
            yb=(YMIN+YMAX)/2;
        }
        if(mode == PENALTY_MODE_WHITE){
            xb=100;
            yb=(YMIN+YMAX)/2;
        }
           /*se rigore=NO_PENALTY si calcolano le coordinate della palla
           in base alla velocit… e alla direzione del tiro*/

           if(rigore ==NO_PENALTY){
                a = cab_getmes(cbi[1]); /*direzione*/
                cab_unget(cbi[1],a);
                s = cab_getmes(cbi[2]); /*velocit…*/
                velocita = *s;
                cab_unget(cbi[2],s);
                acc = (float)cattr * g;
                r = (double)(36*(*a)/12) * PI / 180.;
                if(mode==PASS_MODE){
                vel1= velocita;
                }
                vel2 = vel1 - acc*tau;
                if(vel2>0){
                        x = vel1 *tau -0.5*acc*tau*tau;
                        dx = (float)(x * cos(r));
                        dy = (float)(x * sin(r));
                        xb += dx;
                        yb += dy;
                        ij++;
                        outx = (xb > XMAX-2) || (xb < XMIN+2);
                        outy = (yb > YMAX-6) || (yb < YMIN+6);

                        if (outx || outy) {
                           if ((yb>=(YMIN+YMAX)/2-50) &&(yb<=(YMIN+YMAX)/2+50)){
                              dx=0;
                              dy=0;
                           }
                                xb = xb - dx;
                                yb = yb - dy;
                                if (outx) teta = 60 - (*a);
                                if (outy) teta = 120-(*a);
                                if (teta > 120) teta -= 120;
                                if (teta < 0) teta += 120;
                                *a =(char)teta;
                                r = (double)(36*(*a)/12) * PI / 180.;
                                dx = (float)(x * cos(r));
                                dy = (float)(x * sin(r));
                           if ((yb>=(YMIN+YMAX)/2-50) &&(yb<=(YMIN+YMAX)/2+50)){
                              dx=0;
                              dy=0;
                           }
                                xb += dx;
                                yb += dy;
                }
                modo = NO_BALL_MODE;
                m = cab_reserve(cbi[0]);
                    *m = modo;
                    cab_putmes(cbi[0],m);

                vel1 = vel2;
                }
                if (yb< YMIN+5) yb = yb+10;
                if(xb< XMIN+5) xb = xb +10;
                /*se c'Š un gol*/
                if ((yb>=(YMIN+YMAX)/2-50) &&(yb<=(YMIN+YMAX)/2+50)&&((xb<=XMIN+7)||
                   (xb >=XMAX-7))){
                   /*aggiorno i risultati*/
                    if(xb<XMIN+50) r2++;
                    else r1++;
                    /*assegno alle variabili i valori di riposo*/
                    yb =(YMAX+YMIN)/2;
                    xb =(XMIN+XMAX)/2;
                    teta=0;
                    velocita=0;
                    flag =1;
                }
                /* in base al valore di flag modifico il tabellone*/
                flag = goal_behaviour(flag);
                /*scrivo il nuovo risultato nel tabellone*/
                if (flag == 80){
                   sprintf(tetaa,"BLUE FC %3d        AC WHITE %3d",(r1),(r2));
                   grx_text(tetaa,XMIN+270 ,YMENU+60, rgb16(255,255,255), rgb16(0,0,0));
                   flag =0;
                   o = cab_reserve(cbi[3]);
                   azione = NO_ACT;       /*nessuna azione*/
                         *o = azione;
                         cab_putmes(cbi[3],o);
                   modo = NO_BALL_MODE;
                   m = cab_reserve(cbi[0]);
                         *m = modo;
                         cab_putmes(cbi[0],m);
                }

          }//fine if(rigore==NO_PENALTY)
                draw_ball(0);
                draw_ball(col);
                    xob = xb; yob = yb;

                task_endcycle();
        }

}


/*--------------------------------------------------------------*/



/******************************************************************/

TASK    calc(void *arg){

struct target obj;
int     ox=200, oy=200;
int     alpha=0;
int     teta;
int     col=0;
char    speed;
char    *s;
char    modo;
char    *m;
char    angolo;
char    *a;
int     i = (int)arg;
int     x_min=0,y_min=0;
int     x_max=0,y_max=0;
/*Posiziono i calciatori nel punto iniziale*/
       
        init_position(i,&ox,&oy);

       
        /*Definisco l'area di gioco del calciatore basandomi sul suo PID*/
       
        init_calc_area(i,&x_min,&x_max,&y_min,&y_max);
         
while (1) {
        m = cab_getmes(cbi[0]);
        modo = *m;
        cab_unget(cbi[0],m);

        /*Individua l'obiettivo del calciatore a seconda del modo e del   */
        /*ruolo in PENALTY_MODE un calciatore va sul pallone gli altri    */
        /*ai lati del campo                                               */
        /*in NO_BALL_MODE l'obiettivo Š la palla se essa Š                */
        /*nell'area definita dalla funzione init_calc_area(..)            */
        /*altrimenti Š la posizione iniziale definita con init_position(.)*/


        get_target(modo,i,&obj,x_max,x_min,y_max,y_min);
   
        /*se raggiungo l'obbiettivo  mi fermo*/
                if(obj.x==pos_calc[i].x) pos_calc[i].dx=0;
                if(obj.y==pos_calc[i].y) pos_calc[i].dy=0;

                /*direzione tra il calciatore e l'obiettivo*/
               
                 alpha= get_direction(pos_calc[i].x,pos_calc[i].y,obj.x,obj.y);

                /*direzione di corsa iniziale*/
                               
                pos_calc[i].dy = -VEL*sin((alpha*PI)/180);
                pos_calc[i].dx =  VEL*cos((alpha*PI)/180);


                /*Per evitare che il calciatore corra prima dell'inizio della
                  partita gli impongo di non muoversi in posizione iniziale*/


                if((obj.x==300)&&(obj.y==300)) {
                        pos_calc[i].dx=0;
                        pos_calc[i].dy=0;
                }
                /*velocità di corsa*/
                   
                pos_calc[i].x+=pos_calc[i].dx;
                pos_calc[i].y+=pos_calc[i].dy;

                /*verifico se mi trovo in una situazione di collisione con      */
                /*un altro calciatore                                           */

            collision_detection(i);
               
               

                /*se il calciatore arriva sulla palla tira*/        
           if((modo==NO_BALL_MODE)||(i==7)||(i==2))
           if(((pos_calc[i].x>=xb-27)&&(pos_calc[i].x<=xb+27))&&((pos_calc[i].y>=yb-27)&&(pos_calc[i].y<=yb+27)))
           {
               
                        if((i==7)||(i==2)) rigore =NO_PENALTY;
                        modo = PASS_MODE;
                                m = cab_reserve(cbi[0]);
                                *m = modo;
                                cab_putmes(cbi[0],m);
                if(i<5){
                        a = cab_reserve(cbi[1]);
                        teta =(rand()%(90) + 135 );
                        if(teta >360) teta -= 360;
                        if (teta<0)   teta += 360;
                        angolo = (char)(teta/3);
                        *a = angolo;
                        cab_putmes(cbi[1],a);
                }
                if(i>4){
                           a = cab_reserve(cbi[1]);
                           teta =(rand()%(90) -45);
                           if(teta >360) teta -= 360;
                           if (teta<0)   teta += 360;
                           teta = (teta/3);
                           *a = teta;//angolo;
                           cab_putmes(cbi[1],a);
                        }
                s = cab_reserve(cbi[2]);
                speed=16;
                *s  =speed;
                cab_putmes(cbi[2],s);

           }
             
           
               
               draw_calc(ox, oy, CANC,0);

               /*Disegna l'omino voltato nella direzione della palla*/
            if(i<5){
               DIREZ(alpha,col,158,203, RLEFT,pos_calc[i].x,pos_calc[i].y);/*runleft*/
               DIREZ(alpha,col,249,292, RDOWN,pos_calc[i].x,pos_calc[i].y);/*rundown*/
               DIREZ(alpha,col, 68,113,   RUP,pos_calc[i].x,pos_calc[i].y);/*runup*/
               DIREZ(alpha,col,  0, 23,RRIGHT,pos_calc[i].x,pos_calc[i].y);/*runright*/
               DIREZ(alpha,col,337,360,RRIGHT,pos_calc[i].x,pos_calc[i].y);
               DIREZ(alpha,col, 23, 68,  RRUP,pos_calc[i].x,pos_calc[i].y);/*runrightup*/
               DIREZ(alpha,col,113,158,  RLUP,pos_calc[i].x,pos_calc[i].y);/*runleftup*/
               DIREZ(alpha,col,203,249,  RLDW,pos_calc[i].x,pos_calc[i].y);/*runleftdown*/
               DIREZ(alpha,col,292,337,  RRDW,pos_calc[i].x,pos_calc[i].y);/*runrightdown*/
            }

             if(i>4){

               DIREZ(alpha,col,158,203, RLEFT2,pos_calc[i].x,pos_calc[i].y);/*runleft*/
               DIREZ(alpha,col,249,292, RDOWN2,pos_calc[i].x,pos_calc[i].y);/*rundown*/
               DIREZ(alpha,col, 68,113,   RUP2,pos_calc[i].x,pos_calc[i].y);/*runup*/
               DIREZ(alpha,col,  0, 23,RRIGHT2,pos_calc[i].x,pos_calc[i].y);/*runright*/
               DIREZ(alpha,col,337,360,RRIGHT2,pos_calc[i].x,pos_calc[i].y);
               DIREZ(alpha,col, 23, 68,  RRUP2,pos_calc[i].x,pos_calc[i].y);/*runrightup*/
               DIREZ(alpha,col,113,158,  RLUP2,pos_calc[i].x,pos_calc[i].y);/*runleftup*/
               DIREZ(alpha,col,203,249,  RLDW2,pos_calc[i].x,pos_calc[i].y);/*runleftdown*/
               DIREZ(alpha,col,292,337,  RRDW2,pos_calc[i].x,pos_calc[i].y);/*runrightdown*/
            }

           
                ox =pos_calc[i].x; oy = pos_calc[i].y;

                task_endcycle();
        }
}
/****************************************************************/
TASK gol(void *arg)
{
        while(1){
        draw_goal();
        task_endcycle();
        }
}
/****************************************************************/
TASK  portiere(void *arg)
{
int     yp,yp1,yp0,ypo_0=(YMAX+YMIN)/2,ypo_1=(YMAX+YMIN)/2;
int     xp0,xp1,xpo_0,xpo_1,xo0,xo1;
int     np= (int)arg;
char    speed;
char    *s;
char    modo;
char    *m;
char    angolo;
char     *a;

        yp = (YMIN+YMAX)/2;       /* y di attesa*/
        yp0 = (YMIN+YMAX)/2;
        yp1 = (YMIN+YMAX)/2;
        xp0 = xpo_0 = XMIN+3;     /* xp ascissa attuale portiere, xpo ascissa vecchia posizione portiere*/
        xp1 = xpo_1 = XMAX-30;
        xo0 = XMIN+3;             /* x di attesa*/
        xo1 = XMAX-30;            /* x di attesa*/
        draw_port(1,np,yp,xo0);
        draw_port(1,np,yp,xo1);

        while(1){
          m = cab_getmes(cbi[0]);
          modo = *m;
          cab_unget(cbi[0],m);
        /*in base alla posizione della palla si calcola la posizione del portiere*/
        if ((np==0)  && (xb < (XMIN+XMAX)/2) &&(xb > XMIN+150)){
           yp0 = yportiere(yb,yp0);
           xp0 = xportiere(xo0,xp0);
        }
        if ((np==0) &&(xb <= XMIN+150)){
           yp0 = yportiere(yb,yp0);
           xp0= xportiere(xb,xp0);
        }
        if ((np==0)  && (xb > (XMIN+XMAX)/2)){
           yp0 = yportiere(yp,yp0);
           xp0 = xportiere(xo0,xp0);
        }
        /*il portiere non esce oltre questi limiti*/
        if ((yp0< (YMIN+YMAX)/2-100)|| (yp0>(YMIN+YMAX)/2+100))
           yp0 = ypo_0;
        if(xp0> XMIN+150)
           xp0 =xpo_0;

        pos_calc[10].x = xp0;
        pos_calc[10].y = yp0;

        /*in base alla posizione della palla si calcola la posizione del portiere*/
        if ((np==1)  && (xb > (XMIN+XMAX)/2) && (xb< XMAX-150)){
           yp1 = yportiere(yb,yp1);
           xp1 = xportiere(xo1,xp1);
        }
        if ((np==1) && (xb >= XMAX-150)){
           yp1 = yportiere(yb,yp1);
           xp1 = xportiere(xb,xp1);
        }
        if ((np==1)  && (xb < (XMIN+XMAX)/2)){
           yp1 = yportiere(yp,yp1);
           xp1 = xportiere(xo1,xp1);
        }
        /*il portiere non esce oltre questi limiti*/
        if ((yp1< (YMIN+YMAX)/2-100)|| (yp1>(YMIN+YMAX)/2+100))
           yp1 =ypo_1;
        if(xp1 < XMAX-150)
           xp1 =xpo_1;

        pos_calc[11].x = xp1;
        pos_calc[11].y = yp1;

        /*in caso di rigore il portiere aspetta il tiro sulla linea della porta*/
        if (rigore ==PENALTY) xp0= XMIN+3;

        if ((np==0)){
                draw_port(0,np,ypo_0,xpo_0);
                draw_port(1,np,yp0,xp0);
                ypo_0 = yp0;
                xpo_0 =xp0;
          }

          /*in caso di rigore il portiere aspetta il tiro sulla linea della porta*/
          if(rigore ==PENALTY) xp1= XMAX-30;

          if((np==1)){
                draw_port(0,np,ypo_1,xpo_1);
                draw_port(1,np,yp1,xp1);
                ypo_1 = yp1;
                xpo_1 = xp1;
          }

        /*se para rinvia immediatamente*/
        if( (yp0 >=yb-5) && (yp0<yb+20) && ((xb<=xp0+20)&&(xb>=xp0-30))){
               m = cab_reserve(cbi[0]);
                   modo = PASS_MODE;
                   *m = modo;
                   cab_putmes(cbi[0],m);
               a = cab_reserve(cbi[1]);
                   angolo =0;
                   *a = angolo;
                   cab_putmes(cbi[1],a);
               s = cab_reserve(cbi[2]);
                   speed=20;
                   *s  =speed;
                   cab_putmes(cbi[2],s);
        }
        /*se para rinvia immediatamente*/
        if((yp1 >=yb-5) && (yp1<yb+20) && (xb<=xp1+20)&&(xb>= xp1-30) ){
               m = cab_reserve(cbi[0]);
                   modo = PASS_MODE;
                   *m = modo;
                   cab_putmes(cbi[0],m);
               a = cab_reserve(cbi[1]);
                   angolo =60;
                   *a = angolo;
                   cab_putmes(cbi[1],a);
               s = cab_reserve(cbi[2]);
                   speed=20;
                   *s  =speed;
                   cab_putmes(cbi[2],s);
        }
        task_endcycle();
        }
}

/****************************************************************/
/* This function is called when the system exits */
void byebye(void *arg)
{
  grx_close();
  kern_printf("Bye Bye!\n");
}

/****************************** MAIN ******************************/

int main(int argc, char **argv)
{

 
    char c;             /* character from keyboard      */
    int  z=0;
    int  p=0;
    int  ij=0;
    char modo;
    char *m;
    char  *s;
    char  speed;
    char  *a;
    char  angolo;
    char  *o;
    char  azione;


    TIME seme;          /* used to init the random seed */

    /* Set the exception handler */
    set_exchandler_grx();

    /* Set the closing function */
    sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);

    /* graphic card Initialization */
    if (grx_init() < 1) {
       sys_abort(1);
    }
   
    if (grx_open(ORI_RES,VER_RES,COL_DEP) < 0) {
        kern_printf("GRX Err\n");
        sys_abort(1);
    }
    kern_printf("Video card ok!\n");
    cbi[1] = cab_create("direzione",10,15);
    cbi[0] = cab_create("modo",4,15);
    cbi[2] = cab_create("velocita",10,15);
    cbi[3] = cab_create("azione",3,3);
          m = cab_reserve(cbi[0]);
                      modo = NO_BALL_MODE;
                           *m = modo;
                           cab_putmes(cbi[0],m);
          a = cab_reserve(cbi[1]);
                           angolo =0;
                           *a = angolo;
                           cab_putmes(cbi[1],a);
          s = cab_reserve(cbi[2]);
                           speed=0;
                           *s  =speed;
                           cab_putmes(cbi[2],s);
          o = cab_reserve(cbi[3]);
                           azione = NO_ACT;
                           *o = azione;
                           cab_putmes(cbi[3],o);

    /* The scenario */

    grx_box(0,0,ORI_RES,VER_RES,0);
    disegna_campo();
    for(p=0;p<scale_width;p++)
        for(z=0;z<scale_height;z++){
           grx_plot(100+p,0+z,rgb16(stadio_cmap[(unsigned char)scale_data[z*150+p]][0],stadio_cmap[(unsigned char)scale_data[z*150+p]][1],stadio_cmap[(unsigned char)scale_data[z*150+p]][2]));
           grx_plot(550+p,0+z,rgb16(stadio_cmap[(unsigned char)scale_data[z*150+p]][0],stadio_cmap[(unsigned char)scale_data[z*150+p]][1],stadio_cmap[(unsigned char)scale_data[z*150+p]][2]));
           }
    for(p=0;p<faro_width;p++)
        for(z=0;z<faro_height;z++){
           grx_plot(0+p,0+z,rgb16(stadio_cmap[(unsigned char)faros_data[z*100+p]][0],stadio_cmap[(unsigned char)faros_data[z*100+p]][1],stadio_cmap[(unsigned char)faros_data[z*100+p]][2]));
           grx_plot(700+p,0+z,rgb16(stadio_cmap[(unsigned char)farod_data[z*100+p]][0],stadio_cmap[(unsigned char)farod_data[z*100+p]][1],stadio_cmap[(unsigned char)farod_data[z*100+p]][2]));
           }
      for(p=0;p<schermo_width;p++)
        for(z=0;z<schermo_height;z++){
           grx_plot(250+p,0+z,rgb16(stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][0],stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][1],stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][2]));
           }
      grx_text(" Simulation of Soccer", XMIN+260, YMENU+10, rgb16(255,255,255), rgb16(0,0,0));
      grx_text(" W rigore bianchi, E rigore blue", XMIN+260, YMENU+20, rgb16(255,255,255), rgb16(0,0,0));
      grx_text(" SPACE crea squadre, K kill all  ", XMIN+260, YMENU+30, rgb16(255,255,255), rgb16(0,0,0));
      grx_text(" ESC   Return to MS-DOS   ", XMIN+260, YMENU+40, 12, rgb16(255,255,255));
    /* The program waits a space to create a calc */
    c = keyb_getch(BLOCK);

   /* randomize!!!!*/
    seme = sys_gettime(NULL);
    srand(seme);

    do {
       if ((c == ' ') &&(ij==0)) {
          init_ball();
          init_calc();
          init_portiere();
          ij++;
       }
       if ((c== 'w')){m = cab_reserve(cbi[0]);
                      modo = PENALTY_MODE_WHITE;
                           *m = modo;
                           cab_putmes(cbi[0],m);
                      rigore =PENALTY; }
       if ((c== 'e')){m = cab_reserve(cbi[0]);
                      modo = PENALTY_MODE_BLUE;
                           *m = modo;
                           cab_putmes(cbi[0],m);
                      rigore =PENALTY; }
       if ((c == 'k')) {
          group_kill(GROUP_PLAY);
          group_kill(GROUP_SOFT);
          group_kill(GROUP_BALL);
          ij=0;
            m = cab_reserve(cbi[0]);
                     modo = NO_BALL_MODE;
                           *m = modo;
                           cab_putmes(cbi[0],m);
          disegna_campo();
          for(p=0;p<scale_width;p++)
          for(z=0;z<scale_height;z++){
           grx_plot(100+p,0+z,rgb16(stadio_cmap[(unsigned char)scale_data[z*150+p]][0],stadio_cmap[(unsigned char)scale_data[z*150+p]][1],stadio_cmap[(unsigned char)scale_data[z*150+p]][2]));
           grx_plot(550+p,0+z,rgb16(stadio_cmap[(unsigned char)scale_data[z*150+p]][0],stadio_cmap[(unsigned char)scale_data[z*150+p]][1],stadio_cmap[(unsigned char)scale_data[z*150+p]][2]));
           }
          for(p=0;p<faro_width;p++)
           for(z=0;z<faro_height;z++){
           grx_plot(0+p,0+z,rgb16(stadio_cmap[(unsigned char)faros_data[z*100+p]][0],stadio_cmap[(unsigned char)faros_data[z*100+p]][1],stadio_cmap[(unsigned char)faros_data[z*100+p]][2]));
           grx_plot(700+p,0+z,rgb16(stadio_cmap[(unsigned char)farod_data[z*100+p]][0],stadio_cmap[(unsigned char)farod_data[z*100+p]][1],stadio_cmap[(unsigned char)farod_data[z*100+p]][2]));
           }
           grx_text(" Simulation of Soccer", XMIN+260, YMENU+10, rgb16(255,255,255), rgb16(0,0,0));
           grx_text(" W rigore bianchi, E rigore blue", XMIN+260, YMENU+20, rgb16(255,255,255), rgb16(0,0,0));
           grx_text(" SPACE crea squadre, K kill all  ", XMIN+260, YMENU+30, rgb16(255,255,255), rgb16(0,0,0));
           grx_text(" ESC   Return to MS-DOS   ", XMIN+260, YMENU+40, 12, rgb16(255,255,255));
           xb=(int)(XMAX-XMIN)/2;
           yb=(int)(YMIN+YMAX)/2;
           }
      c = keyb_getch(BLOCK);
    } while (c != ESC);



    sys_end();

    return 0;
}

/*--------------------------------------------------------------*/
void    draw_calc(int x, int y, int c,int f)
{
        int i,j;/*needed in the macro*/
        sem_wait(&mutex);
        if(c==CANC){

            grx_box(x, y,x+27,y+27,SFONDO);
            if((x>(XMIN+XMAX)/2-27) && (x<(XMIN+XMAX)/2+27)){
                grx_line(XMIN+1,YMIN+1,XMAX-1,YMIN+1,rgb16(255,255,255));
                grx_line(XMIN+1,YMAX-1,XMAX-1,YMAX-1,rgb16(255,255,255));
                grx_line(XMIN+1,YMIN+1,XMIN+1,(YMIN+YMAX)/2-50,rgb16(255,255,255));
                grx_line(XMIN+1,(YMIN+YMAX)/2+50,XMIN+1,YMAX-1,rgb16(255,255,255));
                grx_line(XMAX-1,YMIN+1,XMAX-1,(YMIN+YMAX)/2-50,rgb16(255,255,255));
                grx_line(XMAX-1,(YMIN+YMAX)/2+50,XMAX-1,YMAX-1,rgb16(255,255,255));
                grx_line(((XMIN+XMAX)/2),YMIN,((XMIN+XMAX)/2),YMAX-1,rgb16(255,255,255));
                grx_circle((XMIN+XMAX)/2,(YMIN+YMAX)/2,54,rgb16(255,255,255));
                grx_line(XMIN,(YMIN+YMAX)/4+30,(XMIN+XMAX)/5,(YMIN+YMAX)/4+30,rgb16(255,255,255));
                grx_line((XMIN+XMAX)/5,(YMIN+YMAX)/4+30,(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                grx_line(XMIN,3*(YMIN+YMAX)/4-30,(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                grx_line(XMIN,(YMIN+YMAX)/2-70,(XMIN+XMAX)/10,(YMIN+YMAX)/2-70,rgb16(255,255,255));
                grx_line((XMIN+XMAX)/10,(YMIN+YMAX)/2-70,(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                grx_line(XMIN,(YMIN+YMAX)/2+70,(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                grx_line(4*(XMIN+XMAX)/5,(YMIN+YMAX)/4+30,XMAX,(YMIN+YMAX)/4+30,rgb16(255,255,255));
                grx_line(4*(XMIN+XMAX)/5,(YMIN+YMAX)/4+30,4*(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                grx_line(4*(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,XMAX,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                grx_line(9*(XMIN+XMAX)/10,(YMIN+YMAX)/2-70,XMAX,(YMIN+YMAX)/2-70,rgb16(255,255,255));
                grx_line(9*(XMIN+XMAX)/10,(YMIN+YMAX)/2-70,9*(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                grx_line(9*(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,XMAX,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                grx_line(XMIN+1,(YMIN+YMAX)/2-50,XMIN+1,(YMIN+YMAX)/2+50,rgb16(100,100,100));
                grx_line(XMAX-1,(YMIN+YMAX)/2-50,XMAX-1,(YMIN+YMAX)/2+50,rgb16(100,100,100));
                grx_box(XMIN,(YMIN+YMAX)/2-50,XMIN+2,(YMIN+YMAX)/2+50,rgb16(50,0,50));
                grx_box(XMAX-2,(YMIN+YMAX)/2-50,XMAX,(YMIN+YMAX)/2+50,rgb16(50,0,50));
            }
        }
        else
            if(c==RLEFT)
                DIRDRAW(x,y,((unsigned char)runup_data[i*27+j]));
            if(c==RLEFT+1)
                DIRDRAW(x,y,((unsigned char)runup2_data[i*27+j]));
            if(c==RDOWN)
                DIRDRAW(x,y,((unsigned char)rundes2_data[i*27+j]));
            if(c==RDOWN+1)
                  DIRDRAW(x,y,((unsigned char)rundes_data[i*27+j]));
            if(c==RUP)
                  DIRDRAW(x,y,((unsigned char)runleft2_data[i*27+j]));
            if(c==RUP+1)
                  DIRDRAW(x,y,((unsigned char)runleft_data[i*27+j]));
            if(c==RRIGHT)
                  DIRDRAW(x,y,((unsigned char)rundown2_data[i*27+j]));
            if(c==RRIGHT+1)
                  DIRDRAW(x,y,((unsigned char)rundown_data[i*27+j]));
            if(c==RRUP)
                  DIRDRAW(x,y,((unsigned char)runld2_data[i*27+j]));
            if(c==RRUP+1)
                  DIRDRAW(x,y,((unsigned char)runld_data[i*27+j]));
            if(c==RLUP)
                  DIRDRAW(x,y,((unsigned char)runlu2_data[i*27+j]));
            if(c==RLUP+1)
                  DIRDRAW(x,y,((unsigned char)runlu_data[i*27+j]));
            if(c==RLDW)
                  DIRDRAW(x,y,((unsigned char)runru2_data[i*27+j]));
            if(c==RLDW+1)
                  DIRDRAW(x,y,((unsigned char)runru_data[i*27+j]));
            if(c==RRDW)
                  DIRDRAW(x,y,((unsigned char)runrd2_data[i*27+j]));
            if(c==RRDW+1)
                  DIRDRAW(x,y,((unsigned char)runrd_data[i*27+j]));
/**********************************************************************/
            if(c==RLEFT2)
                DIRDRAW(x,y,((unsigned char)B_runup_data[i*27+j]));
            if(c==RLEFT2+1)
                DIRDRAW(x,y,((unsigned char)B_runup2_data[i*27+j]));
            if(c==RDOWN2)
                DIRDRAW(x,y,((unsigned char)B_rundes2_data[i*27+j]));
            if(c==RDOWN2+1)
                  DIRDRAW(x,y,((unsigned char)B_rundes_data[i*27+j]));
            if(c==RUP2)
                  DIRDRAW(x,y,((unsigned char)B_runleft2_data[i*27+j]));
            if(c==RUP2+1)
                  DIRDRAW(x,y,((unsigned char)B_runleft_data[i*27+j]));
            if(c==RRIGHT2)
                  DIRDRAW(x,y,((unsigned char)B_rundown2_data[i*27+j]));
            if(c==RRIGHT2+1)
                  DIRDRAW(x,y,((unsigned char)B_rundown_data[i*27+j]));
            if(c==RRUP2)
                  DIRDRAW(x,y,((unsigned char)B_runld2_data[i*27+j]));
            if(c==RRUP2+1)
                  DIRDRAW(x,y,((unsigned char)B_runld_data[i*27+j]));
            if(c==RLUP2)
                  DIRDRAW(x,y,((unsigned char)B_runlu2_data[i*27+j]));
            if(c==RLUP2+1)
                  DIRDRAW(x,y,((unsigned char)B_runlu_data[i*27+j]));
            if(c==RLDW2)
                  DIRDRAW(x,y,((unsigned char)B_runru2_data[i*27+j]));
            if(c==RLDW2+1)
                  DIRDRAW(x,y,((unsigned char)B_runru_data[i*27+j]));
            if(c==RRDW2)
                  DIRDRAW(x,y,((unsigned char)B_runrd2_data[i*27+j]));
            if(c==RRDW2+1)
                  DIRDRAW(x,y,((unsigned char)B_runrd_data[i*27+j]));
        sem_post(&mutex);
}
/*--------------------------------------------------------------*/
void    draw_ball(int c)
{
        sem_wait(&mutex);
        if(c==0)
        grx_box(xob, yob,xob+5,yob+5,SFONDO);
        else grx_putimage(xb, yb,xb+5,yb+5,pallone);
        sem_post(&mutex);
}
void    draw_port(int c,int p,int yp,int xp)
{
        int i,j;
        sem_wait(&mutex);
        if (c==0){
                if(p==0){
                        /*ridisegna l'area*/
                        grx_box(xp,yp-15,xp+30,yp+25,SFONDO);
                        grx_line(XMIN,(YMIN+YMAX)/4+30,(XMIN+XMAX)/5,(YMIN+YMAX)/4+30,rgb16(255,255,255));
                        grx_line((XMIN+XMAX)/5,(YMIN+YMAX)/4+30,(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                        grx_line(XMIN,3*(YMIN+YMAX)/4-30,(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                        grx_line(XMIN,(YMIN+YMAX)/2-70,(XMIN+XMAX)/10,(YMIN+YMAX)/2-70,rgb16(255,255,255));
                        grx_line((XMIN+XMAX)/10,(YMIN+YMAX)/2-70,(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                        grx_line(XMIN,(YMIN+YMAX)/2+70,(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                        grx_box(XMIN,(YMIN+YMAX)/2-50,XMIN+2,(YMIN+YMAX)/2+50,rgb16(50,0,50));
                        }
                if(p==1){
                        /*ridisegna l'area*/
                        grx_box(xp,yp-15,xp+27,yp+25,SFONDO);
                        grx_line(4*(XMIN+XMAX)/5,(YMIN+YMAX)/4+30,XMAX,(YMIN+YMAX)/4+30,rgb16(255,255,255));
                        grx_line(4*(XMIN+XMAX)/5,(YMIN+YMAX)/4+30,4*(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                        grx_line(4*(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,XMAX,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
                        grx_line(9*(XMIN+XMAX)/10,(YMIN+YMAX)/2-70,XMAX,(YMIN+YMAX)/2-70,rgb16(255,255,255));
                        grx_line(9*(XMIN+XMAX)/10,(YMIN+YMAX)/2-70,9*(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                        grx_line(9*(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,XMAX,(YMIN+YMAX)/2+70,rgb16(255,255,255));
                        grx_box(XMAX-2,(YMIN+YMAX)/2-50,XMAX,(YMIN+YMAX)/2+50,rgb16(50,0,50));
                        }
        }
        else{
                if(p==0)
                        DIRDRAW(xp,yp,((unsigned char)portsx_data[i*27+j]));
                if(p==1)
                        DIRDRAW(xp,yp,((unsigned char)portdx_data[i*27+j]));
        }
        sem_post(&mutex);
}
void init_ball(){
     HARD_TASK_MODEL m_ball;
     hard_task_default_model(m_ball);
          hard_task_def_ctrl_jet (m_ball);
          hard_task_def_arg      (m_ball, (void *)0);
          hard_task_def_wcet     (m_ball, BALL_WCET);
          hard_task_def_mit      (m_ball, PERIOD_BALL);
          hard_task_def_group    (m_ball, GROUP_BALL);
          hard_task_def_usemath  (m_ball);
          pid_ball = task_create("ball", ball, &m_ball, NULL);
          if (pid_ball == NIL) {
             grx_close();
             perror("Could not create task <ball>");
             sys_abort(1);
             }

          task_activate(pid_ball);
}
void init_calc(){
     HARD_TASK_MODEL m_calc;
     int i;
     disegna_campo();
     for(i=0;i<MAX_P;i++){
            hard_task_default_model(m_calc);
            hard_task_def_ctrl_jet (m_calc);
            hard_task_def_arg      (m_calc, (void *)i);
            hard_task_def_wcet     (m_calc, CALC_WCET);
            hard_task_def_mit      (m_calc, PERIOD_CALC);
            hard_task_def_group    (m_calc, GROUP_PLAY);
            hard_task_def_usemath  (m_calc);
            pid_calc = task_create("calc", calc, &m_calc, NULL);
            if (pid_calc == NIL) {
              grx_close();
              perror("Could not create task <calc>");
              sys_abort(1);
            }
            task_activate(pid_calc);
           }
       }
void act_goal(){

 
     SOFT_TASK_MODEL m_goal;
     soft_task_default_model(m_goal);
     soft_task_def_arg      (m_goal,(void*)0);
     soft_task_def_met      (m_goal, 1000);
     soft_task_def_level    (m_goal,1);
     soft_task_def_ctrl_jet (m_goal);
     soft_task_def_period   (m_goal, 1200000);
     soft_task_def_group    (m_goal, GROUP_SOFT);
     soft_task_def_usemath  (m_goal);
     soft_task_def_aperiodic(m_goal);
     
     pid_gol = task_create("gol", gol, &m_goal, NULL);
            if (pid_gol == NIL) {
              grx_close();
              perror("Could not create task <port>");
              sys_abort(1);
            }
            task_activate(pid_gol);
           }
void init_portiere(){
     HARD_TASK_MODEL m_port;
     int g;
     for(g=0;g<2;g++){
            hard_task_default_model(m_port);
            hard_task_def_arg      (m_port, (void *)g);
            hard_task_def_wcet     (m_port, PORT_WCET);
            hard_task_def_mit      (m_port, PERIOD_PORT);
            hard_task_def_group    (m_port, GROUP_SOFT);
            hard_task_def_usemath  (m_port);
            pid_port = task_create("portiere", portiere, &m_port, NULL);
            if (pid_port == NIL) {
              grx_close();
              perror("Could not create task <port>");
              sys_abort(1);
            }
            task_activate(pid_port);
           }
           
        }
void draw_goal(){
     int  p,z;
     char *m;
     char modo;
     char  *o;
     char azione;
        m = cab_reserve(cbi[0]);
                      modo = NO_BALL_MODE;
                      *m = modo;
                      cab_putmes(cbi[0],m);
        o = cab_getmes(cbi[3]);
                      azione = *o;
                      cab_unget(cbi[3],o);

      /*scritta GOAL!!*/
      if(azione == GOAL_ACT){
      for(p=0;p<schermo_width;p++)
           for(z=0;z<schermo_height;z++){
           grx_plot(250+p,0+z,rgb16(stadio_cmap[(unsigned char)goal1_data[z*schermo_width+p]][0],stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][1],stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][2]));
           }
      o = cab_reserve(cbi[3]);
                           azione = 0;
                           *o = azione;
                           cab_putmes(cbi[3],o);
      }

      /*risistema il menu sul tabellone*/
      if (azione == MENU_ACT){
      for(p=0;p<schermo_width;p++)
           for(z=0;z<schermo_height;z++){
           grx_plot(250+p,0+z,rgb16(stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][0],stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][1],stadio_cmap[(unsigned char)schermo_data[z*schermo_width+p]][2]));
           }
           o = cab_reserve(cbi[3]);
                           azione = NO_ACT;
                           *o = azione;
                           cab_putmes(cbi[3],o);
           grx_text(" Simulation of Soccer", XMIN+260, YMENU+10, rgb16(255,255,255), rgb16(0,0,0));
           grx_text(" W rigore bianchi, E rigore blue", XMIN+260, YMENU+20, rgb16(255,255,255), rgb16(0,0,0));
           grx_text(" SPACE crea squadre, K kill all  ", XMIN+260, YMENU+30, rgb16(255,255,255), rgb16(0,0,0));
           grx_text(" ESC   Return to MS-DOS   ", XMIN+260, YMENU+40, 12, rgb16(255,255,255));
           }
}

/*calcola la y del portiere in base alla yi in ingresso*/
int yportiere(int yi,int yf){
    int speedy =3;
    int dy=0;
    int yp;
        /*Se sto per raggiungere la palla rallento*/
        if(abs(yi-yf)<VEL) speedy=1;
        /*se raggiungo la palla mi fermo*/
        if(yi==yf)dy=0;
        /*se palla in basso*/
        if(yi>yf) dy= speedy;
        /*se palla in alto*/
        if(yi<yf) dy=-speedy;
        yp =yf+dy;
        return(yp);
}
/*calcola la x del portiere in base alla xi in ingresso*/
int xportiere(int xi, int xf){
    int speedx=3;
    int dx=0;
    int xp;
    if(abs(xi-xf)<VEL) speedx=1;
        if(xi==xf)dx=0;
        if(xi>xf) dx= speedx;
        if(xi<xf) dx=-speedx;
        xp = xf +dx;
        return(xp);
}
/*disegna il campo di gioco*/
void disegna_campo(){
    //grx_box(0,0,ORI_RES,VER_RES,0);
    grx_box(XMIN, YMIN, XMAX, YMAX, SFONDO);
    grx_rect(XMIN+1, YMIN+1, XMAX-1, YMAX-1, rgb16(255,255,255));
    grx_line(((XMIN+XMAX)/2),YMIN,((XMIN+XMAX)/2),YMAX-1,rgb16(255,255,255));
    grx_circle((XMIN+XMAX)/2,(YMIN+YMAX)/2,54,rgb16(255,255,255));
    grx_rect(XMIN,(YMIN+YMAX)/4+30,(XMIN+XMAX)/5,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
    grx_rect(4*(XMIN+XMAX)/5,(YMIN+YMAX)/4+30,XMAX,3*(YMIN+YMAX)/4-30,rgb16(255,255,255));
    grx_rect(XMIN,(YMIN+YMAX)/2-70,(XMIN+XMAX)/10,(YMIN+YMAX)/2+70,rgb16(255,255,255));
    grx_rect(9*(XMIN+XMAX)/10,(YMIN+YMAX)/2-70,XMAX,(YMIN+YMAX)/2+70,rgb16(255,255,255));
    grx_box(XMIN,(YMIN+YMAX)/2-50,XMIN+2,(YMIN+YMAX)/2+50,rgb16(50,0,50));
    grx_box(XMAX-2,(YMIN+YMAX)/2-50,XMAX,(YMIN+YMAX)/2+50,rgb16(50,0,50));
}
void init_position(int num,int *ox,int *oy)
{
        if(num<5){
                        pos_calc[num].x = *ox = initial_calc_position[num].x+35;
                        pos_calc[num].y = *oy = initial_calc_position[num].y;
        }
        if(num==2){
                pos_calc[num].x =  *ox = initial_calc_position[num].x+100;
                        pos_calc[num].y =  *oy = initial_calc_position[num].y;
        }
         if(num>4){
                        pos_calc[num].x =  *ox = initial_calc_position[num-5].x;
                        pos_calc[num].y =  *oy = initial_calc_position[num-5].y+35;
        }
        if(num==7){
                pos_calc[num].x =  *ox = initial_calc_position[num-5].x-100;
                        pos_calc[num].y =  *oy = initial_calc_position[num-5].y;
        }

}
void init_calc_area(int num,int *xmin,int *xmax,int *ymin,int *ymax){
       
       
        switch(num)
        {
                case 0: /*attaccante bianchi*/
                case 5: /*difensore  blu*/
                {
                *xmin = XMIN;  
                *ymin = YMIN;  
                *xmax = 255;
                *ymax = 305;
        }      
                        break;
                case 1: /*attaccante bianchi*/
                case 6: /*difensore blu*/
                {
                *xmin = XMIN;  
                *ymin = 295;   
                *xmax = 255;
                *ymax = YMAX;
        }
                        break;
        case 2: /*centrocampisti*/
        case 7:
        {      
                *xmin = 255;
                *ymin = YMIN;
                *xmax = 525;
                *ymax = YMAX;
        }               break;
        case 3: /*attaccante blu*/
        case 8: /*difensore bianco*/
        {
                *xmin = 525;   
                *ymin = YMIN;  
                *xmax = XMAX;
                *ymax = 305;
        }
                break;
        case 4: /*attaccante blu*/
        case 9: /*difensore bianco*/
        {
                *xmin = 505;   
                *ymin = 305;   
                *xmax = XMAX;
                *ymax = YMAX;
        }    
        break;
        default:
                break;
        }
}
void    get_target(int modo,int i,struct target * obj,int x_max,int x_min,int y_max,int y_min){



            if((modo==PENALTY_MODE_WHITE)||(modo==PENALTY_MODE_BLUE)){



                if((i<5)){
                    obj->x = (XMAX)-100-50*i;
                    if(pos_calc[i].y>(YMAX+YMIN)/2)
                        obj->y = YMAX-60;
                    if(pos_calc[i].y<(YMAX+YMIN)/2)
                        obj->y = YMIN+60;
                    if(modo==PENALTY_MODE_WHITE){
                        if((i==2)){
                            obj->x = xb;
                            obj->y = yb;
                        }
                    }
                }
                if((i>4)){
                    obj->x = (XMIN)+100+50*i;
                    if(pos_calc[i].y>(YMAX+YMIN)/2)
                        obj->y = YMAX-60;
                    if(pos_calc[i].y<(YMAX+YMIN)/2)
                        obj->y = YMIN+60;
                    if(modo==PENALTY_MODE_BLUE){
                        if((i==7)){
                            obj->x = xb;
                            obj->y = yb;
                        }
                    }

                }
        }        

          if(modo==NO_BALL_MODE)
          {

                /*Valutazione se la palla sia in una zona di interesse per il   */
                /*calciatore                                                    */

                if((xb>x_max)||(xb<x_min)||(yb>y_max)||(yb<y_min))
                {
                        if(i<5)
                        {
                                obj->x=initial_calc_position[i].x;
                                obj->y=initial_calc_position[i].y;
                        }
                        if(i>4)
                        {
                                obj->x=initial_calc_position[i-5].x;
                                obj->y=initial_calc_position[i-5].y;
                        }
                }
                else
                {
                        obj->x=xb;
                        obj->y=yb;
                }
          }




}
int     get_direction(int x,int y,int x2,int y2){

int ang=0;
           if((abs(x-x2) !=0)){
        if((x>x2)&&(y<=y2))
           ang = 180+
                 atan((float)abs(y-y2)/
                        (float)abs(x-x2))*
                   180/PI;
        if((x<x2)&&(y<y2))
           ang = 360-
                 atan((float)abs(y-y2)/
                      (float)abs(x-x2))*
                   180/PI;
        if((x<x2)&&(y>y2))
           ang =
                 atan((float)abs(y-y2)/
                      (float)abs(x-x2))*
                   180/PI;
        if((x>x2)&&(y>y2))
           ang = 180-
                 atan((float)abs(y-y2)/
                 (float)abs(x-x2))*
                   180/PI;
      }

return ang;

}

void collision_detection(int i){

int j;


for(j=0;j<MAX_P+2;j++){

                if(i!=j){
                              if(pos_calc[i].x<pos_calc[j].x+27 && pos_calc[i].x>pos_calc[j].x-27
                        && pos_calc[i].y<pos_calc[j].y && pos_calc[i].y>pos_calc[j].y-27)
                        {
                                        pos_calc[i].y=pos_calc[j].y-27;
                                }
                                if(pos_calc[i].x<pos_calc[j].x && pos_calc[i].x>pos_calc[j].x-27
                                && pos_calc[i].y<pos_calc[j].y+27 && pos_calc[i].y>pos_calc[j].y-27)
                                {
                                        pos_calc[i].x=pos_calc[j].x-27;
                                }
                                if(pos_calc[i].x<pos_calc[j].x+27 && pos_calc[i].x>pos_calc[j].x-27
                                && pos_calc[i].y<pos_calc[j].y+27 && pos_calc[i].y>pos_calc[j].y)
                                {
                                        pos_calc[i].y=pos_calc[j].y+27;
                                }
                                if(pos_calc[i].x<pos_calc[j].x+27 && pos_calc[i].x>pos_calc[j].x
                                && pos_calc[i].y<pos_calc[j].y+27 && pos_calc[i].y>pos_calc[j].y)
                                {
                                        pos_calc[i].x=pos_calc[j].x+27;
                                }
                        }
                }
               
                /*Per impedire un calciatore esca dal campo*/
               
                if(pos_calc[i].x>=XMAX-(pos_calc[i].dx+1))  pos_calc[i].x-=(pos_calc[i].dx+1);
                if(pos_calc[i].x<=XMIN+(pos_calc[i].dx+1))  pos_calc[i].x+=(pos_calc[i].dx+1);
                if(pos_calc[i].y>=YMAX-(pos_calc[i].dy+1))  pos_calc[i].y-=(pos_calc[i].dy+1);
                if(pos_calc[i].y<=YMIN+(pos_calc[i].dy+1))  pos_calc[i].y+=(pos_calc[i].dy+1);
}

int goal_behaviour(int flag){
char    *o;
char    azione;

                if (flag !=0) {
                   flag++;
                   yb =(YMAX+YMIN)/2;
                   xb =(XMIN+XMAX)/2;
                }
                if (flag==20){
                   yb =(YMAX+YMIN)/2;
                   xb =(XMIN+XMAX)/2;
                   /*seleziono l'azione da compiere sul tabellone*/
                   o = cab_reserve(cbi[3]);
                        azione = GOAL_ACT;   /*scritta GOAL!!*/
                                *o = azione;
                                cab_putmes(cbi[3],o);
                   /*carico il task gol*/
                   act_goal();
                }
                if (flag==65){
                   o = cab_reserve(cbi[3]);
                        azione = MENU_ACT;   /*sistema il menu su tabellone*/
                                *o = azione;
                                cab_putmes(cbi[3],o);
                   /*carico il task gol*/
                   act_goal();
                }

                return(flag);
}