aboutsummaryrefslogblamecommitdiffstats
path: root/src/menu/application.cpp
blob: d5f9c34f31b6cdca51f6080a21ae91ac163a2078 (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.
 *
 * $URL$
 * $Id$
 */

#include "application.hpp"
#include "event_manager.hpp"
#include <exception>
#include "software_mouse_pointer.hpp"
#include "frames/loading_frame.hpp"
#include <GL/gl.h>
#include <log4cpp/PropertyConfigurator.hh>

namespace usdx
{
	log4cpp::Category&  Application::log =
		log4cpp::Category::getInstance("usdx.menu.application");

	Application* Application::instance = NULL;

	Application::Application(Control* parent)
		: DrawableControl(parent), display(NULL), frame(NULL),
		  fps_manager(NULL), running(false), display_width(800),
		  display_height(600), frames_per_second(50)
	{
        log4cpp::PropertyConfigurator::configure("log4cpp.property");
		SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
	}

	Application::~Application()
	{
		for (std::list<DrawableControl*>::iterator it =
			     overlays.begin(); it != overlays.end(); it++) {
			delete *it;
		}

		overlays.clear();

		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::draw(void)
	{
		if (frame) {
			frame->repaint();
		}
	}

	void Application::repaint(void) {
		DrawableControl::repaint();

		for (std::list<DrawableControl*>::const_iterator it =
			     overlays.begin();
		     it != overlays.end(); it++) {

			(*it)->repaint();
		}
	}

	const Frame *Application::get_current_frame(void) const
	{
		return frame;
	}

	void Application::set_current_frame(Frame* new_frame)
	{
		frame = new_frame;
	}

	void Application::main_loop(SDL_Surface* display)
	{
		SDL_Event event;
		EventManager event_manager;
		boost::thread event_thread(boost::bind(&EventManager::handle_events, &event_manager));
		overlays.push_front(new SoftwareMousePointer(NULL, &event_manager));

		LoadingFrame frame;
		set_current_frame(&frame);

		running = true;
		while (running) {
			// repaint everything
			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:
					running = false;
					event_thread.interrupt();

				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 test[] = "SDL_VIDEO_CENTERED=center";
			SDL_putenv(test);

			// create screen
			display = SDL_SetVideoMode(display_width,
						   display_height,
						   24,
						   SDL_OPENGL);

			glEnable( GL_TEXTURE_2D );

			glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );

			glViewport( 0, 0, display_width, display_height );

			glClear( GL_COLOR_BUFFER_BIT );

			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
			glEnable(GL_COLOR_MATERIAL);

			glMatrixMode( GL_PROJECTION );
			glLoadIdentity();

			glOrtho(0.0f, display_width, display_height, 0.0f, -1.0f, 1.0f);

			glMatrixMode( GL_MODELVIEW );
			glLoadIdentity();
		}

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

	const int Application::get_display_width(void) const
	{
		return display_width;
	}

	const int Application::get_display_height(void) const
	{
		return display_height;
	}

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