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--------------------------------------*/