// SETI Visualizations
// by Immanuel Buder
#include <stdlib.h>
#include <iostream.h>
#include <GL/glut.h>
#include "tgaload.cpp" //routine for loading texture from targa
#include <time.h>
#define occupied 1; //codes for data
#define vacant 0;
#define spawn 2;
int mainwindow,controlwindow,Twindow; //window id numbers
GLint height, width; //window size
GLuint map; //texture, galaxy map
GLint cheight, cwidth; //controol window size
long long count; // number of run stages
int mode; //alien type
int pos[501][501]; //what at each point
void display (); //main drawing function (prototype)
void outtext (double x, double y, double z, char *string, void *font); //not used
void move1 (int x, int y) { //explorint function for type 1 alien
int dir = rand() % 4; //random mvmt
switch (dir) {
case 0:
if (pos[x-1][y] == 0) { //if no one there
pos[x-1][y] =pos[x][y] = spawn; //go
break;
} //if can't go, move to next
case 1:
if (pos[x+1][y] == 0) {
pos[x+1][y] = pos[x][y] = spawn;
break;
}
case 2:
if (pos[x][y-1] == 0) {
pos[x][y-1]=pos[x][y] = 2;
break;
}
case 3:
if (pos[x][y+1] == 0) {
pos[x][y+1] = pos[x][y] = spawn;
break;
}
}
}
void move2(int x, int y) {
int dir = rand() % 4;
switch (dir) {
case 0:
if (pos[x-1][y] == 0) {
pos[x-1][y] =pos[x][y] = spawn;
}
break; //stop even if can't go
case 1:
if (pos[x+1][y] == 0) {
pos[x+1][y] = pos[x][y] = spawn;
}
break;
case 2:
if (pos[x][y-1] == 0) {
pos[x][y-1]=pos[x][y] = 2;
}
break;
case 3:
if (pos[x][y+1] == 0) {
pos[x][y+1] = pos[x][y] = spawn;
}
break;
}
}
void move3(int x, int y) {
switch (0) { //always 0 direction first
case 0:
if (pos[x-1][y] == 0) {
pos[x-1][y] =pos[x][y] = spawn;
break;
} //next direction if this one fails
case 1:
if (pos[x+1][y] == 0) {
pos[x+1][y] = pos[x][y] = spawn;
break;
}
case 2:
if (pos[x][y-1] == 0) {
pos[x][y-1]=pos[x][y] = 2;
break;
}
case 3:
if (pos[x][y+1] == 0) {
pos[x][y+1] = pos[x][y] = spawn;
break;
}
}
}
void move4 (int x, int y) {
int dir = rand() % 4;
switch (dir) {
case 0:
if (pos[x-1][y] == 0) {
/* coin toss to stop */ if (rand() % 2) pos[x-1][y] =pos[x][y] = spawn;
break;
} //next direction if can't go
case 1:
if (pos[x+1][y] == 0) {
if (rand() % 2) pos[x+1][y] = pos[x][y] = spawn;
break;
}
case 2:
if (pos[x][y-1] == 0) {
if (rand() %2) pos[x][y-1]=pos[x][y] = 2;
break;
}
case 3:
if (pos[x][y+1] == 0) {
if (rand() % 2) pos[x][y+1] = pos[x][y] = spawn;
break;
}
}
}
void loadtextures () { //load texture
glPixelStorei (GL_UNPACK_ALIGNMENT,1);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
map = tgaLoadAndBind ("milky.tga",TGA_DEFAULT);
}
void mouse (int button, int state, int x, int y) {
if (state == GLUT_DOWN && button == 2) { //if right click
cout<<count<<" ticks"<<endl; // say time before exit
exit(0);
}
}
/*
void Tdisplay () { //old control routine
glClearColor (.6,.1,0,0); //no longer used
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glOrtho(0,10,0,10, -1,1);
glColor3f(1.0,1.0,1.0);
outtext(1,3,0,"T",GLUT_BITMAP_TIMES_ROMAN_24);
glFlush();
}
void Tmouse(int button, int state, int x, int y) {
if (state == GLUT_DOWN) {
cout<<"The current time is "<<count<<endl;
}
}
void controldisplay () {
glClear(GL_COLOR_BUFFER_BIT);
}
*/
void initialize () {
height = width = 500; //set size
glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB); //OpenGl mode
glutInitWindowSize(width, height);
mainwindow = glutCreateWindow("SETI Visualizations"); //create main window
glutDisplayFunc(display); //set display function
glutMouseFunc(mouse); //set mouse function
glEnable(GL_RGB); //OpenGL options
glEnable (GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
loadtextures();
glEnable(GL_RGB);
glClearColor(.3,.3,.6,0); //background color
glMatrixMode(GL_PROJECTION); //create view
glLoadIdentity(); //
glOrtho(1,500,1,500,-1,1); //drawspace size
// cwidth= 200; cheight = 200; //no longer used
glutInitDisplayMode(GLUT_DEPTH|GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(cwidth, cheight); //control windoe
/* controlwindow = glutCreateWindow("Controls");
glutDisplayFunc(controldisplay); //no longer used
glClearColor (1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1,1);
Twindow = glutCreateSubWindow(controlwindow, 10, 10, 40, 40);
glutDisplayFunc(Tdisplay);
glutMouseFunc(Tmouse);*/
}
void outtext (double x, double y, double z, char *string, void *font) {
glRasterPos3f(x,y,z); //locate position for output
int len = strlen (string); //find length of output
for (int i = 0; i < len; i++) {
glutBitmapCharacter(font,string[i]); //output by chars
}
}
void display () {
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); //clear
glBindTexture(GL_TEXTURE_2D, map); //use texture
glColor3f (1.0,1.0,1.0); //draw color -- doesn't work
glBegin(GL_QUADS); //square, background
glTexCoord2f (0,0); //coordinate in texture file
glVertex3f (1,1,.1); //coordinate on screen
glTexCoord2f (0,1);
glVertex3f (1,500,.1);
glTexCoord2f (1,1);
glVertex3f (500,500,.1);
glTexCoord2f (1,0);
glVertex3f (500,1,.1);
glEnd(); //done with quads
glColor3f(1.0,1.,1.0); //set draw color -- does not work
glBegin(GL_POINTS); //draw points
glColor3f(1.0,0,0); //set draw color -- does not work
int x,y; //
for (x = 1; x <= 500; x++) //move across screen
for (y = 1; y <= 500; y++) //
if (pos[x][y] == 1)
glVertex3f(x,y,.1); //plot aliens
for (x = 2; x<=499; x++)
for (y=2; y <= 499; y++)
if (pos[x][y] == 1) {
if (mode == 1) move1(x,y); //do movement
if (mode == 2) move2(x,y);
if (mode == 3) move3(x,y);
if (mode == 4) move4(x,y);
}
for (x = 1; x <= 500; x++)
for (y = 1; y<=500; y++){
if (pos[x][y] == 2) //update spawnms
pos[x][y] = occupied;
for (long long j = 0; j < 5; j++); //waste time
}
glEnd(); //done with points
glFlush(); //force drawing
count++; //count updates
glutSwapBuffers(); //animate
// glutPostWindowRedisplay(Twindow);
}
int main (int argc, char ** argv) {
if (argc != 2) {
cout<<"FATAL ERROR. Incorrect number of arguments. You die."<<endl;
exit(0);
}
mode = strtol(argv[1],NULL,10); //read in mode
srand(unsigned(time(NULL))); //seed random
for (int x = 0; x <= 500; x++)
for (int y = 0; y <= 500; y++)
pos[x][y] = vacant; //clear galaxy
pos[(rand()%500)+1][(rand()%500)+1] = occupied; //random start
count = 0; //initialize counter
glutInit(&argc, argv); //initialize graphics
initialize();
glutIdleFunc(display); //
glutMainLoop(); //hand control to OpenGL
cout<<count;
return 0;
}