Subversion Repositories shark

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed


/*--------------------------------------------------------------*/
/*              SIMULATION OF THE HUNGRY SNAKE'S GAME           */

/* AUTHOR : SUNDARA PRABU THESINGU RAJAN

   EMAIL  : Y2KPRABU@YAHOO.COM

   DEVELOPED SYSTEM : AMD DURON 1.1GHz 128MB RAM SVGA MONITOR
   OS     : SHARK
   GCC    : 3.1 (DJGPP VERSION)

   UNDER THE GUIDANCE OF PROFESSORS:
    Mr. Giorgio Buttazzo    <giorgio@sssup.it>
    Mr. Giuseppe Lipari     <lipari@sssup.it>
    Mr. Paolo Gai           <pj@gandalf.sssup.it>


/*--------------------------------------------------------------*/

#include <kernel/kern.h>
#include <drivers/glib.h>
#include <modules/pc.h>
#include <drivers/keyb.h>

#include <semaphore.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>

#define XMIN     40
#define XMAX     600
#define YMIN     100
#define YMAX     450
#define D        3              /* SNAKE RADIUS                 */
#define ESC      27             /* ASCII code of ESCAPE key     */
#define SNGROUP 1
#define FRUIT_WCET 200     //WCET FOR FRUIT
#define FRUIT_T    4000000 //PERIOD FOR FRUIT
#define SN_WCET    4000    //WCET FOR SNAKE
#define SN_T       40000   //PERIOD FOR SNAKE
#define FGROUP 2

PID     pid1,pid2,pid3;
sem_t   mutex;
int dx1,dy1,dx2,dy2; // WHICH DEF NEXT POS OF SNAKE
int scr[XMAX][YMAX]={{0},{0}}; // init all to zero
void assockey();
void endgame();
void pk1(KEY_EVT *KP);

        // FUNCTION WHICH DRAWS SNAKES
void    draw_sn(int x, int y, int c)
{
        sem_wait(&mutex);
        //grx_rect(x, y,x+5,y+5,c);//x+dx1*D,y+dy1*D, c);
    grx_circle(x,y,D,c);
        sem_post(&mutex);
}

        // FRUIT TASK/THREAD WHICH RANDOMLY APPEARS AND DISAPPEARS
TASK FRUIT(void *arg)
{

  int xrnd = rand()%(XMAX-10),ox=5;
  int yrnd = rand()%(YMAX-10),oy=5;
  int colrnd = rand()%15;
  time_t seed;
  seed=sys_gettime(0);
  srand(seed); // RANDOMIZING POSITION OF  FRUIT

  while(1)
   {
    xrnd = rand()%(XMAX-10);
    yrnd = rand()%(YMAX-10);
    if ((xrnd > XMIN) &&(yrnd > YMIN)&& (scr[xrnd][yrnd]!=1))
    {
     sem_wait(&mutex);
     grx_disc(ox,oy,4,80);      // ERASE OLD FRUIT
     grx_disc(xrnd,yrnd,4,colrnd);     //PRINT NEW FRUIT
     sem_post(&mutex);
     colrnd = rand()%80;
     ox=xrnd; // STORE OLD X AND OLD Y POS TO ERASE OLD FRUIT
     oy=yrnd;

    }
    task_endcycle();
   }
  return(0);
}

        // KEY HANDLER FOR PLR1
void kp1(KEY_EVT *keypr)
{
  switch(keypr->ascii)
  { //grx_text(keypr->ascii, XMIN, YMENU+400, 1, 0);
    case 's':
     //  grx_text("S Up    pressed", XMIN, YMENU+450, 14, 0);
       dx1=0;
       dy1=-1;

       break;
    case 'x':
     //  grx_text("X Down  pressed", XMIN, YMENU+450, 14, 0);
       dx1=0;
       dy1=1;

       break;
    case 'c':
     //  grx_text("C Right pressed", XMIN, YMENU+450, 14, 0);
       dx1=1;
       dy1=0;
       break;
    case 'z':
     //  grx_text("Z Left  pressed", XMIN, YMENU+450, 14, 0);
       dx1=-1;
       dy1=0;
       break;
  }
}

   //        KEYHANDLER FOR PLR 2
void kp2(KEY_EVT *keypr)
{ switch(keypr->ascii)
  {
    case 'k':
     //  grx_text("k Up   Pressed", 450, YMENU+450, 14, 0);
       dx2=0;
       dy2=-1;
       break;
    case 44:
     //  grx_text(", Down Pressed",450, YMENU+450, 14, 0);
       dx2=0;
       dy2=1;
       break;
    case 46:
     //  grx_text(". Right Pressed",450, YMENU+450, 14, 0);
       dx2=1;
       dy2=0;
       break;
    case 'm':
     //  grx_text("m Left  Pressed", 450, YMENU+450, 14, 0);
       dx2=-1;
       dy2=0;
       break;
  }
}
     // ASSOCIATE KEYS WITH PLAYER1
void assockey1()
{
    KEY_EVT k;
    k.flag = 0;
    k.scan = KEY_S  ;// UP
    k.ascii = 's';
    keyb_hook(k,kp1);

    k.flag = 0;      // DOWN
    k.scan = KEY_X;
    k.ascii = 'x';
    keyb_hook(k,kp1);
    k.flag = 0;
    k.scan = KEY_Z;  //LEFT
    k.ascii = 'z';
    keyb_hook(k,kp1);
    k.flag = 0;
    k.scan = KEY_C;  //RIGHT
    k.ascii = 'c';
    keyb_hook(k,kp1);
}
     // ASSOCIATE KEYS WITH PLAYER2
void assockey2()
{
    KEY_EVT k;
    k.flag =0;
    k.scan =KEY_K;//UP
    k.ascii=53;
    keyb_hook(k,kp2);

    k.flag = 0;
    k.scan = 51;//DOWN
    k.ascii = ',';
    keyb_hook(k,kp2);
    k.flag = 0;
    k.scan = KEY_M;//LEFT
    k.ascii = 'm';
    keyb_hook(k,kp2);
    k.flag = 0;     //RIGHT
    k.scan = 52;
    k.ascii = '.';
    keyb_hook(k,kp2);
}
    // TASK SNAKE 1 .. PLAYER 1

TASK   sn1(void *arg)
{
    int    x1, y1;
    long score1 =0;
    int    col,outx=0,outy=0;
    //int    i = (int)arg;
    int over1=0;
    char  strk[30];

        x1 =  XMIN+20;
        y1 =  (YMIN+YMAX)/2;
    dx1=1;
    dy1=0;
    assockey1(); //       CALL FN to ASSOCIATE KEYS PLR1
    col = 12;             /* RED COLOUR SNAKE           */

        while (1)
        {
                x1 += dx1;
                y1 += dy1;
                   //CHECK IF BEYOND BORDER
                outx = (x1 >= XMAX-D) || (x1 <= XMIN+D);
                outy = (y1 >= YMAX-D) || (y1 <= YMIN+D);

                  //CHECK IF STONE OR ANOTHER SNAKE
        if ((scr[x1+D*dx1][y1+D*dy1]) ==0)
         {      scr[x1][y1]=1; // bcos the snake radius is 3;
               scr[x1+dy1][y1+dx1] =1;
               scr[x1-dy1][y1-dx1] =1;
         }
        else         //STONE OR SNAKE HIT
         { over1=1;  //SET ERR FLAG=1
           sprintf(strk,"PLR 1 HIT :PID = %d",pid1);
         }

        if (outx || outy) // WALL CRASH
         {
                        sprintf(strk,"PLR 1 WALL CRASH %d ",pid1);
            over1=1;
                }
         if (over1 ==1) //CHECK IF HIT OR CRASH DECLARE OTHER AS WINNER
           {grx_text(strk, 120,70,0,69);
           grx_text(" WINNER !!! ",340+80,70,0,67);
           endgame();
           break;
           }
        score1=score1+10;
          // CHECK IF BACKGROUND COLOUR OR FRUIT
        if (grx_getpixel(x1+D*dx1,y1+D*dy1)!= 80)
          score1+=100;          // BONUS = 1000
        sprintf(strk,"%ld",score1);
        grx_text(strk,120,60,0,15);//PRINT SCORE
                draw_sn(x1, y1, col);
        task_endcycle();

        }
  return(0);
}

    //    TASK SNAKE2 -- PLAYER 2
TASK   sn2(void *arg)
{
    int     x2, y2,col;
    long int   score2=0;
    int     outx=0, outy=0;
    //int    i = (int)arg;
    int over2=0;
    char strk[30];

    assockey2();
        x2 = XMAX-20;
        y2 = (YMIN+YMAX)/2;
    dx2=-1;
    dy2=0;
        col =10;         /* BLUE colore SNAKE2   */

        while (1)
        {
                x2 += dx2; //SET NEW POS
                y2 += dy2;
           //      //CHECK IF BEYOND BORDER
                outx = (x2 >= XMAX-D) || (x2 <= XMIN+D);
                outy = (y2 >= YMAX-D) || (y2 <= YMIN+D);
           //CHECK IF STONE OR ANOTHER SNAKE
         if ((scr[x2+D*dx2][y2+D*dy2]) ==0)
         {      scr[x2][y2]=1; // bcos the snake radius is 3;
               scr[x2+dy2][y2+dx2] =1;
               scr[x2-dy2][y2-dx2] =1;
         }
        else    //STONE OR SNAKE HIT
         {
            over2=1;    //SET ERR FLAG
            sprintf(strk," HIT :PID = %d",pid2);
            grx_text(strk,340+80,70,0,67);

                 }
                if (outx || outy) // WALL CRASH
         {
            over2=1;
            sprintf(strk," WALL CRASH PID= %d",pid2);

                 }
        if(over2==1)      //DECLARE OTHER AS WINNER
         { grx_text(strk,340+80,70,0,67);
           grx_text(" WINNER !!! ",120,70,0,69);
           endgame();
           break;
         }
        score2=score2+10;
        if (grx_getpixel(x2+D*dx2,y2+D*dy2)!= 80)
          score2+=100;

        sprintf(strk,"%ld",score2);
        grx_text(strk,340+80,60,0,15);//
        draw_sn(x2, y2, col);
        sprintf(strk,"%d",scr[x2][y2]);
        task_endcycle();
      }
   return(0);
}
/****************************************************************/

 void endgame()
 {  group_kill(SNGROUP);// KILL ALL SNAKES AND FRUIT TASK
    grx_clear(1);
    grx_text("THANK U FOR PLAYING SNAKES GAME ",200,250,14,1);
    grx_text("PRESS ESC KEY ",250,300,14,1);
 }

                /* FN CALLED WHEN SYSTEM EXITS  */
 void byebye(void *arg)
 {
    grx_close();
    kern_printf("\nCiao ! Bye Bye!\n");
 }
       // FN TO DRAW STONES
 void stone(int xmin,int ymin,int xmax,int ymax,int col)
 {  int i,j;
    grx_box(xmin,ymin,xmax,ymax,col);
    grx_rect(xmin,ymin,xmax,ymax,0);
    for(i=xmin;i<=xmax;i++)
     for(j=ymin;j<=ymax;j++)
      {scr[i][j]=1; // col
      }
 }

void setplarea()
{   int i,j;
    char col[2];
    // SET SCR ARRAY WHICH REPRESENTS BG TO ZERO ALL
    for(i=0;i<=XMAX-1;i++)
     for(j=0;j<=YMAX-1;j++)
         scr[i][j]=0;

     /* GRAPHICS FOR THE  PLAY AREA */
    grx_box(0,0,640,480,15); // FULL SCREEN
    grx_rect(XMIN-D, YMIN-1, XMAX+1, YMAX+1,1); // BOUNDARY
    grx_box(XMIN,YMIN,XMAX,YMAX,80);           //PLAY AREA

    // DRAW STONES

       stone(120,150,140,160,4);
       stone(220,150,230,170,4);
       stone(340,150,360,160,4);
       stone(500,150,510,170,4);

       stone(100,240,110,260,4);
       stone(300,250,320,260,4);
       stone(550,250,560,270,4);
       stone(350,270,370,280,4);

       stone(50, 410,70,420,4);
       stone(250,400,260,420,4);
       stone(370,400,390,410,4);
       stone(490,400,500,420,4);
       stone(150,400,170,410,4);

       stone(60,300,80,310,4);
       stone(530,200,550,210,4);
       stone(510,300,520,320,4);


             // CREATE BACKGROUND
    grx_text("  SIMULATION OF SNAKES GAME  ", XMIN+200,10,9,15);
    grx_text(" 1 . SPACE : START GAME SnakeS" , XMIN, 20,4,15);
    grx_text(" 2 . ESC   : Exit to DOS    ", 380, 20,2,15);
              // PLAYER 1 STATISTICS
    grx_box(XMIN,50,320,80,69);
    grx_rect(XMIN-2,50-2,320,80,0);
    grx_text(" PLAYER 1     ", XMIN, 50, 0, 69);
    grx_text(" SCORE   : "   , XMIN, 60, 0, 69);
    grx_text(" STATUS  : "   , XMIN, 70, 0, 69);

    grx_text("UP    - s",80,460, 0, 69);
    grx_text("DOWN  - x",80,470, 0, 69);
    grx_text("LEFT  - z",200,460, 0, 69);
    grx_text("RIGHT - c",200,470, 0, 69);

              // PLAYER 2 STATISTICS
    grx_box(340,50,600,80,67);
    grx_rect(340-2,50-2,600,80,0);
    grx_text(" PLAYER 2     " , 340, 50, 1, 67);
    grx_text(" SCORE   : "     , 340, 60, 1, 67);
    grx_text(" STATUS  : "     , 340, 70, 1, 67);
    grx_text("UP    - k",380,460, 1, 67);
    grx_text("DOWN  - ,",380,470, 1, 67);
    grx_text("LEFT  - m",500,460, 1, 67);
    grx_text("RIGHT - .",500,470, 1, 67);

             // DESIGN
    for(i=0,j=0;i<=60;i++)
    {
        j=j+10;
        sprintf(col,"C%d",i);
        grx_text(col,j,30,i, 0);
    }
}

void initscr()
{   int i,j,col;
    grx_clear(15);
    for(i=0,col=0;i<640;i=i+10)
      for(j=0;j<480;j=j+10)
    {
      //  sprintf(col,"C%d",col++%255);
        grx_text("",i,j,(col++)%255, 0);
    }

    grx_text("THE HUNGRY SNAKE  ",250,100,9,15);
    sleep(1);
          // DISPLAY MODE SELECTION MENU SCREEN

    grx_clear(8);
    grx_text("THE HUNGRY SNAKE  ",250,100,14,8);
    grx_text("SELECT THE MODE OF PLAY ",200,150,10,8);
    grx_text("1. SINGLE PLAYER MODE ",200,200,12,8);
    grx_text("2. DOUBLE PLAYER MODE ",200,250,80,8);
    grx_text("3. EXIT ",200,300,80,8);

}

int main(int argc, char **argv)
{

    HARD_TASK_MODEL m;
    SOFT_TASK_MODEL f;
    char c;
    int  ntask = 1;        /* NO OF TASKS      */

    hard_task_default_model(m);
    hard_task_def_ctrl_jet (m);
    hard_task_def_arg      (m, (void *)ntask);
    hard_task_def_wcet     (m, SN_WCET);
    hard_task_def_mit      (m, SN_T);
    hard_task_def_group    (m, SNGROUP);
    hard_task_def_unjoinable(m);
    hard_task_def_usemath  (m);//fl pt arith
                  // SOFT TASK FOR FRUIT/FRUIT
    soft_task_default_model(f);
    soft_task_def_level(f,1);
    soft_task_def_arg(f, (void *)4);
    soft_task_def_group(f,SNGROUP);
    soft_task_def_met(f,FRUIT_WCET);
    soft_task_def_period(f,FRUIT_T);
    soft_task_def_usemath(f);
    soft_task_def_unjoinable(f);

    set_exchandler_grx();       /*SET EXCEPN HANDLER */

    /* Set the closing function */
    sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);

    /* graphic card Initialization */

    if (grx_init() < 1)
      {
       cprintf("GRAPHICS INIT ERROR ,ABORTING ");
       sys_abort(1);
      }
    grx_cardinfo(); // TO SEE THE V CARD DETAILS IN TEXT MODE
    grx_modeinfo();

      //sleep(2);
    
    if (grx_open(640, 480, 8) < 0)
     {
        kern_printf("GRX Err CANT OPEN IN REQ MODE\n");
        sys_abort(1);
     }
    kern_printf("Video card ok!\n");

REP:initscr(); // call FN TO DISPLAY MENU

    c= keyb_getchar();  // CHOOSE GAME MODE

    switch(c)
      {
      case '1':
           grx_text("1. SINGLE PLAYER MODE ",200,350,8,0);
           pid1 = task_create("SNAKE1", sn1, &m, NULL); //PLR1
           break;

      case '2':
           pid1 = task_create("SNAKE1", sn1, &m, NULL); //PLR1
           pid2 = task_create("SNAKE2",sn2,&m,NULL);  //PLR2
           break;
      case '3':
           sys_end();
           return 0;
      case ESC:
           grx_clear(0);
           grx_close();
           sys_end();
           return 0;
      default :
           grx_text("WRONG KEY PRESSED ",200,400,69,7);
            goto REP;

      }

     setplarea(); // GRAPHICS FOR PLAY AREA

     /* The program waits a space to start THE SNAKE GAME */
    c = keyb_getch(NON_BLOCK);
    do{
     if ((c == ' '))// && (ntask < 2)) // 2 PLAYERS
            {
                    //CHECK FOR CREATION ERRORS
        if (pid1 == NIL)
         {
              grx_close();
              perror("CANT CREATE PID1 PRESS ESC");
              sys_abort(1);
             }
        if (pid2 == NIL)
         {
              grx_close();
              perror("CANT CREATE PID2 PRESS ESC");
              //sys_abort(1);// I HAVE COMMENTED THIS BCOS IT DOESNT SHOW MSG
                         // IF PID = NIL
             }
        if (pid3 == NIL)
         {
              grx_close();
              perror("CANT CREATE PID3 PRESS ESC ");
              //sys_abort(1);
             }           //ACTIVATE TASKS ;
        //CREATE TASK
        pid3 = task_create("FRUIT",FRUIT,&f,NULL); //FRUIT TASK
        group_activate(SNGROUP);
            ntask++;
        }
     c=keyb_getch(NON_BLOCK);
    } while (c != ESC); //EXIT If ESC PRESSED
    goto REP;
    sys_end();
    return 0;
}

/*------------------END--OVER-----------------------------------*/