Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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