#include "common.hpp"
#include "inet.hpp"
#include "ppm.h"
#include "lin_time.hpp"
shared_ptr<Container> world(new Room(0.0f));//space is black
void loadWorld(const char *filename) {
unsigned char*data;unsigned int width,height;
string east("e");
string west("w");
string north("n");
string south("s");
if (readPPM(filename,&data,&width,&height) ) {
vector<ptrdiff_t>tmprooms(width*height);
vector<shared_ptr<Room> >tmpworld;
for (unsigned int i=0;i<height;++i) {
for (unsigned int j=0;j<width;++j) {
tmprooms[i*width+j]=-1;
unsigned char idata[3];
memcpy(idata,data+3*(j+width*i),3);
if ((idata[0]==127||idata[0]==128)&&
(idata[1]==127||idata[1]==128)&&
(idata[2]==127||idata[2]==128)) {
//no room here
}else {
shared_ptr<Room> roomptr(new Room((float)(idata[2]/255.0f)));
//printf ("r %5d ", tmpworld.size());
tmprooms[i*width+j]=tmpworld.size();
tmpworld.push_back(roomptr);
world->addThing(roomptr);
if (i>0) {
ptrdiff_t index=tmprooms[(i-1)*width+j];
if (index>=0){
tmpworld.back()->exits()[0][north]=tmpworld[index];
tmpworld[index]->exits()[0][south]=tmpworld.back();
}
}
if (j>0) {
ptrdiff_t index=tmprooms[(i)*width+(j-1)];
if (index>=0) {
tmpworld.back()->exits()[0][west]=tmpworld[index];
tmpworld[index]->exits()[0][east]=tmpworld.back();
}
}
if (idata[1]>128||rand()%2==0) {
shared_ptr<Thing> food(new Food);
tmpworld.back()->addThing(food);
}
if (idata[0]>128||rand()%2==0) {
shared_ptr<Thing> poison(new Poison);
tmpworld.back()->addThing(poison);
}
}
}
}
}
}
extern vector<std::pair<GeneticCode,shared_ptr<Thing> > >newlyborngrue;
extern vector<std::pair<GeneticCode,shared_ptr<Thing> > >newlybornsnark;
double etime;
int main (int argc, char ** argv) {
InitTime();
etime = argc>1?atof(argv[1]):1./8;
unsigned short snarkport=argc>3?atoi(argv[3]):7876;
unsigned short grueport=argc>4?atoi(argv[4]):7877;
unsigned short adminport=argc>5?atoi(argv[5]):7878;
INETsocket admin=-1;
INET_startup();
INETsocket adminsocket=INET_listen(adminport);
INETsocket snarksocket=INET_listen(snarkport);
INETsocket gruesocket=INET_listen(grueport);
while(snarksocket==-1) {
snarksocket=INET_listen(++snarkport);
}
while(gruesocket==-1) {
gruesocket=INET_listen(++grueport);
}
while(adminsocket==-1) {
adminsocket=INET_listen(++adminport);
}
if (adminsocket==-1||snarksocket==-1||gruesocket==-1) {
printf ("Failed to bind ports");
exit(1);
}
loadWorld(argc>2?argv[2]:"world.ppm");
shared_ptr<Thing> tmpworld((shared_ptr<Thing>)world);
while(1)
{
double framestarttime=queryTime();
if (INET_BytesToRead(adminsocket)) {
admin=INET_Accept(adminsocket);
}
if (INET_BytesToRead(snarksocket)) {
shared_ptr<Thing> newCreature(new Snark(INET_Accept(snarksocket)));
if (newlybornsnark.empty()) {
dynamic_cast<Container*>(world->examineItem(rand()%world->numItems()))->addThing(newCreature);
printf ("Warning, no new snarks needed");
}else {
dynamic_cast<Container*>(newlybornsnark.back().second.get())->addThing(newCreature);
newlybornsnark.pop_back();
}
}
if (INET_BytesToRead(gruesocket)) {
shared_ptr<Thing> newCreature(new Grue(INET_Accept(gruesocket)));
if (newlyborngrue.empty()) {
dynamic_cast<Container*>(world->examineItem(rand()%world->numItems()))->addThing(newCreature);
printf ("Warning, no new grues needed");
}else {
dynamic_cast<Container*>(newlyborngrue.back().second.get())->addThing(newCreature);
newlyborngrue.pop_back();
}
}
unsigned int numrooms=world->numItems();
for (unsigned int index=0;index<numrooms;++index) {
world->examineItem(index)->tick(tmpworld,index);
}
double frameendtime=queryTime();
double deltatime=frameendtime-framestarttime;
if (deltatime>etime) {
printf ("Frame took %lf ",deltatime);
}else {
micro_sleep((unsigned int)((etime-deltatime)*1000000.));
}
}
INET_cleanup();
return 0;
}