/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #include "framework.h" #include "p_node.h" #include "null_parent.h" #include "state.h" #include "debug.h" #include "light.h" #include "resource_manager.h" #include "camera.h" #include "ini_parser.h" int verbose; void Framework::init(void) { // create parser IniParser parser (DEFAULT_CONFIG_FILE); if( parser.getSection (CONFIG_SECTION_DATA) == -1) { PRINTF(1)("Could not find Section %s in %s\n", CONFIG_SECTION_DATA, DEFAULT_CONFIG_FILE); } char namebuf[256]; char valuebuf[256]; memset (namebuf, 0, 256); memset (valuebuf, 0, 256); while( parser.nextVar (namebuf, valuebuf) != -1) { if (!strcmp(namebuf, CONFIG_NAME_DATADIR)) { // printf("Not yet implemented\n"); if (!ResourceManager::getInstance()->setDataDir(valuebuf)) { PRINTF(1)("Data Could not be located\n"); } } memset (namebuf, 0, 256); memset (valuebuf, 0, 256); } if (!ResourceManager::getInstance()->checkDataDir(DEFAULT_DATA_DIR_CHECKFILE)) { PRINTF(1)("The DataDirectory %s could not be verified\nPlease Change in File %s Section %s Entry %s to a suitable value\n", ResourceManager::getInstance()->getDataDir(), DEFAULT_CONFIG_FILE, CONFIG_SECTION_DATA, CONFIG_NAME_DATADIR); exit(-1); } } void* Framework::mainLoop(void* tmp) { Framework* framework = Framework::getInstance(); while(!framework->isFinished) { #ifdef GUI_MODULE while(gtk_events_pending()) gtk_main_iteration(); #endif // keyhandler returns false if sdl gets quit by some event framework->eventHandler(); // tick the scene float dt = framework->tick(); NullParent::getInstance()->update(dt); // Draw the scene framework->draw(dt); } } bool Framework::draw(float dt) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glLoadIdentity(); // Reset the view this->moduleDraw(); camera->apply(); SDL_GL_SwapBuffers(); // Swap the buffers } float Framework::tick() { currFrame = SDL_GetTicks(); float dt = (float)(currFrame - lastFrame) / 1000.0; lastFrame = currFrame; this->moduleTick(dt); return dt; } bool Framework::eventHandler() { // This is the main loop for the entire program and it will run until done==TRUE { // And poll for events SDL_Event event; while(SDL_PollEvent(&event)) { moduleEventHandler(&event); switch (event.type) { case SDL_MOUSEMOTION: { Vector view = camera->getTarget()->getAbsCoor() - camera->getAbsCoor(); Vector up = Vector(0, 1, 0); up = camera->getAbsDir().apply(up); Vector h = up.cross(view); Vector v = h.cross(view); h.normalize(); v.normalize(); float distance = view.len(); Vector newCameraPos = camera->getAbsCoor(); Vector newTargetPos = camera->getTarget()->getAbsCoor(); int changed = 0; if (mouseDown[1]) { newCameraPos = camera->getRelCoor()+ (h * event.motion.xrel - v * event.motion.yrel) * .005 * distance; changed += 1; } if (mouseDown[3]) { newTargetPos = camera->getTarget()->getRelCoor() + (h * event.motion.xrel - v * event.motion.yrel) * .005 * distance; changed += 2; } Vector newView = newTargetPos - newCameraPos; if (changed == 1) camera->setRelCoor(newCameraPos + newView * (1- distance/newView.len())); else if (changed == 2) camera->getTarget()->setRelCoor(newTargetPos - newView * (1-distance/newView.len())); else if (changed == 3) { camera->setRelCoor(newCameraPos); camera->getTarget()->setRelCoor(newTargetPos); } } break; case SDL_MOUSEBUTTONDOWN: switch (event.button.button) { case 4: PRINTF(4)("MouseWheel up\n"); camera->setRelCoor(camera->getRelCoor() + (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1); break; case 5: PRINTF(4)("MouseWheel down\n"); camera->setRelCoor(camera->getRelCoor() - (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1); break; case 1: case 2: case 3: mouseDown[event.button.button] = true; break; } break; case SDL_MOUSEBUTTONUP: switch (event.button.button) { case 1: case 2: case 3: mouseDown[event.button.button] = false; break; } break; case SDL_VIDEORESIZE: GraphicsEngine::getInstance()->resolutionChanged(&event.resize); break; case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_q: case SDLK_ESCAPE: #ifdef GUI_MODULE quitGui(NULL, NULL); #else this->quit(); #endif break; case SDLK_a: camera->setRelCoor(camera->getRelCoor() + (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1); break; case SDLK_z: camera->setRelCoor(camera->getRelCoor() - (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1); break; case SDLK_r: camera->setAbsCoor(Vector(10, 10, 10)); camera->getTarget()->setAbsCoor(Vector()); break; case SDLK_h: this->printHelp(); break; case SDLK_c: for (int i = 0; i < 3; i++) { backgroundColor[i] += .1; if (backgroundColor[i] > 1.0) backgroundColor[i] = 1.0; GraphicsEngine::setBackgroundColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]); } break; case SDLK_x: for (int i = 0; i < 3; i++) { backgroundColor[i] -= .1; if (backgroundColor[i] < 0.0) backgroundColor[i] = 0.0; GraphicsEngine::setBackgroundColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]); } break; } break; // If a quit event was recieved case SDL_QUIT: // then we're done and we'll end this program #ifdef GUI_MODULE quitGui(NULL, NULL); #else this->quit(); #endif break; default: break; } } // Get the state of the keyboard keys keys = SDL_GetKeyState(NULL); // and check if ESCAPE has been pressed. If so then quit if(keys[SDLK_ESCAPE]) return false; } return true; } void Framework::quit(void) { this->isFinished = true; } Framework* Framework::singletonRef = NULL; Framework::Framework() { this->init(); this->isFinished = false; this->lastFrame = 0; // Create a new OpenGL window with the title "Cone3D Basecode" at // 640x480x32, fullscreen and check for errors along the way GraphicsEngine::getInstance(); LightManager::getInstance(); glEnable(GL_TEXTURE_2D); // Build the font from a TGA image font.tga in the data directory // Hide the mouse cursor SDL_ShowCursor(2); for (int i = 0; i < MOUSE_BUTTON_COUNT; i++) mouseDown[i] = false; for (int i = 0; i < 4; i++) backgroundColor[i] = 0; camera = new Camera(); State::getInstance()->setCamera(camera, camera->getTarget()); camera->setAbsCoor(Vector(10, 10, 10)); } Framework::~Framework() { delete GraphicsEngine::getInstance(); } void Framework::printHelp(void) const { PRINT(0)(" Help for the frameWork\n"); PRINT(0)("========================\n"); PRINT(0)("h - print this Help\n"); PRINT(0)("a - zoom in\n"); PRINT(0)("z - zoom out\n"); PRINT(0)("r - reset camera position\n"); PRINT(0)("x - background color darker\n"); PRINT(0)("c - background color brighter\n"); PRINT(0)("\n"); PRINT(0)("mouse wheel - zoom\n"); PRINT(0)("mouse left button - rotate the camera around its target\n"); PRINT(0)("mouse right button - rotate the camera's target around the camera\n"); PRINT(0)("mouse left-and-right button - move the camera and the target\n"); this->moduleHelp(); } #ifdef GUI_MODULE int quitGui(GtkWidget* widget, void* data) { #ifdef HAVE_GTK2 while(gtk_events_pending()) gtk_main_iteration(); Framework::getInstance()->quit(); #endif /* HAVE_GTK2 */ } #endif int main(int argc, char *argv[]) { verbose = 3; Framework* framework = Framework::getInstance(); framework->moduleInit(argc, argv); #ifdef GUI_MODULE framework->moduleInitGui(argc, argv); #endif framework->mainLoop(NULL); delete framework; // Kill the GL & SDL screens // And quit return 0; }