/* * * Main universe - The one which switches and iterates the other Universes. * This is the PC-SDL version * * Copyright (C) 2006-2008 Alejandro Valenzuela Roca, * * http://mexinetica.com/~lanjoe9 * * This file is part of MotorJ, a free framework for videogame development. * * * MotorJ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MotorJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MotorJ. If not, see . */ /* Support libraries */ #include #include #ifndef VISUAL_STUDIO #include #endif #include #ifdef VISUAL_STUDIO #include #endif /* Note: GLEW _MUST_ be included BEFORE GL_H*/ #ifdef USE_GLEW #include #endif #include #include #ifdef VISUAL_STUDIO #include #endif #include #include #include #include #include #include "motorj/events.h" #include "motorj/app.h" #include "motorj/universe-class.h" #include "motorj/musicplayer-class.h" //#include "motorj/glContexts.h" // Not ready, do not use (yet) #include "universes.h" #include "motorj/app.h" mjApplication App; // Global application variable //Universe * CurrentUniverse; // app_init has been moved to "universes.cpp/.h" //void app_init(int argc, char ** argv); void inicializar(void); void translate_event(SDL_Event & sdl_ev, s_event * event); Universe * switch_universe(Universe * current_universe); int main(int argc, char ** argv){ SDL_Event ev; s_event event; Uint32 t_previous, t_current, t_sleep; Uint32 t_cyclestart, t_maxsleep; app_init(argc, argv); debug("Initializing.."); inicializar(); App.currentUniverse = create_universes(); if (App.fps < 1){ App.fps = 60; } t_maxsleep = (Uint32) (1/App.fps*1000); t_previous = SDL_GetTicks(); while ((App.currentUniverse) != NULL) { while (App.currentUniverse == App.currentUniverse->GetNextUniverse()) { t_cyclestart = SDL_GetTicks(); while (SDL_PollEvent(&ev)) { translate_event(ev,&event); event.pc = &ev; App.currentUniverse->ProcessEvent(event); } t_current = SDL_GetTicks(); App.t_elapsed = t_current - t_previous; t_previous = t_current; App.currentUniverse->Update(App.t_elapsed/1000.0); if (App.video_sup) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); t_previous = t_current; App.currentUniverse->Redraw(); if (App.video_sup) SDL_GL_SwapBuffers(); t_sleep = SDL_GetTicks() - t_cyclestart; if ((t_sleep < t_maxsleep) && (App.fps != 9999)) // 9999 = EGO mode SDL_Delay(t_maxsleep-t_sleep); } App.currentUniverse = switch_universe(App.currentUniverse); } // Cleaning up if (App.network_sup) SDLNet_Quit(); if (App.font_sup) TTF_Quit(); if (App.audio_sup) Mix_CloseAudio(); // Finally clean SDL stuff SDL_Quit(); debug("End of program, cleaning up.."); // And return return App.return_value; } void inicializar(void){ int size; if (App.fullscreen){ App.video_mode = SDL_OPENGL | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN; } else { App.video_mode = SDL_OPENGL | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_RESIZABLE; // | SDL_FULLSCREEN; } SDL_Init(SDL_INIT_VIDEO); App.audio_sup = false; if (!SDL_Init(SDL_INIT_AUDIO)) App.audio_sup = (! Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)); // Old audio API got dropped in favor of newer, cleaner, simpler one. // Set up network support App.network_sup = (SDLNet_Init() == 0); // Set up font support App.font_sup = (TTF_Init() == 0); if (!SDL_Init(SDL_INIT_JOYSTICK)){ //debug("Subsistema de joystick inicializado"); printf("Joystick subsystem initialized; %d joysticks present\n",SDL_NumJoysticks()); } /* Give the window a caption */ SDL_WM_SetCaption(App.argv[1], App.argv[1]); SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 ); App.screen = SDL_SetVideoMode(App.gl_width, App.gl_height, 0, App.video_mode); #ifdef GLCONTEXTS_H // Get current GL context data for multithreading mjGetglXData(&App.glContextData); #endif if (!App.screen){ debug("Error while attempting to set the video mode:"); debug(SDL_GetError()); debug("Exiting."); exit(1); } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0); glClearStencil(0); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_GetAttribute( SDL_GL_STENCIL_SIZE, &size); //FIXME: are these messages still needed? if (size < 8){ //debug("Stencil buffer might not have been correctly initialized (Got a(n) %d-bit buffer, an 8-bit buffer was expected)\n", size); } SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &size); if (size < 8){ //printf("The depth buffer might not have been correctly initialized (Got a(n) %d-bit buffer, a 24-bit buffer was expected)\n", size); } #ifdef USE_GLEW glewInit(); App.shaders_sup = (App.shaders_sup && GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader); if (! App.shaders_sup){ //printf("Shaders are not enabled\n"); } #else App.shaders_sup = 0; #endif glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glDepthMask( GL_TRUE ); glViewport (0, 0, (GLsizei) App.gl_width, (GLsizei) App.gl_height); glMatrixMode(GL_PROJECTION); /* Reset projection matrix */ glLoadIdentity (); // Establish a perspective matrix gluPerspective( 60.0, (GLfloat) App.gl_width / (GLfloat) App.gl_height, 1.0,1000.0); /* Set modelview matrix as the current matrix */ glMatrixMode(GL_MODELVIEW); } void translate_event(SDL_Event & sdl_ev, s_event * event) { /* * Extract data from SDL_Event and send them to the structure defined * in events.h */ SDL_Surface * tmp; event->key_down = NULL; event->key_up = NULL; event->quit = 0; event->mouse_button = 0; event->mouse_motion = false; switch(sdl_ev.type){ case SDL_KEYDOWN: event->key_down = sdl_ev.key.keysym.sym; break; case SDL_KEYUP: event->key_up = sdl_ev.key.keysym.sym; break; case SDL_QUIT: event->quit = 1; break; case SDL_VIDEORESIZE: if (tmp = SDL_SetVideoMode(sdl_ev.resize.w, sdl_ev.resize.h, 0, App.video_mode)) { App.screen = tmp; App.gl_width = sdl_ev.resize.w; App.gl_height = sdl_ev.resize.h; App.currentUniverse->Resize(App.gl_width, App.gl_height); } break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP : event->mouse_motion = false; event->mouse_x = sdl_ev.button.x; event->mouse_y = sdl_ev.button.y; event->mouse_button = sdl_ev.button.button; event->mouse_bdown = (sdl_ev.button.type == SDL_MOUSEBUTTONDOWN); break; case SDL_MOUSEMOTION: event->mouse_motion = true; event->mouse_x = sdl_ev.motion.x; event->mouse_y = sdl_ev.motion.y; break; } } Universe * switch_universe(Universe * current_universe) { //debug("Switching universe: from 0x%x to 0x%x", current_universe, current_universe->GetNextUniverse()); if (current_universe->mustCleanup) { //debug("Running Cleanup() routine for current universe.."); current_universe->Cleanup(); } if (current_universe->GetNextUniverse()) { //debug("Setting next universe's next universe..."); current_universe->GetNextUniverse()->SetNextUniverse(current_universe->GetNextUniverse()); if (current_universe->GetNextUniverse()->mustInit) current_universe->GetNextUniverse()->Init(); } return current_universe->GetNextUniverse(); }