/* 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 "state.h" #include "debug.h" #include "light.h" #include "resource_manager.h" #include "camera.h" #include "parser/ini_parser/ini_parser.h" #include "globals.h" int verbose; void Framework::init(void) { // create parser char* configFileName = ResourceManager::homeDirCheck(DEFAULT_CONFIG_FILE); IniParser iniParser (configFileName); delete configFileName; GraphicsEngine::getInstance()->initFromIniFile(&iniParser); LightManager::getInstance(); const char* dataPath; if ((dataPath = iniParser.getVar(CONFIG_NAME_DATADIR, CONFIG_SECTION_DATA))!= NULL) { if (!ResourceManager::getInstance()->setDataDir(dataPath)) { PRINTF(1)("Data Could not be located\n"); exit(-1); } } if (!ResourceManager::getInstance()->verifyDataDir(DEFAULT_DATA_DIR_CHECKFILE)) { PRINTF(1)("The DataDirectory %s could not be verified\n" \ " Please 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(); // initialize Timing framework->cycle = 0; for (unsigned int i = 0; i < TICK_SMOOTH_VALUE; i++) framework->frameTimes[i] = 100; framework->dtS = 0.0f; framework->lastFrame = SDL_GetTicks (); 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(); PNode::getNullParent()->updateNode(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); camera->apply(); camera->project(); this->moduleDraw(); SDL_GL_SwapBuffers(); // Swap the buffers } float Framework::tick() { // CALCULATE FRAMERATE Uint32 frameTimesIndex; Uint32 getTicks; Uint32 i; frameTimesIndex = this->cycle % TICK_SMOOTH_VALUE; getTicks = SDL_GetTicks(); this->frameTimes[frameTimesIndex] = getTicks - this->lastFrame; this->lastFrame = getTicks; ++this->cycle; this->dtS = 0; for (i = 0; i < TICK_SMOOTH_VALUE; i++) this->dtS += this->frameTimes[i]; this->dtS = this->dtS / TICK_SMOOTH_VALUE / 1000.0f * speed; this->camera->tick(dtS); this->moduleTick(dtS); return dtS; } 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(); camera = new Camera(); State::setCamera(camera, camera->getTarget()); camera->setAbsCoor(Vector(10, 10, 10)); this->isFinished = false; this->lastFrame = 0; // 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; } 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; }