Subversion Repositories shark

Rev

Go to most recent revision | Blame | Compare with Previous | 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 <semaphore.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);
  }
}