Rev 1668 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*--------------------------------------------------------------*/
/* DEFENDER GAME */
/*--------------------------------------------------------------*/
#include <kernel/kern.h>
#include <drivers/shark_fb26.h>
#include <drivers/shark_keyb26.h>
#include <semaphore.h>
#include <stdlib.h>
#include <math.h>
#define YMENU 10 /* menu level */
#define XMIN 50
#define XMAX 600
#define YMIN 100
#define YMAX 450
#define VEL 3 /* linear velocity (def. = 3) */
#define ANG 30 /* angolo massimo sterzata (30) */
#define D 3 /* raggio alieno */
#define DD 6 /* diametro alieno */
#define MAX_ALIEN 30 /* max number of aliens */
#define MAX_MISSIL 10 /* numero massimo di missili */
#define M_GROUP 1
#define ALIEN_GROUP 2
#define MISSILE_GROUP 3
#define STUPID 2
#define NORMAL 14
#define BAD 13
#define BASTARD 4
int tipo
[4] = {STUPID
,NORMAL
,BAD
,BASTARD
};
#define PRODUCED 1
#define CONSUMED 0
#define Ix 16
#define Iy 16
char command_astro
; // comandi astronave
int AstroCmdState
;
extern int vga16color
[16];
struct argAlien
{
int orig_x
; // coordinate iniziali
int orig_y
;
int a_type
; // tipo di alieno
};
int mother_period
= 50000 ; /* task period */
int mother_wcet
= 10000 ; /* task wcet */
int Alien_period
= 40000 ; /* task period */
int Alien_wcet
= 1000 ; /* task wcet */
int Astro_period
= 40000 ; /* task period */
int Astro_wcet
= 2000 ; /* task wcet */
int missile_period
= 40000 ;
int missile_wcet
= 1000 ;
PID pid_Madre
, pid_Alien
, pid_Astro
, pid_Missile
, pid_Monitor
;
sem_t grx_mutex
, keyb_mutex
, astro_mutex
, alien_mutex
, score_mutex
;
sem_t missile_mutex
[MAX_MISSIL
];
/*--------------------------------------------------------------*/
// Risorse condivise
struct s_Astronave
{
int x
, y
, FlagCollisione
, FlagAstronave
;
} AstronavePosition
;
struct s_Missile
{
int x
, y
, FlagCollisione
;
} MissilePosition
[MAX_MISSIL
] ;
struct s_Score
{
int total
, type
[5] ;
} Score
;
int alieni_vivi
; // numero di alieni attualmente in vita
/*--------------------------------------------------------------*/
// Disegna l'astronave a partire dalla "poppa" x,y di colore c
void draw_Astronave
(int x
, int y
, int c
)
{
// Il disegno degli oggetti e' fatto sotto mutex per migliorare
// l'aspetto del sistema.
if (x
< 3) x
= 3;
if (y
< 8) y
= 8;
sem_wait
(&grx_mutex
);
grx_line
(x
, y
-8, x
, y
+8, vga16color
[c
]);
grx_line
(x
, y
-8, x
+5, y
-4, vga16color
[c
]);
grx_line
(x
, y
+8, x
+5, y
+4, vga16color
[c
]);
grx_line
(x
+5, y
-4, x
+10, y
-4, vga16color
[c
]);
grx_line
(x
+5, y
+4, x
+10, y
+4, vga16color
[c
]);
grx_line
(x
+10, y
-4, x
+15, y
, vga16color
[c
]);
grx_line
(x
+10, y
+4, x
+15, y
, vga16color
[c
]);
grx_line
(x
+15, y
, x
+17, y
, vga16color
[c
]);
grx_box
(x
-3, y
-6, x
, y
-2, vga16color
[c
]);
grx_box
(x
-3, y
+2, x
, y
+6, vga16color
[c
]);
grx_box
(x
+8, y
-3, x
+10, y
-1, vga16color
[c
]);
grx_box
(x
+8, y
+1, x
+10, y
+3, vga16color
[c
]);
grx_line
(x
+3, y
-4, x
+8, y
-1, vga16color
[c
]);
grx_line
(x
+3, y
+4, x
+8, y
+1, vga16color
[c
]);
sem_post
(&grx_mutex
);
}
// disegno del generico alieno "centro" x,y colore
void draw_Alieno
(int x
, int y
, int c
)
{
if (x
< DD
) x
= DD
;
if (y
< 0) y
= 0;
sem_wait
(&grx_mutex
);
grx_disc
(x
, y
, D
, vga16color
[c
]); // disco
grx_line
(x
-DD
, y
, x
+DD
, y
, vga16color
[c
]); // linea
sem_post
(&grx_mutex
);
}
// disegno della madre alieni
void draw_Mother
(int x
, int y
, int c
, int d
)
{
int i
;
if (x
< 10) x
= 10;
if (y
< 8) y
= 8;
sem_wait
(&grx_mutex
);
grx_box
(x
-10, y
-10, x
-5, y
+5, vga16color
[c
]); // box
grx_box
(x
+5, y
-10, x
+10, y
+5, vga16color
[c
]); // box
grx_disc
(x
, y
, 5, vga16color
[c
]); // disco
grx_line
(x
, y
+8, x
, y
-8, vga16color
[c
]); // linea
for (i
= 0; i
< d
; i
++) {
grx_disc
(x
+ (rand()%20)-10, y
+ (rand()%10)-5, d
/2, vga16color
[0]);
}
sem_post
(&grx_mutex
);
}
void draw_Missile
(int x
, int y
, int c
)
{
if (y
< 3) y
= 3;
sem_wait
(&grx_mutex
);
grx_box
(x
, y
-1, x
+6, y
+1, vga16color
[c
]);
grx_line
(x
+1, y
-3, x
+1, y
+3, vga16color
[c
]);
grx_line
(x
+1, y
+3, x
+3, y
, vga16color
[c
]);
grx_line
(x
+1, y
-3, x
+3, y
, vga16color
[c
]);
grx_disc
(x
+6, y
, 1, vga16color
[c
]);
sem_post
(&grx_mutex
);
}
/******************************************************************/
// ------------------------------------------------------------------->
// ALIENO
// ------------------------------------------------------------------->
TASK Alieno
(void *arg
)
{
int x
, y
;
int xa1
, ya1
;
int ox
, oy
;
int x1
= 0 ; /* variabile di appoggio */
int dx
, dy
, da
;
int teta
= 0 ;
int col
;
int outx
, outy
;
double r
;
int j
= 0 ;
int morto
= FALSE
;
int score
= 0 ;
int x_MissilePosition
;
int y_MissilePosition
;
int FlagCollisione
;
int x_AstronavePosition
;
int y_AstronavePosition
;
int xi
,yi
;
int FlagAstro
;
float Kp
= 0.01 ;
float Ki
= 0.005 ;
float Kd
= 0.00005 ;
float ex_k
, ey_k
, ex_sum
, ey_sum
, ex_km1
, ey_km1
;
ex_k
= ey_k
= ex_sum
= ey_sum
= ex_km1
= ey_km1
= 0 ;
struct argAlien
*arg_Alieno
= (struct argAlien
*)arg
;
// Punto di partenza dell'alieno
x
= ox
= arg_Alieno
->orig_x
;
y
= oy
= arg_Alieno
->orig_y
;
col
= arg_Alieno
->a_type
; /* tipo alieno */
// Ciclo infinito
while (1) {
// Lettura valori Astronave
sem_wait
(&astro_mutex
);
x_AstronavePosition
= AstronavePosition.
x ;
y_AstronavePosition
= AstronavePosition.
y ;
FlagAstro
= AstronavePosition.
FlagAstronave ;
sem_post
(&astro_mutex
);
switch (col
)
{
case STUPID
:
{ // Parametri di spostamento
dx
= -VEL
;
x
+= dx
;
if (x
<= XMIN
+ DD
) x
= XMAX
- DD
;
score
= 1 ;
}
break;
case NORMAL
:
{ // Spostamento oggetto
dx
= -VEL
;
dy
= VEL
* (rand()%3 -1) ;
x
+= dx
;
y
+= dy
;
outy
= (y
>= YMAX
) || (y
<= YMIN
);
if (outy
) y
= y
- dy
;
if (x
<= XMIN
+ DD
) x
= XMAX
- DD
;
score
= 2 ;
}
break;
case BAD
:
{
da
= rand()%(2*ANG
) - ANG
; /* da = [-ANG,ANG] */
teta
+= da
;
if (teta
> 360) teta
-= 360;
if (teta
< 0) teta
+= 360;
r
= (double)teta
* PI
/ 180.
;
dx
= (float)(-VEL
* cos(r
));
dy
= (float)(VEL
* sin(r
));
x
+= dx
;
y
+= dy
;
outx
= (x
>= XMAX
-DD
) || (x
<= XMIN
+DD
);
outy
= (y
>= YMAX
) || (y
<= YMIN
);
if (outy
) {
y
= y
- dy
;
teta
= -teta
;
if (teta
> 360) teta
-= 360;
if (teta
< 0) teta
+= 360;
r
= (double)teta
* PI
/ 180.
;
dy
= (float)(VEL
* sin(r
));
y
+= dy
;
}
if (outx
) {
x
= x
- dx
;
if (x
+dx
>= XMAX
-DD
) x1
= XMIN
+ DD
;
if (x
<= XMIN
+DD
) x1
= XMAX
- DD
;
x
= x1
+ dx
;
}
score
= 3 ;
}
break;
case BASTARD
: // alieno bastardo
{
xa1
= x_AstronavePosition
;
ya1
= y_AstronavePosition
;
if (!FlagAstro
) col
= BAD
;
// PID di inseguimento asse X
ex_k
=(float) (xa1
- x
);
if (ex_k
> 50) ex_k
= 50 ; // saturazione simmetrica dell'errore
if (ex_k
< -50) ex_k
= -50 ;
ex_sum
= ex_sum
+ ex_k
; // aggiornamento dell'errore integrale
dx
= (int) ( ex_k
* Kp
+ ex_sum
* Ki
+ (ex_k
- ex_km1
) *Kd
); // PID classico
ex_km1
= ex_k
; // salvataggio dell'errore vecchio x il termine derivativo
// PID di inseguimento asse Y
ey_k
= (float) (ya1
- y
);
if (ey_k
> 50) ey_k
= 50 ; // saturazione simmetrica dell'errore
if (ey_k
< -50) ey_k
= -50 ;
ey_sum
= ey_sum
+ ey_k
; // aggiornamento dell'errore integrale
dy
= (int) ( ey_k
* Kp
+ ey_sum
* Ki
+ (ey_k
-ey_km1
) *Kd
) ;
ey_km1
= ey_k
;
x
= x
+ dx
; // aggiornamento delle posizioni
y
= y
+ dy
;
outx
= (x
>= XMAX
-DD
) || (x
<= XMIN
+DD
); // flag di schianto
outy
= (y
>= YMAX
) || (y
<= YMIN
);
if (outy
)
{
y
= y
- dy
;
ey_sum
= 0;
}
if (outx
)
{
x
= x
- dx
;
if (x
+dx
>= XMAX
-DD
) x1
= XMIN
+ DD
;
if (x
<= XMIN
+DD
) x1
= XMAX
- DD
;
x
= x1
+ dx
;
}
score
= 4 ;
} // chiude il CASE BASTARD
break;
} //chiude lo switch
// Disegno l'alieno
draw_Alieno
(ox
, oy
, 0); /* cancello il vecchio alieno */
// Rilevatore di collisioni con l'Astronave
if (FlagAstro
)
{
// verifica della presenza dell'astronave nell'intorno
xi
= ( (abs(x
- x_AstronavePosition
)) < Ix
) ;
yi
= ( (abs(y
- y_AstronavePosition
)) < Iy
) ;
if (xi
&& yi
)
{
sem_wait
(&astro_mutex
) ;
AstronavePosition.
FlagCollisione = TRUE
;
sem_post
(&astro_mutex
) ;
break ; // morto x collisione astronave
}
}
// Controllo di collisione dell'ALIENO con i missili
for (j
= 0; j
< MAX_MISSIL
; j
++)
{
sem_wait
(&missile_mutex
[j
]);
x_MissilePosition
= MissilePosition
[j
].
x ;
y_MissilePosition
= MissilePosition
[j
].
y ;
FlagCollisione
= MissilePosition
[j
].
FlagCollisione;
sem_post
(&missile_mutex
[j
]);
if (FlagCollisione
== FALSE
) {
// verifica della presenza nell'intorno
xi
= ( (x
- x_MissilePosition
) > 0 && (x
- x_MissilePosition
) < Ix
) ;
yi
= ( (abs(y
- y_MissilePosition
)) < Iy
) ;
if (xi
&& yi
) {
sem_wait
(&missile_mutex
[j
]) ;
MissilePosition
[j
].
FlagCollisione = TRUE
;
sem_post
(&missile_mutex
[j
]) ;
morto
= TRUE
;
}
}
else break ; // esco dal ciclo for
}
if (morto
== TRUE
) break ; // esco dal ciclo while
draw_Alieno
(x
, y
, col
); /* disegno il nuovo alieno */
ox
= x
; oy
= y
;
task_endcycle
(); /* fine del ciclo */
} // chiusura del while
sem_wait
(&alien_mutex
) ;
alieni_vivi
-- ;
sem_post
(&alien_mutex
) ;
sem_wait
(&score_mutex
) ;
Score.
total+=score
;
Score.
type[score
-1]++;
sem_post
(&score_mutex
) ;
pid_Alien
= NIL
;
return 0 ; // morte dell'alieno
}
// ------------------------------------------------------------------->
// MADRE ALIENI
// ------------------------------------------------------------------->
TASK MadreAlieni
(void *arg
)
{
int v
= 0;
int a_v
;
int i
= 150;
int conta_spari
= 0;
int xi
, yi
;
int j
= 0;
int x_MissilePosition
;
int y_MissilePosition
;
int FlagCollisione
;
int x_AstronavePosition
;
int y_AstronavePosition
;
int FlagAstro
;
int x
, y
;
int ox
, oy
;
int dx
, dy
, da
;
int teta
= 0;
int outx
, outy
;
double r
;
struct argAlien arg_Alieno
;
struct argAlien
*p_Alien
;
p_Alien
= &arg_Alieno
;
HARD_TASK_MODEL Alien
;
// Punto di partenza della Madre alieni
x
= ox
= (rand()%XMIN
) + (rand()%(XMAX
-2*XMIN
)) + XMIN
;
y
= oy
= (rand()%YMIN
) + (rand()%(YMAX
-2*YMIN
)) + YMIN
;
// Ciclo infinito
while (1)
{
// Punto di partenza dell'alieno (dal culo della Madre alieni)
arg_Alieno.
orig_x = x
;
arg_Alieno.
orig_y = y
+ 15;
// Tipo alieno casuale
v
= rand()%4;
arg_Alieno.
a_type = tipo
[v
];
sem_wait
(&alien_mutex
) ;
a_v
= alieni_vivi
;
sem_post
(&alien_mutex
) ;
if ((a_v
< MAX_ALIEN
) && (i
== 0))
{
hard_task_default_model
(Alien
);
hard_task_def_ctrl_jet
(Alien
);
hard_task_def_arg
(Alien
, (void *)p_Alien
);
hard_task_def_wcet
(Alien
, Alien_wcet
);
hard_task_def_mit
(Alien
, Alien_period
);
hard_task_def_group
(Alien
, ALIEN_GROUP
);
hard_task_def_usemath
(Alien
);
pid_Alien
= task_create
("Alieno", Alieno
, &Alien
, NULL
);
if (pid_Alien
== NIL
)
{
grx_text
("pid_Alien == NIL", 200, 80 , vga16color
[4], 0);
return 0;
}
task_activate
(pid_Alien
);
i
= 40 ; // count down alla generarazione di un alieno
sem_wait
(&alien_mutex
) ;
alieni_vivi
++ ;
sem_post
(&alien_mutex
) ;
}
// Spostamento madre alieni
da
= rand()%(2*ANG
) - ANG
; /* da = [-ANG,ANG] */
teta
+= da
;
if (teta
> 360) teta
-= 360;
if (teta
< 0) teta
+= 360;
r
= (double)teta
* PI
/ 180.
;
dx
= (float)(2 * cos(r
));
dy
= (float)(2 * sin(r
));
x
+= dx
;
y
+= dy
;
outx
= (x
>= XMAX
- 20) || (x
<= XMIN
+ 20);
outy
= (y
>= YMAX
- 20) || (y
<= YMIN
+ 20);
if (outx
|| outy
)
{
x
= x
- dx
;
y
= y
- dy
;
if (outx
) teta
= 180 - teta
;
if (outy
) teta
= -teta
;
if (teta
> 360) teta
-= 360;
if (teta
< 0) teta
+= 360;
r
= (double)teta
* PI
/ 180.
;
dx
= (float)(2 * cos(r
));
dy
= (float)(2 * sin(r
));
x
+= dx
;
y
+= dy
;
}
draw_Mother
(ox
, oy
, 0, 0);
// Controllo di collisione della MADRE con i missili
for (j
= 0; j
< MAX_MISSIL
; j
++)
{
sem_wait
(&missile_mutex
[j
]);
x_MissilePosition
= MissilePosition
[j
].
x ;
y_MissilePosition
= MissilePosition
[j
].
y ;
FlagCollisione
= MissilePosition
[j
].
FlagCollisione;
sem_post
(&missile_mutex
[j
]);
if (FlagCollisione
== FALSE
)
{
// verifica della presenza nell'intorno
xi
= ( (x
- x_MissilePosition
) > 0 && (x
- x_MissilePosition
) < Ix
) ;
yi
= ( (abs(y
- y_MissilePosition
)) < Iy
) ;
if (xi
&& yi
)
{
sem_wait
(&missile_mutex
[j
]) ;
MissilePosition
[j
].
FlagCollisione = TRUE
;
sem_post
(&missile_mutex
[j
]) ;
conta_spari
++;
}
}
if (FlagCollisione
== TRUE
) break ; // esco dal ciclo for
}
if (conta_spari
== 5) {
sem_wait
(&score_mutex
) ;
Score.
total+=10 ;
Score.
type[4]++ ;
sem_post
(&score_mutex
) ;
pid_Madre
= NIL
;
return 0 ;
}
// Controllo di collisione della madre con l'astronave
// Lettura valori Astronave
sem_wait
(&astro_mutex
);
x_AstronavePosition
= AstronavePosition.
x ;
y_AstronavePosition
= AstronavePosition.
y ;
FlagAstro
= AstronavePosition.
FlagAstronave ;
sem_post
(&astro_mutex
);
if (FlagAstro
)
{
// verifica della presenza dell'astronave nell'intorno
xi
= ( (abs(x
- x_AstronavePosition
)) < Ix
) ;
yi
= ( (abs(y
- y_AstronavePosition
)) < Iy
) ;
if (xi
&& yi
)
{
sem_wait
(&astro_mutex
) ;
AstronavePosition.
FlagCollisione = TRUE
;
sem_post
(&astro_mutex
) ;
conta_spari
++ ;
}
}
if (conta_spari
== 5) {
sem_wait
(&score_mutex
) ;
Score.
total+=10 ;
Score.
type[4]++ ;
sem_post
(&score_mutex
) ;
pid_Madre
= NIL
;
return 0 ;
}
draw_Mother
(x
, y
, 15, conta_spari
);
ox
= x
; oy
= y
;
i
-- ;
task_endcycle
(); /* fine del ciclo while */
}
}
// ------------------------------------------------------------------->
// ASTRONAVE
// ------------------------------------------------------------------->
TASK Astronave
(void *arg
)
{
int x
, y
;
int ox
, oy
;
int dx
, dy
;
int col
;
int outy
;
char c
;
int FlagCollisione
;
x
= ox
= XMIN
+ 10;
y
= oy
= (YMIN
+YMAX
)/2;
col
= 15;
while (1) {
sem_wait
(&keyb_mutex
);
if (AstroCmdState
== PRODUCED
)
{
c
= command_astro
;
AstroCmdState
= CONSUMED
;
}
else
{
c
= 0 ;
}
sem_post
(&keyb_mutex
);
dx
= VEL
;
dy
= 0 ;
switch (c
)
{
case 'w' :
{
dy
= -VEL
;
}
break;
case 's' :
{
dy
= VEL
;
}
break;
}
x
+= dx
;
y
+= dy
;
outy
= (y
>= YMAX
-DD
) || (y
<= YMIN
+DD
);
if (outy
) y
= y
- dy
;
if (x
>= XMAX
- DD
) x
= XMIN
+ DD
;
sem_wait
(&astro_mutex
);
AstronavePosition.
x = x
;
AstronavePosition.
y = y
;
FlagCollisione
= AstronavePosition.
FlagCollisione ;
sem_post
(&astro_mutex
);
draw_Astronave
(ox
, oy
, 0);
if (FlagCollisione
)
break ;
draw_Astronave
(x
, y
, col
);
ox
= x
; oy
= y
;
task_endcycle
();
} // chiusura del while
sem_wait
(&astro_mutex
) ;
AstronavePosition.
FlagCollisione = FALSE
;
AstronavePosition.
FlagAstronave = FALSE
;
sem_post
(&astro_mutex
) ;
pid_Astro
= NIL
; // cleanup
return 0 ;
} // chiusura dell'astronave
// ------------------------------------------------------------------->
// MISSILE
// ------------------------------------------------------------------->
TASK Missile
(void *arg
)
{
int x
, y
;
int ox
, oy
;
int dx
;
int col
;
int xa1
;
int ya1
;
int FlagCollisione
;
int i
= (int)arg
;
// Punto di partenza del missile (la punta dell'astronave)
col
= 15; /* colore missile (bianco) */
sem_wait
(&astro_mutex
);
xa1
= AstronavePosition.
x ;
ya1
= AstronavePosition.
y ;
sem_post
(&astro_mutex
);
x
= ox
= xa1
+ 15;
y
= oy
= ya1
;
// Ciclo infinito
while (1) {
// Parametri di spostamento
dx
= 2*VEL
;
x
+= dx
;
sem_wait
(&missile_mutex
[i
]) ;
MissilePosition
[i
].
x = x
; // aggiorno posizione
MissilePosition
[i
].
y = y
;
FlagCollisione
= MissilePosition
[i
].
FlagCollisione ; // leggo collisione
sem_post
(&missile_mutex
[i
]) ;
// Esplosione del missile : a) per raggimento del bordo dx
// b) per collisione con un alieno
// Disegno l'alieno
draw_Missile
(ox
, oy
, 0); /* cancello il vecchio missile */
if ( (x
>= XMAX
- D
) || FlagCollisione
)
break ;
draw_Missile
(x
, y
, col
); /* disegno il nuovo missile */
ox
= x
; oy
= y
;
task_endcycle
(); /* fine del ciclo */
} // chiusura del while(1): quando il missile arriva alla fine della sua esistenza
// (bordo dx o collisione) temina cancellandosi.
//
sem_wait
(&missile_mutex
[i
]) ;
MissilePosition
[i
].
FlagCollisione = FALSE
;
MissilePosition
[i
].
x = 0 ;
MissilePosition
[i
].
y = 0 ; // Missile fuori dall'area di gioco
sem_post
(&missile_mutex
[i
]) ;
return 0 ;
}
// ------------------------------------------------------------------->
// M O N I T O R
// ------------------------------------------------------------------->
TASK Monitor
(void *arg
)
{
int stat1
,stat2
;
int giri
= 0 ;
TIME T_Astro_Sum
, T_Astro_Max
, T_Astro_Curr
;
TIME T_Madre_Sum
, T_Madre_Max
, T_Madre_Curr
;
char s
[400] ;
// Ciclo infinito
while (1)
{
stat1
= jet_getstat
(pid_Astro
, &T_Astro_Sum
, &T_Astro_Max
, &giri
, &T_Astro_Curr
);
if (stat1
==0)
{
sprintf(s
,"Astro->TimeMax = %d ", (int) T_Astro_Max
);
grx_text
(s
, XMIN
+350, YMENU
+20, vga16color
[4], vga16color
[0]);
}
else
{
sprintf(s
," ") ;
grx_text
(s
, XMIN
+350, YMENU
+20, vga16color
[4], vga16color
[0]) ;
}
//--------------------------------------------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
stat2
= jet_getstat
(pid_Madre
, &T_Madre_Sum
, &T_Madre_Max
, &giri
, &T_Madre_Curr
);
if (stat2
==0)
{
sprintf(s
,"Madre->TimeMax = %d ", (int) T_Madre_Max
);
grx_text
(s
, XMIN
+350, YMENU
+30, vga16color
[4], vga16color
[0]);
}
else
{
sprintf(s
," ") ;
grx_text
(s
, XMIN
+350, YMENU
+30, vga16color
[4], vga16color
[0]) ;
}
//-----------------------------------------------------------------------------
}
}
/****************************** MAIN ******************************/
int main
(int argc
, char **argv
)
{
HARD_TASK_MODEL m
,a
,ms
; // Task hard
NRT_TASK_MODEL monitor
; // Task non real time
char c
; /* character from keyboard */
int i
= 0 ; /* missile numero */
TIME seme
; /* used to init the random seed */
int miss
= 0;
int totalscore
= 0;
int typescore
[5] = {0,0,0,0,0};
char s
[30] ;
char s1
[30] ;
char s2
[30] ;
char s3
[30] ;
char s4
[30] ;
char s5
[30] ;
AstroCmdState
= CONSUMED
;
for (i
= 0; i
< MAX_MISSIL
; i
++) {
MissilePosition
[i
].
FlagCollisione = FALSE
;
}
AstronavePosition.
FlagCollisione = FALSE
;
AstronavePosition.
FlagAstronave = FALSE
;
pid_Madre
= NIL
;
pid_Astro
= NIL
;
Score.
total = 0 ;
/* */
nrt_task_default_model
(monitor
) ; // inizializza il task monitor
pid_Monitor
= task_create
("Monitor", Monitor
, &monitor
, NULL
);
if (pid_Monitor
== NIL
) {
sys_shutdown_message
("Could not create task <Monitor>\n");
sys_end
();
}
task_activate
(pid_Monitor
); // parte immediatamente
/* Semaphore Initialization */
sem_init
(&grx_mutex
,0,1);
sem_init
(&keyb_mutex
,0,1);
sem_init
(&astro_mutex
,0,1);
sem_init
(&alien_mutex
,0,1);
sem_init
(&score_mutex
,0,1);
for (i
= 0; i
< MAX_MISSIL
; i
++) {
sem_init
(&missile_mutex
[i
],0,1);
}
/* The scenario */
grx_line
(XMIN
-D
-1, YMIN
-D
-1, XMAX
+D
+1, YMIN
-D
-1, vga16color
[14]);
grx_line
(XMIN
-D
-1, YMAX
+D
+1, XMAX
+D
+1, YMAX
+D
+1, vga16color
[14]);
grx_text
("Simulation of Defender Game", XMIN
, YMENU
+10, vga16color
[1], 0);
grx_text
("a -> crea Astronave" , XMIN
, YMENU
+20, vga16color
[3], 0);
grx_text
("m -> crea Madre alieni" , XMIN
, YMENU
+30, vga16color
[13], 0);
grx_text
("space -> sparo" , XMIN
, YMENU
+40, vga16color
[14], 0);
grx_text
("ESC exit to DOS" , XMIN
, YMENU
+50, vga16color
[4], 0);
grx_text
("SCORE " , XMIN
, YMENU
+60, vga16color
[4], 0);
c
= keyb_getch
(BLOCK
);
/* randomize!!!! */
seme
= sys_gettime
(NULL
);
srand(seme
);
do {
//barra spazio lancia il task missile
if ((c
== ' ') && AstronavePosition.
FlagAstronave==TRUE
) {
for (i
= 0; i
< MAX_MISSIL
; i
++) {
sem_wait
(&missile_mutex
[i
]) ;
miss
= MissilePosition
[i
].
x ;
sem_post
(&missile_mutex
[i
]) ;
if (miss
== 0) {
hard_task_default_model
(ms
);
hard_task_def_ctrl_jet
(ms
);
hard_task_def_arg
(ms
, (void *)i
);
hard_task_def_wcet
(ms
, missile_wcet
);
hard_task_def_mit
(ms
, missile_period
);
hard_task_def_group
(ms
, MISSILE_GROUP
);
hard_task_def_usemath
(ms
);
pid_Missile
= task_create
("Missile", Missile
, &ms
, NULL
);
if (pid_Missile
== NIL
) {
sys_shutdown_message
("Could not create task <Missile>\n");
sys_end
();
}
task_activate
(pid_Missile
);
break ;
}
}
}
if ((c
== 'm') && (pid_Madre
== NIL
) ) {
hard_task_default_model
(m
);
hard_task_def_ctrl_jet
(m
);
hard_task_def_arg
(m
, (void *)i
);
hard_task_def_wcet
(m
, mother_wcet
);
hard_task_def_mit
(m
, mother_period
);
hard_task_def_group
(m
, M_GROUP
);
hard_task_def_usemath
(m
);
pid_Madre
= task_create
("MadreAlieni", MadreAlieni
, &m
, NULL
);
if (pid_Madre
== NIL
) {
sys_shutdown_message
("Could not create task <MadreAlieni>\n");
sys_end
();
}
task_activate
(pid_Madre
);
}
if ((c
== 'a') && !AstronavePosition.
FlagAstronave) { // creazione del task Astronave
hard_task_default_model
(a
);
hard_task_def_ctrl_jet
(a
);
hard_task_def_arg
(a
, (void *)i
);
hard_task_def_wcet
(a
, Astro_wcet
);
hard_task_def_mit
(a
, Astro_period
);
hard_task_def_usemath
(a
);
pid_Astro
= task_create
("Astronave", Astronave
, &a
, NULL
);
if (pid_Astro
== NIL
) {
sys_shutdown_message
("Could not create task <Astronave>\n");
sys_end
();
}
AstronavePosition.
FlagAstronave = TRUE
;
task_activate
(pid_Astro
);
}
sem_wait
(&score_mutex
);
totalscore
= Score.
total;
for (i
= 0; i
< 5; i
++) {
typescore
[i
] = Score.
type[i
];
}
sem_post
(&score_mutex
);
sprintf ( s
, "SCORE = %d", totalscore
);
sprintf ( s1
, "STUPID = %d", typescore
[0]);
sprintf ( s2
, "NORMAL = %d", typescore
[1]);
sprintf ( s3
, "BAD = %d", typescore
[2]);
sprintf ( s4
, "BASTARD = %d", typescore
[3]);
sprintf ( s5
, "MOTHER = %d", typescore
[4]);
grx_text
( s
, XMIN
, YMENU
+60, 4, 0);
grx_text
("Nemici uccisi", XMIN
+250, YMENU
+10, vga16color
[1], 0);
grx_text
(s1
, XMIN
+250, YMENU
+20, vga16color
[1], 0);
grx_text
(s2
, XMIN
+250, YMENU
+30, vga16color
[1], 0);
grx_text
(s3
, XMIN
+250, YMENU
+40, vga16color
[1], 0);
grx_text
(s4
, XMIN
+250, YMENU
+50, vga16color
[1], 0);
grx_text
(s5
, XMIN
+250, YMENU
+60, vga16color
[1], 0);
c
= keyb_getch
(BLOCK
);
sem_wait
(&keyb_mutex
);
command_astro
= c
;
AstroCmdState
= PRODUCED
;
sem_post
(&keyb_mutex
);
} while (c
!= ESC
);
sys_end
();
return 0;
}
/*--------------------------------------------------------------*/