0,0 → 1,1045 |
|
/*--------------------------------------------------------------*/ |
/* 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; |
} |
|
/*--------------------------------------------------------------*/ |