aboutsummaryrefslogblamecommitdiffstats
path: root/src/menu/application.cpp
blob: 55edd69cf0cbb65216f91ce938d1fe0b9384d723 (plain) (tree)





















                                                                        

   






                                          
                          
                            
                            
                                     
 
                                   


              

                                                                        


                                                  
                                                   
                                                                                    
                                                       
         
                                                                             
                                      

                                                            
                                                          



                                   




                                      





                                           


                                                                      










                                                         





                                    




                                              




                                                                                 


                                                         
                                           
                                                          
                                                                                                        
 
                                                                   
                                         
 


                                             

                                                     

                                             
 
                                                                     

                                              
                                                                                    

                                                     
                                               



                                                                             
                                                       


                                                      




                                                                                                    
                                                           



                                                                       


                                 



                                                                
                 

                                    




                                   







                                                                    

                                                                 
 




                                                                
 

                                                                                         
                                                                    
 
                                                             
                                                     


                                                                                           
 
                                                              
                                                    
                                         
                                                                                    
 
                                                     
                                                   
                                         
 

                                                                                     
                                                 


                                

                                                                          

                 


                                                                 
 

                                            
                                   

                                           

         





                                         




















                                                                         
  
/*
 * 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 <cstddef>
#include <exception>

#include <GL/gl.h>

#include <log4cpp/PropertyConfigurator.hh>

#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);
		}
	}
};