Subversion Repositories shark

Rev

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

//////////////////////////////////////////////////////////////////
// This file is submitted to Prof. Buttazzo, Prof. G.Lipari and //
// Prof. P. Gai, as project submission on RTOS SHaRK programming//
//                                                              //
// Description: SHIP - BULLETS - ASTEROIDS simulation           //
// This file creates bullets and asteroids tasks. It Creates a  //
// ship which is controlled by keyboard. The ship fires bullets //
// and hence tries to destroy the asteroids. When the bullets   //
// hits asteroids, they are destroyed. Moreover, when an        //
// asteroid hits the ship, the game ends.                       //
//                                                              //
// Future work: More work has to be done to enhance this game to//
// be user friendly game.                                       //
//////////////////////////////////////////////////////////////////
/*
Project group members:
1. Kailash Kumar Sharma
2. RamaKrishnan  S.
3. Rekh Rao
*/
/**
 ------------
 Created on :2 nd June 2002
 File Name  :Asteroids.C
 Modified on:<none>
 Last update:<none>
 ------------
**/

/*
 */

/*--------------------------------------------------------------*/
/*              SIMULATION OF BULLETS                           */
/*--------------------------------------------------------------*/

#include <kernel/kern.h>
#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <semaphore.h>
#include <stdlib.h>
#include <math.h>

/****************Beginning of Global Variable definition**************/
#define YMENU    10             /* menu level                   */
#define XMIN     50
#define XMAX     600
#define YMIN     100
#define YMAX     450
#define VEL      5              /* velocity of bullet           */
#define AD        4              /* The diameter of asteroid    */
#define BD        2              /* The diameter of bullet      */
#define ESC      27             /* ASCII code of ESCAPE key     */
#define MAX_B    35             /* max number of bullets        */
#define MAX_A    35             /* max number of asteroids      */
#define BULLETGROUP 1
#define ASTEROIDGROUP 1

double  tick = 1.0;                       /* system tick = 1 ms           */
int     bullet_period = 40000;            /* bullet task period           */
int     bullet_wcet = 1000;               /* bullet task wcet             */
int     asteroid_period = 20000;          /* asteroid task period         */
int     asteroid_wcet = 1000;             /* asteroid task wcet           */
int     asteroid_gp_period = 400000;      /* asteroid create task period  */
int     asteroid_gp_wcet = 1000;          /* asteroid create task wcet    */
int     sx1 = 52;         /* X1 coordinate of ship  */
int     sx2 = 72;         /* X2 coordinate of ship  */
int     sy1 = 300;        /* Y1 coordinate of ship  */
int     sy2 = 315;        /* Y2 coordinate of ship  */
int     a_num = 0;        /* Number of active asteroids */
int     b_num = 0;        /* Number of active bullets   */
int     astr_speed = 100000;        /* Delay counter for Asteroid        */
int     bult_speed = 10000;         /* Delay counter for Bullet          */
int     astr_rate  = 100000;        /* Delay counter for Asteroid create */
int     bullet_col = 15;            /* Bullet colour  */
int     ship_col = 12;              /* Ship   colour  */
int     points = 0;
int     game_finish = 0;
PID     pid, apid, mapid;           /* Task IDs       */
sem_t   mutex;
char    retbuf[20];



/*-----------------End of Global Variable definition------------------*/
/*
// This function draws bullet
*/
void    draw_bullet(int x, int y, int c)
{
        sem_wait(&mutex);
        grx_disc(x, y, BD, c);
        sem_post(&mutex);
}

/*
// This function draws asteroid
*/
void    draw_asteroid(int x, int y, int c)
{
        sem_wait(&mutex);
        grx_disc(x, y, AD, c);
        sem_post(&mutex);
}

/*
// This function draws ship
*/
void    draw_ship(int x1, int y1, int x2, int y2, int c)
{
        sem_wait(&mutex);
        grx_box(x1, y1, x2, y2, c);
        sem_post(&mutex);
}

/*
// This is an asteroid task. This task is responsible for controlling
// the game. This task checks if it encouters a bullet or ship, while
// travelling. If the encoutered object is a bullet, the task gets
// destroyed. If the encoutered object is ship, the game terminates!!!
*/
TASK    asteroid(void *arg)
{
int     x=0, y=0;
int     ox=0, oy=0;
int     col=0;
int     outx=0;
int     i = (int)arg;
int     j;
int     scan_col1, scan_col2, scan_col3;
int     scan_col4, scan_col5, scan_col6;

        x = ox = (XMAX-10);  /* X coordinate of the asteroid   */
        y = oy = (YMIN+10+(rand()%(YMAX-YMIN-10)));          /*  y = [YMIN,YMAX] */
        col = 2 + i;           /* color of asteroid           */

        while (1) {
                x -= 5;
                outx = (x<=XMIN);
                // **** START for scanning for bullets and ship ****
                scan_col1 = grx_getpixel(x-4, y-4);
                scan_col2 = grx_getpixel(x-4, y+4);
                scan_col3 = grx_getpixel(x-7, y);
                scan_col4 = grx_getpixel(x-4, y-4);
                scan_col5 = grx_getpixel(x-4, y+4);
                scan_col6 = grx_getpixel(x-7, y);
                // **** END for scanning for bullets and ship ****

                if((scan_col1 == ship_col) || (scan_col2 == ship_col) ||
                              (scan_col3 == ship_col)){
                              game_finish = 1;
                }
                else if((outx) || (game_finish == 1)){
                  draw_asteroid(ox, oy, 0);
                  a_num--;
                  break;
                }
                else if((scan_col4 == bullet_col) ||
                             (scan_col5 == bullet_col) ||
                             (scan_col6 == bullet_col)) {
                  draw_asteroid(ox, oy, 0);
                  a_num--;
                  points++;
                  break;
                }
                else {
                draw_asteroid(ox, oy, 0);
                draw_asteroid(x, y, col);
                ox = x; oy = y;
                }
                for(j=0; j <= astr_speed; j++);
                task_endcycle();
        }
}
/*
// Function to convert integer to string
*/
char *itos(int n){
sprintf(retbuf," %d ", n);
return(retbuf);
}

/*
// This task is created by main and runs in parallel with it. It
// is responsible for creating asteroids at random location periodically.
*/
TASK    a_gp(void *arg)
{
int     j;
HARD_TASK_MODEL n;

        while (1) {
            if (game_finish == 1) break;
            else if (a_num < MAX_A) {
                grx_text("POINTS", XMAX-150, YMENU+50, 13, 0);
                grx_text(itos(points), XMAX-145, YMENU+65, 14, 0);
                hard_task_default_model(n);
                hard_task_def_ctrl_jet (n);
                hard_task_def_arg      (n, (void *)a_num);
                hard_task_def_wcet     (n, asteroid_wcet);
                hard_task_def_mit      (n, asteroid_period);
                hard_task_def_group    (n, ASTEROIDGROUP);
                hard_task_def_usemath  (n);
                mapid = task_create("asteroid", asteroid, &n, NULL);
                if (mapid == NIL) {
                   grx_close();
                   perror("Could not create task <asteroid>");
                   sys_abort(1);
                }
            task_activate(mapid);
            a_num++;
            for (j=0; j <= astr_rate; j++);
            }
            task_endcycle();
        }
}

/*
// This is a bullet task. It traverses it originates from the ship and
// and traverses its path from left to right. It hits the asteroids and
// destroys them.
*/
TASK    bullet(void *arg)
{
int     x=0, y=0;
int     ox=0, oy=0;
int     outx=0;
int     j;

        x = ox = (sx2+(2*BD));  /* Fire bullet from sx2 coordinate of ship */
        y = oy = (sy2-8);       /* Fire bullet from sy2 coordinate of ship */
//        col = 2 + i;            /* color of bullet*/

        while (1) {
                x += 5;
                outx = (x>=XMAX);
                if((outx) || (game_finish == 1)) {
                  draw_bullet(ox, oy, 0);
                  b_num--;
                  break;
                }
                else {
                draw_bullet(ox, oy, 0);
                draw_bullet(x, y, bullet_col);
                ox = x; oy = y;
                }
                for(j=0; j <= bult_speed; j++);
                task_endcycle();
        }
}

/*
// This function is called when the system exits
*/
void byebye(void *arg)
{
  grx_close();
  kern_printf("Your ship is hit!!!Bye Bye!\n");
}

/****************************** MAIN ******************************/
/*
// MAIN is responsible for creating ship. It controls the motion of
// ship and fires bullets (creates bullet task) to destroy asteroids.
*/
int main(int argc, char **argv)
{
    HARD_TASK_MODEL m;
    HARD_TASK_MODEL a;
    char c;             /* character from keyboard      */
    TIME seme;          /* used to init the random seed */

    /* Set the exception handler */
    set_exchandler_grx();

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

    /* graphic card Initialization */
    if (grx_init() < 1) {
       sys_abort(1);
    }
    
    if (grx_open(640, 480, 8) < 0) {
        kern_printf("GRX Err\n");
        sys_abort(1);
    }
    kern_printf("Video card ok!\n");

    /* Intialization of graphics window */
    grx_rect(XMIN-BD-1, YMIN-BD-1, XMAX+BD+1, YMAX+BD+1, 14);
    grx_text("Simulation of a SHIP-BULLETS-ASTEROIDS",
                         XMIN, YMENU+10, 13, 0);
    grx_text("SPACE create a bullet", XMIN, YMENU+20, 12, 0);
    grx_text("ESC   exit to DOS"    , XMIN, YMENU+30, 14, 0);
    grx_text("Developers: Kailash Kumar Sharma",
                         XMIN, YMENU+40, 12, 0);
    grx_text("            Ramakrishnana S.    ",
                         XMIN, YMENU+50, 12, 0);
    grx_text("            Rekha Rao            ",
                         XMIN, YMENU+60, 12, 0);
    grx_text("UP    :Press E", XMIN+40, YMAX+10, 12, 0);
    grx_text("DOWN  :PRESS C", XMIN+40, YMAX+20, 12, 0);
    grx_text("LEFT  :PRESS S", XMAX-200, YMAX+10, 12, 0);
    grx_text("RIGHT :PRESS F", XMAX-200, YMAX+20, 12, 0);

    /* Draws a default ship */
    draw_ship(sx1, sy1,  sx2, sy2, ship_col);

    /* randomize!!!! */
    seme = sys_gettime(NULL);
    srand(seme);

    /******Creating a task that creates Asteroids randomly*******/
    hard_task_default_model(a);
    hard_task_def_ctrl_jet (a);
    hard_task_def_arg      (a, (void *)a_num);
    hard_task_def_wcet     (a, asteroid_wcet);
    hard_task_def_mit      (a, asteroid_gp_period);
    hard_task_def_usemath  (a);
    apid = task_create("a_gp", a_gp, &a, NULL);
    if (apid == NIL) {
        grx_close();
        perror("Could not create task <asteroid>");
        sys_abort(1);
    }
    task_activate(apid);
    /******END of Creating a task that creates Asteroids randomly*******/

    /******* Infinite loop to create bullets and move the ship *******/
    do {
        if(game_finish == 1) {
        grx_text("GAME OVER !!! ", 300, 300, 13, 0);
        break;
        }
        c = keyb_getch(BLOCK);
        // **** Begin of code to fire bullet ****
        if ((c == ' ') && (b_num < MAX_B)) {
            hard_task_default_model(m);
            hard_task_def_ctrl_jet (m);
            hard_task_def_arg      (m, (void *)b_num);
            hard_task_def_wcet     (m, bullet_wcet);
            hard_task_def_mit      (m, bullet_period);
            hard_task_def_group    (m, BULLETGROUP);
            hard_task_def_usemath  (m);

            pid = task_create("bullet", bullet, &m, NULL);
            if (pid == NIL) {
              grx_close();
              perror("Could not create task <bullet>");
              sys_abort(1);
            }
            task_activate(pid);
            b_num++;

        }
        //**** END of code to fire bullet ****
        //**** BEGIN of code to control the position of ship ****
        else if ((c == 's') && (sx1 > (XMIN+10))) {
            draw_ship(sx1,sy1,sx2,sy2,0);
            sx1 -=5; sx2-=5;
            draw_ship(sx1,sy1,sx2,sy2,12);
        }
        else if ((c == 'f') && (sx2 < (XMAX-10))) {
            draw_ship(sx1,sy1,sx2,sy2,0);
            sx1+=5; sx2+=5;
            draw_ship(sx1,sy1,sx2,sy2,12);
        }
        else if ((c == 'e') && (sy1 > (YMIN+10))) {
            draw_ship(sx1,sy1,sx2,sy2,0);
            sy1-=5; sy2-=5;
            draw_ship(sx1,sy1,sx2,sy2,12);
        }
        else if ((c == 'c') && (sy2 < (YMAX-10))) {
            draw_ship(sx1,sy1,sx2,sy2,0);
            sy1+=5; sy2+=5;
            draw_ship(sx1,sy1,sx2,sy2,12);
        }
        //**** END of code to control the position of ship ****

    } while (c != ESC);
    /******* END of Infinite loop to create bullets *******/
    do{
    c = keyb_getch(BLOCK);
    } while (c != ESC);
    sys_end();
    return 0;
}

/*----------------END OF PROGRAM--------------------------------------*/