#include #include #include #include #include #include "antwindow.h" #include "../include/simulator.h" #include "../include/language.h" #ifndef FXSELTYPE #define FXSELTYPE SELTYPE #define OLD_FOX #endif static int msx,msy; static float scale=1.0f; static float mapdx=0,mapdy=0; extern Command* algo[2]; extern int algosize[2]; extern int numants[2]; extern int max_id; extern Ant* ants; extern Map map; extern char* antfilename[2]; static int selectedAnt=0; static int maintime=0; static int focuscol; /**************************** Function Map **********************************/ FXDEFMAP(AntWindow) AntWindowMap[]= { //________Message_Type_____________________ID_______________Message_Handler_______ FXMAPFUNC(SEL_KEYPRESS, 0, AntWindow::onKeyPress), FXMAPFUNC(SEL_MOTION, AntWindow::ID_MAP, AntWindow::onMouseMove), FXMAPFUNC(SEL_PAINT, AntWindow::ID_MAP, AntWindow::onPaintMap), FXMAPFUNC(SEL_LEFTBUTTONPRESS, AntWindow::ID_MAP, AntWindow::onMouseDown), FXMAPFUNC(SEL_LEFTBUTTONRELEASE,AntWindow::ID_MAP, AntWindow::onMouseUp), FXMAPFUNC(SEL_RIGHTBUTTONPRESS, AntWindow::ID_MAP, AntWindow::onMouseDown), FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,AntWindow::ID_MAP, AntWindow::onMouseUp), FXMAPFUNC(SEL_COMMAND, AntWindow::ID_PICK, AntWindow::onCmdPick), FXMAPFUNC(SEL_COMMAND, AntWindow::ID_QUIT, AntWindow::onCmdClose), }; FXIMPLEMENT(AntWindow,FXMainWindow,AntWindowMap,ARRAYNUMBER(AntWindowMap)) /************************** Initialization code ******************************/ AntWindow::AntWindow(FXApp *a):FXMainWindow(a,"Ant Simulator",NULL,NULL,DECOR_ALL,100,100,800,600) { FXColor white=FXRGB(255,255,255); glvisual=new FXGLVisual(a,VISUAL_DOUBLEBUFFER); contents=new FXSplitter(this,SPLITTER_HORIZONTAL|SPLITTER_REVERSED|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y); mainFrame=new FXVerticalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 1,0,DEFAULT_SPACING,0, 0,2); graphFrame=new FXVerticalFrame(mainFrame,LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0,0,0,0,0, 0,0); canvas=new FXGLCanvas(graphFrame,glvisual,this,ID_MAP,LAYOUT_FILL_X|LAYOUT_FILL_Y); consoleFrame=new FXVerticalFrame(contents,LAYOUT_FILL_Y,0,0,200,0, 0,1,DEFAULT_SPACING,0); FXHorizontalFrame* frame1=new FXHorizontalFrame(consoleFrame,LAYOUT_FILL_X|LAYOUT_CENTER_X,0,0,0,0, 3,0,1,0); antID=new FXTextField(frame1,5,NULL,0,TEXTFIELD_NORMAL); new FXButton(frame1,"Pick",NULL,this,ID_PICK,BUTTON_NORMAL,0,0,0,0, 2,1,0,0); timeText=new FXTextField(frame1,8,NULL,0,TEXTFIELD_NORMAL); infoArea=new FXText(consoleFrame,NULL,0,LAYOUT_FILL_X, 0,0, 0,200); outputFrame=new FXPacker(consoleFrame,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_NORMAL,0,0,0,0,0,0,0,0,0,0); stateList[0]=new FXList(outputFrame,NULL,0,LIST_SINGLESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y); stateList[1]=new FXList(outputFrame,NULL,0,LIST_SINGLESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y); stateList[1]->hide(); focuscol=0; } void AntWindow::create() { FILE *fi; FXString str; char buf[100]; int i; FXMainWindow::create(); for(int col=0;col<2;col++) { fi=fopen(antfilename[col],"rt"); assert(fi); for(i=0;iappendItem(new FXListItem(str)); } fclose(fi); } doUpdateState(); show(); } /******************************* GUI code ************************************/ static int mouseDn=0; long AntWindow::onMouseDown(FXObject*,FXSelector sel,void* ptr) { if(mouseDn!=0) return 1; //ignore clicks while dragging FXEvent *ev=(FXEvent*)ptr; if(FXSELTYPE(sel)==SEL_RIGHTBUTTONPRESS) { mouseDn=RIGHTBUTTON; } else if(FXSELTYPE(sel)==SEL_LEFTBUTTONPRESS) { mouseDn=LEFTBUTTON; } else if(FXSELTYPE(sel)==SEL_MIDDLEBUTTONPRESS) { mouseDn=MIDDLEBUTTON; } else return 1; //mouseClick(mouseDn,ev->state,ev->win_x,ev->win_y); return 1; } long AntWindow::onMouseMove(FXObject*, FXSelector,void* ptr) { FXEvent *ev=(FXEvent*)ptr; if(mouseDn==0) { //mouseHover(ev->state,ev->win_x,ev->win_y); return 1; } int dx=ev->win_x-ev->last_x; //movement right int dy=ev->win_y-ev->last_y; //movement down if(mouseDn==LEFTBUTTON) { mapdx+=dx*100.0f/scale/canvas->getWidth(); mapdy+=dy*100.0f/scale/canvas->getHeight(); canvas->update(); } else if(mouseDn=RIGHTBUTTON) { if(dy>70) dy=70; scale*=(100-dy)/100.0f; canvas->update(); } return 1; } long AntWindow::onMouseUp(FXObject* sender,FXSelector sel,void* ptr) { if(FXSELTYPE(sel)==SEL_RIGHTBUTTONRELEASE) { if(mouseDn==RIGHTBUTTON) mouseDn=0; } else if(FXSELTYPE(sel)==SEL_LEFTBUTTONRELEASE) { if(mouseDn==LEFTBUTTON) mouseDn=0; } return 1; } #define WC 100 static GLbyte wirecol[3]={WC,WC,WC}; static GLbyte wallcol[3]={70,53,16}; static float red[3]= {1.0f, 0, 0 }; static float blue[3]= {0, 0, 1.0f}; static float yellow[3]= {1.0f, 1.0f, 0 }; static float lightred[3]= {1.0f, 0.9f, 0.9f}; static float lightblue[3]={0.9f, 0.9f, 1.0f}; static float redmark[3]= {1.0f, 0.25f, 1.0f}; static float bluemark[3]= {0, 0.5f, 0.5f}; static float mixmark[3]= {0.4f, 0.5f, 0.7f}; static float r3d2=0.86602540378443864f; static float hht=0.5; static float hside=0.57735026918962576f; static float hsd2=0.288675134594812882f; static float deltay=0.8660254037844386467f; static float antsz=0.25f; inline void drawHex() { glVertex2f(0,-hside); glVertex2f(hht,-hsd2); glVertex2f(hht,hsd2); glVertex2f(0,hside); glVertex2f(-hht,hsd2); glVertex2f(-hht,-hsd2); } inline void drawTri(int x) { glBegin(GL_POLYGON); glVertex2f(0,0); if(x==0 || x==1) glVertex2f(0,-hside); if(x==1 || x==2) glVertex2f(hht,-hsd2); if(x==2 || x==3) glVertex2f(hht,hsd2); if(x==3 || x==4) glVertex2f(0,hside); if(x==4 || x==5) glVertex2f(-hht,hsd2); if(x==5 || x==0) glVertex2f(-hht,-hsd2); glEnd(); } inline void drawAnt(boolean hasfood) { glBegin(GL_POLYGON); glVertex2f(-antsz,-antsz); glVertex2f(-antsz,antsz); glVertex2f(antsz,antsz); glVertex2f(antsz,-antsz); glEnd(); if(hasfood) { glColor3f(1.0f,1.0f,0); glBegin(GL_LINES); glVertex2f(-antsz,-antsz); glVertex2f(antsz,antsz); glVertex2f(-antsz,antsz); glVertex2f(antsz,-antsz); glEnd(); } } long AntWindow::onPaintMap(FXObject*,FXSelector,void*ptr) { int x,y; FXEvent *ev=(FXEvent*)ptr; if(!canvas->isCurrent()) canvas->makeCurrent(); glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); if(msx!=canvas->getWidth() || msy!=canvas->getHeight()) { msx=canvas->getWidth(); msy=canvas->getHeight(); glViewport(0,0,(GLsizei)msx,(GLsizei)msy); //glEnable(GL_POLYGON_SMOOTH); //glEnable(GL_LINE_SMOOTH); } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1,101,101,-1,-1,1); //glOrtho(-51,51,51,-51,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(+51.0f,+51.0f,0); glScalef(scale,scale,1.0f); glTranslatef(-51.0f,-51.0f,0); glTranslatef(mapdx,mapdy,0); for(x=0;x0) { GLbyte food=(GLbyte)map.foodcount[x][y]; if(food>10) food=10; glColor3f(0.1f*(10-food),1.0,0); glBegin(GL_POLYGON);drawHex();glEnd(); } //base? else if(map.marker[0][x][y]&homeCode) { glColor3fv(lightred); glBegin(GL_POLYGON);drawHex();glEnd(); } else if(map.marker[1][x][y]&homeCode) { glColor3fv(lightblue); glBegin(GL_POLYGON);drawHex();glEnd(); } //markers if(map.marker[0][x][y]&ALY_MARKER_MASK || map.marker[1][x][y]&ALY_MARKER_MASK) { for(int i=0;i<6;i++) { int found=0; if(map.marker[0][x][y]&markerCode(i) && map.marker[1][x][y]&markerCode(i)) glColor3fv(mixmark); else if(map.marker[0][x][y]&markerCode(i)) glColor3fv(redmark); else if(map.marker[1][x][y]&markerCode(i)) glColor3fv(bluemark); else continue; drawTri(i); } } //ant? if(map.object[x][y]==ANTRED) { glColor3fv(red); if(ants[selectedAnt].color==RED && ants[selectedAnt].pos.x==x && ants[selectedAnt].pos.y==y) glColor3fv(yellow); drawAnt(map.marker[0][x][y]&foodCarryCode); } else if(map.object[x][y]==ANTBLACK) { glColor3fv(blue); if(ants[selectedAnt].color==BLACK && ants[selectedAnt].pos.x==x && ants[selectedAnt].pos.y==y) glColor3fv(yellow); drawAnt(map.marker[1][x][y]&foodCarryCode); } glPopMatrix(); } canvas->swapBuffers(); return 1; } void AntWindow::doUpdateState() { //return; char buf[100]; int index=ants[selectedAnt].pc; if(ants[selectedAnt].color!=focuscol) { assert(focuscol>=0 && focuscol<2); stateList[focuscol]->hide(); focuscol=ants[selectedAnt].color; assert(focuscol>=0 && focuscol<2); stateList[focuscol]->show(); stateList[focuscol]->getParent()->layout(); } stateList[focuscol]->selectItem(index); stateList[focuscol]->makeItemVisible(index); sprintf(buf,"%d",selectedAnt); antID->setText(buf); sprintf(buf,"%d",maintime); timeText->setText(buf); } long AntWindow::onKeyPress(FXObject* sender,FXSelector sel,void* ptr) { FXEvent* event=(FXEvent*)ptr; if((event->state&(CONTROLMASK|SHIFTMASK|ALTMASK))==0) { if(event->code==KEY_Home) { scale=1.0f; mapdx=mapdy=0; canvas->update(); return 1; } else if(event->code=='n') { simulate(1,0); maintime++; doUpdateState(); canvas->update(); return 1; } else if(event->code=='m') { simulate(100,0); maintime+=100; doUpdateState(); canvas->update(); return 1; } else if(event->code==KEY_Return || event->code==KEY_KP_Enter) { return onCmdPick(0,0,0); } else if(event->code==',') { if(selectedAnt>0) { selectedAnt--; doUpdateState(); canvas->update(); } return 1; } else if(event->code=='.') { if(selectedAntupdate(); } return 1; } else if(event->code=='p') { showResults(); return 1; } else if(event->code=='f') { simulate(100000-maintime,0); maintime++; doUpdateState(); canvas->update(); return 1; } else if(event->code==KEY_Up) { } else if(event->code==KEY_Down) { } else if(event->code==KEY_Escape) { } else if(event->code==KEY_Page_Up) { } else if(event->code==KEY_Page_Down) { } } FXMainWindow::onKeyPress(sender,sel,ptr); return 1; } long AntWindow::onCmdClose(FXObject* sender,FXSelector sel,void* ptr) { #ifndef OLD_FOX close(FALSE); #endif return 1; } long AntWindow::onCmdPick(FXObject* sender,FXSelector sel,void* ptr) { return 1; FXString newselstr=antID->getText(); int newsel=atoi(newselstr.text()); if(newsel<=0 || newsel>=max_id) return 1; selectedAnt=newsel; doUpdateState(); canvas->update(); return 1; }