Go to most recent revision |
Blame |
Last modification |
View Log
| RSS feed
//*******************************tasks.c************************************
// task bodies
#include <drivers/glib.h>
#include <stdlib.h>
#include <string.h>
#include <kernel/func.h>
#include <drivers/glib.h>
#include <semaphor.h>
#include <math.h>
#include "include/simcity.h"
#include "include/states.h"
#include "include/draw.h"
#include "include/misc.h"
#include "include/car.h"
#include "include/proc.h"
#define rgb rgb16
/*extern starting_set starting_set_array[S_POINT];
extern short maxc; */
TASK killer
(void *arg
) {
short i
,j
=0;
DWORD col
[3];
char flag
=0;
col
[0]=red
;
col
[1]=green
;
col
[2]=white
;
while(1) {
if(maxc
>0) {
for(i
=0;i
<MAX_CAR
;i
++) {
sem_wait
(&(kill_mutex
[i
]));
if(car_data_array
[i
].
boom && car_data_array
[i
].
running) flag
=1;
else flag
=0;
sem_post
(&(kill_mutex
[i
]));
if(flag
) {
del
(i
);
killing
(i
);
}
}
}
j
=(j
+1)%3;
sem_wait
(&mutex
);
grx_text
("Killer active!",CAMX
,CAMY
+MAX_CAR
*46,col
[j
],black
);
sem_post
(&mutex
);
task_endcycle
();
}
}
TASK refresher
(void *arg
) {
int i
;
tl_data
*d
;
while(1) {
sem_wait
(&mutex
);
grx_putimage
(MAPX
,MAPY
,MAPX
+W
-1,MAPY
+H
-1,street
);
for(i
=0;i
<MAX_TL
;i
++) {
d
=&(tl_data_array
[i
]);
if((d
->vpos
=='g')) {
draw_tl
(d
->u.
x,d
->u.
y,g_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,g_sem
[D
]);
draw_tl
(d
->l.
x,d
->l.
y,r_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,r_sem
[R
]);
} else if(d
->vpos
=='y') {
draw_tl
(d
->u.
x,d
->u.
y,y_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,y_sem
[D
]);
draw_tl
(d
->l.
x,d
->l.
y,r_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,r_sem
[R
]);
} else if(d
->hpos
=='g') {
draw_tl
(d
->u.
x,d
->u.
y,r_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,r_sem
[D
]);
draw_tl
(d
->l.
x,d
->l.
y,g_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,g_sem
[R
]);
} else if(d
->hpos
=='y') {
draw_tl
(d
->u.
x,d
->u.
y,r_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,r_sem
[D
]);
draw_tl
(d
->l.
x,d
->l.
y,y_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,y_sem
[R
]);
}
}
sem_post
(&mutex
);
task_endcycle
();
}
}
TASK blink_arrow
(int number
) {
char ld
=0,prev
=0,dir
=0;
short c
;
BYTE
*arrow_img
;
c
=number
*46;
while(1) {
if(kill_flag
[number
]) {
return 0;
}
if(!car_data_array
[number
].
boom) {
dir
=car_data_array
[number
].
dir+1;
if(dir
==prev
) {
ld
=(ld
+1)%2;
if(ld
==1)
arrow_img
=arrow
[(int)dir
];
else
arrow_img
=arrow
[1];
sem_wait
(&mutex
);
grx_putimage
(CAMX
+80,CAMY
-1+c
,CAMX
+80+29,CAMY
-1+c
+29,arrow_img
);
sem_post
(&mutex
);
} else {
prev
=dir
;
ld
=0;
sem_wait
(&mutex
);
grx_putimage
(CAMX
+80,CAMY
-1+c
,CAMX
+80+29,CAMY
-1+c
+29,arrow
[(int)dir
]);
sem_post
(&mutex
);
}
}
task_endcycle
();
}
}
TASK gauge_c
(int number
) {
int c
;
float angle
,ro
;
int x
,y
;
char vel
[5];
c
=number
*46;
while(1) {
if(kill_flag
[number
]) {
return 0;
}
if(!car_data_array
[number
].
boom) {
angle
=180.0*car_data_array
[number
].
speed/MAX_SPEED
;
sprintf(vel
,"%.1f",car_data_array
[number
].
speed);
ro
=9.0;
y
=my_rint
(ro
*sine
[my_rint
(angle
)]);
x
=my_rint
(ro
*cosine
[my_rint
(angle
)]);
sem_wait
(&mutex
);
grx_putimage
(CAMX
,CAMY
+c
,CAMX
+29,CAMY
+29+c
,gauge_img
);
grx_line
(CAMX
+14,CAMY
-1+c
+25,CAMX
+14-x
,CAMY
-1+c
+25-y
,blue
);
grx_text
(vel
,CAMX
,CAMY
+c
+30,white
,black
);
sem_post
(&mutex
);
} else {
sem_wait
(&mutex
);
grx_putimage
(CAMX
,CAMY
+c
,CAMX
+29,CAMY
+29+c
,brk_gauge
);
sem_post
(&mutex
);
}
task_endcycle
();
}
}
TASK camera
(int number
) {
int c
;
c
=number
*46;
grx_rect
(CAMX
+40-1,CAMY
-1+c
,CAMX
+40+30,CAMY
+30+c
,green
);
while(1) {
if(kill_flag
[number
]) {
return 0;
}
sem_wait
(&mutex
);
grx_putimage
(CAMX
+40,CAMY
+c
,CAMX
+40+29,CAMY
+c
+29,vbuf
[number
]);
sem_post
(&mutex
);
task_endcycle
();
}
}
TASK traffic_light
(tl_data
*d
) {
char hpos
,vpos
,flag
;
flag
=0;
vpos
=d
->vpos
;
if(vpos
=='g') {
hpos
='r';
#ifdef GRAPH
sem_wait
(&mutex
);
draw_tl
(d
->l.
x,d
->l.
y,r_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,r_sem
[R
]);
draw_tl
(d
->u.
x,d
->u.
y,g_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,g_sem
[D
]);
sem_post
(&mutex
);
#endif
} else {
vpos
='r';
hpos
='g';
#ifdef GRAPH
sem_wait
(&mutex
);
draw_tl
(d
->l.
x,d
->l.
y,g_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,g_sem
[R
]);
draw_tl
(d
->u.
x,d
->u.
y,r_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,r_sem
[D
]);
sem_post
(&mutex
);
#endif
}
task_endcycle
();
while(1) {
if(vpos
=='g') {
vpos
='y';
flag
=1;
#ifdef GRAPH
sem_wait
(&mutex
);
draw_tl
(d
->u.
x,d
->u.
y,y_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,y_sem
[D
]);
sem_post
(&mutex
);
#endif
}
if((vpos
=='y')&&(!flag
)) {
vpos
='r';
hpos
='g';
flag
=1;
#ifdef GRAPH
sem_wait
(&mutex
);
draw_tl
(d
->u.
x,d
->u.
y,r_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,r_sem
[D
]);
draw_tl
(d
->l.
x,d
->l.
y,g_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,g_sem
[R
]);
sem_post
(&mutex
);
#endif
}
if((vpos
=='r')&&(!flag
)) {
if(hpos
=='g') {
hpos
='y';
flag
=1;
#ifdef GRAPH
sem_wait
(&mutex
);
draw_tl
(d
->l.
x,d
->l.
y,y_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,y_sem
[R
]);
sem_post
(&mutex
);
#endif
}
if((hpos
=='y')&&(!flag
)) {
hpos
='r';
vpos
='g';
#ifdef GRAPH
sem_wait
(&mutex
);
draw_tl
(d
->l.
x,d
->l.
y,r_sem
[L
]);
draw_tl
(d
->r.
x,d
->r.
y,r_sem
[R
]);
draw_tl
(d
->u.
x,d
->u.
y,g_sem
[U
]);
draw_tl
(d
->d.
x,d
->d.
y,g_sem
[D
]);
sem_post
(&mutex
);
#endif
}
}
flag
=0;
d
->vpos
=vpos
;
d
->hpos
=hpos
;
#ifndef GRAPH
sem_wait
(&mutex
);
cprintf
("semaforo %s: verticale:%c orizz.:%c\n",d
->tl_name
,vpos
,hpos
);
sem_post
(&mutex
);
#endif
task_endcycle
();
}
}
TASK car
(car_data
*cd
) {
char ob_type
=FREE
;
int start_point
,sat_angle
=0;
int tl
=0;
short stato
=NORM
,dir_flag
=0;
sem_wait
(&(kill_mutex
[cd
->number
]));
while(kill_flag
[cd
->number
]){
cd
->running
=0;
sem_post
(&(kill_mutex
[cd
->number
]));
return 0;
}
sem_post
(&(kill_mutex
[cd
->number
]));
while(1) {
sem_wait
(&(kill_mutex
[cd
->number
]));
while(kill_flag
[cd
->number
]){
cd
->running
=0;
sem_post
(&(kill_mutex
[cd
->number
]));
return 0;
}
sem_post
(&(kill_mutex
[cd
->number
]));
if(cd
->xp
>630||cd
->yp
>590||cd
->xp
<18||cd
->yp
<MAPY
+3) {
start_point
=rand()%S_POINT
;
if(start_point
==2)
start_point
++;
cd
->xpos
=cd
->xp
=starting_set_array
[start_point
].
xpos;
cd
->ypos
=cd
->yp
=starting_set_array
[start_point
].
ypos;
cd
->angle
=starting_set_array
[start_point
].
angles;
}
if (!cd
->boom
) {
// Control State Machine
if(stato
==NORM
) {
cd
->dir
=STRAIGHT
;
ob_type
=collision_sensor
(cd
);
ch_spd
(cd
,ob_type
);
if(cd
->dist_obs
<30 && ob_type
==STOP
) {
stato
=INC1
;
}
if(ob_type
==FREE
|| cd
->dist_obs
>=27 || cd
->speed
>=2.0) {
cd
->angle
=sensore
(cd
);
cd
->angle
=normalize
(cd
->angle
);
}
}
if(stato
==INC1
) {
tl
=find_tl
(cd
->angle
,cd
->xp
,cd
->yp
);
if(!dir_flag
)
cd
->dir
=rand()%3-1;
if(find_col
(cd
->angle
,tl
)=='g') {
switch(cd
->dir
) {
case STEER_RIGHT
:
stato
=DX1
;
break;
case STRAIGHT
:
case STEER_LEFT
:
stato
=STR1
;
break;
default:
stato
=DX1
;
}
} else {
cd
->speed
=0.0;
dir_flag
=1;
}
}
if(stato
==DX1
) {
dir_flag
=0;
cd
->speed
=4.0;
cd
->angle
=sensore
(cd
);
if(ob_type
!=STOP
)
stato
=NORM
;
else {
ob_type
=collision_sensor
(cd
);
if(ob_type
==CAR
)
ch_spd
(cd
,ob_type
);
}
}
if(stato
==STR1
) {
dir_flag
=0;
cd
->angle
=allinea
(cd
->angle
);
sensore
(cd
);
cd
->speed
=4.0;
ob_type
=collision_sensor
(cd
);
if(ob_type
==CAR
)
ch_spd
(cd
,ob_type
);
if(cd
->middle
==MAX_DIST
) {
if(cd
->dir
==STRAIGHT
)
stato
=STR2
;
else {
sat_angle
=cd
->angle
+90;
stato
=SX1
;
}
}
}
if(stato
==STR2
) {
cd
->speed
=4.0;
sensore
(cd
);
ob_type
=collision_sensor
(cd
);
if(ob_type
==CAR
)
ch_spd
(cd
,ob_type
);
if(abs(cd
->front
-cd
->rear
)<0.1 && ((cd
->middle
-NORM_DIST
)<7.0))
stato
=NORM
;
}
if(stato
==SX1
) {
cd
->speed
=4.0;
sensore
(cd
);
ob_type
=collision_sensor
(cd
);
if(ob_type
==CAR
)
ch_spd
(cd
,ob_type
);
else {
cd
->angle
+=7;
if(cd
->angle
>=sat_angle
) {
cd
->angle
=sat_angle
;
}
}
if(abs(cd
->front
-cd
->rear
)<0.1 && ((cd
->middle
-NORM_DIST
)<7.0))
stato
=NORM
;
}
}
if (cd
->dist_obs
<COLL_DIST
&& ob_type
==CAR
) {
cd
->boom
=1;
cd
->speed
=0.0;
}
sem_wait
(&mutex
);
grx_getimage
(cd
->xp
-15,cd
->yp
-15,cd
->xp
+14,cd
->yp
+14,vbuf
[cd
->number
]);
if (cd
->boom
==0) {
drawCar
(cd
->xp
,cd
->yp
,cd
->angle
,DRAW
);
}
if (cd
->boom
==1) {
drawSprites
(cd
->xp
,cd
->yp
,0,DRAW
);
}
sem_post
(&mutex
);
task_endcycle
();
sem_wait
(&mutex
);
if (cd
->boom
==0) {
grx_putimage
(cd
->xp
-15,cd
->yp
-15,cd
->xp
+14,cd
->yp
+14,vbuf
[cd
->number
]);
} else {
drawSprites
(cd
->xp
,cd
->yp
,0,CANCEL
);
}
sem_post
(&mutex
);
sem_wait
(&(kill_mutex
[cd
->number
]));
while(kill_flag
[cd
->number
]){
cd
->running
=0;
sem_post
(&(kill_mutex
[cd
->number
]));
return 0;
}
sem_post
(&(kill_mutex
[cd
->number
]));
cd
->xpos
+=cd
->speed
*cos(DEG_TO_RAD
(cd
->angle
));
cd
->ypos
-=cd
->speed
*sin(DEG_TO_RAD
(cd
->angle
));
cd
->xp
=my_rint
(cd
->xpos
);
cd
->yp
=my_rint
(cd
->ypos
);
}
}