/* * UltraStar Deluxe - Karaoke Game * * UltraStar Deluxe is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include #include #include "application.hpp" #include "event_manager.hpp" #include "mouse_manager.hpp" #include "software_mouse_pointer.hpp" #include "frames/loading_frame.hpp" namespace usdx { log4cpp::Category& Application::log = log4cpp::Category::getInstance("usdx.menu.application"); Application* Application::instance = NULL; Application::Application(Container* parent) : Container(parent), config(NULL), display(NULL), fps_manager(NULL), running(false), frames_per_second(50) { log4cpp::PropertyConfigurator::configure("log4cpp.property"); config = new Config(); set_size(config->get_graphics_resolution()); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); } Application::~Application() { if (config) { delete config; config = NULL; } if (fps_manager) { delete fps_manager; fps_manager = NULL; } SDL_Quit(); // reset instance to be able to recreate the singleton instance = NULL; } Application* Application::get_instance(void) { if (! instance) { instance = new Application(NULL); } return instance; } void Application::free(void) { delete instance; instance = NULL; } Config* Application::get_config(void) { return get_instance()->config; } bool Application::is_gl_thread(void) { return boost::this_thread::get_id() == get_instance()->gl_thread; } void Application::main_loop(SDL_Surface* display) { SDL_Event event; EventManager event_manager; MouseManager mouse_manager(event_manager); event_thread = boost::thread(boost::bind(&EventManager::handle_events, &event_manager)); SoftwareMousePointer pointer(this, &event_manager); LoadingFrame frame(this); running = true; while (running) { // repaint everything glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); repaint(); SDL_GL_SwapBuffers(); log << log4cpp::Priority::DEBUG << "repaint"; // poll current events while (event_manager.available() && SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: quit(); break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_q) { quit(); break; } if (event.key.keysym.sym == SDLK_d) { config->set_debug_boxes(!config->get_debug_boxes()); break; } /* fall throught */ default: event_manager.add_event(event); break; } } if (running) { // limit frames SDL_framerateDelay(fps_manager); } } event_thread.join(); } void Application::run(void) { if (! display) { // opengl settings SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // center screen char env[] = "SDL_VIDEO_CENTERED=center"; SDL_putenv(env); // fullscreen if requested from config Uint32 flags = SDL_OPENGL; if (config->get_graphics_fullscreen()) { flags |= SDL_FULLSCREEN; } // create screen display = SDL_SetVideoMode(get_width(), get_height(), 24, flags); glViewport(0, 0, get_width(), get_height()); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); // save current thread, to be able to detect whether some method is // called from the thread owning the OpenGL contect gl_thread = boost::this_thread::get_id(); // set-up the opengl projection matrix glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, get_width(), get_height(), 0.0f, -1.0f, 1.0f); // reset the modelview matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // the depth layer is not used, so disable the depth test for // higher performance glDisable(GL_DEPTH_TEST); } if (! display) { log << log4cpp::Priority::ERROR << "SDL_SetVideoMode failed."; throw new std::exception(); } init_fps_manager(); SDL_setFramerate(fps_manager, frames_per_second); SDL_ShowCursor(SDL_DISABLE); main_loop(display); SDL_ShowCursor(SDL_ENABLE); } void Application::quit(void) { running = false; event_thread.interrupt(); } const int Application::get_frames_per_second(void) const { return frames_per_second; } void Application::set_frames_per_second(int fps) { this->frames_per_second = fps; if (fps_manager) { SDL_setFramerate(fps_manager, frames_per_second); } } void Application::init_fps_manager(void) { if (! fps_manager) { fps_manager = new FPSmanager(); SDL_initFramerate(fps_manager); } } };