Subversion Repositories shark

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1668 pj 1
 
2
/*--------------------------------------------------------------*/
3
/*                        DEFENDER GAME                         */
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
 
13
#define YMENU    10             /* menu level                   */
14
#define XMIN     50
15
#define XMAX     600
16
#define YMIN     100
17
#define YMAX     450
18
#define VEL      3              /* linear velocity (def. = 3)   */
19
#define ANG      30             /* angolo massimo sterzata (30) */
20
#define D        3              /* raggio alieno                */
21
#define DD       6              /* diametro alieno              */
22
#define ESC      27             /* ASCII code of ESCAPE key     */
23
#define MAX_ALIEN    30         /* max number of aliens         */
24
#define MAX_MISSIL   10         /* numero massimo di missili    */
25
 
26
#define M_GROUP        1
27
#define ALIEN_GROUP    2
28
#define MISSILE_GROUP  3
29
 
30
#define STUPID   2
31
#define NORMAL   14
32
#define BAD      13
33
#define BASTARD  4
34
 
35
int tipo[4] = {STUPID,NORMAL,BAD,BASTARD};
36
 
37
#define PRODUCED    1
38
#define CONSUMED    0
39
 
40
#define Ix       16
41
#define Iy       16
42
 
43
char command_astro ; // comandi astronave
44
int  AstroCmdState ;
45
 
46
struct argAlien {
47
  int orig_x ; // coordinate iniziali
48
  int orig_y ;
49
  int a_type ; // tipo di alieno
50
};
51
 
52
int     mother_period =   50000 ;     /* task period                  */
53
int     mother_wcet   =   10000 ;     /* task wcet                    */
54
 
55
int     Alien_period =    40000 ;     /* task period                  */
56
int     Alien_wcet   =     1000 ;     /* task wcet                    */
57
 
58
int     Astro_period =    40000 ;     /* task period                  */
59
int     Astro_wcet =       2000 ;     /* task wcet                    */
60
 
61
int     missile_period =  40000 ;
62
int     missile_wcet =     1000 ;
63
 
64
 
65
PID     pid_Madre, pid_Alien, pid_Astro, pid_Missile, pid_Monitor ;
66
sem_t   grx_mutex, keyb_mutex, astro_mutex, alien_mutex, score_mutex;
67
sem_t   missile_mutex[MAX_MISSIL];
68
 
69
/*--------------------------------------------------------------*/
70
 
71
// Risorse condivise
72
 
73
struct s_Astronave {
74
  int x, y, FlagCollisione, FlagAstronave ;
75
} AstronavePosition ;
76
 
77
struct s_Missile {
78
  int x, y, FlagCollisione ;
79
} MissilePosition[MAX_MISSIL] ;
80
 
81
struct s_Score {
82
  int total, type[5] ;
83
} Score ;
84
 
85
int alieni_vivi ;  // numero di alieni attualmente in vita
86
 
87
/*--------------------------------------------------------------*/
88
 
89
// Disegna l'astronave a partire dalla "poppa" x,y di colore c
90
void    draw_Astronave(int x, int y, int c)
91
{
92
  // Il disegno degli oggetti e' fatto sotto mutex per migliorare
93
  // l'aspetto del sistema.
94
 
95
  if (x < 3) x = 3;
96
  if (y < 8) y = 8;
97
 
98
  sem_wait(&grx_mutex);
99
    grx_line(x, y-8, x, y+8, c);
100
    grx_line(x, y-8, x+5, y-4, c);
101
    grx_line(x, y+8, x+5, y+4, c);
102
    grx_line(x+5, y-4, x+10, y-4, c);
103
    grx_line(x+5, y+4, x+10, y+4, c);
104
    grx_line(x+10, y-4, x+15, y, c);
105
    grx_line(x+10, y+4, x+15, y, c);
106
    grx_line(x+15, y, x+17, y, c);
107
    grx_box(x-3, y-6, x, y-2, c);
108
    grx_box(x-3, y+2, x, y+6, c);
109
    grx_box(x+8, y-3, x+10, y-1, c);
110
    grx_box(x+8, y+1, x+10, y+3, c);
111
    grx_line(x+3, y-4, x+8, y-1, c);
112
    grx_line(x+3, y+4, x+8, y+1, c);
113
  sem_post(&grx_mutex);
114
}
115
 
116
// disegno del generico alieno "centro" x,y colore
117
void    draw_Alieno(int x, int y, int c)
118
{
119
  if (x < DD) x = DD;
120
  if (y < 0) y = 0;
121
 
122
  sem_wait(&grx_mutex);
123
    grx_disc(x, y, D, c); // disco
124
    grx_line(x-DD, y, x+DD, y, c); // linea
125
  sem_post(&grx_mutex);
126
}
127
 
128
// disegno della madre alieni
129
void    draw_Mother(int x, int y, int c, int d)
130
{
131
  int i;
132
 
133
  if (x < 10) x = 10;
134
  if (y < 8) y = 8;
135
 
136
  sem_wait(&grx_mutex);
137
    grx_box(x-10, y-10, x-5, y+5, c); // box
138
    grx_box(x+5, y-10, x+10, y+5, c); // box
139
    grx_disc(x, y, 5, c); // disco
140
    grx_line(x, y+8, x, y-8, c); // linea
141
    for (i = 0; i < d ; i++) {
142
      grx_disc(x + (rand()%20)-10, y + (rand()%10)-5, d/2, 0);
143
    }
144
  sem_post(&grx_mutex);
145
}
146
 
147
void    draw_Missile(int x, int y, int c)
148
{
149
  if (y < 3) y = 3;
150
 
151
  sem_wait(&grx_mutex);
152
    grx_box (x, y-1, x+6, y+1, c);
153
    grx_line(x+1, y-3, x+1, y+3, c);
154
    grx_line(x+1, y+3, x+3, y, c);
155
    grx_line(x+1, y-3, x+3, y, c);
156
    grx_disc(x+6, y, 1, c);
157
  sem_post(&grx_mutex);
158
}
159
/******************************************************************/
160
 
161
// ------------------------------------------------------------------->
162
 
163
//                              ALIENO
164
 
165
// ------------------------------------------------------------------->
166
 
167
TASK    Alieno(void *arg)
168
{
169
  int     x, y          ;
170
  int     xa1, ya1      ;
171
  int     ox, oy        ;
172
  int     x1 = 0        ;   /* variabile di appoggio */
173
  int     dx, dy, da    ;
174
  int     teta = 0      ;
175
  int     col           ;
176
  int     outx, outy    ;
177
  double  r             ;
178
  int     j = 0         ;
179
  int     morto = FALSE ;
180
  int     score = 0     ;
181
 
182
  int x_MissilePosition ;
183
  int y_MissilePosition ;
184
  int FlagCollisione    ;
185
 
186
  int x_AstronavePosition ;
187
  int y_AstronavePosition ;
188
 
189
  int xi,yi ;
190
 
191
  int FlagAstro ;
192
 
193
  float Kp = 0.01     ;
194
  float Ki = 0.005    ;
195
  float Kd = 0.00005  ;
196
 
197
  float ex_k, ey_k, ex_sum, ey_sum, ex_km1, ey_km1 ;
198
 
199
  ex_k = ey_k = ex_sum = ey_sum = ex_km1 = ey_km1 = 0 ;
200
 
201
  struct argAlien *arg_Alieno = (struct argAlien *)arg ;
202
 
203
  // Punto di partenza dell'alieno
204
  x = ox = arg_Alieno->orig_x ;
205
  y = oy = arg_Alieno->orig_y ;
206
  col = arg_Alieno->a_type    ;   /* tipo alieno */
207
 
208
 
209
  // Ciclo infinito
210
  while (1) {
211
 
212
 
213
    // Lettura valori Astronave
214
    sem_wait(&astro_mutex);
215
      x_AstronavePosition = AstronavePosition.x   ;
216
      y_AstronavePosition = AstronavePosition.y   ;
217
      FlagAstro = AstronavePosition.FlagAstronave ;
218
    sem_post(&astro_mutex);
219
 
220
    switch (col)
221
    {
222
      case STUPID :
223
      {    // Parametri di spostamento
224
 
225
        dx = -VEL;
226
        x += dx;
227
        if (x <= XMIN + DD) x = XMAX - DD;
228
 
229
        score = 1 ;
230
 
231
      }
232
      break;
233
 
234
      case NORMAL :
235
      {  // Spostamento oggetto
236
        dx = -VEL                ;
237
        dy = VEL * (rand()%3 -1) ;
238
        x += dx                  ;
239
        y += dy                  ;
240
 
241
        outy = (y >= YMAX) || (y <= YMIN);
242
        if (outy) y = y - dy;
243
 
244
        if (x <= XMIN + DD) x = XMAX - DD;
245
 
246
        score = 2 ;
247
 
248
      }
249
      break;
250
 
251
      case BAD :
252
      {
253
        da = rand()%(2*ANG) - ANG;  /*  da = [-ANG,ANG] */
254
        teta += da;
255
 
256
        if (teta > 360) teta -= 360;
257
        if (teta < 0) teta += 360;
258
        r = (double)teta * PI / 180.;
259
        dx = (float)(-VEL * cos(r));
260
        dy = (float)(VEL * sin(r));
261
        x += dx;
262
        y += dy;
263
 
264
        outx = (x >= XMAX-DD) || (x <= XMIN+DD);
265
        outy = (y >= YMAX) || (y <= YMIN);
266
 
267
        if (outy) {
268
          y = y - dy;
269
          teta = -teta;
270
          if (teta > 360) teta -= 360;
271
          if (teta < 0) teta += 360;
272
          r = (double)teta * PI / 180.;
273
 
274
          dy = (float)(VEL * sin(r));
275
 
276
          y += dy;
277
        }
278
 
279
        if (outx) {
280
          x = x - dx;
281
 
282
          if (x+dx >= XMAX-DD) x1 = XMIN + DD;
283
          if (x <= XMIN+DD) x1 = XMAX - DD;
284
 
285
          x = x1 + dx;
286
        }
287
 
288
        score = 3 ;
289
 
290
      }
291
      break;
292
 
293
      case BASTARD : // alieno bastardo
294
      {
295
 
296
          xa1 = x_AstronavePosition ;
297
          ya1 = y_AstronavePosition ;
298
 
299
        if (!FlagAstro) col = BAD;
300
 
301
// PID di inseguimento asse X
302
 
303
        ex_k =(float) (xa1 - x);
304
        if (ex_k >  50) ex_k =  50 ; // saturazione simmetrica dell'errore
305
        if (ex_k < -50) ex_k = -50 ;
306
 
307
        ex_sum = ex_sum + ex_k ;       // aggiornamento dell'errore integrale
308
        dx = (int) ( ex_k * Kp + ex_sum * Ki + (ex_k - ex_km1) *Kd ); // PID classico
309
        ex_km1 = ex_k ; // salvataggio dell'errore vecchio x il termine derivativo
310
 
311
// PID di inseguimento asse Y
312
        ey_k = (float) (ya1 - y);
313
        if (ey_k >  50) ey_k =  50 ; // saturazione simmetrica dell'errore
314
        if (ey_k < -50) ey_k = -50 ;
315
 
316
        ey_sum = ey_sum + ey_k ;       // aggiornamento dell'errore integrale
317
        dy = (int) ( ey_k * Kp + ey_sum * Ki + (ey_k-ey_km1) *Kd ) ;
318
        ey_km1 = ey_k ;
319
 
320
        x = x + dx ; // aggiornamento delle posizioni
321
        y = y + dy ;
322
 
323
        outx = (x >= XMAX-DD) || (x <= XMIN+DD); // flag di schianto
324
        outy = (y >= YMAX) || (y <= YMIN);
325
 
326
        if (outy)
327
        {
328
            y = y - dy;
329
            ey_sum = 0;
330
        }
331
 
332
        if (outx)
333
        {
334
            x = x - dx;
335
 
336
            if (x+dx >= XMAX-DD) x1 = XMIN + DD;
337
            if (x <= XMIN+DD) x1 = XMAX - DD;
338
 
339
             x = x1 + dx;
340
        }
341
 
342
        score = 4 ;
343
 
344
      } // chiude il CASE BASTARD
345
      break;
346
 
347
    } //chiude lo switch
348
 
349
    // Disegno l'alieno
350
    draw_Alieno(ox, oy, 0);             /* cancello il vecchio alieno */
351
 
352
 
353
 
354
    // Rilevatore di collisioni con l'Astronave
355
 
356
 
357
 
358
    if (FlagAstro)
359
    {
360
        // verifica della presenza dell'astronave nell'intorno
361
           xi = ( (abs(x - x_AstronavePosition)) < Ix ) ;
362
           yi = ( (abs(y - y_AstronavePosition)) < Iy ) ;
363
        if (xi && yi)
364
          {
365
             sem_wait(&astro_mutex)   ;
366
                AstronavePosition.FlagCollisione = TRUE    ;
367
             sem_post(&astro_mutex)   ;
368
         break ; // morto x collisione astronave
369
          }
370
     }
371
 
372
    // Controllo di collisione dell'ALIENO con i missili
373
    for (j = 0; j < MAX_MISSIL; j++)
374
      {
375
 
376
      sem_wait(&missile_mutex[j]);
377
        x_MissilePosition = MissilePosition[j].x ;
378
        y_MissilePosition = MissilePosition[j].y ;
379
        FlagCollisione = MissilePosition[j].FlagCollisione;
380
      sem_post(&missile_mutex[j]);
381
 
382
      if (FlagCollisione == FALSE) {
383
 
384
        // verifica della presenza nell'intorno
385
        xi = ( (x - x_MissilePosition) > 0 && (x - x_MissilePosition) < Ix ) ;
386
        yi = ( (abs(y - y_MissilePosition)) < Iy )                           ;
387
 
388
        if (xi && yi) {
389
          sem_wait(&missile_mutex[j])   ;
390
            MissilePosition[j].FlagCollisione = TRUE    ;
391
          sem_post(&missile_mutex[j])   ;
392
 
393
          morto = TRUE ;
394
 
395
        }
396
      }
397
      else break ;  // esco dal ciclo for
398
    }
399
 
400
    if (morto == TRUE) break ;  // esco dal ciclo while
401
 
402
    draw_Alieno(x, y, col);             /* disegno il nuovo alieno */
403
    ox = x; oy = y;
404
 
405
    task_endcycle();    /* fine del ciclo */
406
 
407
  } // chiusura del while
408
 
409
     sem_wait(&alien_mutex) ;
410
       alieni_vivi--        ;
411
     sem_post(&alien_mutex) ;
412
 
413
     sem_wait(&score_mutex) ;
414
       Score.total+=score   ;
415
       Score.type[score-1]++;
416
     sem_post(&score_mutex) ;
417
 
418
     pid_Alien = NIL ;
419
 
420
  return 0 ; // morte dell'alieno
421
 
422
}
423
 
424
 
425
// ------------------------------------------------------------------->
426
 
427
//                              MADRE ALIENI
428
 
429
// ------------------------------------------------------------------->
430
 
431
 
432
TASK    MadreAlieni(void *arg)
433
{
434
 
435
  int v = 0;
436
  int a_v ;
437
  int i = 150;
438
  int conta_spari = 0;
439
  int xi, yi;
440
  int j = 0;
441
 
442
  int x_MissilePosition ;
443
  int y_MissilePosition ;
444
  int FlagCollisione ;
445
 
446
  int x_AstronavePosition ;
447
  int y_AstronavePosition ;
448
  int FlagAstro ;
449
 
450
  int     x, y;
451
  int     ox, oy;
452
  int     dx, dy, da;
453
  int     teta = 0;
454
  int     outx, outy;
455
  double  r;
456
 
457
  struct argAlien arg_Alieno;
458
 
459
  struct argAlien *p_Alien;
460
 
461
  p_Alien = &arg_Alieno;
462
 
463
  HARD_TASK_MODEL Alien;
464
 
465
  // Punto di partenza della Madre alieni
466
 
467
  x = ox = (rand()%XMIN) + (rand()%(XMAX-2*XMIN)) + XMIN;
468
  y = oy = (rand()%YMIN) + (rand()%(YMAX-2*YMIN)) + YMIN;
469
 
470
 
471
  // Ciclo infinito
472
  while (1)
473
    {
474
 
475
    // Punto di partenza dell'alieno (dal culo della Madre alieni)
476
 
477
    arg_Alieno.orig_x = x;
478
    arg_Alieno.orig_y = y + 15;
479
 
480
    // Tipo alieno casuale
481
    v = rand()%4;
482
 
483
    arg_Alieno.a_type = tipo[v];
484
 
485
    sem_wait(&alien_mutex) ;
486
      a_v = alieni_vivi   ;
487
    sem_post(&alien_mutex) ;
488
 
489
    if ((a_v < MAX_ALIEN) && (i == 0))
490
      {
491
 
492
      hard_task_default_model(Alien);
493
      hard_task_def_ctrl_jet (Alien);
494
      hard_task_def_arg      (Alien, (void *)p_Alien);
495
      hard_task_def_wcet     (Alien, Alien_wcet);
496
      hard_task_def_mit      (Alien, Alien_period);
497
      hard_task_def_group    (Alien, ALIEN_GROUP);
498
      hard_task_def_usemath  (Alien);
499
 
500
      pid_Alien = task_create("Alieno", Alieno, &Alien, NULL);
501
 
502
      if (pid_Alien == NIL)
503
        {
504
        grx_text("pid_Alien == NIL", 200, 80 ,  4, 0);
505
        return 0;
506
        //grx_close();
507
        //perror("Could not create task <Alieno>\n");
508
        //sys_abort(1);
509
      }
510
 
511
      task_activate(pid_Alien);
512
 
513
      i = 40 ; // count down alla generarazione di un alieno
514
 
515
      sem_wait(&alien_mutex) ;
516
        alieni_vivi++   ;
517
      sem_post(&alien_mutex) ;
518
 
519
    }
520
 
521
    // Spostamento madre alieni
522
    da = rand()%(2*ANG) - ANG;  /*  da = [-ANG,ANG] */
523
    teta += da;
524
 
525
    if (teta > 360) teta -= 360;
526
    if (teta < 0) teta += 360;
527
    r = (double)teta * PI / 180.;
528
    dx = (float)(2 * cos(r));
529
    dy = (float)(2 * sin(r));
530
    x += dx;
531
    y += dy;
532
 
533
    outx = (x >= XMAX - 20) || (x <= XMIN + 20);
534
    outy = (y >= YMAX - 20) || (y <= YMIN + 20);
535
 
536
    if (outx || outy)
537
      {
538
      x = x - dx;
539
      y = y - dy;
540
      if (outx) teta = 180 - teta;
541
      if (outy) teta = -teta;
542
      if (teta > 360) teta -= 360;
543
      if (teta < 0) teta += 360;
544
      r = (double)teta * PI / 180.;
545
 
546
      dx = (float)(2 * cos(r));
547
      dy = (float)(2 * sin(r));
548
 
549
      x += dx;
550
      y += dy;
551
    }
552
 
553
    draw_Mother(ox, oy, 0, 0);
554
 
555
    // Controllo di collisione della MADRE con i missili
556
    for (j = 0; j < MAX_MISSIL; j++)
557
      {
558
 
559
      sem_wait(&missile_mutex[j]);
560
        x_MissilePosition = MissilePosition[j].x ;
561
        y_MissilePosition = MissilePosition[j].y ;
562
        FlagCollisione = MissilePosition[j].FlagCollisione;
563
      sem_post(&missile_mutex[j]);
564
 
565
      if (FlagCollisione == FALSE)
566
        {
567
 
568
        // verifica della presenza nell'intorno
569
        xi = ( (x - x_MissilePosition) > 0 && (x - x_MissilePosition) < Ix ) ;
570
        yi = ( (abs(y - y_MissilePosition)) < Iy )                           ;
571
 
572
        if (xi && yi)
573
          {
574
          sem_wait(&missile_mutex[j])   ;
575
            MissilePosition[j].FlagCollisione = TRUE    ;
576
          sem_post(&missile_mutex[j])   ;
577
 
578
          conta_spari++;
579
 
580
        }
581
      }
582
 
583
      if (FlagCollisione == TRUE) break ;  // esco dal ciclo for
584
    }
585
 
586
    if (conta_spari == 5) {
587
 
588
      sem_wait(&score_mutex) ;
589
        Score.total+=10      ;
590
        Score.type[4]++      ;
591
      sem_post(&score_mutex) ;
592
 
593
      pid_Madre = NIL ;
594
      return 0 ;
595
 
596
    }
597
 
598
    // Controllo di collisione della madre con l'astronave
599
    // Lettura valori Astronave
600
    sem_wait(&astro_mutex);
601
      x_AstronavePosition = AstronavePosition.x ;
602
      y_AstronavePosition = AstronavePosition.y ;
603
      FlagAstro = AstronavePosition.FlagAstronave ;
604
    sem_post(&astro_mutex);
605
 
606
    if (FlagAstro)
607
      {
608
      // verifica della presenza dell'astronave nell'intorno
609
      xi = ( (abs(x - x_AstronavePosition)) < Ix ) ;
610
      yi = ( (abs(y - y_AstronavePosition)) < Iy ) ;
611
      if (xi && yi)
612
        {
613
        sem_wait(&astro_mutex)   ;
614
          AstronavePosition.FlagCollisione = TRUE    ;
615
        sem_post(&astro_mutex)   ;
616
        conta_spari++ ;
617
      }
618
    }
619
 
620
    if (conta_spari == 5) {
621
 
622
      sem_wait(&score_mutex) ;
623
        Score.total+=10      ;
624
        Score.type[4]++      ;
625
      sem_post(&score_mutex) ;
626
 
627
      pid_Madre = NIL ;
628
      return 0 ;
629
 
630
    }
631
 
632
    draw_Mother(x, y, 15, conta_spari);
633
    ox = x; oy = y;
634
 
635
    i-- ;
636
 
637
    task_endcycle();    /* fine del ciclo while */
638
  }
639
}
640
 
641
// ------------------------------------------------------------------->
642
 
643
//                              ASTRONAVE
644
 
645
// ------------------------------------------------------------------->
646
 
647
 
648
TASK    Astronave(void *arg)
649
{
650
  int     x, y;
651
  int     ox, oy;
652
  int     dx, dy;
653
  int     col;
654
  int     outy;
655
  char          c;
656
 
657
  int FlagCollisione ;
658
 
659
  x = ox = XMIN + 10;
660
  y = oy = (YMIN+YMAX)/2;
661
  col = 15;
662
 
663
  while (1) {
664
 
665
    sem_wait(&keyb_mutex);
666
       if (AstroCmdState == PRODUCED)
667
         {
668
           c = command_astro;
669
           AstroCmdState = CONSUMED ;
670
         }
671
        else
672
         {
673
           c = 0 ;
674
         }
675
    sem_post(&keyb_mutex);
676
 
677
    dx = VEL ;
678
    dy = 0   ;
679
 
680
    switch (c)
681
    {
682
      case 'w' :
683
      {
684
        dy = -VEL;
685
      }
686
      break;
687
 
688
      case 's' :
689
      {
690
        dy = VEL;
691
      }
692
      break;
693
     }
694
 
695
 
696
    x += dx;
697
    y += dy;
698
 
699
    outy = (y >= YMAX-DD) || (y <= YMIN+DD);
700
 
701
    if (outy) y = y - dy;
702
 
703
    if (x >= XMAX - DD) x = XMIN + DD;
704
 
705
 
706
    sem_wait(&astro_mutex);
707
      AstronavePosition.x = x   ;
708
      AstronavePosition.y = y   ;
709
      FlagCollisione = AstronavePosition.FlagCollisione ;
710
    sem_post(&astro_mutex);
711
 
712
    draw_Astronave(ox, oy, 0);
713
 
714
    if (FlagCollisione)
715
       break ;
716
 
717
    draw_Astronave(x, y, col);
718
    ox = x; oy = y;
719
 
720
    task_endcycle();
721
 
722
  } // chiusura del while
723
 
724
    sem_wait(&astro_mutex)                   ;
725
       AstronavePosition.FlagCollisione = FALSE  ;
726
       AstronavePosition.FlagAstronave  = FALSE  ;
727
    sem_post(&astro_mutex)                   ;
728
 
729
       pid_Astro = NIL ; // cleanup
730
  return 0 ;
731
 
732
} // chiusura dell'astronave
733
 
734
// ------------------------------------------------------------------->
735
 
736
//                              MISSILE
737
 
738
// ------------------------------------------------------------------->
739
 
740
 
741
TASK    Missile(void *arg)
742
{
743
  int     x, y;
744
  int     ox, oy;
745
  int     dx;
746
  int     col;
747
  int     xa1;
748
  int     ya1;
749
 
750
  int     FlagCollisione ;
751
 
752
  int     i = (int)arg;
753
 
754
  // Punto di partenza del missile (la punta dell'astronave)
755
  col = 15;                    /* colore missile (bianco) */
756
 
757
  sem_wait(&astro_mutex);
758
     xa1 = AstronavePosition.x ;
759
     ya1 = AstronavePosition.y ;
760
  sem_post(&astro_mutex);
761
 
762
  x = ox = xa1 + 15;
763
  y = oy = ya1;
764
 
765
  // Ciclo infinito
766
  while (1) {
767
 
768
    // Parametri di spostamento
769
 
770
    dx = 2*VEL;
771
    x += dx;
772
 
773
    sem_wait(&missile_mutex[i])                           ;
774
       MissilePosition[i].x = x ; // aggiorno posizione
775
       MissilePosition[i].y = y ;
776
       FlagCollisione = MissilePosition[i].FlagCollisione ; // leggo collisione
777
    sem_post(&missile_mutex[i])   ;
778
 
779
    // Esplosione del missile : a) per raggimento del bordo dx
780
    //                          b) per collisione con un alieno
781
 
782
    // Disegno l'alieno
783
    draw_Missile(ox, oy, 0);            /* cancello il vecchio missile */
784
 
785
    if ( (x >= XMAX - D) || FlagCollisione )
786
       break ;
787
 
788
    draw_Missile(x, y, col);            /* disegno il nuovo missile */
789
    ox = x; oy = y;
790
 
791
    task_endcycle();    /* fine del ciclo */
792
 
793
  } // chiusura del while(1): quando il missile arriva alla fine della sua esistenza
794
    // (bordo dx o collisione) temina cancellandosi.
795
    //
796
 
797
    sem_wait(&missile_mutex[i])                   ;
798
       MissilePosition[i].FlagCollisione = FALSE  ;
799
       MissilePosition[i].x = 0                   ;
800
       MissilePosition[i].y = 0                   ;  // Missile fuori dall'area di gioco
801
    sem_post(&missile_mutex[i])                   ;
802
 
803
  return 0 ;
804
}
805
 
806
// ------------------------------------------------------------------->
807
 
808
//                              M O N I T O R
809
 
810
// ------------------------------------------------------------------->
811
 
812
 
813
TASK    Monitor(void *arg)
814
{
815
  int stat1,stat2;
816
  int giri = 0 ;
817
  TIME T_Astro_Sum, T_Astro_Max, T_Astro_Curr ;
818
  TIME T_Madre_Sum, T_Madre_Max, T_Madre_Curr ;
819
 
820
  char s[400] ;
821
 
822
  // Ciclo infinito
823
  while (1)
824
    {
825
     stat1 = jet_getstat(pid_Astro, &T_Astro_Sum , &T_Astro_Max , &giri , &T_Astro_Curr);
826
 
827
       if (stat1==0)
828
         {
829
           sprintf(s,"Astro->TimeMax = %d ", (int) T_Astro_Max);
830
           grx_text(s , XMIN+350, YMENU+20,  4, 0);
831
         }
832
        else
833
        {
834
           sprintf(s,"                        ")   ;
835
           grx_text(s , XMIN+350, YMENU+20,  4, 0) ;
836
        }
837
 
838
 
839
//--------------------------------------------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
840
 
841
 
842
       stat2 = jet_getstat(pid_Madre, &T_Madre_Sum , &T_Madre_Max , &giri , &T_Madre_Curr);
843
 
844
       if (stat2==0)
845
         {
846
           sprintf(s,"Madre->TimeMax = %d ", (int) T_Madre_Max);
847
           grx_text(s , XMIN+350, YMENU+30,  4, 0);
848
         }
849
        else
850
        {
851
           sprintf(s,"                        ")   ;
852
           grx_text(s , XMIN+350, YMENU+30,  4, 0) ;
853
        }
854
 
855
 
856
//-----------------------------------------------------------------------------
857
 
858
     }
859
}
860
/****************************************************************/
861
 
862
/* This function is called when the system exits */
863
void byebye(void *arg)
864
{
865
  grx_close();
866
  cprintf("Bye Bye!\n");
867
}
868
 
869
/****************************** MAIN ******************************/
870
 
871
int main(int argc, char **argv)
872
 
873
{
874
  HARD_TASK_MODEL m,a,ms; // Task hard
875
 
876
  NRT_TASK_MODEL  monitor ; // Task non real time
877
 
878
  char c      ;             /* character from keyboard      */
879
  int  i = 0  ;         /* missile numero      */
880
  TIME seme   ;          /* used to init the random seed */
881
  int miss = 0;
882
  int totalscore = 0;
883
  int typescore[5] = {0,0,0,0,0};
884
 
885
  char s[30]  ;
886
  char s1[30] ;
887
  char s2[30] ;
888
  char s3[30] ;
889
  char s4[30] ;
890
  char s5[30] ;
891
 
892
 
893
  AstroCmdState = CONSUMED ;
894
  for (i = 0; i < MAX_MISSIL; i++) {
895
    MissilePosition[i].FlagCollisione = FALSE ;
896
  }
897
 
898
  AstronavePosition.FlagCollisione = FALSE    ;
899
  AstronavePosition.FlagAstronave = FALSE     ;
900
 
901
  pid_Madre = NIL ;
902
  pid_Astro   = NIL ;
903
 
904
  Score.total = 0 ;
905
/* */
906
  nrt_task_default_model(monitor) ; // inizializza il task monitor
907
 
908
  pid_Monitor = task_create("Monitor", Monitor, &monitor, NULL);
909
 
910
          if (pid_Monitor == NIL) {
911
            grx_close();
912
            perror("Could not create task <Monitor>\n");
913
            sys_abort(1);
914
          }
915
 
916
  task_activate(pid_Monitor); // parte immediatamente
917
 
918
 
919
  /* Set the closing function */
920
  sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);
921
 
922
  /* Semaphore Initialization */
923
  sem_init(&grx_mutex,0,1);
924
  sem_init(&keyb_mutex,0,1);
925
  sem_init(&astro_mutex,0,1);
926
  sem_init(&alien_mutex,0,1);
927
  sem_init(&score_mutex,0,1);
928
  for (i = 0; i < MAX_MISSIL; i++) {
929
    sem_init(&missile_mutex[i],0,1);
930
  }
931
 
932
  /* graphic card Initialization */
933
  if (grx_init() < 1) {
934
    cprintf("GRX Init\n");
935
    sys_abort(1);
936
  }
937
 
938
  if (grx_open(640, 480, 8) < 0) {
939
    cprintf("GRX Err\n");
940
    sys_abort(1);
941
  }
942
 
943
  /* The scenario */
944
  grx_line(XMIN-D-1, YMIN-D-1, XMAX+D+1, YMIN-D-1, 14);
945
  grx_line(XMIN-D-1, YMAX+D+1, XMAX+D+1, YMAX+D+1, 14);
946
 
947
  grx_text("Simulation of Defender Game", XMIN, YMENU+10,  1, 0);
948
  grx_text("a -> crea Astronave"        , XMIN, YMENU+20,  3, 0);
949
  grx_text("m -> crea Madre alieni"     , XMIN, YMENU+30, 13, 0);
950
  grx_text("space -> sparo"             , XMIN, YMENU+40, 14, 0);
951
  grx_text("ESC   exit to DOS"          , XMIN, YMENU+50,  4, 0);
952
  grx_text("SCORE  "                    , XMIN, YMENU+60,  4, 0);
953
 
954
  c = keyb_getch(BLOCK);
955
 
956
  /* randomize!!!! */
957
  seme = sys_gettime(NULL);
958
  srand(seme);
959
 
960
  do {
961
           //barra spazio lancia il task missile
962
    if ((c == ' ') && AstronavePosition.FlagAstronave==TRUE) {
963
 
964
      for (i = 0; i < MAX_MISSIL; i++) {
965
 
966
        sem_wait(&missile_mutex[i])   ;
967
          miss = MissilePosition[i].x ;
968
        sem_post(&missile_mutex[i])   ;
969
 
970
        if (miss == 0) {
971
 
972
          hard_task_default_model(ms);
973
          hard_task_def_ctrl_jet (ms);
974
          hard_task_def_arg      (ms, (void *)i);
975
          hard_task_def_wcet     (ms, missile_wcet);
976
          hard_task_def_mit      (ms, missile_period);
977
          hard_task_def_group    (ms, MISSILE_GROUP);
978
          hard_task_def_usemath  (ms);
979
 
980
          pid_Missile = task_create("Missile", Missile, &ms, NULL);
981
 
982
          if (pid_Missile == NIL) {
983
            grx_close();
984
            perror("Could not create task <Missile>\n");
985
            sys_abort(1);
986
          }
987
 
988
          task_activate(pid_Missile);
989
 
990
          break ;
991
        }
992
      }
993
    }
994
 
995
    if ((c == 'm') && (pid_Madre == NIL) ) {
996
 
997
      hard_task_default_model(m);
998
      hard_task_def_ctrl_jet (m);
999
      hard_task_def_arg      (m, (void *)i);
1000
      hard_task_def_wcet     (m, mother_wcet);
1001
      hard_task_def_mit      (m, mother_period);
1002
      hard_task_def_group    (m, M_GROUP);
1003
      hard_task_def_usemath  (m);
1004
 
1005
      pid_Madre = task_create("MadreAlieni", MadreAlieni, &m, NULL);
1006
 
1007
      if (pid_Madre == NIL) {
1008
        grx_close();
1009
        perror("Could not create task <MadreAlieni>\n");
1010
        sys_abort(1);
1011
      }
1012
      task_activate(pid_Madre);
1013
    }
1014
 
1015
    if ((c == 'a') && !AstronavePosition.FlagAstronave) { // creazione del task Astronave
1016
 
1017
      hard_task_default_model(a);
1018
      hard_task_def_ctrl_jet (a);
1019
      hard_task_def_arg      (a, (void *)i);
1020
      hard_task_def_wcet     (a, Astro_wcet);
1021
      hard_task_def_mit      (a, Astro_period);
1022
      hard_task_def_usemath  (a);
1023
 
1024
      pid_Astro = task_create("Astronave", Astronave, &a, NULL);
1025
 
1026
      if (pid_Astro == NIL) {
1027
        grx_close();
1028
        perror("Could not create task <Astronave>\n");
1029
        sys_abort(1);
1030
      }
1031
 
1032
      AstronavePosition.FlagAstronave = TRUE ;
1033
      task_activate(pid_Astro);
1034
    }
1035
 
1036
     sem_wait(&score_mutex);
1037
       totalscore = Score.total;
1038
       for (i = 0; i < 5; i++) {
1039
         typescore[i] = Score.type[i];
1040
       }
1041
     sem_post(&score_mutex);
1042
 
1043
     sprintf ( s, "SCORE = %d", totalscore);
1044
     sprintf ( s1, "STUPID = %d", typescore[0]);
1045
     sprintf ( s2, "NORMAL = %d", typescore[1]);
1046
     sprintf ( s3, "BAD = %d", typescore[2]);
1047
     sprintf ( s4, "BASTARD = %d", typescore[3]);
1048
     sprintf ( s5, "MOTHER = %d", typescore[4]);
1049
 
1050
     grx_text( s , XMIN, YMENU+60,  4, 0);
1051
 
1052
     grx_text("Nemici uccisi", XMIN+250, YMENU+10,  1, 0);
1053
     grx_text(s1 , XMIN+250, YMENU+20,  1, 0);
1054
     grx_text(s2 , XMIN+250, YMENU+30,  1, 0);
1055
     grx_text(s3 , XMIN+250, YMENU+40,  1, 0);
1056
     grx_text(s4 , XMIN+250, YMENU+50,  1, 0);
1057
     grx_text(s5 , XMIN+250, YMENU+60,  1, 0);
1058
 
1059
     c = keyb_getch(BLOCK);
1060
 
1061
     sem_wait(&keyb_mutex);
1062
         command_astro = c ;
1063
         AstroCmdState = PRODUCED ;
1064
     sem_post(&keyb_mutex);
1065
 
1066
  } while (c != ESC);
1067
 
1068
  sys_end();
1069
 
1070
  return 0;
1071
}
1072
 
1073
/*--------------------------------------------------------------*/