commit e22b4910d516a2ed4356b1495541e8ce5da8533c Author: seba Date: Wed Jan 21 01:15:42 2009 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f1db45a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +GameOfLife +*.o diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ca2b04a --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +CC = g++ +LINK = `sdl-config --libs` -lGL -lGLU -lSDL_image -Wl,-rpath,. +OBJ = `sdl-config --cflags` -Wall -c -I../libsegl +LIBS = libsegl.so.1 + +prog: life.o gameoflife.o + $(CC) $(LINK) $+ -o GameOfLife $(LIBS) + +run: prog + ./GameOfLife + +life.o: gameoflife.o + +%.o: %.cpp %.h + $(CC) $(OBJ) $< + +%.o: %.cpp + $(CC) $(OBJ) $< + +clean: + rm -f *.o diff --git a/defaultfont.png b/defaultfont.png new file mode 100644 index 0000000..759551d Binary files /dev/null and b/defaultfont.png differ diff --git a/example.fld b/example.fld new file mode 100644 index 0000000..371982f --- /dev/null +++ b/example.fld @@ -0,0 +1,14 @@ +13 13 1 +0000000000000 +0000000000000 +0000000000000 +0000011100000 +0000010100000 +0000010100000 +0000000000000 +0000010100000 +0000010100000 +0000011100000 +0000000000000 +0000000000000 +0000000000000 \ No newline at end of file diff --git a/gameoflife.cpp b/gameoflife.cpp new file mode 100644 index 0000000..36b742d --- /dev/null +++ b/gameoflife.cpp @@ -0,0 +1,571 @@ +#include "gameoflife.h" + +GameOfLife::GameOfLife(int _x, int _y) { + init(); + x = _x; + y = _y; + allocate(); +} + +GameOfLife::GameOfLife(std::string file) { + init(); + load(file); +} + +GameOfLife::GameOfLife(int _x, int _y, int r_life, int r_dead) { + init(); + fillRandom(_x, _y, r_life, r_dead); +} + +void GameOfLife::init() { + view3d = true; + feld = 0; + x = y = 0; + generation = 0; + thickness = 0.5f; + cellwidth = 1.0f; + torus = true; + fullcelluse = true; + radius = 0.3f; + height = 1.0f; + parts = 12; + sectobuild = 0.91f; + b_secdone = 0.0f; + secpertick = 1.0f; + t_secdone = 0.0f; + editmode = false; + + // Calc cylinder sinvals + sinval = new float[parts]; + cosval = new float[parts]; + + for(int i=0; i> x; + data >> y; + data >> torus; + if(x<=0 || y <=0) + return false; + + cleanup(); + allocate(); + int j=0; + getline(data, tmp); // Remove \n + while(getline(data, tmp) && j=0 && _x=0 && _y0) + setpos.y = ((int)setpos.y+y+1)%y; + else if(up<0) + setpos.y = ((int)setpos.y+y-1)%y; + if(right>0) + setpos.x = ((int)setpos.x+x+1)%x; + else if(right<0) + setpos.x = ((int)setpos.x+x-1)%x; + +} + +void GameOfLife::toggle() { + if(feld[(int)setpos.x][(int)setpos.y]==born||feld[(int)setpos.x][(int)setpos.y]==alife) { + feld[(int)setpos.x][(int)setpos.y] = dead; + } else { + feld[(int)setpos.x][(int)setpos.y] = alife; + } +} + +void GameOfLife::render(float sec) { + if(!feld) + return; + + // Cylinder-building-timer + if(b_secdone<=sectobuild) { + b_secdone += sec; + if(b_secdone>=sectobuild) { + lockStates(); + } + } + + // Tick-timer + t_secdone += sec; + if(t_secdone>=secpertick) { + tick(); + t_secdone = 0.0f; + b_secdone = 0.0f; + } + + if(view3d) { + renderBrett(); + + for(int j=0; jw /(float)x; + float hperp = screen->h /(float)y; + float border; + + glPushMatrix(); + if(wperpsecpertick) + lockStates(); + + int near; + int x1, y1; + for(int i=0; i=x || b>=y))) + continue; + if(torus) { + x1 = (a+x)%x; + y1 = (b+y)%y; + } else { + x1 = a; + y1 = b; + } + + if(feld[x1][y1]==alife || (fullcelluse && (feld[x1][y1]==dies))) + near++; + } + } + + if(feld[i][j]==alife) { + if(near!=2 && near!=3) + feld[i][j] = dies; + } else if(feld[i][j]==dead) { + if(near==3) + feld[i][j] = born; + } + } + } + if(sectobuild<0.1f) + lockStates(); + generation++; +} + +void GameOfLife::clear() { + for(int i=0; i +#include +#include +#include +#include +#include +#include "emath.h" +#include "punkt2d.h" + +typedef enum { dead=0, alife, dies, born } State; + +class GameOfLife { + private: + State **feld; + int x, y; + bool torus; + bool fullcelluse; + unsigned long generation; + + GLUquadricObj *quad; + + // Brett + float thickness; + float cellwidth; + + // Cylinder + float radius; + float height; + int parts; + float *sinval; + float *cosval; + + //render + bool view3d; + float sectobuild; + float b_secdone; + float secpertick; + float t_secdone; + + // Edit + segl::Punkt2D setpos; + bool editmode; + + void init(); + void allocate(); + void cleanup(); + + void renderBrett(); + void renderStein(State s); + + void translateTo(int _x, int _y); + void lockStates(); + public: + GameOfLife(int _x, int _y); + GameOfLife(int _x, int _y, int r_life, int r_dead); + GameOfLife(std::string file); + ~GameOfLife(); + + void set3D(bool on); + bool load(std::string file); + bool save(std::string file); + + void fillRandom(int _x, int _y, int r_life, int r_dead); +// void toggle(int _x, int _y); + + void setEditMode(bool e); + void move(int up, int right); + void toggle(); + + float getTickSec(); + float getBuildSec(); + void setTickSec(float s); + void setBuildSec(float s); + void setTorus(bool t); + unsigned long getGeneration(); + +// const bool** getFeld(); + void tick(); + void render(float sec); + void clear(); +}; + +#endif diff --git a/libsegl.so.1 b/libsegl.so.1 new file mode 100755 index 0000000..e37527f Binary files /dev/null and b/libsegl.so.1 differ diff --git a/life.cpp b/life.cpp new file mode 100644 index 0000000..db27038 --- /dev/null +++ b/life.cpp @@ -0,0 +1,386 @@ +#include +#include +#include +#include +#include +#include "gameoflife.h" +#include "glcamera.h" +#include "fpsmanager.h" +#include "glfontengine.h" + +void setVideo(bool view3d, int width, int height); +void displayUsage(); + +int main(int argc, char **argv) { + int width = 1024; + int height= 768; + bool view3d = true; + bool renderosd = true; + bool paused = false; + bool editmode = false; +// bool showcam2d = false; + GameOfLife feld(20, 20, 1, 2); + + { + std::string loadfile = ""; + int feld_x = 20; + int feld_y = 20; + int rand_alife = 1; + int rand_dead = 3; + bool torus = true; + for(int i=1; i=0.1f) { + feld.setTickSec(feld.getTickSec()+0.1f); + if(feld.getBuildSec()!=0.0f) + feld.setBuildSec(feld.getBuildSec()+0.1f); + } else { + feld.setTickSec(feld.getTickSec()+0.01f); + if(feld.getBuildSec()!=0.0f) + feld.setBuildSec(feld.getBuildSec()+0.01f); + } + break; + case SDLK_MINUS: + if(feld.getTickSec()>0.1f) { + feld.setTickSec(feld.getTickSec()-0.1f); + if(feld.getBuildSec()!=0.0f) + feld.setBuildSec(feld.getBuildSec()-0.1f); + } else if(feld.getTickSec()>=0.01f) { + feld.setTickSec(feld.getTickSec()-0.01f); + if(feld.getBuildSec()!=0.0f) + feld.setBuildSec(feld.getBuildSec()-0.01f); + } + break; + case SDLK_e: + editmode = !editmode; + feld.setEditMode(editmode); + if(editmode) + paused = true; + else + paused = false; + break; + // Edit Mode Stuff + case SDLK_SPACE: + if(editmode) + feld.toggle(); + break; + case SDLK_UP: + if(editmode && (!view3d || event.key.keysym.mod&KMOD_SHIFT)) + feld.move(-1, 0); + break; + case SDLK_DOWN: + if(editmode && (!view3d || event.key.keysym.mod&KMOD_SHIFT)) + feld.move(1, 0); + break; + case SDLK_RIGHT: + if(editmode && (!view3d || event.key.keysym.mod&KMOD_SHIFT)) + feld.move(0, 1); + break; + case SDLK_LEFT: + if(editmode && (!view3d || event.key.keysym.mod&KMOD_SHIFT)) + feld.move(0, -1); + break; + default: + + break; + } + break; + case SDL_VIDEORESIZE: + + break; + } + } else { + // Set scene stuff + lastframe = thisframe; + thisframe = SDL_GetTicks(); + float sec = (thisframe-lastframe)/1000.0f; + if(view3d) { + Uint8 *keystate = SDL_GetKeyState(NULL); + if(!keystate[SDLK_LSHIFT]&&!keystate[SDLK_RSHIFT]) + camera.handleKeys(sec); + } + + //Render scene + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + + if(view3d) + camera.setCamera(); + + glLightfv(GL_LIGHT1, GL_POSITION, light_position); +// glLightfv(GL_LIGHT1, GL_POSITION, light1_position); + + feld.render(sec*(!paused)); + + + if(renderosd) { + if(view3d) { + glDisable(GL_LIGHTING); + fontengine.prepare2DbyPushingMatrix(); + } + + std::stringstream txt; + + glEnable(GL_TEXTURE_2D); + if(paused) + fontengine.renderLine(" Paused...", width/2, 0, true); + if(editmode) + fontengine.renderLine("Edit mode", width/2, 21, true); + txt << "Sec/Build: "; + if(feld.getBuildSec()!=0.0f) + txt << feld.getBuildSec(); + else + txt << "Off"; + fontengine.renderLine(txt.str(), width/3, height-21, true); + txt.str(""); + txt.clear(); + txt << "Sec/Tick: " << feld.getTickSec(); + fontengine.renderLine(txt.str(), width*2/3, height-21, true); + txt.str(""); + txt << "Generation: " << feld.getGeneration(); + if(!paused) + fontengine.renderLine(txt.str(), width/2, 0, true); + glDisable(GL_TEXTURE_2D); + + if(view3d) { + glEnable(GL_LIGHTING); + fontengine.regain3DbyPoppingMatrix(); + } + } + + SDL_GL_SwapBuffers(); + fpsman.delay(); + } + + } + return 0; +} + +void setVideo(bool view3d, int width, int height) { + glViewport(0, 0, (GLsizei)width, (GLsizei)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if(view3d) + gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.2f, 100.0f); + else + glOrtho(0, width, height, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); +} + +void displayUsage() { + std::cout << "Usage: GameOfLife [options]" << std::endl << + std::endl << + "Options: " << std:: endl << + " -fx, --field-x Set field width (Default: 20)" << std::endl << + " -fy, --field-y Set field height (Default: 20)" << std::endl << + " -t, --torus <1/0> Enable/Disable Torus (Default: 1)" << std::endl << + " -l, --load Load field from textfile" << std::endl << + " -rd, --rand-dead Defines dead-cellratio for random fill (Default: 3)" << std::endl << + " -ra, --rand-alife Defines alife-cellratio for random fill (Default: 1)" << std::endl << + " -h, --help Shows this help and exits" << std::endl << + " -v, --version Displays versioninfo and exits" << std::endl << + std::endl << + "Read the readme.txt supplied with this program for further information" << std::endl; +} diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..d16ba11 --- /dev/null +++ b/readme.txt @@ -0,0 +1,27 @@ +Conway's "Game of Life" in 2d/3d +written by seba (www.seba-geek.de) + + - Write a field-file + Begin with a header in the first line + + For example "21 21 1" would be a 21x21 field torus + + After the header follows the field-definition, + col => x-axis, row => y-axis + 0 is a dead cell + 1 is a living cell + + Look at the example.fld for further explaination + + + - Controls + t Toggle 2d/3d mode + p Pause + o Toggle OSD + e Toggle Edit-Mode + Move with shift + arrows + Toggle fieldstate withs Space + Clear field with shift + c + b Toggle buildup of cells + -/+ In- or decrease speed + \ No newline at end of file diff --git a/start.fld b/start.fld new file mode 100644 index 0000000..32886bb --- /dev/null +++ b/start.fld @@ -0,0 +1,22 @@ +21 21 1 +000000000000000000000 +001000000000001000000 +011100000000011100000 +001000000000001000000 +000000000000000000000 +000000000000000000000 +000000000000000000000 +000000000111000000000 +000000000101000000000 +000000000101000000000 +000000000000000000000 +000000000101000000000 +000000000101000000000 +000000000111000000000 +000000000000000000000 +000000000000000000000 +001000000000000100000 +011100000000001110000 +001000000000000100000 +000000000000000000000 +000000000000000000000 diff --git a/waves.fld b/waves.fld new file mode 100644 index 0000000..a3ade37 --- /dev/null +++ b/waves.fld @@ -0,0 +1,7 @@ +20 6 1 +00000000010000000000 +00000000010000000000 +00000000010000000000 +00000000010000000000 +00000000010000000000 +00000000010000000000