Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1668 pj 1
 
2
/*--------------------------------------------------------------*/
3
/*              GIUOCO DEL PING - PONG                     */
4
/*--------------------------------------------------------------*/
5
 
6
#include <kernel/kern.h>
7
#include <drivers/glib.h>
8
#include <drivers/keyb.h>
9
#include <semaphore.h>
10
#include <stdlib.h>
11
#include <math.h>
12
#include <drivers/mouse.h>
13
 
14
#define YMENU    10             /* menu level                   */
15
#define XMIN     50
16
#define XMAX     600
17
#define YMIN     100
18
#define YMAX     450
19
#define D        3              /* raggio pallina                 */
20
#define ESC      27             /* ASCII code of ESCAPE key     */
21
#define FLYGROUP 1
22
#define sinistra       1
23
#define destra       0
24
 
25
double  tick = 1.0;             /* system tick = 1 ms           */
26
int     fly_period = 40000;     /* task period  */                 /*Siamo a circa 25Hz --> ok per l'occhio umano*/
27
int     avv_period = 40000;     /* task period   */                /*Siamo a circa 25Hz --> ok per l'occhio umano*/
28
int     fly_wcet = 5000;  /* task wcet pallina    *//*12000 ok per un PIII a 450 MHz*//*700 ok per Athlon Xp 2000+*/
29
int     avv_wcet =3000;    /*task wcet avversario*/  /*1000 ok per un PIII a 450 MHz*//*200 ok per Athlon Xp 2000+*/
30
PID     pid,pid_av;
31
sem_t   mutex_av,mutex_gi; //semafori per mutua avversario e giocatore
32
int indice=0; //controllo per numero palline lanciate
33
float inerzia_av=0.3; //incremento passo avversario
34
int veloc_pallina =8; //velocità pallina
35
int punteggio =0;
36
int vmax_av=10; //velocità massima avversario
37
char s2[100]; //scrittura punteggio su monitor
38
float passo=0;//passo avversario
39
 
40
/*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.   */
41
struct dati_condivisi {
42
        int     x; //coordinata della pallina 
43
        int     y; //coordinata della pallina
44
        int yvecchio;//coordinate del mouse per cancellare il cursore giocatore
45
        int xvecchio;//coordinate del mouse per cancellare il cursore giocatore
46
        int yattuale;//coordinate del mouse per disegnare il cursore giocatore
47
        int xattuale;//coordinate del mouse per disegnare il cursore giocatore
48
        int yvecchio_av;//coordinate del mouse per cancellare il cursore avversario
49
        int xvecchio_av;//coordinate del mouse per cancellare il cursore avversario
50
        int yattuale_av;//coordinate del mouse per disegnare il cursore avversario
51
        int xattuale_av;//coordinate del mouse per disegnare il cursore avversario
52
        int direzione_mouse; /*mouse proveniente da destra o sinistra per rilanciare la pallina                                 nella stessa direzione*/
53
 
54
} str_cond;
55
 
56
 
57
 
58
 
59
 
60
void my_mouse_handler(MOUSE_EVT *m)
61
        { sem_wait(&mutex_gi);
62
/*Calcolo direzione di provenienza del cursore giocatore*/
63
        if (m->x > str_cond.xattuale) str_cond.direzione_mouse =destra;
64
        if (m->x < str_cond.xattuale) str_cond.direzione_mouse=sinistra;       
65
/*scrittura delle coordinate del mouse nella struttura dati*/
66
        str_cond.xattuale=m->x;
67
        str_cond.yattuale=m->y;
68
/*disegno del cursore*/
69
        grx_box(str_cond.xvecchio,str_cond.yvecchio,str_cond.xvecchio+50,str_cond.yvecchio+15,BLACK);  
70
        grx_box(m->x,m->y,m->x+50,m->y+15,RED);
71
        str_cond.xvecchio=m->x;
72
        str_cond.yvecchio=m->y;
73
        sem_post(&mutex_gi);
74
        }
75
 
76
 
77
/*--------------------------------------------------------------*/
78
 
79
void    draw_fly(int x, int y, int c)
80
        {
81
        grx_disc(x, y, D, c);
82
        }
83
 
84
/******************************************************************/
85
 
86
TASK avversario(void *arg)
87
        {
88
        while (1){
89
                sem_wait(&mutex_av);
90
 
91
/*Inseguimento traiettoria pallina con con simulazione inerzia*/
92
                if ((str_cond.xattuale_av + 25) < str_cond.x)
93
                        {
94
                        passo = passo + inerzia_av;
95
                        if (passo>=vmax_av) //limite velocità avversario
96
                                {passo=vmax_av;}
97
                        str_cond.xattuale_av += passo;//incremento passo avversario
98
                        }
99
 
100
                if ((str_cond.xattuale_av + 25) > str_cond.x)
101
                        {
102
                        passo=passo - inerzia_av;
103
                        if (passo <= -vmax_av)
104
                                {
105
                                passo=-vmax_av;
106
                                }
107
                        str_cond.xattuale_av += passo;
108
                        }
109
/* CONTROLLO SULLO SFONDAMNETO DEI BORDI DELL'AVVERSARIO*/
110
                if (str_cond.xattuale_av < (XMIN+2))
111
                        {
112
                        str_cond.xattuale_av = XMIN+2;
113
                        passo=0;
114
                        }
115
 
116
                if (str_cond.xattuale_av > (XMAX-52))
117
                        {
118
                        str_cond.xattuale_av = XMAX-52;
119
                        passo=0;
120
                        }
121
/*disegno del cursore avversario*/             
122
                grx_box(str_cond.xvecchio_av,str_cond.yvecchio_av,str_cond.xvecchio_av+50,str_cond.yvecchio_av+15,BLACK);      
123
                grx_box(str_cond.xattuale_av,str_cond.yattuale_av,str_cond.xattuale_av+50,str_cond.yattuale_av+15,YELLOW);
124
                str_cond.yvecchio_av = str_cond.yattuale_av;
125
                str_cond.xvecchio_av = str_cond.xattuale_av;
126
                sem_post(&mutex_av);
127
                task_endcycle();
128
                }      
129
        }
130
 
131
 
132
/*task pallina*/
133
TASK    fly(void *arg)
134
{
135
int     timer=0;//contatore pausa prima del rilancio pallina
136
int     xold;//per controllo direzione provenienza pallina (destra - sinistr)
137
int     direzione;//direzione provenienzaa pallina (destra - sinistra)
138
int     ox, oy;// coordinate per cancellare la pallina
139
int     dx, dy;//passo della pallina
140
int     col;//colore pallina
141
double  r;//angolo iniziale per lancio pallina
142
int     i = (int)arg;
143
        r = rand()%(120) + 30;      /*  angolo iniziale random*/
144
        grx_text("GIUOCO DEL PING-PONG                           ", XMIN, YMENU+10, 13, 0);
145
        grx_text("SPACE TO LUNCH A BALL                 "        , XMIN, YMENU+20, 12, 0);
146
        grx_text("ESC   exit to DOS      "         , XMIN, YMENU+30, 12, 0);
147
        grx_text("                                           ", XMIN, YMENU+40, 12, 0);
148
 
149
 
150
        punteggio=0;
151
        str_cond.x = ox = (XMIN+XMAX)/2;
152
        str_cond.y = oy = (YMIN+YMAX)/2;
153
        col = 2 + i;                    /* colore pallina           */
154
        dx = 5;
155
        dy = 5;
156
        dx = (int)(veloc_pallina * cos(r*PI/180));
157
        dy = (int)(veloc_pallina * sin(r*PI/180));
158
 
159
                while (1) {        
160
                sem_wait(&mutex_av);
161
                sem_wait(&mutex_gi);   
162
/*timer per pausa pallina se l'avversario subisce goal*/
163
                timer--;
164
                if (timer < 0) timer=0;
165
/*Per calcolare la provenienza della pallina utile per il rimbalzo sull'avversario*/
166
                xold=str_cond.x;
167
/*calcolo nuova posizione della pallina*/
168
                str_cond.x = str_cond.x + dx;
169
                str_cond.y = str_cond.y + dy;
170
/*controllo provenienza pallina*/
171
                if (xold < str_cond.x)
172
                        {
173
                        direzione=sinistra;
174
                        }
175
                else    direzione=destra;
176
 
177
/*Game over: se il giocatore subisce goal*/            
178
                if (str_cond.y >= YMAX-4)  
179
                        {
180
                        indice--;//do la possibilità di lanciare una nuova pallina
181
                        /*ripristino valori iniziali*/
182
                        inerzia_av=0.3;
183
                        veloc_pallina = 8;
184
                        draw_fly(ox, oy, 0);
185
                        vmax_av=10;
186
                        /*rilascio i semafori presi*/
187
                        sem_post(&mutex_gi);
188
                        sem_post(&mutex_av);
189
                        break;
190
                        }
191
/*gol subito dall'avversario*/
192
                if (str_cond.y <= YMIN+4)  
193
                        {
194
                        veloc_pallina++;       
195
                        punteggio++;
196
                        timer=50;/*timer per pausa dopo il goal*/
197
                        if (punteggio == 18) vmax_av = 11;
198
                        grx_text("IL TUO PUNTEGGIO E' ", XMIN, YMENU+40, WHITE, 0);
199
                        sprintf(s2,"%3d",punteggio);
200
                        grx_text(s2, XMIN +150, YMENU+40, WHITE, 0);
201
                        if (veloc_pallina >= 14) veloc_pallina=14;//limite velocità pallina
202
                        inerzia_av = inerzia_av + 0.33;
203
                        dy = -dy;
204
                        }
205
 
206
/*Rimbalzo sulle pareti laterali*/
207
 
208
                if (str_cond.x <= XMIN+4)
209
                        {
210
                        dx = abs(dx);
211
                        str_cond.x +=dx;
212
                        }
213
 
214
                if (str_cond.x >= XMAX-4)
215
                        {
216
                        dx = -abs(dx);
217
                        str_cond.x +=dx;
218
                        }
219
 
220
/*Rimbalzo sul cursore giocatore*/
221
 
222
/*lATO ESTERNO SINISTRO*/
223
                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))  
224
                        {
225
                        dx = (int)(veloc_pallina * cos(20*PI/180));
226
                        dy = (int)(veloc_pallina * sin(20*PI/180));
227
                        dy = -abs(dy);
228
                        if (str_cond.direzione_mouse == sinistra)
229
                                {
230
                                dx=-abs(dx);
231
                                str_cond.x +=dx;
232
                                }
233
                        else    {dx=abs(dx);
234
                                str_cond.x +=dx;
235
                                }      
236
                        str_cond.y +=dy;
237
                        }
238
 
239
/*Lato ESTERNO destro del cursore*/
240
                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))  
241
                        {
242
                        dx = (int)(veloc_pallina * cos(20*PI/180));
243
                        dy = (int)(veloc_pallina * sin(20*PI/180));
244
                        dy = -abs(dy);
245
                        if (str_cond.direzione_mouse == sinistra){
246
                                dx=-abs(dx);
247
                                str_cond.x +=dx;
248
                                }
249
                        else    {dx=abs(dx);
250
                                str_cond.x +=dx;
251
                                }
252
                        str_cond.y +=dy;
253
                        }
254
 
255
/*Lato sinistro del cursore*/
256
                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))  
257
                        {
258
                        dx = (int)(veloc_pallina * cos(30*PI/180));
259
                        dy = (int)(veloc_pallina * sin(30*PI/180));
260
                        dy = -abs(dy);
261
                        if (str_cond.direzione_mouse == sinistra)
262
                                {
263
                                dx=-abs(dx);
264
                                str_cond.x +=dx;
265
                                }
266
                        else    {dx=abs(dx);
267
                                str_cond.x +=dx;
268
                                }      
269
                        str_cond.y +=dy;
270
                        }
271
/*Lato destro del cursore*/
272
                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))  
273
                        {
274
                        dx = (int)(veloc_pallina * cos(30*PI/180));
275
                        dy = (int)(veloc_pallina * sin(30*PI/180));
276
                        dy = -abs(dy);
277
                        if (str_cond.direzione_mouse == sinistra){
278
                                dx=-abs(dx);
279
                                str_cond.x +=dx;
280
                                }
281
                        else    {dx=abs(dx);
282
                                str_cond.x +=dx;
283
                                }
284
                        str_cond.y +=dy;
285
                        }
286
/*Lato centrale del cursore*/
287
                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))  
288
                        {
289
                        dx = (int)(veloc_pallina * cos(45*PI/180));
290
                        dy = (int)(veloc_pallina * sin(45*PI/180));
291
                        if (str_cond.direzione_mouse == sinistra){
292
                                dx=-abs(dx);
293
                                str_cond.x +=dx;
294
                                }
295
                        else    {dx=abs(dx);
296
                                str_cond.x +=dx;
297
                                }
298
                        dy = -abs(dy);
299
                        str_cond.y +=dy;
300
                        }
301
sem_post(&mutex_gi);
302
 
303
/*Controllo posizione avversario*/
304
/*lato sinistro avversario*/
305
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))  
306
                        {
307
                        dx = (int)(veloc_pallina * cos(30*PI/180));
308
                        dy = (int)(veloc_pallina * sin(30*PI/180));
309
                        dy = abs(dy);
310
                        if (direzione == destra)
311
                                {
312
                                dx=-dx;
313
                                str_cond.x +=dx;
314
                                }      
315
                        str_cond.y +=dy;
316
                        }
317
/*lato esterno sinistro*/
318
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))  
319
                        {
320
                        dx = (int)(veloc_pallina * cos(30*PI/180));
321
                        dy = (int)(veloc_pallina * sin(30*PI/180));
322
                        dy = abs(dy);
323
                        if (direzione == destra)
324
                                {
325
                                dx=-dx;
326
                                str_cond.x +=dx;
327
                                }      
328
                        str_cond.y +=dy;
329
                        }
330
 
331
 
332
/*lato destro avversario*/
333
                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))  
334
                        {
335
                        dx = (int)(veloc_pallina * cos(30*PI/180));
336
                        dy = (int)(veloc_pallina * sin(30*PI/180));
337
                        dy = abs(dy);
338
                        if (direzione == destra){
339
                                dx=-dx;
340
                                str_cond.x +=dx;
341
                                }
342
                        str_cond.y +=dy;
343
                        }
344
 
345
/*lato destro esterno avversario*/
346
                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))  
347
                        {
348
                        dx = (int)(veloc_pallina * cos(30*PI/180));
349
                        dy = (int)(veloc_pallina * sin(30*PI/180));
350
                        dy = abs(dy);
351
                        if (direzione == destra){
352
                                dx=-dx;
353
                                str_cond.x +=dx;
354
                                }
355
                        str_cond.y +=dy;
356
                        }
357
 
358
/*lato centrale avversario*/
359
                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))  
360
                        {
361
                        dx = (int)(veloc_pallina * cos(45*PI/180));
362
                        dy = (int)(veloc_pallina * sin(45*PI/180));
363
                        if (direzione == destra){
364
                                dx=-dx;
365
                                str_cond.x +=dx;
366
                                }
367
                        dy = abs(dy);
368
                        str_cond.y +=dy;
369
                        }
370
 
371
 
372
                if (timer >0)//lascia la pallina bloccata davanti all'avversario e scrive gol
373
                        {
374
                        str_cond.x=str_cond.xattuale_av+25;
375
                        str_cond.y=str_cond.yattuale_av+30;
376
                        grx_text("GOAL!!! ", (XMAX-XMIN)/2+XMIN, (YMAX-YMIN)/2+YMIN, WHITE, 0);
377
                        }      
378
                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 
379
                draw_fly(ox, oy, 0);           
380
                draw_fly(str_cond.x, str_cond.y, col);
381
                sem_post(&mutex_av);
382
 
383
 
384
                ox = str_cond.x; oy = str_cond.y;
385
                task_endcycle();
386
                }
387
        i--;
388
        grx_text("HAI PERSO!! (Ah! Ah! Ah!) GAME OVER", XMIN, YMENU+10, 13, 0);
389
        grx_text("SPACE TO START A NEW MATCH"        , XMIN, YMENU+20, 12, 0);
390
        grx_text("ESC   exit to DOS"         , XMIN, YMENU+30, 12, 0);
391
        grx_text("IL TUO PUNTEGGIO E' ", XMIN, YMENU+40, WHITE, 0);
392
        sprintf(s2,"%3d",punteggio);
393
        grx_text(s2, XMIN +150, YMENU+40, WHITE, 0);
394
}
395
 
396
/****************************************************************/
397
 
398
/* This function is called when the system exits */
399
void byebye(void *arg)
400
        {
401
        grx_close();
402
        cprintf("Bye Bye!\n");
403
        }
404
 
405
/****************************** MAIN ******************************/
406
 
407
int main(int argc, char **argv)
408
        {str_cond.x=0;
409
        str_cond.y=0;  
410
        str_cond.yvecchio = 150;
411
        str_cond.xvecchio =150;
412
        str_cond.yattuale=150;
413
        str_cond.xattuale=150;
414
        str_cond.yvecchio_av=110;
415
        str_cond.xvecchio_av=110;
416
        str_cond.yattuale_av=110;
417
        str_cond.xattuale_av=110;
418
        str_cond.direzione_mouse=sinistra;
419
 
420
 
421
 
422
 
423
        sem_init(&mutex_av,0,1);
424
        sem_init(&mutex_av,0,1);
425
        HARD_TASK_MODEL m;
426
        MOUSE_PARMS mouse = BASE_MOUSE;
427
        char c;             /* character from keyboard      */
428
        TIME seme;          /* used to init the random seed */
429
        int  i = 0;         /* number of tasks created      */
430
 
431
/* Set the closing function */
432
        sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);
433
 
434
/* graphic card Initialization */
435
        if (grx_init() < 1)
436
                {
437
                sys_abort(1);
438
                }
439
 
440
        if (grx_open(640, 480, 8) < 0)
441
                {
442
                cprintf("GRX Err\n");
443
                sys_abort(1);
444
                }
445
 
446
    /* The scenario */
447
        grx_rect(XMIN-D-1, YMIN-D-1, XMAX+D+1, YMAX+D+1, 14);
448
        grx_text("GIUOCO DEL PING-PONG", XMIN, YMENU+10, 13, 0);
449
        grx_text("SPACE TO LUNCH A BALL"        , XMIN, YMENU+20, 12, 0);
450
        grx_text("ESC   exit to DOS"         , XMIN, YMENU+30, 12, 0);
451
 
452
   /* randomize!!!! */
453
        seme = sys_gettime(NULL);
454
        srand(seme);
455
/*Inizalizzazione del mouse*/
456
        mouse_def_ps2(mouse);
457
        mouse_init(&mouse);
458
        mouse_limit(53, 430,547,430);
459
        mouse_position(150,430);
460
        mouse_threshold(3);
461
        mouse_grxcursor(ENABLE);
462
        mouse_hook(my_mouse_handler);
463
 
464
 /* The program waits a space to create a fly */
465
        c = keyb_getch(BLOCK);
466
/*inizializzazione e attivazione del task avversario*/
467
        hard_task_default_model(m);
468
        hard_task_def_ctrl_jet (m);
469
        hard_task_def_arg      (m, (void *)i);
470
        hard_task_def_wcet     (m, avv_wcet);
471
        hard_task_def_mit      (m, avv_period);
472
        hard_task_def_group    (m, FLYGROUP);
473
        hard_task_def_usemath  (m);
474
        pid_av = task_create("avversario", avversario, &m, NULL);
475
        if (pid_av == NIL) {
476
                grx_close();
477
                perror("Could not create task <fly>");
478
                sys_abort(1);
479
                }
480
        task_activate(pid_av);
481
 
482
 
483
        do {
484
        if ((c == ' ') && (indice == 0))
485
                {
486
                indice++;
487
                hard_task_default_model(m);
488
                hard_task_def_ctrl_jet (m);
489
                hard_task_def_arg      (m, (void *)i);
490
                hard_task_def_wcet     (m, fly_wcet);
491
                hard_task_def_mit      (m, fly_period);
492
                hard_task_def_group    (m, FLYGROUP);
493
                hard_task_def_usemath  (m);
494
                pid = task_create("fly", fly, &m, NULL);
495
                if (pid == NIL) {
496
                        grx_close();
497
                        perror("Could not create task <fly>");
498
                        sys_abort(1);
499
                        }
500
                task_activate(pid);
501
                i++;
502
                }
503
        c = keyb_getch(BLOCK);
504
        } while (c != ESC);
505
 
506
        mouse_end();
507
        grx_close();
508
        sys_end();
509
        return 0;
510
}
511
 
512
/*------------------------------------THE END--------------------------------------------*/