Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1665 → Rev 1666

/unsupported/trunk/defender/def_01.c
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;
}
 
/*--------------------------------------------------------------*/
/unsupported/trunk/defender/initfile.c
0,0 → 1,198
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Giacomo Guidi <giacomo@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
#include "kernel/kern.h"
#include "modules/intdrive.h"
#include "modules/edf.h"
#include "modules/hardcbs.h"
#include "modules/rr.h"
#include "modules/dummy.h"
 
#include "modules/sem.h"
#include "modules/hartport.h"
#include "modules/cabs.h"
 
#include <drivers/shark_linuxc26.h>
#include <drivers/shark_pci26.h>
#include <drivers/shark_input26.h>
#include <drivers/shark_keyb26.h>
#include <drivers/shark_fb26.h>
 
#define FRAME_BUFFER_DEVICE 0
 
/*+ sysyem tick in us +*/
#define TICK 0
 
/*+ RR tick in us +*/
#define RRTICK 2000
 
/*+ Interrupt Server +*/
#define INTDRIVE_Q 1000
#define INTDRIVE_T 10000
#define INTDRIVE_FLAG 0
 
void call_shutdown_task(void *arg);
int device_drivers_init();
int device_drivers_close();
void set_shutdown_task();
TASK shutdown_task_body(void *arg);
 
PID shutdown_task_PID = -1;
 
TIME __kernel_register_levels__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
INTDRIVE_register_level(INTDRIVE_Q,INTDRIVE_T,INTDRIVE_FLAG);
EDF_register_level(EDF_ENABLE_ALL);
HCBS_register_level(HCBS_ENABLE_ALL, 1);
RR_register_level(RRTICK, RR_MAIN_YES, mb);
dummy_register_level();
 
SEM_register_module();
CABS_register_module();
 
return TICK;
}
 
TASK __init__(void *arg)
{
struct multiboot_info *mb = (struct multiboot_info *)arg;
 
HARTPORT_init();
 
/* Create the shutdown task. It will be activated at RUNLEVEL
SHUTDOWN */
set_shutdown_task();
 
/* Init the drivers */
device_drivers_init();
 
/* Set the shutdown task activation */
sys_atrunlevel(call_shutdown_task, NULL, RUNLEVEL_SHUTDOWN);
 
__call_main__(mb);
 
return (void *)0;
}
 
void set_shutdown_task() {
 
/* WARNING: the shutdown task is a background thread. It cannot execute
if the system is overloaded */
NRT_TASK_MODEL nrt;
 
nrt_task_default_model(nrt);
nrt_task_def_system(nrt);
 
shutdown_task_PID = task_create("Shutdown Task",shutdown_task_body,&nrt,NULL);
if (shutdown_task_PID == NIL) {
sys_shutdown_message("Error: Cannot create shutdown task\n");
sys_end();
}
 
}
 
int device_drivers_init() {
 
int res;
KEYB_PARMS kparms = BASE_KEYB;
LINUXC26_register_module();
 
PCI26_init();
 
INPUT26_init();
 
keyb_def_ctrlC(kparms, NULL);
 
KEYB26_init(&kparms);
 
FB26_init();
res = FB26_open(FRAME_BUFFER_DEVICE);
if (res) {
cprintf("Error: Cannot open graphical mode\n");
KEYB26_close();
INPUT26_close();
sys_end();
}
FB26_use_grx(FRAME_BUFFER_DEVICE);
FB26_setmode(FRAME_BUFFER_DEVICE,"640x480-16");
return 0;
 
}
 
int device_drivers_close() {
FB26_close(FRAME_BUFFER_DEVICE);
KEYB26_close();
INPUT26_close();
return 0;
}
 
#define SHUTDOWN_TIMEOUT_SEC 3
 
void call_shutdown_task(void *arg)
{
struct timespec t;
 
sys_gettime(&t);
t.tv_sec += SHUTDOWN_TIMEOUT_SEC;
 
/* Emergency timeout to exit from RUNLEVEL_SHUTDOWN */
kern_event_post(&t,(void *)((void *)sys_abort_shutdown),(void *)0);
 
task_activate(shutdown_task_PID);
}
 
TASK shutdown_task_body(void *arg) {
 
device_drivers_close();
 
sys_shutdown_message("-- S.Ha.R.K. Closed --\n");
 
sys_abort_shutdown(0);
 
return NULL;
 
}
/unsupported/trunk/defender/makefile
0,0 → 1,17
#
#
#
 
ifndef BASE
BASE=../..
endif
include $(BASE)/config/config.mk
 
PROGS= def_01
 
include $(BASE)/config/example.mk
 
def_01:
make -f $(SUBMAKE) APP=def_01 INIT= OTHEROBJS="initfile.o" OTHERINCL= SHARKOPT="__LINUXC26__ __PCI__ __INPUT__ __FB__ __NET__"