This commit is contained in:
konstin 2014-06-02 16:57:14 +02:00
commit 0db8531a5d
33 changed files with 398 additions and 237 deletions

View File

@ -61,5 +61,6 @@
</box>
<spacer width="20" height="15"/>
</div>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
</stkgui>

View File

@ -70,5 +70,6 @@
</box>
<spacer width="20" height="15"/>
</div>
<icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/>
</stkgui>

View File

@ -89,6 +89,19 @@ static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs_ARB;
static HGLRC getMeAGLContext(HDC HDc)
{
HGLRC hrc = 0;
int ctx44[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
0
};
hrc = wglCreateContextAttribs_ARB(HDc, 0, ctx44);
if (hrc)
return hrc;
int ctx40[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,

View File

@ -272,10 +272,12 @@ void PlayerManager::save()
<< m_current_player->getName() << L"\"/>\n";
}
// Save all non-guest players
PlayerProfile *player;
for_in(player, m_all_players)
{
player->save(players_file);
if(!player->isGuestAccount())
player->save(players_file);
}
players_file << L"</players>\n";
players_file.close();
@ -373,10 +375,36 @@ void PlayerManager::addDefaultPlayer()
// screen to be shown.
m_all_players.push_back(new Online::OnlinePlayerProfile(username.c_str()) );
// add default guest player
m_all_players.push_back(new Online::OnlinePlayerProfile(_LTR("Guest"), /*guest*/true));
} // addDefaultPlayer
// ----------------------------------------------------------------------------
/** Makes sure at least n guest players exist. This is used by the multiplayer
* KartSelection screen to make sure enough guest players can be picked by
* the players.
* \param n Minimum number of guest players that must exist.
*/
void PlayerManager::createGuestPlayers(int n)
{
int num_guests = m_all_players.size() - getNumNonGuestPlayers();
for(int i=num_guests; i<n; i++)
{
core::stringw guest_name;
if(i==0)
{
// I18N: Name of first guest player (without number)
guest_name = _LTR("Guest");
}
else
{
// I18N: Name of further guest players, with a 1, 2, ... attached
guest_name = _LTR("Guest %d", i);
}
PlayerProfile *guest = new Online::OnlinePlayerProfile(guest_name,
/*guest*/ true);
m_all_players.push_back(guest);
}
} // createGuestPlayers
// ----------------------------------------------------------------------------
/** Returns the number of 'real' (non-guest) players.
*/

View File

@ -92,6 +92,7 @@ public:
unsigned int getUniqueId() const;
void addDefaultPlayer();
PlayerProfile* addNewPlayer(const irr::core::stringw& name);
void createGuestPlayers(int n);
void deletePlayer(PlayerProfile *player);
void setCurrentPlayer(PlayerProfile *player);
const PlayerProfile *getPlayerById(unsigned int id);

View File

@ -146,7 +146,7 @@ void PlayerProfile::initRemainingData()
*/
void PlayerProfile::addIcon()
{
if (m_icon_filename.size() > 0)
if (m_icon_filename.size() > 0 || isGuestAccount())
return;
int n = m_unique_id % kart_properties_manager->getNumberOfKarts();

View File

@ -71,6 +71,9 @@ PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
PFNGLBLENDCOLORPROC glBlendColor;
PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
PFNGLTEXSTORAGE1DPROC glTexStorage1D;
PFNGLTEXSTORAGE2DPROC glTexStorage2D;
PFNGLTEXSTORAGE3DPROC glTexStorage3D;
#endif
static bool is_gl_init = false;
@ -220,6 +223,9 @@ void initGL()
glBlendColor = (PFNGLBLENDCOLORPROC)IRR_OGL_LOAD_EXTENSION("glBlendColor");
glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glCompressedTexImage2D");
glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)IRR_OGL_LOAD_EXTENSION("glGetCompressedTexImage");
glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage1D");
glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage2D");
glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexStorage3D");
#ifdef DEBUG
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB");
#endif

View File

@ -94,6 +94,9 @@ extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding;
extern PFNGLBLENDCOLORPROC glBlendColor;
extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
#ifdef DEBUG
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
#endif

View File

@ -361,12 +361,13 @@ private:
void renderTransparent();
void renderParticles();
void computeSunVisibility();
void renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadows);
void renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadows);
void computeCameraMatrix(scene::ICameraSceneNode * const camnode, size_t width, size_t height);
void renderShadows();
void renderGlow(std::vector<GlowData>& glows);
void renderSSAO();
void renderLights(scene::ICameraSceneNode * const camnode, float dt);
unsigned UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt);
void renderLights(unsigned pointlightCount);
void renderDisplacement();
void doScreenShot();
public:

View File

@ -143,8 +143,9 @@ void IrrDriver::renderGLSL(float dt)
const core::recti &viewport = camera->getViewport();
unsigned plc = UpdateLightsInfo(camnode, dt);
computeCameraMatrix(camnode, viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
renderScene(camnode, glows, dt, track->hasShadows());
renderScene(camnode, plc, glows, dt, track->hasShadows());
// Debug physic
// Note that drawAll must be called before rendering
@ -260,7 +261,7 @@ void IrrDriver::renderGLSL(float dt)
getPostProcessing()->update(dt);
}
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector<GlowData>& glows, float dt, bool hasShadow)
void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned pointlightcount, std::vector<GlowData>& glows, float dt, bool hasShadow)
{
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
@ -287,7 +288,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, std::vector
{
PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00);
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
renderLights(camnode, dt);
renderLights(pointlightcount);
PROFILER_POP_CPU_MARKER();
}
@ -900,37 +901,8 @@ static void renderPointLights(unsigned count)
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, count);
}
void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
unsigned IrrDriver::UpdateLightsInfo(scene::ICameraSceneNode * const camnode, float dt)
{
//RH
if (UserConfigParams::m_gi)
{
glDisable(GL_BLEND);
m_rtts->getRH().Bind();
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
}
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
sun_ortho_matrix[i] *= getInvViewMatrix();
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
if (!UserConfigParams::m_dynamic_lights)
glClearColor(.5, .5, .5, .5);
glClear(GL_COLOR_BUFFER_BIT);
if (!UserConfigParams::m_dynamic_lights)
return;
if (UserConfigParams::m_gi)
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
if (SkyboxCubeMap)
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
const u32 lightcount = m_lights.size();
const core::vector3df &campos = camnode->getAbsolutePosition();
@ -940,10 +912,6 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
if (!m_lights[i]->isPointLight())
{
m_lights[i]->render();
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
else
m_post_processing->renderSunlight();
continue;
}
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
@ -998,8 +966,51 @@ void IrrDriver::renderLights(scene::ICameraSceneNode * const camnode, float dt)
}
lightnum++;
return lightnum;
}
renderPointLights(MIN2(lightnum, MAXLIGHT));
void IrrDriver::renderLights(unsigned pointlightcount)
{
//RH
if (UserConfigParams::m_gi)
{
glDisable(GL_BLEND);
m_rtts->getRH().Bind();
glUseProgram(FullScreenShader::RadianceHintsConstructionShader::Program);
glBindVertexArray(FullScreenShader::RadianceHintsConstructionShader::vao);
setTexture(0, m_rtts->getRSM().getRTT()[0], GL_LINEAR, GL_LINEAR);
setTexture(1, m_rtts->getRSM().getRTT()[1], GL_LINEAR, GL_LINEAR);
setTexture(2, m_rtts->getRSM().getDepthTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::RadianceHintsConstructionShader::setUniforms(rsm_matrix, rh_matrix, rh_extend, 0, 1, 2);
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
}
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
sun_ortho_matrix[i] *= getInvViewMatrix();
m_rtts->getFBO(FBO_COMBINED_TMP1_TMP2).Bind();
if (!UserConfigParams::m_dynamic_lights)
glClearColor(.5, .5, .5, .5);
glClear(GL_COLOR_BUFFER_BIT);
if (!UserConfigParams::m_dynamic_lights)
return;
if (UserConfigParams::m_gi)
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH().getRTT()[0], m_rtts->getRH().getRTT()[1], m_rtts->getRH().getRTT()[2]);
if (SkyboxCubeMap)
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
// Render sunlight if and only if track supports shadow
if (World::getWorld()->getTrack()->hasShadows())
{
if (UserConfigParams::m_shadows)
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
else
m_post_processing->renderSunlight();
}
renderPointLights(MIN2(pointlightcount, MAXLIGHT));
if (SkyboxCubeMap)
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
}

View File

@ -27,7 +27,10 @@ static GLuint generateRTT(const core::dimension2du &res, GLint internalFormat, G
GLuint result;
glGenTextures(1, &result);
glBindTexture(GL_TEXTURE_2D, result);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
if (irr_driver->getGLSLVersion() < 420)
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, res.Width, res.Height, 0, format, type, 0);
else
glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, res.Width, res.Height);
return result;
}
@ -88,7 +91,7 @@ RTT::RTT(size_t width, size_t height)
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB8, GL_BGR, GL_UNSIGNED_BYTE);
RenderTargetTextures[RTT_SSAO] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_DISPLACE] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
@ -188,7 +191,7 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_TMP_128]);
FrameBuffers.push_back(new FrameBuffer(somevector, 128, 128));
if (irr_driver->getGLSLVersion() >= 150)
if (UserConfigParams::m_shadows)
{
glGenTextures(1, &shadowColorTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex);
@ -200,7 +203,10 @@ RTT::RTT(size_t width, size_t height)
somevector.clear();
somevector.push_back(shadowColorTex);
m_shadow_FBO = new FrameBuffer(somevector, shadowDepthTex, 1024, 1024, true);
}
if (UserConfigParams::m_gi)
{
//Todo : use "normal" shadowtex
glGenTextures(1, &RSM_Color);
glBindTexture(GL_TEXTURE_2D, RSM_Color);
@ -240,10 +246,13 @@ RTT::~RTT()
{
glDeleteTextures(RTT_COUNT, RenderTargetTextures);
glDeleteTextures(1, &DepthStencilTexture);
if (irr_driver->getGLSLVersion() >= 150)
if (UserConfigParams::m_shadows)
{
glDeleteTextures(1, &shadowColorTex);
glDeleteTextures(1, &shadowDepthTex);
}
if (UserConfigParams::m_gi)
{
glDeleteTextures(1, &RSM_Color);
glDeleteTextures(1, &RSM_Normal);
glDeleteTextures(1, &RSM_Depth);

View File

@ -668,6 +668,7 @@ namespace GUIEngine
#include "guiengine/widget.hpp"
#include "guiengine/dialog_queue.hpp"
#include "modes/demo_world.hpp"
#include "modes/cutscene_world.hpp"
#include "modes/world.hpp"
#include "states_screens/race_gui_base.hpp"
@ -1210,6 +1211,12 @@ namespace GUIEngine
}
if (gamestate == INGAME_MENU && dynamic_cast<CutsceneWorld*>(World::getWorld()) != NULL)
{
RaceGUIBase* rg = World::getWorld()->getRaceGUI();
if (rg != NULL) rg->renderGlobal(elapsed_time);
}
if (gamestate == MENU || gamestate == INGAME_MENU)
{
g_skin->drawTooltips();

View File

@ -309,6 +309,17 @@ namespace GUIEngine
virtual void onDialogClose() {}
};
class CutsceneScreen : public Screen
{
public:
CutsceneScreen(const char* name) : Screen(name, false)
{
setNeeds3D(true);
m_throttle_FPS = false;
}
virtual void onCutsceneEnd() = 0;
};
}
#endif

View File

@ -585,7 +585,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
if (device != NULL)
{
KartSelectionScreen::getRunningInstance()->playerJoin(device,
KartSelectionScreen::getRunningInstance()->joinPlayer(device,
false );
}
}

View File

@ -403,7 +403,7 @@ void setupRaceStart()
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(
PlayerManager::get()->getPlayer(0), device, NULL);
PlayerManager::get()->getPlayer(0), device);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{

View File

@ -43,6 +43,7 @@
#include <IMeshSceneNode.h>
#include <ISceneManager.h>
#include <algorithm>
#include <string>
bool CutsceneWorld::s_use_duration = false;
@ -187,12 +188,12 @@ void CutsceneWorld::update(float dt)
{
/*
{
PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
TrackObject* curr;
for_in(curr, objects)
{
printf("* %s\n", curr->getType().c_str());
}
PtrVector<TrackObject>& objects = m_track->getTrackObjectManager()->getObjects();
TrackObject* curr;
for_in(curr, objects)
{
printf("* %s\n", curr->getType().c_str());
}
}
**/
@ -235,18 +236,29 @@ void CutsceneWorld::update(float dt)
dt = (float)(m_time - prev_time);
}
float fade;
float fade = 0.0f;
float fadeIn = -1.0f;
float fadeOut = -1.0f;
if (m_time < 2.0f)
{
fade = 1.0f - (float)m_time / 2.0f;
fadeIn = 1.0f - (float)m_time / 2.0f;
}
else if (m_time > m_duration - 2.0f)
if (m_time > m_duration - 2.0f)
{
fade = (float)(m_time - (m_duration - 2.0f)) / 2.0f;
fadeOut = (float)(m_time - (m_duration - 2.0f)) / 2.0f;
}
else
if (fadeIn >= 0.0f && fadeOut >= 0.0f)
{
fade = 0.0f;
fade = std::max(fadeIn, fadeOut);
}
else if (fadeIn >= 0.0f)
{
fade = fadeIn;
}
else if (fadeOut >= 0.0f)
{
fade = fadeOut;
}
dynamic_cast<CutsceneGUI*>(m_race_gui)->setFadeLevel(fade);
@ -354,6 +366,15 @@ void CutsceneWorld::update(float dt)
it++;
}
}
bool isOver = (m_time > m_duration);
if (isOver && (s_use_duration || m_aborted))
{
GUIEngine::CutsceneScreen* cs = dynamic_cast<GUIEngine::CutsceneScreen*>(
GUIEngine::getCurrentScreen());
if (cs != NULL)
cs->onCutsceneEnd();
}
} // update
//-----------------------------------------------------------------------------
@ -440,10 +461,12 @@ void CutsceneWorld::enterRaceOverState()
*/
bool CutsceneWorld::isRaceOver()
{
bool isOver = (m_time > m_duration);
if (!s_use_duration && !m_aborted)
return false;
return m_time > m_duration;
return isOver;
} // isRaceOver
//-----------------------------------------------------------------------------

View File

@ -142,7 +142,7 @@ bool DemoWorld::updateIdleTimeAndStartDemo(float dt)
// Use keyboard 0 by default in --no-start-screen
device = input_manager->getDeviceList()->getKeyboard(0);
StateManager::get()->createActivePlayer(
PlayerManager::get()->getPlayer(0), device , NULL);
PlayerManager::get()->getPlayer(0), device);
// ASSIGN should make sure that only input from assigned devices
// is read.
input_manager->getDeviceList()->setAssignMode(ASSIGN);

View File

@ -67,7 +67,7 @@ void OverWorld::enterOverWorld()
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
device);
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))
{

View File

@ -824,7 +824,7 @@ void World::updateWorld(float dt)
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
device);
if (!kart_properties_manager->getKart(UserConfigParams::m_default_kart))
{

View File

@ -122,7 +122,7 @@ void StartGameProtocol::update()
if (StateManager::get()->getActivePlayers().size() >= 1) // more than one player, we're the first
new_player_id = 0;
else
new_player_id = StateManager::get()->createActivePlayer( profile_to_use, device , players[i]->user_profile);
new_player_id = StateManager::get()->createActivePlayer( profile_to_use, device);
device->setPlayer(StateManager::get()->getActivePlayer(new_player_id));
input_manager->getDeviceList()->setSinglePlayer(StateManager::get()->getActivePlayer(new_player_id));
@ -147,7 +147,7 @@ void StartGameProtocol::update()
if (!is_me)
{
StateManager::get()->createActivePlayer( NULL, NULL , players[i]->user_profile);
StateManager::get()->createActivePlayer( NULL, NULL );
race_manager->setPlayerKart(i, rki);
}

View File

@ -82,15 +82,76 @@ DEFINE_SCREEN_SINGLETON( GrandPrixLose );
// -------------------------------------------------------------------------------------
GrandPrixLose::GrandPrixLose() : Screen("grand_prix_lose.stkgui", false /* pause race */)
GrandPrixLose::GrandPrixLose() : CutsceneScreen("grand_prix_lose.stkgui")
{
setNeeds3D(true);
m_throttle_FPS = false;
} // GrandPrixLose
// -------------------------------------------------------------------------------------
void GrandPrixLose::onCutsceneEnd()
{
TrackObjectManager* tobjman = World::getWorld()->getTrack()->getTrackObjectManager();
if (m_kart_node[0] != NULL)
m_kart_node[0]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
if (m_kart_node[1] != NULL)
m_kart_node[1]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
if (m_kart_node[2] != NULL)
m_kart_node[2]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
if (m_kart_node[3] != NULL)
m_kart_node[3]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
for (unsigned int i = 0; i<m_all_kart_models.size(); i++)
delete m_all_kart_models[i];
m_all_kart_models.clear();
m_kart_node[0] = NULL;
m_kart_node[1] = NULL;
m_kart_node[2] = NULL;
m_kart_node[3] = NULL;
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
if (unlocked.size() > 0)
{
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->replaceTopMostScreen(scene);
PlayerManager::getCurrentPlayer()->clearUnlocked();
}
else
{
if (race_manager->raceWasStartedFromOverworld())
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
OverWorld::enterOverWorld();
}
else
{
// we assume the main menu was pushed before showing this menu
StateManager::get()->popMenu();
}
}
}
// -------------------------------------------------------------------------------------
bool GrandPrixLose::onEscapePressed()
{
((CutsceneWorld*)World::getWorld())->abortCutscene();
return false;
}
// -------------------------------------------------------------------------------------
void GrandPrixLose::loadedFromFile()
{
m_kart_node[0] = NULL;
@ -121,17 +182,6 @@ void GrandPrixLose::init()
void GrandPrixLose::tearDown()
{
Screen::tearDown();
((CutsceneWorld*)World::getWorld())->abortCutscene();
for (unsigned int i=0; i<m_all_kart_models.size(); i++)
delete m_all_kart_models[i];
m_all_kart_models.clear();
m_kart_node[0] = NULL;
m_kart_node[1] = NULL;
m_kart_node[2] = NULL;
m_kart_node[3] = NULL;
} // tearDown
// -------------------------------------------------------------------------------------
@ -181,36 +231,7 @@ void GrandPrixLose::eventCallback(GUIEngine::Widget* widget,
{
if (name == "continue")
{
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
if (unlocked.size() > 0)
{
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->replaceTopMostScreen(scene);
PlayerManager::getCurrentPlayer()->clearUnlocked();
}
else
{
if (race_manager->raceWasStartedFromOverworld())
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
OverWorld::enterOverWorld();
}
else
{
// we assume the main menu was pushed before showing this menu
StateManager::get()->popMenu();
}
}
((CutsceneWorld*)World::getWorld())->abortCutscene();
}
} // eventCallback

View File

@ -33,7 +33,7 @@ class TrackObject;
* \brief Screen shown at the end of a Grand Prix
* \ingroup states_screens
*/
class GrandPrixLose : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<GrandPrixLose>
class GrandPrixLose : public GUIEngine::CutsceneScreen, public GUIEngine::ScreenSingleton<GrandPrixLose>
{
friend class GUIEngine::ScreenSingleton<GrandPrixLose>;
@ -53,6 +53,10 @@ class GrandPrixLose : public GUIEngine::Screen, public GUIEngine::ScreenSingleto
public:
virtual void onCutsceneEnd() OVERRIDE;
virtual bool onEscapePressed() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE;

View File

@ -53,24 +53,21 @@ using namespace irr::core;
using namespace irr::gui;
using namespace irr::video;
const float KARTS_X = -0.62f;
const float KARTS_DELTA_X = 0.815f;
const float KARTS_X = -0.95f;
const float KARTS_DELTA_X = 1.9f;
const float KARTS_DELTA_Y = -0.55f;
const float KARTS_DEST_Z = 1.2f;
const float KARTS_INITIAL_Z = -10.0f;
const float KARTS_DEST_Z = -1.8f;
const float INITIAL_Y = 0.0f;
const float INITIAL_PODIUM_Y = -0.89f;
const float PODIUM_HEIGHT[3] = { 0.325f, 0.5f, 0.15f };
const float INITIAL_PODIUM_Y = -1.27f;
const float PODIUM_HEIGHT[3] = { 0.650f, 1.0f, 0.30f };
DEFINE_SCREEN_SINGLETON( GrandPrixWin );
// -------------------------------------------------------------------------------------
GrandPrixWin::GrandPrixWin() : Screen("grand_prix_win.stkgui", false /* pause race */)
GrandPrixWin::GrandPrixWin() : CutsceneScreen("grand_prix_win.stkgui")
{
setNeeds3D(true);
m_throttle_FPS = false;
m_kart_node[0] = NULL;
m_kart_node[1] = NULL;
m_kart_node[2] = NULL;
@ -83,6 +80,70 @@ GrandPrixWin::GrandPrixWin() : Screen("grand_prix_win.stkgui", false /* pause ra
// -------------------------------------------------------------------------------------
GrandPrixWin::~GrandPrixWin()
{
}
// -------------------------------------------------------------------------------------
void GrandPrixWin::onCutsceneEnd()
{
for (unsigned int i = 0; i<m_all_kart_models.size(); i++)
delete m_all_kart_models[i];
m_all_kart_models.clear();
if (m_unlocked_label != NULL)
{
manualRemoveWidget(m_unlocked_label);
delete m_unlocked_label;
m_unlocked_label = NULL;
}
TrackObjectManager* tobjman = World::getWorld()->getTrack()->getTrackObjectManager();
if (m_kart_node[0] != NULL)
m_kart_node[0]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
if (m_kart_node[1] != NULL)
m_kart_node[1]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
if (m_kart_node[2] != NULL)
m_kart_node[2]->getPresentation<TrackObjectPresentationSceneNode>()->getNode()->remove();
m_kart_node[0] = NULL;
m_kart_node[1] = NULL;
m_kart_node[2] = NULL;
m_podium_steps[0] = NULL;
m_podium_steps[1] = NULL;
m_podium_steps[2] = NULL;
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
if (PlayerManager::getCurrentPlayer()
->getRecentlyCompletedChallenges().size() > 0)
{
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->clearUnlocked();
FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance();
assert(unlocked.size() > 0);
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->replaceTopMostScreen(scene);
}
else
{
// we assume the main menu was pushed before showing this menu
StateManager::get()->popMenu();
}
}
// -------------------------------------------------------------------------------------
void GrandPrixWin::loadedFromFile()
{
} // loadedFromFile
@ -160,29 +221,17 @@ void GrandPrixWin::init()
// -------------------------------------------------------------------------------------
bool GrandPrixWin::onEscapePressed()
{
((CutsceneWorld*)World::getWorld())->abortCutscene();
return false;
}
// -------------------------------------------------------------------------------------
void GrandPrixWin::tearDown()
{
Screen::tearDown();
((CutsceneWorld*)World::getWorld())->abortCutscene();
for (unsigned int i = 0; i<m_all_kart_models.size(); i++)
delete m_all_kart_models[i];
m_all_kart_models.clear();
if (m_unlocked_label != NULL)
{
manualRemoveWidget(m_unlocked_label);
delete m_unlocked_label;
m_unlocked_label = NULL;
}
m_kart_node[0] = NULL;
m_kart_node[1] = NULL;
m_kart_node[2] = NULL;
m_podium_steps[0] = NULL;
m_podium_steps[1] = NULL;
m_podium_steps[2] = NULL;
} // tearDown
// -------------------------------------------------------------------------------------
@ -221,7 +270,7 @@ void GrandPrixWin::onUpdate(float dt)
core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
}
} // end for
@ -246,7 +295,7 @@ void GrandPrixWin::onUpdate(float dt)
core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
core::vector3df podium_pos = m_podium_steps[k]->getInitXYZ();
@ -274,7 +323,7 @@ void GrandPrixWin::onUpdate(float dt)
m_kart_y[k] += dt*(PODIUM_HEIGHT[k]);
core::vector3df kart_pos(m_kart_x[k], m_kart_y[k], m_kart_z[k]);
core::vector3df kart_rot(0, m_kart_rotation[k], 0);
core::vector3df kart_scale(0.5f, 0.5f, 0.5f);
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
m_kart_node[k]->move(kart_pos, kart_rot, kart_scale, false);
@ -310,29 +359,7 @@ void GrandPrixWin::eventCallback(GUIEngine::Widget* widget,
{
if (name == "continue")
{
// un-set the GP mode so that after unlocking, it doesn't try to continue the GP
race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE);
if (PlayerManager::getCurrentPlayer()
->getRecentlyCompletedChallenges().size() > 0)
{
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
PlayerManager::getCurrentPlayer()->clearUnlocked();
FeatureUnlockedCutScene* scene = FeatureUnlockedCutScene::getInstance();
assert(unlocked.size() > 0);
scene->addTrophy(race_manager->getDifficulty());
scene->findWhatWasUnlocked(race_manager->getDifficulty());
StateManager::get()->replaceTopMostScreen(scene);
}
else
{
// we assume the main menu was pushed before showing this menu
StateManager::get()->popMenu();
}
((CutsceneWorld*)World::getWorld())->abortCutscene();
}
} // eventCallback
@ -359,12 +386,12 @@ void GrandPrixWin::setKarts(const std::string idents_arg[3])
m_kart_x[i] = KARTS_X + i*KARTS_DELTA_X;
m_kart_y[i] = INITIAL_Y + KARTS_DELTA_Y;
m_kart_z[i] = -4; // to 1.2
m_kart_z[i] = KARTS_INITIAL_Z;
m_kart_rotation[i] = 0.0f;
core::vector3df kart_pos(m_kart_x[i], m_kart_y[i], m_kart_z[i]);
core::vector3df kart_rot(0, 0, 0);
core::vector3df kart_scale(0.5, 0.5, 0.5);
core::vector3df kart_scale(1.0f, 1.0f, 1.0f);
//FIXME: it's not ideal that both the track object and the presentation know the initial coordinates of the object
TrackObjectPresentationSceneNode* presentation = new TrackObjectPresentationSceneNode(

View File

@ -32,12 +32,14 @@ class TrackObject;
* \brief Screen shown at the end of a Grand Prix
* \ingroup states_screens
*/
class GrandPrixWin : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<GrandPrixWin>
class GrandPrixWin : public GUIEngine::CutsceneScreen, public GUIEngine::ScreenSingleton<GrandPrixWin>
{
friend class GUIEngine::ScreenSingleton<GrandPrixWin>;
GrandPrixWin();
virtual ~GrandPrixWin();
/** Global evolution of time */
double m_global_time;
@ -61,6 +63,10 @@ class GrandPrixWin : public GUIEngine::Screen, public GUIEngine::ScreenSingleton
public:
virtual void onCutsceneEnd() OVERRIDE;
virtual bool onEscapePressed() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE;

View File

@ -67,7 +67,7 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
device);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{

View File

@ -1005,7 +1005,7 @@ void KartSelectionScreen::init()
else */
// For now this is what will happen
{
playerJoin( input_manager->getDeviceList()->getLatestUsedDevice(),
joinPlayer( input_manager->getDeviceList()->getLatestUsedDevice(),
true );
w->updateItemDisplay();
}
@ -1063,24 +1063,24 @@ void KartSelectionScreen::unloaded()
// ----------------------------------------------------------------------------
// Return true if event was handled successfully
bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
bool KartSelectionScreen::joinPlayer(InputDevice* device, bool first_player)
{
if (UserConfigParams::logGUI())
Log::info("[KartSelectionScreen]", "playerJoin() invoked");
if (!m_multiplayer && !firstPlayer) return false;
Log::info("[KartSelectionScreen]", "joinPlayer() invoked");
if (!m_multiplayer && !first_player) return false;
assert (g_dispatcher != NULL);
DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts");
if (w == NULL)
{
Log::error("[KartSelectionScreen]", "playerJoin(): Called outside of "
Log::error("[KartSelectionScreen]", "joinPlayer(): Called outside of "
"kart selection screen.");
return false;
}
else if (device == NULL)
{
Log::error("[KartSelectionScreen]", "playerJoin(): Received null "
Log::error("[KartSelectionScreen]", "joinPlayer(): Received null "
"device pointer");
return false;
}
@ -1093,32 +1093,19 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
return false;
}
// ---- Get available area for karts
// make a copy of the area, ands move it to be outside the screen
Widget* kartsAreaWidget = getWidget("playerskarts");
// start at the rightmost of the screen
const int shift = irr_driver->getFrameSize().Width;
core::recti kartsArea(kartsAreaWidget->m_x + shift,
kartsAreaWidget->m_y,
kartsAreaWidget->m_x + shift + kartsAreaWidget->m_w,
kartsAreaWidget->m_y + kartsAreaWidget->m_h);
// ---- Create new active player
PlayerProfile* profile_to_use = PlayerManager::getCurrentPlayer();
if (!firstPlayer)
// Make sure enough guest character exists. At this stage this player has
// not been added, so the number of guests requested for the first player
// is 0 --> forcing at least one real player.
PlayerManager::get()->createGuestPlayers(
StateManager::get()->activePlayerCount());
if (!first_player)
{
const int player_profile_count = PlayerManager::get()->getNumPlayers();
for (int i=0; i<player_profile_count; i++)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(i);
if (player->isGuestAccount())
{
profile_to_use = player;
break;
}
}
// Give each player a different start profile
const int num_active_players = StateManager::get()->activePlayerCount();
profile_to_use = PlayerManager::get()->getPlayer(num_active_players);
// Remove multiplayer message
if (m_multiplayer_message != NULL)
@ -1132,7 +1119,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
}
const int new_player_id =
StateManager::get()->createActivePlayer( profile_to_use, device, NULL );
StateManager::get()->createActivePlayer( profile_to_use, device);
StateManager::ActivePlayer* aplayer =
StateManager::get()->getActivePlayer(new_player_id);
@ -1142,6 +1129,16 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
std::string selected_kart_group =
tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER);
// ---- Get available area for karts
// make a copy of the area, ands move it to be outside the screen
Widget* kartsAreaWidget = getWidget("playerskarts");
// start at the rightmost of the screen
const int shift = irr_driver->getFrameSize().Width;
core::recti kartsArea(kartsAreaWidget->m_x + shift,
kartsAreaWidget->m_y,
kartsAreaWidget->m_x + shift + kartsAreaWidget->m_w,
kartsAreaWidget->m_y + kartsAreaWidget->m_h);
// ---- Create player/kart widget
PlayerKartWidget* newPlayerWidget =
new PlayerKartWidget(this, aplayer, NULL, kartsArea, m_kart_widgets.size(),
@ -1157,7 +1154,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
Widget* fullarea = getWidget("playerskarts");
// in this special case, leave room for a message on the right
if (m_multiplayer && firstPlayer)
if (m_multiplayer && first_player)
{
const int splitWidth = fullarea->m_w / 2;
@ -1189,7 +1186,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
}
if (!firstPlayer)
if (!first_player)
{
// select something (anything) in the ribbon; by default, only the
// game master has something selected. Thus, when a new player joins,
@ -1197,17 +1194,17 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
w->setSelection(new_player_id, new_player_id, true);
newPlayerWidget->m_player_ident_spinner
->setFocusForPlayer(new_player_id);
->setFocusForPlayer(new_player_id);
}
if (!m_multiplayer)
{
input_manager->getDeviceList()->setSinglePlayer( StateManager::get()
->getActivePlayer(0));
->getActivePlayer(0));
}
return true;
} // playerJoin
} // joinPlayer
// -----------------------------------------------------------------------------

View File

@ -132,7 +132,7 @@ public:
/** \brief Called when a player hits 'fire'/'select' on his device to
* join the game */
bool playerJoin(InputDevice* device, bool firstPlayer);
bool joinPlayer(InputDevice* device, bool first_player);
/**
* \brief Called when a player hits 'rescue'/'cancel' on his device

View File

@ -358,7 +358,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
// Create player and associate player with keyboard
StateManager::get()->createActivePlayer(PlayerManager::getCurrentPlayer(),
device, NULL);
device);
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{

View File

@ -344,7 +344,10 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
{
race_manager->exitRace();
race_manager->setAIKartOverride("");
NetworkKartSelectionScreen::getInstance()->tearDown(); // be sure to delete the kart selection screen
// FIXME: why is this call necessary here? tearDown should be
// automatically called when the screen is left. Note that the
// NetworkKartSelectionScreen::getInstance()->tearDown(); caused #1347
KartSelectionScreen::getRunningInstance()->tearDown();
Screen* newStack[] = {MainMenuScreen::getInstance(),
RaceSetupScreen::getInstance(),
NULL};
@ -358,7 +361,10 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
{
race_manager->exitRace();
race_manager->setAIKartOverride("");
NetworkKartSelectionScreen::getInstance()->tearDown(); // be sure to delete the kart selection screen
// FIXME: why is this call necessary here? tearDown should be
// automatically called when the screen is left. Note that the
// NetworkKartSelectionScreen::getInstance()->tearDown(); caused #1347
KartSelectionScreen::getRunningInstance()->tearDown();
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
if (race_manager->raceWasStartedFromOverworld())

View File

@ -102,12 +102,11 @@ void StateManager::updateActivePlayerIDs()
// ----------------------------------------------------------------------------
int StateManager::createActivePlayer(PlayerProfile *profile,
InputDevice *device,
Online::OnlineProfile* user)
InputDevice *device)
{
ActivePlayer *p;
int i;
p = new ActivePlayer(profile, device, user);
p = new ActivePlayer(profile, device);
i = m_active_players.size();
m_active_players.push_back(p);
@ -254,8 +253,7 @@ void StateManager::onStackEmptied()
#endif
StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
InputDevice *device,
Online::OnlineProfile* user)
InputDevice *device)
{
#ifdef DEBUG
m_magic_number = 0xAC1EF1AE;
@ -264,7 +262,6 @@ StateManager::ActivePlayer::ActivePlayer(PlayerProfile* player,
m_player = player;
m_device = NULL;
m_kart = NULL;
m_online_user = user;
setDevice(device);
} // ActivePlayer

View File

@ -76,7 +76,6 @@ public:
{
friend class StateManager;
Online::OnlineProfile *m_online_user;
PlayerProfile *m_player;
InputDevice *m_device;
@ -86,8 +85,7 @@ public:
/** ID of this player within the list of active players */
int m_id;
ActivePlayer(PlayerProfile* player, InputDevice* device,
Online::OnlineProfile* user);
ActivePlayer(PlayerProfile* player, InputDevice* device);
#ifdef DEBUG
unsigned int m_magic_number;
@ -128,19 +126,6 @@ public:
* selecting his identity) */
void setPlayerProfile(PlayerProfile* player);
// --------------------------------------------------------------------
Online::OnlineProfile* getOnlineUser()
{
return m_online_user;
} // getOnlineUser
// --------------------------------------------------------------------
/** Call to change the identity of this player (useful when player is
* selecting his identity) */
void setOnlineUser(Online::OnlineProfile* user)
{
m_online_user = user;
}
// --------------------------------------------------------------------
/** ID of this player within the list of active players */
int getID() const
@ -197,8 +182,7 @@ public:
*/
const PlayerProfile* getActivePlayerProfile(const int id);
int createActivePlayer(PlayerProfile *profile, InputDevice *device,
Online::OnlineProfile* use);
int createActivePlayer(PlayerProfile *profile, InputDevice *device);
void removeActivePlayer(int id);
unsigned int activePlayerCount();

View File

@ -42,7 +42,7 @@ class TracksScreen : public GUIEngine::Screen,
public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() {} OVERRIDE;
virtual void loadedFromFile() OVERRIDE {};
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget,

View File

@ -284,6 +284,10 @@ void BaseUserScreen::eventCallback(Widget* widget,
deletePlayer();
}
} // options
else if (name == "back")
{
StateManager::get()->escapePressed();
}
return;