stk-code_catmod/src/states_screens/state_manager.cpp
2017-11-13 12:48:03 +11:00

320 lines
8.8 KiB
C++

// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Marianne Gagnon
//
// 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 3
// 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; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/state_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "audio/music_manager.hpp"
#include "config/stk_config.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/screen_keyboard.hpp"
#include "input/input_device.hpp"
#include "input/input_manager.hpp"
#include "main_loop.hpp"
#include "modes/profile_world.hpp"
#include "modes/world.hpp"
#include "utils/translation.hpp"
#include "utils/log.hpp"
using namespace GUIEngine;
static StateManager* state_manager_singleton = NULL;
StateManager* StateManager::get()
{
if (state_manager_singleton == NULL)
state_manager_singleton = new StateManager();
return state_manager_singleton;
} // get
void StateManager::deallocate()
{
delete state_manager_singleton;
state_manager_singleton = NULL;
} // deallocate
// ============================================================================
#if 0
#pragma mark -
#pragma mark Player Management
#endif
// ----------------------------------------------------------------------------
StateManager::ActivePlayer* StateManager::getActivePlayer(const int id)
{
ActivePlayer *returnPlayer = NULL;
if (id < (int)m_active_players.size() && id >= 0)
{
returnPlayer = m_active_players.get(id);
}
else
{
Log::error("StateManager", "getActivePlayer(): id %d out of bounds", id);
assert(false);
return NULL;
}
assert( returnPlayer->m_id == id );
return returnPlayer;
} // getActivePlayer
// ----------------------------------------------------------------------------
const PlayerProfile* StateManager::getActivePlayerProfile(const int id)
{
ActivePlayer* a = getActivePlayer(id);
if (a == NULL) return NULL;
return a->getProfile();
} // getActivePlayerProfile
// ----------------------------------------------------------------------------
void StateManager::updateActivePlayerIDs()
{
const int amount = m_active_players.size();
for (int n=0; n<amount; n++)
{
m_active_players[n].m_id = n;
}
} // updateActivePlayerIDs
// ----------------------------------------------------------------------------
int StateManager::createActivePlayer(PlayerProfile *profile,
InputDevice *device)
{
ActivePlayer *p;
int i;
p = new ActivePlayer(profile, device);
i = m_active_players.size();
m_active_players.push_back(p);
updateActivePlayerIDs();
return i;
} // createActivePlayer
// ----------------------------------------------------------------------------
void StateManager::removeActivePlayer(int id)
{
m_active_players.erase(id);
updateActivePlayerIDs();
} // removeActivePlayer
// ----------------------------------------------------------------------------
unsigned int StateManager::activePlayerCount()
{
return m_active_players.size();
} // activePlayerCount
// ----------------------------------------------------------------------------
void StateManager::resetActivePlayers()
{
const int amount = m_active_players.size();
for(int i=0; i<amount; i++)
{
m_active_players[i].setDevice(NULL);
}
m_active_players.clearAndDeleteAll();
} // resetActivePlayers
// ----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark misc stuff
#endif
bool StateManager::throttleFPS()
{
#ifndef SERVER_ONLY
return m_game_mode != GUIEngine::GAME &&
GUIEngine::getCurrentScreen()->throttleFPS();
#else
return true;
#endif
} // throttleFPS
// ----------------------------------------------------------------------------
void StateManager::escapePressed()
{
// in input sensing mode
if(input_manager->isInMode(InputManager::INPUT_SENSE_KEYBOARD) ||
input_manager->isInMode(InputManager::INPUT_SENSE_GAMEPAD) )
{
ScreenKeyboard::dismiss();
ModalDialog::dismiss();
input_manager->setMode(InputManager::MENU);
}
// when another modal dialog is visible
else if(ScreenKeyboard::isActive())
{
if(ScreenKeyboard::getCurrent()->onEscapePressed())
ScreenKeyboard::getCurrent()->dismiss();
}
// when another modal dialog is visible
else if(ModalDialog::isADialogActive())
{
if(ModalDialog::getCurrent()->onEscapePressed())
ModalDialog::getCurrent()->dismiss();
}
// In-game
else if(m_game_mode == GAME)
{
if(World::getWorld()->getPhase()!=WorldStatus::RESULT_DISPLAY_PHASE
&& !ProfileWorld::isProfileMode())
World::getWorld()->escapePressed();
}
// In menus
else
{
if (getCurrentScreen() != NULL &&
getCurrentScreen()->onEscapePressed()) popMenu();
}
} // escapePressed
// ----------------------------------------------------------------------------
void StateManager::onGameStateChange(GameState new_state)
{
if (new_state == GAME)
{
if (race_manager->getMinorMode() != RaceManager::MINOR_MODE_OVERWORLD)
irr_driver->hidePointer();
input_manager->setMode(InputManager::INGAME);
}
else // menu (including in-game menu)
{
irr_driver->showPointer();
input_manager->setMode(InputManager::MENU);
SFXManager::get()->positionListener( Vec3(0,0,0), Vec3(0,1,0), Vec3(0, 1, 0) );
if (new_state == MENU)
{
GUIEngine::Screen* screen = GUIEngine::getCurrentScreen();
if (screen != NULL)
{
music_manager->startMusic(
GUIEngine::getCurrentScreen()->getMusic());
}
}
}
} // onGameStateChange
// ----------------------------------------------------------------------------
void StateManager::onTopMostScreenChanged()
{
if (m_game_mode == MENU && GUIEngine::getCurrentScreen() != NULL)
{
if (GUIEngine::getCurrentScreen()->getMusic() != NULL)
{
music_manager->startMusic(GUIEngine::getCurrentScreen()->getMusic());
}
}
else if (m_game_mode == INGAME_MENU && GUIEngine::getCurrentScreen() != NULL)
{
if (GUIEngine::getCurrentScreen()->getInGameMenuMusic() != NULL)
{
music_manager->startMusic(GUIEngine::getCurrentScreen()->getInGameMenuMusic());
}
}
} // onTopMostScreenChanged
// ----------------------------------------------------------------------------
void StateManager::onStackEmptied()
{
#ifdef ANDROID
ANativeActivity_finish(global_android_app->activity);
#else
GUIEngine::cleanUp();
GUIEngine::deallocate();
main_loop->abort();
#endif
} // onStackEmptied
// ============================================================================
#if 0
#pragma mark -
#pragma mark ActivePlayer
#endif
StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
InputDevice *device)
{
#ifdef DEBUG
m_magic_number = 0xAC1EF1AE;
#endif
m_player = player;
m_device = NULL;
m_kart = NULL;
setDevice(device);
} // ActivePlayer
// ----------------------------------------------------------------------------
StateManager::ActivePlayer::~ActivePlayer()
{
setDevice(NULL);
#ifdef DEBUG
m_magic_number = 0xDEADBEEF;
#endif
} // ~ActivePlayer
// ----------------------------------------------------------------------------
void StateManager::ActivePlayer::setPlayerProfile(PlayerProfile* player)
{
#ifdef DEBUG
assert(m_magic_number == 0xAC1EF1AE);
#endif
m_player = player;
} // setPlayerProfile
// ----------------------------------------------------------------------------
void StateManager::ActivePlayer::setDevice(InputDevice* device)
{
#ifdef DEBUG
assert(m_magic_number == 0xAC1EF1AE);
#endif
// unset player from previous device he was assigned to, if any
if (m_device != NULL) m_device->setPlayer(NULL);
m_device = device;
// inform the devce of its new owner
if (device != NULL) device->setPlayer(this);
} // setDevice