X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fsupertux%2Fscreen_manager.cpp;h=decc603e39b7a810acdb1e0d35b8f04752503566;hb=4344af0025fd9b399666864e4cb96b3f81fd50bc;hp=add990f652f0fd925bcf91e88d4fd6c9d256afea;hpb=e7b6de66f52eaf5ac50a6d15754adbc9e3966418;p=supertux.git diff --git a/src/supertux/screen_manager.cpp b/src/supertux/screen_manager.cpp index add990f65..decc603e3 100644 --- a/src/supertux/screen_manager.cpp +++ b/src/supertux/screen_manager.cpp @@ -1,5 +1,6 @@ // SuperTux // Copyright (C) 2006 Matthias Braun +// 2014 Ingo Ruhnke // // 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 @@ -17,20 +18,23 @@ #include "supertux/screen_manager.hpp" #include "audio/sound_manager.hpp" -#include "control/joystickkeyboardcontroller.hpp" +#include "control/input_manager.hpp" #include "gui/menu.hpp" #include "gui/menu_manager.hpp" +#include "scripting/scripting.hpp" #include "scripting/squirrel_util.hpp" #include "scripting/time_scheduler.hpp" -#include "supertux/constants.hpp" #include "supertux/console.hpp" +#include "supertux/constants.hpp" #include "supertux/gameconfig.hpp" +#include "supertux/game_session.hpp" #include "supertux/globals.hpp" #include "supertux/main.hpp" +#include "supertux/menu/menu_storage.hpp" #include "supertux/player_status.hpp" #include "supertux/resources.hpp" -#include "supertux/screen_fade.hpp" #include "supertux/screen.hpp" +#include "supertux/screen_fade.hpp" #include "supertux/timer.hpp" #include "video/drawing_context.hpp" #include "video/renderer.hpp" @@ -42,18 +46,15 @@ static const Uint32 TICKS_PER_FRAME = (Uint32) (1000.0 / LOGICAL_FPS); static const int MAX_FRAME_SKIP = 2; ScreenManager::ScreenManager() : - waiting_threads(), - running(), - speed(1.0), - nextpop(false), - nextpush(false), - fps(0), - next_screen(), - current_screen(), - console(), - screen_fade(), - screen_stack(), - screenshot_requested(false) + m_waiting_threads(), + m_menu_storage(new MenuStorage), + m_menu_manager(new MenuManager), + m_speed(1.0), + m_actions(), + m_fps(0), + m_screen_fade(), + m_screen_stack(), + m_screenshot_requested(false) { using namespace scripting; TimeScheduler::instance = new TimeScheduler(); @@ -64,65 +65,50 @@ ScreenManager::~ScreenManager() using namespace scripting; delete TimeScheduler::instance; TimeScheduler::instance = NULL; - - for(std::vector::iterator i = screen_stack.begin(); - i != screen_stack.end(); ++i) { - delete *i; - } } void -ScreenManager::push_screen(Screen* screen, ScreenFade* screen_fade) +ScreenManager::push_screen(std::unique_ptr screen, std::unique_ptr screen_fade) { - this->next_screen.reset(screen); - this->screen_fade.reset(screen_fade); - nextpush = !nextpop; - nextpop = false; - speed = 1.0f; + log_debug << "ScreenManager::push_screen(): " << screen.get() << std::endl; + assert(screen); + + m_screen_fade = std::move(screen_fade); + m_actions.push_back(Action(Action::PUSH_ACTION, std::move(screen))); } void -ScreenManager::exit_screen(ScreenFade* screen_fade) +ScreenManager::pop_screen(std::unique_ptr screen_fade) { - next_screen.reset(NULL); - this->screen_fade.reset(screen_fade); - nextpop = true; - nextpush = false; + log_debug << "ScreenManager::pop_screen(): stack_size: " << m_screen_stack.size() << std::endl; + + m_screen_fade = std::move(screen_fade); + m_actions.push_back(Action(Action::POP_ACTION)); } void -ScreenManager::set_screen_fade(ScreenFade* screen_fade) +ScreenManager::set_screen_fade(std::unique_ptr screen_fade) { - this->screen_fade.reset(screen_fade); + m_screen_fade = std::move(screen_fade); } void -ScreenManager::quit(ScreenFade* screen_fade) +ScreenManager::quit(std::unique_ptr screen_fade) { - for(std::vector::iterator i = screen_stack.begin(); - i != screen_stack.end(); ++i) - delete *i; - screen_stack.clear(); - - exit_screen(screen_fade); + m_screen_fade = std::move(screen_fade); + m_actions.push_back(Action(Action::QUIT_ACTION)); } void ScreenManager::set_speed(float speed) { - this->speed = speed; + m_speed = speed; } float ScreenManager::get_speed() const { - return speed; -} - -bool -ScreenManager::has_no_pending_fadeout() const -{ - return screen_fade.get() == NULL || screen_fade->done(); + return m_speed; } void @@ -131,8 +117,8 @@ ScreenManager::draw_fps(DrawingContext& context, float fps_fps) char str[60]; snprintf(str, sizeof(str), "%3.1f", fps_fps); const char* fpstext = "FPS"; - context.draw_text(Resources::small_font, fpstext, - Vector(SCREEN_WIDTH - Resources::small_font->get_text_width(fpstext) - Resources::small_font->get_text_width(" 99999") - BORDER_X, + context.draw_text(Resources::small_font, fpstext, + Vector(SCREEN_WIDTH - Resources::small_font->get_text_width(fpstext) - Resources::small_font->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), ALIGN_LEFT, LAYER_HUD); context.draw_text(Resources::small_font, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), ALIGN_RIGHT, LAYER_HUD); } @@ -140,34 +126,42 @@ ScreenManager::draw_fps(DrawingContext& context, float fps_fps) void ScreenManager::draw(DrawingContext& context) { + assert(!m_screen_stack.empty()); + static Uint32 fps_ticks = SDL_GetTicks(); - static int frame_count = 0; - current_screen->draw(context); - if(MenuManager::current() != NULL) - MenuManager::current()->draw(context); - if(screen_fade.get() != NULL) - screen_fade->draw(context); - Console::instance->draw(context); + m_screen_stack.back()->draw(context); + m_menu_manager->draw(context); - if(g_config->show_fps) - draw_fps(context, fps); + if (m_screen_fade) + { + m_screen_fade->draw(context); + } + + Console::current()->draw(context); + + if (g_config->show_fps) + { + draw_fps(context, m_fps); + } // if a screenshot was requested, pass request on to drawing_context - if (screenshot_requested) { + if (m_screenshot_requested) + { context.take_screenshot(); - screenshot_requested = false; + m_screenshot_requested = false; } context.do_drawing(); /* Calculate frames per second */ - if(g_config->show_fps) + if (g_config->show_fps) { + static int frame_count = 0; ++frame_count; - if(SDL_GetTicks() - fps_ticks >= 500) + if (SDL_GetTicks() - fps_ticks >= 500) { - fps = (float) frame_count / .5; + m_fps = (float) frame_count / .5; frame_count = 0; fps_ticks = SDL_GetTicks(); } @@ -177,55 +171,68 @@ ScreenManager::draw(DrawingContext& context) void ScreenManager::update_gamelogic(float elapsed_time) { - scripting::update_debugger(); + scripting::Scripting::current()->update_debugger(); scripting::TimeScheduler::instance->update(game_time); - current_screen->update(elapsed_time); - if (MenuManager::current() != NULL) - MenuManager::current()->update(); - if(screen_fade.get() != NULL) - screen_fade->update(elapsed_time); - Console::instance->update(elapsed_time); + + if (!m_screen_stack.empty()) + { + m_screen_stack.back()->update(elapsed_time); + } + + m_menu_manager->process_input(); + + if (m_screen_fade) + { + m_screen_fade->update(elapsed_time); + } + + Console::current()->update(elapsed_time); } void ScreenManager::process_events() { - g_jk_controller->update(); + InputManager::current()->update(); SDL_Event event; - while(SDL_PollEvent(&event)) + while (SDL_PollEvent(&event)) { - g_jk_controller->process_event(event); + InputManager::current()->process_event(event); - if(MenuManager::current() != NULL) - MenuManager::current()->event(event); + m_menu_manager->event(event); switch(event.type) { case SDL_QUIT: quit(); break; - + case SDL_WINDOWEVENT: - switch(event.window.type) + switch(event.window.event) { case SDL_WINDOWEVENT_RESIZED: - Renderer::instance()->resize(event.window.data1, - event.window.data2); - MenuManager::recalc_pos(); + VideoSystem::current()->resize(event.window.data1, + event.window.data2); + m_menu_manager->on_window_resize(); + break; + + case SDL_WINDOWEVENT_FOCUS_LOST: + if(GameSession::current() != NULL) { + GameSession::current()->toggle_pause(); + } break; } break; - + case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_F10) { g_config->show_fps = !g_config->show_fps; } - if (event.key.keysym.sym == SDLK_F11) + else if (event.key.keysym.sym == SDLK_F11) { g_config->use_fullscreen = !g_config->use_fullscreen; - Renderer::instance()->apply_config(); - MenuManager::recalc_pos(); + VideoSystem::current()->apply_config(); + m_menu_manager->on_window_resize(); } else if (event.key.keysym.sym == SDLK_PRINTSCREEN || event.key.keysym.sym == SDLK_F12) @@ -235,47 +242,88 @@ ScreenManager::process_events() else if (event.key.keysym.sym == SDLK_F1 && event.key.keysym.mod & KMOD_CTRL) { - Console::instance->toggle(); + Console::current()->toggle(); g_config->console_enabled = true; g_config->save(); } + else if (event.key.keysym.sym == SDLK_F2 && + event.key.keysym.mod & KMOD_CTRL) + { + g_config->developer_mode = !g_config->developer_mode; + log_info << "developer mode: " << g_config->developer_mode << std::endl; + } break; } } } +bool +ScreenManager::has_pending_fadeout() const +{ + return m_screen_fade && !m_screen_fade->done(); +} + void ScreenManager::handle_screen_switch() { - while( (next_screen.get() != NULL || nextpop) && - has_no_pending_fadeout()) { - if(current_screen.get() != NULL) { - current_screen->leave(); - } + if (has_pending_fadeout()) + { + // wait till the fadeout is completed before switching screens + } + else + { + m_screen_fade.reset(); - if(nextpop) { - if(screen_stack.empty()) { - running = false; - break; + // keep track of the current screen, as only that needs a call to Screen::leave() + Screen* current_screen = m_screen_stack.empty() ? nullptr : m_screen_stack.back().get(); + + // Screen::setup() might push more screens, so loop till everything is done + while (!m_actions.empty()) + { + // move actions to a new vector since setup() might modify it + auto actions = std::move(m_actions); + + for(auto it = actions.begin(); it != actions.end(); ++it) + { + auto& action = *it; + + switch (action.type) + { + case Action::POP_ACTION: + assert(!m_screen_stack.empty()); + if (current_screen == m_screen_stack.back().get()) + { + m_screen_stack.back()->leave(); + } + m_screen_stack.pop_back(); + break; + + case Action::PUSH_ACTION: + assert(action.screen); + + if (!m_screen_stack.empty()) + { + if (current_screen == m_screen_stack.back().get()) + { + m_screen_stack.back()->leave(); + } + } + m_screen_stack.push_back(std::move(action.screen)); + break; + + case Action::QUIT_ACTION: + m_screen_stack.clear(); + break; + } } - next_screen.reset(screen_stack.back()); - screen_stack.pop_back(); - } - if(nextpush && current_screen.get() != NULL) { - screen_stack.push_back(current_screen.release()); - } - nextpush = false; - nextpop = false; - speed = 1.0; - Screen* next_screen_ptr = next_screen.release(); - next_screen.reset(0); - if(next_screen_ptr) - next_screen_ptr->setup(); - current_screen.reset(next_screen_ptr); - screen_fade.reset(NULL); - - waiting_threads.wakeup(); + if (!m_screen_stack.empty()) + { + m_screen_stack.back()->setup(); + m_speed = 1.0; + m_waiting_threads.wakeup(); + } + } } } @@ -285,27 +333,25 @@ ScreenManager::run(DrawingContext &context) Uint32 last_ticks = 0; Uint32 elapsed_ticks = 0; - running = true; - while(running) { - - handle_screen_switch(); - if(!running || current_screen.get() == NULL) - break; + handle_screen_switch(); + while (!m_screen_stack.empty()) + { Uint32 ticks = SDL_GetTicks(); elapsed_ticks += ticks - last_ticks; last_ticks = ticks; Uint32 ticks_per_frame = (Uint32) (TICKS_PER_FRAME * g_game_speed); - if (elapsed_ticks > ticks_per_frame*4) { + if (elapsed_ticks > ticks_per_frame*4) + { // when the game loads up or levels are switched the // elapsed_ticks grows extremely large, so we just ignore those // large time jumps elapsed_ticks = 0; } - if(elapsed_ticks < ticks_per_frame) + if (elapsed_ticks < ticks_per_frame) { Uint32 delay_ticks = ticks_per_frame - elapsed_ticks; SDL_Delay(delay_ticks); @@ -315,12 +361,12 @@ ScreenManager::run(DrawingContext &context) int frames = 0; - while(elapsed_ticks >= ticks_per_frame && frames < MAX_FRAME_SKIP) + while (elapsed_ticks >= ticks_per_frame && frames < MAX_FRAME_SKIP) { elapsed_ticks -= ticks_per_frame; float timestep = 1.0 / LOGICAL_FPS; real_time += timestep; - timestep *= speed; + timestep *= m_speed; game_time += timestep; process_events(); @@ -328,16 +374,21 @@ ScreenManager::run(DrawingContext &context) frames += 1; } - draw(context); + if (!m_screen_stack.empty()) + { + draw(context); + } + + SoundManager::current()->update(); - sound_manager->update(); + handle_screen_switch(); } } -void +void ScreenManager::take_screenshot() { - screenshot_requested = true; + m_screenshot_requested = true; } /* EOF */