#include "MainWindow.h" #include "types.h" #include //#include #include #define WINDOW_TIMER 15 #define WALL_SIZE 0.5f void f_onChangeSize(int w, int h) { MainWindow::getInstance().onChangeSize(w, h); } void f_onDisplay() { MainWindow::getInstance().onRenderScene(); } void f_onTimer(int v) { MainWindow::getInstance().onTimer(); } void f_onNormalKeyPressed(unsigned char key, int x, int y) { MainWindow::getInstance().onNormalKeyPressed(key); } void f_onSpecialKeyPressed(int key, int x, int y) { MainWindow::getInstance().onSpecialKeyPressed(key); } void hex2fColor(uint color, float &out_red, float &out_green, float &out_blue) { float colors[3]; colors[0] = (float) ((color & 0x0000FF) >> 0) / 256.f; colors[1] = (float) ((color & 0x00FF00) >> 8) / 256.f; colors[2] = (float) ((color & 0xFF0000) >> 16) / 256.f; out_blue = colors[0]; out_green = colors[1]; out_red = colors[2]; } void f_doNothing() {} MainWindow &MainWindow::getInstance() { static MainWindow s_mainWindow; // calling it static will create it if it's the first time and retrieve it otherwise. return s_mainWindow; } void MainWindow::drawString(GLfloat x, GLfloat y, char *text, uint color, TextAlign align) { char *p; float red, green, blue; hex2fColor(color, red, green, blue); glLineWidth(3.0); glPushMatrix(); glTranslatef(x, y, 0); glScalef(0.001, 0.001, 0.00); if (align) glTranslatef( ((float) align / 2) * glutStrokeLength(GLUT_STROKE_MONO_ROMAN, (const unsigned char *) text), 0, 0); glColor3f(red, green, blue); for (p = text; *p; p++) glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, *p); glPopMatrix(); } void MainWindow::onChangeSize(int w, int h) { if (h == 0) h = 1; float ratio = w * 1.0f / h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, w, h); gluPerspective(45.0f, ratio, 0.1f, 100.0f); glMatrixMode(GL_MODELVIEW); m_width = w; m_height = h; //gluOrtho2D(0, 0, m_width, m_height); } void MainWindow::onRenderScene() { // Clear Color and Depth Buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(m_pField) { Coordinates maxC = m_pField->getMaxCoordinates(); float GridStepX = 2*(1.f/(maxC.x+2*WALL_SIZE)); float GridStepY = 2*(1.f/(maxC.y+2*WALL_SIZE)); PlayerColor color; float red, green, blue; color = 0xFFFFFF; hex2fColor(color, red, green, blue); glColor3f(red, green, blue); glBegin(GL_POLYGON); glVertex2f(-1, -1); glVertex2f( 1, -1); glVertex2f( 1, 1); glVertex2f(-1, 1); glEnd(); color = emptyColors[0]; hex2fColor(color, red, green, blue); glColor3f(red, green, blue); glBegin(GL_POLYGON); glVertex2f(-(maxC.x/(maxC.x+2*WALL_SIZE)), -(maxC.x/(maxC.x+2*WALL_SIZE))); glVertex2f( (maxC.x/(maxC.x+2*WALL_SIZE)), -(maxC.x/(maxC.x+2*WALL_SIZE))); glVertex2f( (maxC.x/(maxC.x+2*WALL_SIZE)), (maxC.x/(maxC.x+2*WALL_SIZE))); glVertex2f(-(maxC.x/(maxC.x+2*WALL_SIZE)), (maxC.x/(maxC.x+2*WALL_SIZE))); glEnd(); int lineX = 0; int lineY = 0; color = emptyColors[1]; hex2fColor(color, red, green, blue); glColor3f(red, green, blue); glBegin(GL_LINES); for (lineX = 0; lineX < maxC.x; lineX += 10) { glVertex2f(2 * ((float) lineX / (maxC.x + 2*WALL_SIZE)) - 1, -1); glVertex2f(2 * ((float) lineX / (maxC.x + 2*WALL_SIZE)) - 1, 1); } for (lineY = 0; lineY < maxC.y; lineY += 10) { glVertex2f(-1, 2 * ((float) lineY / (maxC.y + 2*WALL_SIZE)) - 1); glVertex2f( 1, 2 * ((float) lineY / (maxC.y + 2*WALL_SIZE)) - 1); } glEnd(); for(int coordX = 0; coordX < maxC.x; ++coordX) { for(int coordY = 0; coordY < maxC.y; ++coordY) { Cell c = m_pField->getCell(Coordinates(coordX, coordY)); if (c.getState() != EMPTY_CELL) { switch(c.getState()) { case BOOM: color = 0xFFFFFF; hex2fColor(color, red, green, blue); glColor3f(red, green, blue); break; case PLAYER_WALL: color = playerColors[c.getPlayer()->getNumber() % numColors]; color = (c.getPlayer()->isAlive() ? playerColors[c.getPlayer()->getNumber() % numColors] : emptyColors[2]); hex2fColor(color, red, green, blue); glColor3f(red/2, green/2, blue/2); break; case PLAYER: color = playerColors[c.getPlayer()->getNumber() % numColors]; hex2fColor(color, red, green, blue); glColor3f(red, green, blue); break; } glBegin(GL_POLYGON); float floatCoordX = 2 * ((float) (coordX+WALL_SIZE) / (maxC.x + 2*WALL_SIZE)) - 1; float floatCoordY = 2 * ((float) (coordY+WALL_SIZE) / (maxC.y + 2*WALL_SIZE)) - 1; glVertex2f(floatCoordX , floatCoordY ); glVertex2f(floatCoordX + GridStepX, floatCoordY ); glVertex2f(floatCoordX + GridStepX, floatCoordY + GridStepY); glVertex2f(floatCoordX , floatCoordY + GridStepY); glEnd(); } } } if (! m_pGame->isRunning()) drawString(0, -0.02, (char*)"PAUSED", 0xffffff, center); } glutSwapBuffers(); } void MainWindow::onTimer() { if(m_pGame) { int time = glutGet(GLUT_ELAPSED_TIME); m_pGame->updateGame(time); onRenderScene(); } glutTimerFunc(WINDOW_TIMER, f_onTimer, 0); } KeyboardController* MainWindow::generateNewKeyboardController(Player* pPlayer, KeyCode leftKey, KeyCode rightKey) { KeyboardController* pKeyboardController = new KeyboardController(pPlayer, leftKey, rightKey); m_vpKeyboardController.push_back(pKeyboardController); return pKeyboardController; } void MainWindow::onNormalKeyPressed(uint8 key) { if (key >= 'A' && key <= 'Z') { onKeyPressed((KeyCode) (key - 'A' + KEY_A)); } else if (key >= 'a' && key <= 'z') { onKeyPressed((KeyCode) (key - 'a'+ KEY_A)); } else if (key >= '0' && key <= '9') { onKeyPressed((KeyCode) (key - '0' + KEY_0)); } else if (key == 27) { exit(0); } if(m_pGame) { if (key == 13) { m_pGame->restart(); }else if (key == 32) { m_pGame->toggleGame(); } } } void MainWindow::onSpecialKeyPressed(int key) { switch(key) { case GLUT_KEY_UP: onKeyPressed(KEY_UP); break; case GLUT_KEY_DOWN: onKeyPressed(KEY_DOWN); break; case GLUT_KEY_LEFT: onKeyPressed(KEY_LEFT); break; case GLUT_KEY_RIGHT: onKeyPressed(KEY_RIGHT); break; } } void MainWindow::onKeyPressed(KeyCode key) { for(std::vector::iterator it = m_vpKeyboardController.begin(); it != m_vpKeyboardController.end(); ++it) { (*it)->PressKey(key); } } void MainWindow::init(int *argcp, char **argv){ glutInit(argcp, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); } void MainWindow::create(std::string name, int x, int y, int width, int height) { glutInitWindowPosition(x, y); glutInitWindowSize(width, height); m_width = width; m_height = height; if (m_width && m_height) { glutCreateWindow(name.c_str()); gluOrtho2D(0, 0,m_width, m_height); } } void MainWindow::startLoop() { // register callbacks #ifdef __APPLE__ glutDisplayFunc(f_onDisplay); #else //glutReshapeFunc(f_onChangeSize); //glutDisplayFunc(f_doNothing); #endif glutTimerFunc(WINDOW_TIMER, f_onTimer, 0); //glutIdleFunc(f_onDisplay); // enter GLUT event processing cycle glutKeyboardFunc(f_onNormalKeyPressed); glutSpecialFunc(f_onSpecialKeyPressed); glutMainLoop(); } MainWindow::MainWindow(): m_width(0), m_height(0) { m_pField = NULL; m_pGame = NULL; m_vpKeyboardController.clear(); } // The field has the info of what to draw void MainWindow::setField(Field* pField) { m_pField = pField; } Field* MainWindow::getField() { return(m_pField); } // The game needs to be updated whenever we want to update the display content. void MainWindow::setGame(Game* pGame) { m_pGame = pGame; } Game* MainWindow::getGame() { return(m_pGame); } MainWindow::~MainWindow(void) { }