Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed


/*--------------------------------------------------------------*/
/*              GIUOCO DEL PING - PONG                     */
/*--------------------------------------------------------------*/

#include <kernel/kern.h>
#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <semaphore.h>
#include <stdlib.h>
#include <math.h>
#include <drivers/mouse.h>

#define YMENU    10             /* menu level                   */
#define XMIN     50
#define XMAX     600
#define YMIN     100
#define YMAX     450
#define D        3              /* raggio pallina                 */
#define ESC      27             /* ASCII code of ESCAPE key     */
#define FLYGROUP 1
#define sinistra       1
#define destra       0

double  tick = 1.0;             /* system tick = 1 ms           */
int     fly_period = 40000;     /* task period  */                 /*Siamo a circa 25Hz --> ok per l'occhio umano*/
int     avv_period = 40000;     /* task period   */                /*Siamo a circa 25Hz --> ok per l'occhio umano*/
int     fly_wcet = 5000;  /* task wcet pallina    *//*12000 ok per un PIII a 450 MHz*//*700 ok per Athlon Xp 2000+*/
int     avv_wcet =3000;    /*task wcet avversario*/  /*1000 ok per un PIII a 450 MHz*//*200 ok per Athlon Xp 2000+*/
PID     pid,pid_av;
sem_t   mutex_av,mutex_gi; //semafori per mutua avversario e giocatore
int indice=0; //controllo per numero palline lanciate
float inerzia_av=0.3; //incremento passo avversario
int veloc_pallina =8; //velocità pallina
int punteggio =0;
int vmax_av=10; //velocità massima avversario
char s2[100]; //scrittura punteggio su monitor
float passo=0;//passo avversario

/*Nella struttura dati condivisa sono elencate quelle varabili che, trovandosi in sezione critica, devono essere utilizzate in mutua esclusione per garantire la perfetta funzionalità del programma.   */
struct dati_condivisi {
        int     x; //coordinata della pallina
        int     y; //coordinata della pallina
        int yvecchio;//coordinate del mouse per cancellare il cursore giocatore
        int xvecchio;//coordinate del mouse per cancellare il cursore giocatore
        int yattuale;//coordinate del mouse per disegnare il cursore giocatore
        int xattuale;//coordinate del mouse per disegnare il cursore giocatore
        int yvecchio_av;//coordinate del mouse per cancellare il cursore avversario
        int xvecchio_av;//coordinate del mouse per cancellare il cursore avversario
        int yattuale_av;//coordinate del mouse per disegnare il cursore avversario
        int xattuale_av;//coordinate del mouse per disegnare il cursore avversario
        int direzione_mouse; /*mouse proveniente da destra o sinistra per rilanciare la pallina                                 nella stessa direzione*/
       
} str_cond;





void my_mouse_handler(MOUSE_EVT *m)
        { sem_wait(&mutex_gi);
/*Calcolo direzione di provenienza del cursore giocatore*/
        if (m->x > str_cond.xattuale) str_cond.direzione_mouse =destra;
        if (m->x < str_cond.xattuale) str_cond.direzione_mouse=sinistra;       
/*scrittura delle coordinate del mouse nella struttura dati*/
        str_cond.xattuale=m->x;
        str_cond.yattuale=m->y;
/*disegno del cursore*/
        grx_box(str_cond.xvecchio,str_cond.yvecchio,str_cond.xvecchio+50,str_cond.yvecchio+15,BLACK);  
        grx_box(m->x,m->y,m->x+50,m->y+15,RED);
        str_cond.xvecchio=m->x;
        str_cond.yvecchio=m->y;
        sem_post(&mutex_gi);
        }


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

void    draw_fly(int x, int y, int c)
        {
        grx_disc(x, y, D, c);
        }

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

TASK avversario(void *arg)
        {
        while (1){
                sem_wait(&mutex_av);

/*Inseguimento traiettoria pallina con con simulazione inerzia*/
                if ((str_cond.xattuale_av + 25) < str_cond.x)
                        {
                        passo = passo + inerzia_av;
                        if (passo>=vmax_av) //limite velocità avversario
                                {passo=vmax_av;}
                        str_cond.xattuale_av += passo;//incremento passo avversario
                        }
               
                if ((str_cond.xattuale_av + 25) > str_cond.x)
                        {
                        passo=passo - inerzia_av;
                        if (passo <= -vmax_av)
                                {
                                passo=-vmax_av;
                                }
                        str_cond.xattuale_av += passo;
                        }
/* CONTROLLO SULLO SFONDAMNETO DEI BORDI DELL'AVVERSARIO*/
                if (str_cond.xattuale_av < (XMIN+2))
                        {
                        str_cond.xattuale_av = XMIN+2;
                        passo=0;
                        }

                if (str_cond.xattuale_av > (XMAX-52))
                        {
                        str_cond.xattuale_av = XMAX-52;
                        passo=0;
                        }
/*disegno del cursore avversario*/             
                grx_box(str_cond.xvecchio_av,str_cond.yvecchio_av,str_cond.xvecchio_av+50,str_cond.yvecchio_av+15,BLACK);      
                grx_box(str_cond.xattuale_av,str_cond.yattuale_av,str_cond.xattuale_av+50,str_cond.yattuale_av+15,YELLOW);
                str_cond.yvecchio_av = str_cond.yattuale_av;
                str_cond.xvecchio_av = str_cond.xattuale_av;
                sem_post(&mutex_av);
                task_endcycle();
                }      
        }


/*task pallina*/
TASK    fly(void *arg)
{
int     timer=0;//contatore pausa prima del rilancio pallina
int     xold;//per controllo direzione provenienza pallina (destra - sinistr)
int     direzione;//direzione provenienzaa pallina (destra - sinistra)
int     ox, oy;// coordinate per cancellare la pallina
int     dx, dy;//passo della pallina
int     col;//colore pallina
double  r;//angolo iniziale per lancio pallina
int     i = (int)arg;
        r = rand()%(120) + 30;      /*  angolo iniziale random*/
        grx_text("GIUOCO DEL PING-PONG                           ", XMIN, YMENU+10, 13, 0);
        grx_text("SPACE TO LUNCH A BALL                 "        , XMIN, YMENU+20, 12, 0);
        grx_text("ESC   exit to DOS      "         , XMIN, YMENU+30, 12, 0);
        grx_text("                                           ", XMIN, YMENU+40, 12, 0);
       

        punteggio=0;
        str_cond.x = ox = (XMIN+XMAX)/2;
        str_cond.y = oy = (YMIN+YMAX)/2;
        col = 2 + i;                    /* colore pallina           */
        dx = 5;
        dy = 5;
        dx = (int)(veloc_pallina * cos(r*PI/180));
        dy = (int)(veloc_pallina * sin(r*PI/180));
       
                while (1) {        
                sem_wait(&mutex_av);
                sem_wait(&mutex_gi);   
/*timer per pausa pallina se l'avversario subisce goal*/
                timer--;
                if (timer < 0) timer=0;
/*Per calcolare la provenienza della pallina utile per il rimbalzo sull'avversario*/
                xold=str_cond.x;
/*calcolo nuova posizione della pallina*/
                str_cond.x = str_cond.x + dx;
                str_cond.y = str_cond.y + dy;
/*controllo provenienza pallina*/
                if (xold < str_cond.x)
                        {
                        direzione=sinistra;
                        }
                else    direzione=destra;

/*Game over: se il giocatore subisce goal*/            
                if (str_cond.y >= YMAX-4)  
                        {
                        indice--;//do la possibilità di lanciare una nuova pallina
                        /*ripristino valori iniziali*/
                        inerzia_av=0.3;
                        veloc_pallina = 8;
                        draw_fly(ox, oy, 0);
                        vmax_av=10;
                        /*rilascio i semafori presi*/
                        sem_post(&mutex_gi);
                        sem_post(&mutex_av);
                        break;
                        }
/*gol subito dall'avversario*/
                if (str_cond.y <= YMIN+4)  
                        {
                        veloc_pallina++;       
                        punteggio++;
                        timer=50;/*timer per pausa dopo il goal*/
                        if (punteggio == 18) vmax_av = 11;
                        grx_text("IL TUO PUNTEGGIO E' ", XMIN, YMENU+40, WHITE, 0);
                        sprintf(s2,"%3d",punteggio);
                        grx_text(s2, XMIN +150, YMENU+40, WHITE, 0);
                        if (veloc_pallina >= 14) veloc_pallina=14;//limite velocità pallina
                        inerzia_av = inerzia_av + 0.33;
                        dy = -dy;
                        }
               
/*Rimbalzo sulle pareti laterali*/

                if (str_cond.x <= XMIN+4)
                        {
                        dx = abs(dx);
                        str_cond.x +=dx;
                        }

                if (str_cond.x >= XMAX-4)
                        {
                        dx = -abs(dx);
                        str_cond.x +=dx;
                        }

/*Rimbalzo sul cursore giocatore*/

/*lATO ESTERNO SINISTRO*/
                if ((str_cond.y>=str_cond.yattuale-5) && (str_cond.y<=str_cond.yattuale+5) && (str_cond.x>=str_cond.xattuale-3) && (str_cond.x<str_cond.xattuale))  
                        {
                        dx = (int)(veloc_pallina * cos(20*PI/180));
                        dy = (int)(veloc_pallina * sin(20*PI/180));
                        dy = -abs(dy);
                        if (str_cond.direzione_mouse == sinistra)
                                {
                                dx=-abs(dx);
                                str_cond.x +=dx;
                                }
                        else    {dx=abs(dx);
                                str_cond.x +=dx;
                                }      
                        str_cond.y +=dy;
                        }

/*Lato ESTERNO destro del cursore*/
                if ((str_cond.y>=str_cond.yattuale-5) && (str_cond.y<=str_cond.yattuale +5)&&(str_cond.x>str_cond.xattuale+50) && (str_cond.x<=str_cond.xattuale+53))  
                        {
                        dx = (int)(veloc_pallina * cos(20*PI/180));
                        dy = (int)(veloc_pallina * sin(20*PI/180));
                        dy = -abs(dy);
                        if (str_cond.direzione_mouse == sinistra){
                                dx=-abs(dx);
                                str_cond.x +=dx;
                                }
                        else    {dx=abs(dx);
                                str_cond.x +=dx;
                                }
                        str_cond.y +=dy;
                        }

/*Lato sinistro del cursore*/
                if ((str_cond.y>=str_cond.yattuale-5) && (str_cond.y<=str_cond.yattuale+5) && (str_cond.x>=str_cond.xattuale) && (str_cond.x<=str_cond.xattuale+16))  
                        {
                        dx = (int)(veloc_pallina * cos(30*PI/180));
                        dy = (int)(veloc_pallina * sin(30*PI/180));
                        dy = -abs(dy);
                        if (str_cond.direzione_mouse == sinistra)
                                {
                                dx=-abs(dx);
                                str_cond.x +=dx;
                                }
                        else    {dx=abs(dx);
                                str_cond.x +=dx;
                                }      
                        str_cond.y +=dy;
                        }
/*Lato destro del cursore*/
                if ((str_cond.y>=str_cond.yattuale-5) && (str_cond.y<=str_cond.yattuale+5)&&(str_cond.x>=str_cond.xattuale+34) && (str_cond.x<=str_cond.xattuale+50))  
                        {
                        dx = (int)(veloc_pallina * cos(30*PI/180));
                        dy = (int)(veloc_pallina * sin(30*PI/180));
                        dy = -abs(dy);
                        if (str_cond.direzione_mouse == sinistra){
                                dx=-abs(dx);
                                str_cond.x +=dx;
                                }
                        else    {dx=abs(dx);
                                str_cond.x +=dx;
                                }
                        str_cond.y +=dy;
                        }
/*Lato centrale del cursore*/
                if ((str_cond.y>=str_cond.yattuale-5) && (str_cond.y<=str_cond.yattuale+5)&&(str_cond.x>str_cond.xattuale+16) && (str_cond.x<str_cond.xattuale+34))  
                        {
                        dx = (int)(veloc_pallina * cos(45*PI/180));
                        dy = (int)(veloc_pallina * sin(45*PI/180));
                        if (str_cond.direzione_mouse == sinistra){
                                dx=-abs(dx);
                                str_cond.x +=dx;
                                }
                        else    {dx=abs(dx);
                                str_cond.x +=dx;
                                }
                        dy = -abs(dy);
                        str_cond.y +=dy;
                        }
sem_post(&mutex_gi);

/*Controllo posizione avversario*/
/*lato sinistro avversario*/
if ((str_cond.y>=str_cond.yattuale_av+10) && (str_cond.y<=str_cond.yattuale_av+20)&&(str_cond.x>=str_cond.xattuale_av) && (str_cond.x<=str_cond.xattuale_av+16))  
                        {
                        dx = (int)(veloc_pallina * cos(30*PI/180));
                        dy = (int)(veloc_pallina * sin(30*PI/180));
                        dy = abs(dy);
                        if (direzione == destra)
                                {
                                dx=-dx;
                                str_cond.x +=dx;
                                }      
                        str_cond.y +=dy;
                        }
/*lato esterno sinistro*/
if ((str_cond.y>=str_cond.yattuale_av+10) && (str_cond.y<=str_cond.yattuale_av+20)&&(str_cond.x>=str_cond.xattuale_av-3) && (str_cond.x<=str_cond.xattuale_av))  
                        {
                        dx = (int)(veloc_pallina * cos(30*PI/180));
                        dy = (int)(veloc_pallina * sin(30*PI/180));
                        dy = abs(dy);
                        if (direzione == destra)
                                {
                                dx=-dx;
                                str_cond.x +=dx;
                                }      
                        str_cond.y +=dy;
                        }


/*lato destro avversario*/
                if ((str_cond.y>=str_cond.yattuale_av+10) && (str_cond.y<=str_cond.yattuale_av+20)&&(str_cond.x>=str_cond.xattuale_av+34) && (str_cond.x<=str_cond.xattuale_av+50))  
                        {
                        dx = (int)(veloc_pallina * cos(30*PI/180));
                        dy = (int)(veloc_pallina * sin(30*PI/180));
                        dy = abs(dy);
                        if (direzione == destra){
                                dx=-dx;
                                str_cond.x +=dx;
                                }
                        str_cond.y +=dy;
                        }

/*lato destro esterno avversario*/
                if ((str_cond.y>=str_cond.yattuale_av+10) && (str_cond.y<=str_cond.yattuale_av+20)&&(str_cond.x>str_cond.xattuale_av+50) && (str_cond.x<=str_cond.xattuale_av+53))  
                        {
                        dx = (int)(veloc_pallina * cos(30*PI/180));
                        dy = (int)(veloc_pallina * sin(30*PI/180));
                        dy = abs(dy);
                        if (direzione == destra){
                                dx=-dx;
                                str_cond.x +=dx;
                                }
                        str_cond.y +=dy;
                        }

/*lato centrale avversario*/
                if ((str_cond.y>=str_cond.yattuale_av+10) && (str_cond.y<=str_cond.yattuale_av+20)&&(str_cond.x>=str_cond.xattuale_av+16) && (str_cond.x<=str_cond.xattuale_av+34))  
                        {
                        dx = (int)(veloc_pallina * cos(45*PI/180));
                        dy = (int)(veloc_pallina * sin(45*PI/180));
                        if (direzione == destra){
                                dx=-dx;
                                str_cond.x +=dx;
                                }
                        dy = abs(dy);
                        str_cond.y +=dy;
                        }


                if (timer >0)//lascia la pallina bloccata davanti all'avversario e scrive gol
                        {
                        str_cond.x=str_cond.xattuale_av+25;
                        str_cond.y=str_cond.yattuale_av+30;
                        grx_text("GOAL!!! ", (XMAX-XMIN)/2+XMIN, (YMAX-YMIN)/2+YMIN, WHITE, 0);
                        }      
                if (timer ==1)  grx_text("GOAL!!! ", (XMAX-XMIN)/2+XMIN, (YMAX-YMIN)/2+YMIN, BLACK, 0);//cancella la scritta gol prima di rilanciare la pallina
                draw_fly(ox, oy, 0);           
                draw_fly(str_cond.x, str_cond.y, col);
                sem_post(&mutex_av);
               
               
                ox = str_cond.x; oy = str_cond.y;
                task_endcycle();
                }
        i--;
        grx_text("HAI PERSO!! (Ah! Ah! Ah!) GAME OVER", XMIN, YMENU+10, 13, 0);
        grx_text("SPACE TO START A NEW MATCH"        , XMIN, YMENU+20, 12, 0);
        grx_text("ESC   exit to DOS"         , XMIN, YMENU+30, 12, 0);
        grx_text("IL TUO PUNTEGGIO E' ", XMIN, YMENU+40, WHITE, 0);
        sprintf(s2,"%3d",punteggio);
        grx_text(s2, XMIN +150, YMENU+40, WHITE, 0);
}

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

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

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

int main(int argc, char **argv)
        {str_cond.x=0;
        str_cond.y=0;  
        str_cond.yvecchio = 150;
        str_cond.xvecchio =150;
        str_cond.yattuale=150;
        str_cond.xattuale=150;
        str_cond.yvecchio_av=110;
        str_cond.xvecchio_av=110;
        str_cond.yattuale_av=110;
        str_cond.xattuale_av=110;
        str_cond.direzione_mouse=sinistra;




        sem_init(&mutex_av,0,1);
        sem_init(&mutex_av,0,1);
        HARD_TASK_MODEL m;
        MOUSE_PARMS mouse = BASE_MOUSE;
        char c;             /* character from keyboard      */
        TIME seme;          /* used to init the random seed */
        int  i = 0;         /* number of tasks created      */
 
/* Set the closing function */
        sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);

/* graphic card Initialization */
        if (grx_init() < 1)
                {
                sys_abort(1);
                }
   
        if (grx_open(640, 480, 8) < 0)
                {
                cprintf("GRX Err\n");
                sys_abort(1);
                }

    /* The scenario */
        grx_rect(XMIN-D-1, YMIN-D-1, XMAX+D+1, YMAX+D+1, 14);
        grx_text("GIUOCO DEL PING-PONG", XMIN, YMENU+10, 13, 0);
        grx_text("SPACE TO LUNCH A BALL"        , XMIN, YMENU+20, 12, 0);
        grx_text("ESC   exit to DOS"         , XMIN, YMENU+30, 12, 0);

   /* randomize!!!! */
        seme = sys_gettime(NULL);
        srand(seme);
/*Inizalizzazione del mouse*/
        mouse_def_ps2(mouse);
        mouse_init(&mouse);
        mouse_limit(53, 430,547,430);
        mouse_position(150,430);
        mouse_threshold(3);
        mouse_grxcursor(ENABLE);
        mouse_hook(my_mouse_handler);

 /* The program waits a space to create a fly */
        c = keyb_getch(BLOCK);
/*inizializzazione e attivazione del task avversario*/
        hard_task_default_model(m);
        hard_task_def_ctrl_jet (m);
        hard_task_def_arg      (m, (void *)i);
        hard_task_def_wcet     (m, avv_wcet);
        hard_task_def_mit      (m, avv_period);
        hard_task_def_group    (m, FLYGROUP);
        hard_task_def_usemath  (m);
        pid_av = task_create("avversario", avversario, &m, NULL);
        if (pid_av == NIL) {
                grx_close();
                perror("Could not create task <fly>");
                sys_abort(1);
                }
        task_activate(pid_av);
           
       
        do {
        if ((c == ' ') && (indice == 0))
                {
                indice++;
                hard_task_default_model(m);
                hard_task_def_ctrl_jet (m);
                hard_task_def_arg      (m, (void *)i);
                hard_task_def_wcet     (m, fly_wcet);
                hard_task_def_mit      (m, fly_period);
                hard_task_def_group    (m, FLYGROUP);
                hard_task_def_usemath  (m);
                pid = task_create("fly", fly, &m, NULL);
                if (pid == NIL) {
                        grx_close();
                        perror("Could not create task <fly>");
                        sys_abort(1);
                        }
                task_activate(pid);
                i++;
                }
        c = keyb_getch(BLOCK);
        } while (c != ESC);

        mouse_end();
        grx_close();
        sys_end();
        return 0;
}

/*------------------------------------THE END--------------------------------------------*/