diff --git a/.gitignore b/.gitignore index 845c64ce0..0dbc751f9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,12 +6,15 @@ build-win/ cmake_build/ dependencies/ CMakeFiles/ +stk-editor/ .config/ supertuxkart-64 +data/editor data/karts data/library +data/models data/music data/sfx data/textures diff --git a/.travis.yml b/.travis.yml index 86a203378..06ef93281 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,8 +15,9 @@ before_install: - sudo apt-get update -qq # Install dependencies - sudo apt-get install build-essential cmake libogg-dev libvorbis-dev libopenal-dev libxxf86vm-dev libcurl4-openssl-dev libfribidi-dev libbluetooth-dev - # Install mesa from an other repo (a newer version is required) - - sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu quantal main restricted" + # Install mesa from an other repo (a newer version is required). Quantal is not supported anymore, saucy is only supported till July 2014, + # so we try to use trusty (precise which is what traiv uses a too old mesa version which doesn't link) + - sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu trusty main restricted" - sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 3B4FE6ACC0B21F32 - sudo apt-get update -qq - sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev diff --git a/data/gui/custom_video_settings.stkgui b/data/gui/custom_video_settings.stkgui index 2942c4312..e5383347b 100644 --- a/data/gui/custom_video_settings.stkgui +++ b/data/gui/custom_video_settings.stkgui @@ -70,27 +70,11 @@ - - -
-
- - -
- - - -
- - -
-
-
+ +
@@ -105,7 +89,27 @@
+ + +
+ + +
+ + +
+ + + +
+ + +
+
+
@@ -136,9 +140,9 @@
- + -
diff --git a/data/shaders/grass_pass2.frag b/data/shaders/grass_pass2.frag index 5d1b17101..55aeecf59 100644 --- a/data/shaders/grass_pass2.frag +++ b/data/shaders/grass_pass2.frag @@ -3,6 +3,7 @@ uniform mat4 ViewMatrix; uniform mat4 ProjectionMatrix; uniform mat4 InverseViewMatrix; uniform mat4 InverseProjectionMatrix; +uniform vec2 screen; #else layout (std140) uniform MatrixesData { diff --git a/data/shaders/instanciedgrassshadow.vert b/data/shaders/instanciedgrassshadow.vert index f644039f9..92c21af65 100644 --- a/data/shaders/instanciedgrassshadow.vert +++ b/data/shaders/instanciedgrassshadow.vert @@ -17,6 +17,7 @@ layout(location = 8) in vec3 Orientation; layout(location = 9) in vec3 Scale; #else in vec3 Position; +in vec4 Color; in vec2 Texcoord; in vec3 Origin; diff --git a/data/shaders/rh.frag b/data/shaders/rh.frag index 6b1a45c16..ed760b4ab 100644 --- a/data/shaders/rh.frag +++ b/data/shaders/rh.frag @@ -60,7 +60,7 @@ void main(void) vec2 uv = RHuv + offset * 0.01; // Get world position and normal from the RSM sample - float depth = texture2D(dtex, uv).z; + float depth = texture(dtex, uv).z; vec4 RSMPos = inverse(RSMMatrix) * (2. * vec4(uv, depth, 1.) - 1.); RSMPos /= RSMPos.w; vec3 RSMAlbedo = texture(ctex, uv).xyz; diff --git a/data/shaders/rsm.vert b/data/shaders/rsm.vert index 5ed3b9ad4..69846d811 100644 --- a/data/shaders/rsm.vert +++ b/data/shaders/rsm.vert @@ -8,11 +8,17 @@ uniform mat4 TextureMatrix = 0., 0., 1., 0., 0., 0., 0., 1.); - +#if __VERSION__ >= 330 layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; layout(location = 2) in vec4 Color; layout(location = 3) in vec2 Texcoord; +#else +in vec3 Position; +in vec3 Normal; +in vec4 Color; +in vec2 Texcoord; +#endif out vec3 nor; out vec2 uv; diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert index d1212e7ea..d7f6316e6 100644 --- a/data/shaders/shadow.vert +++ b/data/shaders/shadow.vert @@ -9,8 +9,13 @@ layout (std140) uniform MatrixesData uniform mat4 ModelMatrix; +#if __VERSION__ >= 330 layout(location = 0) in vec3 Position; layout(location = 3) in vec2 Texcoord; +#else +in vec3 Position; +in vec2 Texcoord; +#endif #ifdef VSLayer out vec2 uv; diff --git a/data/shaders/shadow_grass.vert b/data/shaders/shadow_grass.vert index 0e26cdb4f..7b1ce0caf 100644 --- a/data/shaders/shadow_grass.vert +++ b/data/shaders/shadow_grass.vert @@ -10,9 +10,15 @@ layout (std140) uniform MatrixesData uniform mat4 ModelMatrix; uniform vec3 windDir; +#if __VERSION__ >= 330 layout(location = 0) in vec3 Position; layout(location = 2) in vec4 Color; layout(location = 3) in vec2 Texcoord; +#else +in vec3 Position; +in vec4 Color; +in vec2 Texcoord; +#endif #ifdef VSLayer out vec2 uv; diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag index 7ecd3dbaa..c31e34f0b 100644 --- a/data/shaders/ssao.frag +++ b/data/shaders/ssao.frag @@ -26,7 +26,7 @@ out float AO; const float sigma = 1.; const float tau = 7.; -const float beta = 0.001; +const float beta = 0.002; const float epsilon = .00001; const float radius = 1.; const float k = 1.5; diff --git a/src/config/device_config.cpp b/src/config/device_config.cpp index 32db91569..488550389 100644 --- a/src/config/device_config.cpp +++ b/src/config/device_config.cpp @@ -19,6 +19,7 @@ #include #include "config/device_config.hpp" +#include "utils/log.hpp" #include using namespace irr; @@ -226,7 +227,7 @@ bool DeviceConfig::deserializeAction(irr::io::IrrXMLReader* xml) // Never hurts to check ;) if (xml == NULL) { - fprintf(stderr, "Error: null pointer (DeviceConfig::deserializeAction)\n"); + Log::error("DeviceConfig", "Null pointer (DeviceConfig::deserializeAction)"); return false; } @@ -243,8 +244,8 @@ bool DeviceConfig::deserializeAction(irr::io::IrrXMLReader* xml) } if(binding_id==-1) { - printf("WARNING: DeviceConfig::deserializeAction : action '%s' is unknown\n", - name_string); + Log::warn("DeviceConfig", "DeviceConfig::deserializeAction : action '%s' is unknown.", + name_string); return false; } @@ -349,23 +350,15 @@ GamepadConfig::GamepadConfig(irr::io::IrrXMLReader* xml) : DeviceConfig( DEVICE_ { const char* name_string = xml->getAttributeValue("name"); if(name_string == NULL) - { - printf("ERROR: Unnamed joystick in config file\n"); - } + Log::error("DeviceConfig", "Unnamed joystick in config file."); else - { m_name = name_string; - } const char* enabled_string = xml->getAttributeValue("enabled"); if (enabled_string != NULL) - { m_enabled = (strcmp(enabled_string, "true") == 0); - } else - { m_enabled = true; - } m_plugged = 0; setDefaultBinds(); diff --git a/src/config/user_config.cpp b/src/config/user_config.cpp index 3cf9171cb..5294ef234 100644 --- a/src/config/user_config.cpp +++ b/src/config/user_config.cpp @@ -713,8 +713,8 @@ bool UserConfig::loadConfig() // add back the code previously there that upgraded the config file to the new // format instead of overwriting it. - GUIEngine::showMessage( _("Your config file was too old, so it was deleted and a new one will be created."), 10.0f); - printf("Your config file was too old, so it was deleted and a new one will be created."); + GUIEngine::showMessage(_("Your config file was too old, so it was deleted and a new one will be created."), 10.0f); + Log::info("UserConfig", "Your config file was too old, so it was deleted and a new one will be created."); delete root; return false; diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 70a57c36f..2ebed145a 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -205,8 +205,8 @@ void Camera::setupCamera() break; default: if(UserConfigParams::logMisc()) - fprintf(stderr, "Incorrect number of players: '%d' - assuming 1.\n", - race_manager->getNumLocalPlayers()); + Log::warn("Camera", "Incorrect number of players: '%d' - assuming 1.", + race_manager->getNumLocalPlayers()); m_viewport = core::recti(0, 0, UserConfigParams::m_width, UserConfigParams::m_height); diff --git a/src/graphics/camera.hpp b/src/graphics/camera.hpp index e9555ea7f..125bc439f 100644 --- a/src/graphics/camera.hpp +++ b/src/graphics/camera.hpp @@ -155,10 +155,9 @@ private: m_type = EC_AHEAD_OF_KART; else { - fprintf(stderr, - "Invalid camera type '%s' - camera is ignored.\n", - s.c_str()); - return false; + Log::warn("Camera", "Invalid camera type '%s' - camera is ignored.", + s.c_str()); + return false; } node.get("xyz", &m_position); node.get("distance", &m_distance2); diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index b2418fa0e..fedc76f07 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1931,8 +1931,9 @@ void IrrDriver::update(float dt) // ================================= if (!m_device->run()) { - GUIEngine::cleanUp(); - GUIEngine::deallocate(); + // Don't bother cleaning up GUI, has no use and may result in crashes + //GUIEngine::cleanUp(); + //GUIEngine::deallocate(); main_loop->abort(); return; } diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index a5fea5f95..544cf635a 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -239,7 +239,7 @@ bool MaterialManager::pushTempMaterial(const XMLNode *root, if(!node) { // We don't have access to the filename at this stage anymore :( - fprintf(stderr, "Unknown node in material.xml file\n"); + Log::warn("MaterialManager", "Unknown node in material.xml file."); continue; } try @@ -249,7 +249,7 @@ bool MaterialManager::pushTempMaterial(const XMLNode *root, catch(std::exception& e) { // The message contains a '%s' for the filename - fprintf(stderr, e.what(), filename.c_str()); + Log::warn("MaterialManager", e.what(), filename.c_str()); } } // for igetNumNodes)( return true; diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index bfc66d6b3..8bf4d0ada 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -581,7 +581,7 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) } default: { - fprintf(stderr, "[ParticleEmitter] Unknown shape\n"); + Log::error("ParticleEmitter", "Unknown shape"); return; } } diff --git a/src/graphics/particle_kind.cpp b/src/graphics/particle_kind.cpp index e23b4e92e..d332ceacf 100644 --- a/src/graphics/particle_kind.cpp +++ b/src/graphics/particle_kind.cpp @@ -100,7 +100,7 @@ ParticleKind::ParticleKind(const std::string file) : m_min_start_color(255,255,2 } else { - fprintf(stderr, "[ParticleKind] main node has unknown value for attribute 'emitter'\n"); + Log::warn("ParticleKind", " main node has unknown value for attribute 'emitter'."); m_shape = EMITTER_POINT; } @@ -254,8 +254,8 @@ Material* ParticleKind::getMaterial() const } else { - fprintf(stderr, "[ParticleKind] WARNING: particle image '%s' does not appear in the list of " - "currently known materials\n", m_material_file.c_str()); + Log::warn("ParticleKind", "Particle image '%s' does not appear in the list of " + "currently known materials.", m_material_file.c_str()); return NULL; } } diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 1e5d36c65..90bf81d42 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -266,10 +266,6 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po { glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); - PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00); - renderSolidFirstPass(); - PROFILER_POP_CPU_MARKER(); - // Shadows { PROFILER_PUSH_CPU_MARKER("- Shadow", 0x30, 0x6F, 0x90); @@ -283,6 +279,12 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po PROFILER_POP_CPU_MARKER(); } + PROFILER_PUSH_CPU_MARKER("- Solid Pass 1", 0xFF, 0x00, 0x00); + renderSolidFirstPass(); + PROFILER_POP_CPU_MARKER(); + + + // Lights { PROFILER_PUSH_CPU_MARKER("- Light", 0x00, 0xFF, 0x00); diff --git a/src/graphics/render_geometry.cpp b/src/graphics/render_geometry.cpp index d0ac5f935..20ee1d760 100644 --- a/src/graphics/render_geometry.cpp +++ b/src/graphics/render_geometry.cpp @@ -32,6 +32,31 @@ #include +template +void draw(const GLMesh *mesh, uniforms... Args) +{ + irr_driver->IncreaseObjectCount(); + GLenum ptype = mesh->PrimitiveType; + GLenum itype = mesh->IndexType; + size_t count = mesh->IndexCount; + + Shader::setUniforms(Args...); + glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex); +} + + +template +void draw(const T *Shader, const GLMesh *mesh, uniforms... Args) +{ + irr_driver->IncreaseObjectCount(); + GLenum ptype = mesh->PrimitiveType; + GLenum itype = mesh->IndexType; + size_t count = mesh->IndexCount; + + Shader->setUniforms(Args...); + glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex); +} + template struct unroll_args_instance { @@ -58,8 +83,32 @@ void apply_instance(const T *Shader, const std::tuple &arg) unroll_args_instance >::value >::template exec(Shader, arg); } -template -void renderMeshes1stPass(const std::vector &TexUnits, std::vector > &meshes) +template +struct custom_unroll_args; + +template<> +struct custom_unroll_args<> +{ + template + static void exec(const T *Shader, const std::tuple &t, Args... args) + { + draw(Shader, std::get<0>(t), args...); + } +}; + +template +struct custom_unroll_args +{ + template + static void exec(const T *Shader, const std::tuple &t, Args... args) + { + custom_unroll_args::template exec(Shader, t, std::get(t), args...); + } +}; + + +template +void renderMeshes1stPass(const std::vector > &TexUnits, std::vector > &meshes) { glUseProgram(Shader::getInstance()->Program); glBindVertexArray(getVAO(VertexType)); @@ -70,8 +119,8 @@ void renderMeshes1stPass(const std::vector &TexUnits, std::vector &TexUnits, std::vector::template exec(Shader::getInstance(), meshes[i]); } } @@ -97,11 +146,14 @@ void IrrDriver::renderSolidFirstPass() glDisable(GL_BLEND); glEnable(GL_CULL_FACE); irr_driver->setPhase(SOLID_NORMAL_AND_DEPTH_PASS); - ListDefaultStandardG::Arguments.clear(); - ListDefault2TCoordG::Arguments.clear(); - ListAlphaRefG::Arguments.clear(); - ListNormalG::Arguments.clear(); - ListGrassG::Arguments.clear(); + ListMatDefault::Arguments.clear(); + ListMatAlphaRef::Arguments.clear(); + ListMatSphereMap::Arguments.clear(); + ListMatDetails::Arguments.clear(); + ListMatUnlit::Arguments.clear(); + ListMatNormalMap::Arguments.clear(); + ListMatGrass::Arguments.clear(); + ListMatSplatting::Arguments.clear(); m_scene_manager->drawAll(scene::ESNRP_SOLID); if (!UserConfigParams::m_dynamic_lights) @@ -109,18 +161,21 @@ void IrrDriver::renderSolidFirstPass() { ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1)); - renderMeshes1stPass({ MeshShader::ObjectPass1Shader::getInstance()->TU_tex }, ListDefaultStandardG::Arguments); - renderMeshes1stPass({ MeshShader::ObjectPass1Shader::getInstance()->TU_tex }, ListDefault2TCoordG::Arguments); - renderMeshes1stPass({ MeshShader::ObjectRefPass1Shader::getInstance()->TU_tex }, ListAlphaRefG::Arguments); - renderMeshes1stPass({ MeshShader::NormalMapShader::getInstance()->TU_glossy, MeshShader::NormalMapShader::getInstance()->TU_normalmap }, ListNormalG::Arguments); - renderMeshes1stPass({ MeshShader::GrassPass1Shader::getInstance()->TU_tex }, ListGrassG::Arguments); + renderMeshes1stPass({ { MeshShader::ObjectPass1Shader::getInstance()->TU_tex, true } }, ListMatDefault::Arguments); + renderMeshes1stPass({ { MeshShader::ObjectPass1Shader::getInstance()->TU_tex, true } }, ListMatSphereMap::Arguments); + renderMeshes1stPass({ { MeshShader::ObjectPass1Shader::getInstance()->TU_tex, true } }, ListMatUnlit::Arguments); + renderMeshes1stPass({ { MeshShader::ObjectPass1Shader::getInstance()->TU_tex, true } }, ListMatDetails::Arguments); + renderMeshes1stPass({ { MeshShader::ObjectPass1Shader::getInstance()->TU_tex, true } }, ListMatSplatting::Arguments); + renderMeshes1stPass({ { MeshShader::ObjectRefPass1Shader::getInstance()->TU_tex, true } }, ListMatAlphaRef::Arguments); + renderMeshes1stPass({ { MeshShader::GrassPass1Shader::getInstance()->TU_tex, true } }, ListMatGrass::Arguments); + renderMeshes1stPass({ { MeshShader::NormalMapShader::getInstance()->TU_glossy, true }, { MeshShader::NormalMapShader::getInstance()->TU_normalmap, false } }, ListMatNormalMap::Arguments); } } -template -void renderMeshes2ndPass(const T *Shader, const std::vector &TexUnits, std::vector > &meshes) +template +void renderMeshes2ndPass(const std::vector > &TexUnits, std::vector > &meshes) { - glUseProgram(Shader->Program); + glUseProgram(Shader::getInstance()->Program); glBindVertexArray(getVAO(VertexType)); for (unsigned i = 0; i < meshes.size(); i++) { @@ -129,8 +184,8 @@ void renderMeshes2ndPass(const T *Shader, const std::vector &TexUnits, s { if (!mesh.textures[j]) mesh.textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - compressTexture(mesh.textures[j], true); - setTexture(TexUnits[j], getTextureGLuint(mesh.textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + compressTexture(mesh.textures[j], TexUnits[j].second); + setTexture(TexUnits[j].first, getTextureGLuint(mesh.textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA }; @@ -150,7 +205,7 @@ void renderMeshes2ndPass(const T *Shader, const std::vector &TexUnits, s #endif continue; } - apply_instance(Shader, meshes[i]); + custom_unroll_args::template exec(Shader::getInstance(), meshes[i]); } } @@ -176,14 +231,6 @@ void IrrDriver::renderSolidSecondPass() glEnable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); - ListDefaultStandardSM::Arguments.clear(); - ListDefaultTangentSM::Arguments.clear(); - ListAlphaRefSM::Arguments.clear(); - ListSphereMapSM::Arguments.clear(); - ListUnlitSM::Arguments.clear(); - ListDetailSM::Arguments.clear(); - ListSplattingSM::Arguments.clear(); - ListGrassSM::Arguments.clear(); setTexture(0, m_rtts->getRenderTarget(RTT_TMP1), GL_NEAREST, GL_NEAREST); setTexture(1, m_rtts->getRenderTarget(RTT_TMP2), GL_NEAREST, GL_NEAREST); setTexture(2, m_rtts->getRenderTarget(RTT_HALF1_R), GL_LINEAR, GL_LINEAR); @@ -193,14 +240,14 @@ void IrrDriver::renderSolidSecondPass() m_scene_manager->drawAll(scene::ESNRP_SOLID); - renderMeshes2ndPass(MeshShader::ObjectPass2ShaderInstance, { MeshShader::ObjectPass2ShaderInstance->TU_Albedo }, ListDefaultStandardSM::Arguments); - renderMeshes2ndPass(MeshShader::ObjectPass2ShaderInstance, { MeshShader::ObjectPass2ShaderInstance->TU_Albedo }, ListDefaultTangentSM::Arguments); - renderMeshes2ndPass(MeshShader::ObjectRefPass2ShaderInstance, { MeshShader::ObjectRefPass2ShaderInstance->TU_Albedo }, ListAlphaRefSM::Arguments); - renderMeshes2ndPass(MeshShader::SphereMapShaderInstance, { MeshShader::SphereMapShaderInstance->TU_tex }, ListSphereMapSM::Arguments); - renderMeshes2ndPass(MeshShader::ObjectUnlitShaderInstance, { MeshShader::ObjectUnlitShaderInstance->TU_tex }, ListUnlitSM::Arguments); - renderMeshes2ndPass(MeshShader::DetailledObjectPass2ShaderInstance, { MeshShader::DetailledObjectPass2ShaderInstance->TU_Albedo, MeshShader::DetailledObjectPass2ShaderInstance->TU_detail }, ListDetailSM::Arguments); - renderMeshes2ndPass(MeshShader::SplattingShaderInstance, { 8, MeshShader::SplattingShaderInstance->TU_tex_layout, MeshShader::SplattingShaderInstance->TU_tex_detail0, MeshShader::SplattingShaderInstance->TU_tex_detail1, MeshShader::SplattingShaderInstance->TU_tex_detail2, MeshShader::SplattingShaderInstance->TU_tex_detail3 }, ListSplattingSM::Arguments); - renderMeshes2ndPass(MeshShader::GrassPass2ShaderInstance, { MeshShader::GrassPass2ShaderInstance->TU_Albedo }, ListGrassSM::Arguments); + renderMeshes2ndPass({ { MeshShader::ObjectPass2Shader::getInstance()->TU_Albedo, true } }, ListMatDefault::Arguments); + renderMeshes2ndPass({ { MeshShader::ObjectRefPass2Shader::getInstance()->TU_Albedo, true } }, ListMatAlphaRef::Arguments); + renderMeshes2ndPass({ { MeshShader::SphereMapShader::getInstance()->TU_tex, true } }, ListMatSphereMap::Arguments); + renderMeshes2ndPass({ { MeshShader::DetailledObjectPass2Shader::getInstance()->TU_Albedo, true }, { MeshShader::DetailledObjectPass2Shader::getInstance()->TU_detail, true } }, ListMatDetails::Arguments); + renderMeshes2ndPass({ { MeshShader::GrassPass2Shader::getInstance()->TU_Albedo, true } }, ListMatGrass::Arguments); + renderMeshes2ndPass({ { MeshShader::ObjectUnlitShader::getInstance()->TU_tex, true } }, ListMatUnlit::Arguments); + renderMeshes2ndPass({ { 8, true }, { MeshShader::SplattingShader::getInstance()->TU_tex_layout, false }, { MeshShader::SplattingShader::getInstance()->TU_tex_detail0, true }, { MeshShader::SplattingShader::getInstance()->TU_tex_detail1, true }, { MeshShader::SplattingShader::getInstance()->TU_tex_detail2, true }, { MeshShader::SplattingShader::getInstance()->TU_tex_detail3, true } }, ListMatSplatting::Arguments); + renderMeshes2ndPass({ { MeshShader::ObjectPass2Shader::getInstance()->TU_Albedo, true } }, ListMatNormalMap::Arguments); } } @@ -227,16 +274,16 @@ void IrrDriver::renderTransparent() if (World::getWorld() && World::getWorld()->isFogEnabled()) { glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - renderMeshes2ndPass(MeshShader::TransparentFogShaderInstance, { MeshShader::TransparentFogShaderInstance->TU_tex }, ListBlendTransparentFog::Arguments); + renderMeshes2ndPass({ { MeshShader::TransparentFogShader::getInstance()->TU_tex, true } }, ListBlendTransparentFog::Arguments); glBlendFunc(GL_ONE, GL_ONE); - renderMeshes2ndPass(MeshShader::TransparentFogShaderInstance, { MeshShader::TransparentFogShaderInstance->TU_tex }, ListAdditiveTransparentFog::Arguments); + renderMeshes2ndPass({ { MeshShader::TransparentFogShader::getInstance()->TU_tex, true } }, ListAdditiveTransparentFog::Arguments); } else { glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - renderMeshes2ndPass(MeshShader::TransparentShaderInstance, { MeshShader::TransparentShaderInstance->TU_tex }, ListBlendTransparent::Arguments); + renderMeshes2ndPass({ { MeshShader::TransparentShader::getInstance()->TU_tex, true } }, ListBlendTransparent::Arguments); glBlendFunc(GL_ONE, GL_ONE); - renderMeshes2ndPass(MeshShader::TransparentShaderInstance, { MeshShader::TransparentShaderInstance->TU_tex }, ListAdditiveTransparent::Arguments); + renderMeshes2ndPass({ { MeshShader::TransparentShader::getInstance()->TU_tex, true } }, ListAdditiveTransparent::Arguments); } if (!UserConfigParams::m_dynamic_lights) @@ -318,48 +365,56 @@ void IrrDriver::renderTransparent() } -template -void drawShadow(const T *Shader, const std::vector TextureUnits, const std::vector >&t) +template +void drawShadow(const T *Shader, const GLMesh *mesh, uniforms... Args) +{ + irr_driver->IncreaseObjectCount(); + GLenum ptype = mesh->PrimitiveType; + GLenum itype = mesh->IndexType; + size_t count = mesh->IndexCount; + + Shader->setUniforms(Args...); + glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, 4, mesh->vaoBaseVertex); +} + +template +struct shadow_custom_unroll_args; + +template<> +struct shadow_custom_unroll_args<> +{ + template + static void exec(const T *Shader, const std::tuple &t, Args... args) + { + drawShadow(Shader, std::get<0>(t), args...); + } +}; + +template +struct shadow_custom_unroll_args +{ + template + static void exec(const T *Shader, const std::tuple &t, Args... args) + { + shadow_custom_unroll_args::template exec(Shader, t, std::get(t), args...); + } +}; + +template +void renderShadow(const T *Shader, const std::vector TextureUnits, const std::vector >&t) { glUseProgram(Shader->Program); glBindVertexArray(getVAO(VertexType)); for (unsigned i = 0; i < t.size(); i++) { const GLMesh *mesh = std::get<0>(t[i]); - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh->PrimitiveType; - GLenum itype = mesh->IndexType; - size_t count = mesh->IndexCount; for (unsigned j = 0; j < TextureUnits.size(); j++) { compressTexture(mesh->textures[j], true); setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); } - Shader->setUniforms(std::get<1>(t[i])); - glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, 4, mesh->vaoBaseVertex); - } -} - -static void drawShadowGrass(const std::vector TextureUnits, const std::vector > &t) -{ - glUseProgram(MeshShader::GrassShadowShaderInstance->Program); - glBindVertexArray(getVAO(EVT_STANDARD)); - for (unsigned i = 0; i < t.size(); i++) - { - const GLMesh *mesh = std::get<0>(t[i]); - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh->PrimitiveType; - GLenum itype = mesh->IndexType; - size_t count = mesh->IndexCount; - for (unsigned j = 0; j < TextureUnits.size(); j++) - { - compressTexture(mesh->textures[j], true); - setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - } - - MeshShader::GrassShadowShaderInstance->setUniforms(std::get<1>(t[i]), std::get<3>(t[i])); - glDrawElementsInstancedBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, 4, mesh->vaoBaseVertex); + shadow_custom_unroll_args::template exec(Shader, t[i]); } } @@ -370,9 +425,11 @@ void drawRSM(const core::matrix4 & rsm_matrix, const std::vector Texture glBindVertexArray(getVAO(VertexType)); for (unsigned i = 0; i < t.size(); i++) { - const GLMesh *mesh = std::get<0>(t[i]); + GLMesh *mesh = std::get<0>(t[i]); for (unsigned j = 0; j < TextureUnits.size(); j++) { + if (!mesh->textures[j]) + mesh->textures[j] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); compressTexture(mesh->textures[j], true); setTexture(TextureUnits[j], getTextureGLuint(mesh->textures[j]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); } @@ -382,23 +439,36 @@ void drawRSM(const core::matrix4 & rsm_matrix, const std::vector Texture void IrrDriver::renderShadows() { - irr_driver->setPhase(SHADOW_PASS); + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.5, 0.); m_rtts->getShadowFBO().Bind(); glClear(GL_DEPTH_BUFFER_BIT); glDrawBuffer(GL_NONE); - glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); - + irr_driver->setPhase(SHADOW_PASS); + ListMatDefault::Arguments.clear(); + ListMatAlphaRef::Arguments.clear(); + ListMatSphereMap::Arguments.clear(); + ListMatDetails::Arguments.clear(); + ListMatUnlit::Arguments.clear(); + ListMatNormalMap::Arguments.clear(); + ListMatGrass::Arguments.clear(); + ListMatSplatting::Arguments.clear(); m_scene_manager->drawAll(scene::ESNRP_SOLID); - drawShadow(MeshShader::ShadowShaderInstance, {}, ListDefaultStandardG::Arguments); - drawShadow(MeshShader::ShadowShaderInstance, {}, ListDefault2TCoordG::Arguments); - drawShadow(MeshShader::ShadowShaderInstance, {}, ListNormalG::Arguments); - drawShadow(MeshShader::RefShadowShaderInstance, { MeshShader::RefShadowShaderInstance->TU_tex }, ListAlphaRefG::Arguments); - drawShadowGrass({ MeshShader::GrassShadowShaderInstance->TU_tex }, ListGrassG::Arguments); + renderShadow(MeshShader::ShadowShaderInstance, {}, ListMatDefault::Arguments); + renderShadow(MeshShader::ShadowShaderInstance, {}, ListMatSphereMap::Arguments); + renderShadow(MeshShader::ShadowShaderInstance, {}, ListMatUnlit::Arguments); + renderShadow(MeshShader::ShadowShaderInstance, {}, ListMatDetails::Arguments); + renderShadow(MeshShader::ShadowShaderInstance, {}, ListMatSplatting::Arguments); + renderShadow(MeshShader::ShadowShaderInstance, {}, ListMatNormalMap::Arguments); + renderShadow(MeshShader::RefShadowShaderInstance, { MeshShader::RefShadowShaderInstance->TU_tex }, ListMatAlphaRef::Arguments); + renderShadow(MeshShader::GrassShadowShaderInstance, { MeshShader::GrassShadowShaderInstance->TU_tex }, ListMatGrass::Arguments); glDisable(GL_POLYGON_OFFSET_FILL); @@ -408,6 +478,9 @@ void IrrDriver::renderShadows() m_rtts->getRSM().Bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - drawRSM(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListDefaultStandardG::Arguments); - drawRSM(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListDefault2TCoordG::Arguments); -} \ No newline at end of file + drawRSM(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListMatDefault::Arguments); + drawRSM(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListMatSphereMap::Arguments); + drawRSM(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListMatUnlit::Arguments); + drawRSM(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListMatDetails::Arguments); + drawRSM(rsm_matrix, { MeshShader::RSMShader::TU_tex }, ListMatSplatting::Arguments); +} diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 466b706a3..43f1e2c87 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -328,19 +328,10 @@ void Shaders::loadShaders() MeshShader::InstancedObjectPass1ShaderInstance = new MeshShader::InstancedObjectPass1Shader(); MeshShader::InstancedObjectRefPass1ShaderInstance = new MeshShader::InstancedObjectRefPass1Shader(); MeshShader::InstancedGrassPass1ShaderInstance = new MeshShader::InstancedGrassPass1Shader(); - MeshShader::ObjectPass2ShaderInstance = new MeshShader::ObjectPass2Shader(); MeshShader::InstancedObjectPass2ShaderInstance = new MeshShader::InstancedObjectPass2Shader(); MeshShader::InstancedObjectRefPass2ShaderInstance = new MeshShader::InstancedObjectRefPass2Shader(); MeshShader::InstancedGrassPass2ShaderInstance = new MeshShader::InstancedGrassPass2Shader(); - MeshShader::DetailledObjectPass2ShaderInstance = new MeshShader::DetailledObjectPass2Shader(); - MeshShader::ObjectRefPass2ShaderInstance = new MeshShader::ObjectRefPass2Shader(); - MeshShader::ObjectUnlitShaderInstance = new MeshShader::ObjectUnlitShader(); - MeshShader::SphereMapShaderInstance = new MeshShader::SphereMapShader(); - MeshShader::SplattingShaderInstance = new MeshShader::SplattingShader(); - MeshShader::GrassPass2ShaderInstance = new MeshShader::GrassPass2Shader(); MeshShader::BubbleShader::init(); - MeshShader::TransparentShaderInstance = new MeshShader::TransparentShader(); - MeshShader::TransparentFogShaderInstance = new MeshShader::TransparentFogShader(); MeshShader::BillboardShader::init(); LightShader::PointLightShader::init(); MeshShader::DisplaceShaderInstance = new MeshShader::DisplaceShader(); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 8077a0f6f..e5d0eecd2 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -198,7 +198,7 @@ public: extern InstancedGrassPass1Shader *InstancedGrassPass1ShaderInstance; -class ObjectPass2Shader : public ShaderHelper +class ObjectPass2Shader : public ShaderHelperSingleton { public: GLuint TU_Albedo; @@ -206,8 +206,6 @@ public: ObjectPass2Shader(); }; -extern ObjectPass2Shader *ObjectPass2ShaderInstance; - class InstancedObjectPass2Shader : public ShaderHelper { public: @@ -228,7 +226,7 @@ public: extern InstancedObjectRefPass2Shader *InstancedObjectRefPass2ShaderInstance; -class DetailledObjectPass2Shader : public ShaderHelper +class DetailledObjectPass2Shader : public ShaderHelperSingleton { public: GLuint TU_Albedo, TU_detail; @@ -236,9 +234,7 @@ public: DetailledObjectPass2Shader(); }; -extern DetailledObjectPass2Shader *DetailledObjectPass2ShaderInstance; - -class ObjectUnlitShader : public ShaderHelper +class ObjectUnlitShader : public ShaderHelperSingleton { public: GLuint TU_tex; @@ -246,9 +242,7 @@ public: ObjectUnlitShader(); }; -extern ObjectUnlitShader *ObjectUnlitShaderInstance; - -class ObjectRefPass2Shader : public ShaderHelper +class ObjectRefPass2Shader : public ShaderHelperSingleton { public: GLuint TU_Albedo; @@ -256,9 +250,7 @@ public: ObjectRefPass2Shader(); }; -extern ObjectRefPass2Shader *ObjectRefPass2ShaderInstance; - -class GrassPass2Shader : public ShaderHelper +class GrassPass2Shader : public ShaderHelperSingleton { public: GLuint TU_Albedo; @@ -266,8 +258,6 @@ public: GrassPass2Shader(); }; -extern GrassPass2Shader *GrassPass2ShaderInstance; - class InstancedGrassPass2Shader : public ShaderHelper { public: @@ -278,7 +268,7 @@ public: extern InstancedGrassPass2Shader *InstancedGrassPass2ShaderInstance; -class SphereMapShader : public ShaderHelper +class SphereMapShader : public ShaderHelperSingleton { public: GLuint TU_tex; @@ -286,9 +276,7 @@ public: SphereMapShader(); }; -extern SphereMapShader *SphereMapShaderInstance; - -class SplattingShader : public ShaderHelper +class SplattingShader : public ShaderHelperSingleton { public: GLuint TU_tex_layout, TU_tex_detail0, TU_tex_detail1, TU_tex_detail2, TU_tex_detail3; @@ -296,8 +284,6 @@ public: SplattingShader(); }; -extern SplattingShader *SplattingShaderInstance; - class BubbleShader { public: @@ -308,7 +294,7 @@ public: static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex, float time, float transparency); }; -class TransparentShader : public ShaderHelper +class TransparentShader : public ShaderHelperSingleton { public: GLuint TU_tex; @@ -316,9 +302,7 @@ public: TransparentShader(); }; -extern TransparentShader *TransparentShaderInstance; - -class TransparentFogShader : public ShaderHelper +class TransparentFogShader : public ShaderHelperSingleton { public: GLuint TU_tex; @@ -326,8 +310,6 @@ public: TransparentFogShader(); }; -extern TransparentFogShader *TransparentFogShaderInstance; - class BillboardShader { public: diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index cb36955f9..babbfdad9 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -39,10 +39,8 @@ void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh) { firstTime = true; GLmeshes.clear(); - for (unsigned i = 0; i < FPSM_COUNT; i++) - GeometricMesh[i].clearWithoutDeleting(); - for (unsigned i = 0; i < SM_COUNT; i++) - ShadedMesh[i].clearWithoutDeleting(); + for (unsigned i = 0; i < MAT_COUNT; i++) + MeshSolidMaterial[i].clearWithoutDeleting(); CAnimatedMeshSceneNode::setMesh(mesh); } @@ -98,10 +96,8 @@ void STKAnimatedMesh::render() } else { - GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type, mb->getVertexType()); - ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures, mb->getVertexType()); - GeometricMesh[GeometricType].push_back(&mesh); - ShadedMesh[ShadedType].push_back(&mesh); + MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); + MeshSolidMaterial[MatType].push_back(&mesh); } std::pair p = getVAOOffsetAndBase(mb); mesh.vaoBaseVertex = p.first; @@ -117,7 +113,7 @@ void STKAnimatedMesh::render() const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; if (isObject(material.MaterialType)) { - if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == TRANSPARENT_PASS) + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == TRANSPARENT_PASS || irr_driver->getPhase() == SHADOW_PASS) { glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, getVBO(mb->getVertexType())); @@ -137,45 +133,24 @@ void STKAnimatedMesh::render() continue; } - if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS) { ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation); core::matrix4 invmodel; AbsoluteTransformation.getInverse(invmodel); GLMesh* mesh; - for_in(mesh, GeometricMesh[FPSM_DEFAULT_STANDARD]) - ListDefaultStandardG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel)); + for_in(mesh, MeshSolidMaterial[MAT_DEFAULT]) + ListMatDefault::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); - for_in(mesh, GeometricMesh[FPSM_DEFAULT_2TCOORD]) - ListDefault2TCoordG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel)); + for_in(mesh, MeshSolidMaterial[MAT_ALPHA_REF]) + ListMatAlphaRef::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); - for_in(mesh, GeometricMesh[FPSM_ALPHA_REF_TEXTURE]) - ListAlphaRefG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix)); + for_in(mesh, MeshSolidMaterial[MAT_DETAIL]) + ListMatDetails::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); - return; - } - - if (irr_driver->getPhase() == SOLID_LIT_PASS) - { - core::matrix4 invmodel; - AbsoluteTransformation.getInverse(invmodel); - - GLMesh* mesh; - for_in(mesh, ShadedMesh[SM_DEFAULT_STANDARD]) - ListDefaultStandardSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_DEFAULT_TANGENT]) - ListDefaultTangentSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_ALPHA_REF_TEXTURE]) - ListAlphaRefSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight())); - - for_in (mesh, ShadedMesh[SM_UNLIT]) - ListUnlitSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation)); - - for_in(mesh, ShadedMesh[SM_DETAILS]) - ListDetailSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, irr_driver->getSceneManager()->getAmbientLight())); + for_in(mesh, MeshSolidMaterial[MAT_UNLIT]) + ListMatUnlit::Arguments.emplace_back(mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY); return; } @@ -216,10 +191,10 @@ void STKAnimatedMesh::render() else { for_in(mesh, TransparentMesh[TM_DEFAULT]) - ListBlendTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); + ListBlendTransparent::Arguments.emplace_back(mesh, AbsoluteTransformation, mesh->TextureMatrix); for_in(mesh, TransparentMesh[TM_ADDITIVE]) - ListAdditiveTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); + ListAdditiveTransparent::Arguments.emplace_back(mesh, AbsoluteTransformation, mesh->TextureMatrix); } return; } diff --git a/src/graphics/stkanimatedmesh.hpp b/src/graphics/stkanimatedmesh.hpp index 92e12991a..c5c113da0 100644 --- a/src/graphics/stkanimatedmesh.hpp +++ b/src/graphics/stkanimatedmesh.hpp @@ -11,8 +11,7 @@ class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode { protected: bool firstTime; - PtrVector GeometricMesh[FPSM_COUNT]; - PtrVector ShadedMesh[SM_COUNT]; + PtrVector MeshSolidMaterial[MAT_COUNT]; PtrVector TransparentMesh[TM_COUNT]; std::vector GLmeshes; core::matrix4 ModelViewProjectionMatrix; diff --git a/src/graphics/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index e9f2b0d45..27ae172df 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -55,7 +55,7 @@ void STKInstancedSceneNode::createGLMeshes() isMaterialInitialized = false; } -void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat) +void STKInstancedSceneNode::initinstancedvaostate(GLMesh &mesh) { mesh.vao = createVAO(mesh.vertex_buffer, mesh.index_buffer, getVTXTYPEFromStride(mesh.Stride)); glGenBuffers(1, &instances_vbo); @@ -99,11 +99,9 @@ void STKInstancedSceneNode::setFirstTimeMaterial() video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType; GLMesh &mesh = GLmeshes[i]; - GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type, mb->getVertexType()); - ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures, mb->getVertexType()); - initinstancedvaostate(mesh, GeometricType, ShadedType); - GeometricMesh[GeometricType].push_back(&mesh); - ShadedMesh[ShadedType].push_back(&mesh); + MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); + initinstancedvaostate(mesh); + MeshSolidMaterial[MatType].push_back(&mesh); } isMaterialInitialized = true; } @@ -224,7 +222,7 @@ static void drawFSPMGrass(GLMesh &mesh, const core::vector3df &windDir, size_t i glDrawElementsInstanced(ptype, count, itype, 0, instance_count); } -static void drawSMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count) +static void drawSMDefault(GLMesh &mesh, size_t instance_count) { irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; @@ -249,7 +247,7 @@ static void drawSMDefault(GLMesh &mesh, const core::matrix4 &ModelViewProjection glDrawElementsInstanced(ptype, count, itype, 0, instance_count); } -static void drawSMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, size_t instance_count) +static void drawSMAlphaRefTexture(GLMesh &mesh, size_t instance_count) { irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; @@ -275,7 +273,7 @@ static void drawSMAlphaRefTexture(GLMesh &mesh, const core::matrix4 &ModelViewPr glDrawElementsInstanced(ptype, count, itype, 0, instance_count); } -static void drawSMGrass(GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDir, size_t instance_count) +static void drawSMGrass(GLMesh &mesh, const core::vector3df &windDir, size_t instance_count) { irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; @@ -318,59 +316,59 @@ void STKInstancedSceneNode::render() ModelViewProjectionMatrix = irr_driver->getProjMatrix(); ModelViewProjectionMatrix *= irr_driver->getViewMatrix(); - if (!GeometricMesh[FPSM_DEFAULT_STANDARD].empty()) + if (!MeshSolidMaterial[MAT_DEFAULT].empty()) glUseProgram(MeshShader::InstancedObjectPass1ShaderInstance->Program); - for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT_STANDARD].size(); i++) - drawFSPMDefault(*GeometricMesh[FPSM_DEFAULT_STANDARD][i], instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++) + drawFSPMDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9); - if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty()) + if (!MeshSolidMaterial[MAT_ALPHA_REF].empty()) glUseProgram(MeshShader::InstancedObjectRefPass1ShaderInstance->Program); - for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++) - drawFSPMAlphaRefTexture(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++) + drawFSPMAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9); windDir = getWind(); - if (!GeometricMesh[FPSM_GRASS].empty()) + if (!MeshSolidMaterial[MAT_GRASS].empty()) glUseProgram(MeshShader::InstancedGrassPass1ShaderInstance->Program); - for (unsigned i = 0; i < GeometricMesh[FPSM_GRASS].size(); i++) - drawFSPMGrass(*GeometricMesh[FPSM_GRASS][i], windDir, instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++) + drawFSPMGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9); return; } if (irr_driver->getPhase() == SOLID_LIT_PASS) { - if (!ShadedMesh[SM_DEFAULT_STANDARD].empty()) + if (!MeshSolidMaterial[MAT_DEFAULT].empty()) glUseProgram(MeshShader::InstancedObjectPass2ShaderInstance->Program); - for (unsigned i = 0; i < ShadedMesh[SM_DEFAULT_STANDARD].size(); i++) - drawSMDefault(*ShadedMesh[SM_DEFAULT_STANDARD][i], ModelViewProjectionMatrix, instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++) + drawSMDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9); - if (!ShadedMesh[SM_ALPHA_REF_TEXTURE].empty()) + if (!MeshSolidMaterial[MAT_ALPHA_REF].empty()) glUseProgram(MeshShader::InstancedObjectRefPass2ShaderInstance->Program); - for (unsigned i = 0; i < ShadedMesh[SM_ALPHA_REF_TEXTURE].size(); i++) - drawSMAlphaRefTexture(*ShadedMesh[SM_ALPHA_REF_TEXTURE][i], ModelViewProjectionMatrix, instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++) + drawSMAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9); - if (!ShadedMesh[SM_GRASS].empty()) + if (!MeshSolidMaterial[MAT_GRASS].empty()) glUseProgram(MeshShader::InstancedGrassPass2ShaderInstance->Program); - for (unsigned i = 0; i < ShadedMesh[SM_GRASS].size(); i++) - drawSMGrass(*ShadedMesh[SM_GRASS][i], ModelViewProjectionMatrix, windDir, instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++) + drawSMGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9); return; } if (irr_driver->getPhase() == SHADOW_PASS) { - if (!GeometricMesh[FPSM_DEFAULT_STANDARD].empty()) + if (!MeshSolidMaterial[MAT_DEFAULT].empty()) glUseProgram(MeshShader::InstancedShadowShaderInstance->Program); - for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT_STANDARD].size(); i++) - drawShadowDefault(*GeometricMesh[FPSM_DEFAULT_STANDARD][i], instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_DEFAULT].size(); i++) + drawShadowDefault(*MeshSolidMaterial[MAT_DEFAULT][i], instance_pos.size() / 9); - if (!GeometricMesh[FPSM_ALPHA_REF_TEXTURE].empty()) + if (!MeshSolidMaterial[MAT_ALPHA_REF].empty()) glUseProgram(MeshShader::InstancedRefShadowShaderInstance->Program); - for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++) - drawShadowAlphaRefTexture(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_ALPHA_REF].size(); i++) + drawShadowAlphaRefTexture(*MeshSolidMaterial[MAT_ALPHA_REF][i], instance_pos.size() / 9); - if (!GeometricMesh[FPSM_GRASS].empty()) + if (!MeshSolidMaterial[MAT_GRASS].empty()) glUseProgram(MeshShader::InstancedGrassShadowShaderInstance->Program); - for (unsigned i = 0; i < GeometricMesh[FPSM_GRASS].size(); i++) - drawShadowGrass(*GeometricMesh[FPSM_GRASS][i], windDir, instance_pos.size() / 9); + for (unsigned i = 0; i < MeshSolidMaterial[MAT_GRASS].size(); i++) + drawShadowGrass(*MeshSolidMaterial[MAT_GRASS][i], windDir, instance_pos.size() / 9); return; } } diff --git a/src/graphics/stkinstancedscenenode.hpp b/src/graphics/stkinstancedscenenode.hpp index 19f37abf3..5d9bbb784 100644 --- a/src/graphics/stkinstancedscenenode.hpp +++ b/src/graphics/stkinstancedscenenode.hpp @@ -8,8 +8,7 @@ class STKInstancedSceneNode : public irr::scene::CMeshSceneNode { protected: int m_ref_count; - std::vector GeometricMesh[FPSM_COUNT]; - std::vector ShadedMesh[SM_COUNT]; + std::vector MeshSolidMaterial[MAT_COUNT]; std::vector GLmeshes; std::vector instance_pos; core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; @@ -17,7 +16,7 @@ protected: void createGLMeshes(); bool isMaterialInitialized; void setFirstTimeMaterial(); - void initinstancedvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat); + void initinstancedvaostate(GLMesh &mesh); void cleanGL(); core::vector3df windDir; public: diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index d7bde2d5f..84134720e 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -9,37 +9,23 @@ #include "graphics/camera.hpp" #include "modes/world.hpp" -GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE MaterialType, video::E_VERTEX_TYPE tp) +MeshMaterial MaterialTypeToMeshMaterial(video::E_MATERIAL_TYPE MaterialType, video::E_VERTEX_TYPE tp) { + if (MaterialType == irr_driver->getShader(ES_SPHERE_MAP)) + return MAT_SPHEREMAP; if (MaterialType == irr_driver->getShader(ES_NORMAL_MAP)) - return FPSM_NORMAL_MAP; + return MAT_NORMAL_MAP; else if (MaterialType == irr_driver->getShader(ES_OBJECTPASS_REF) || MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF) - return FPSM_ALPHA_REF_TEXTURE; + return MAT_ALPHA_REF; else if (MaterialType == irr_driver->getShader(ES_GRASS) || MaterialType == irr_driver->getShader(ES_GRASS_REF)) - return FPSM_GRASS; + return MAT_GRASS; + else if (MaterialType == irr_driver->getShader(ES_SPLATTING)) + return MAT_SPLATTING; + else if (MaterialType == irr_driver->getShader(ES_OBJECT_UNLIT)) + return MAT_UNLIT; else if (tp == video::EVT_2TCOORDS) - return FPSM_DEFAULT_2TCOORD; - assert(tp == video::EVT_STANDARD); - return FPSM_DEFAULT_STANDARD; -} - -ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE type, video::ITexture **textures, video::E_VERTEX_TYPE tp) -{ - if (type == irr_driver->getShader(ES_SPHERE_MAP)) - return SM_SPHEREMAP; - else if (type == irr_driver->getShader(ES_SPLATTING)) - return SM_SPLATTING; - else if (type == irr_driver->getShader(ES_OBJECTPASS_REF) || type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF) - return SM_ALPHA_REF_TEXTURE; - else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - return SM_GRASS; - else if (type == irr_driver->getShader(ES_OBJECT_UNLIT)) - return SM_UNLIT; - else if (tp == video::EVT_2TCOORDS) - return SM_DETAILS; - else if (tp == video::EVT_TANGENTS) - return SM_DEFAULT_TANGENT; - return SM_DEFAULT_STANDARD; + return MAT_DETAIL; + return MAT_DEFAULT; } TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE type, f32 MaterialTypeParam) @@ -307,22 +293,17 @@ bool isObject(video::E_MATERIAL_TYPE type) return false; } -std::vector > ListDefaultStandardG::Arguments; -std::vector > ListDefault2TCoordG::Arguments; -std::vector > ListAlphaRefG::Arguments; -std::vector > ListNormalG::Arguments; -std::vector > ListGrassG::Arguments; +std::vector > ListMatDefault::Arguments; +std::vector > ListMatAlphaRef::Arguments; +std::vector > ListMatSphereMap::Arguments; +std::vector > ListMatDetails::Arguments; +std::vector > ListMatGrass::Arguments; +std::vector > ListMatUnlit::Arguments; +std::vector > ListMatSplatting::Arguments; +std::vector > ListMatNormalMap::Arguments; -std::vector > ListDefaultStandardSM::Arguments; -std::vector > ListDefaultTangentSM::Arguments; -std::vector > ListAlphaRefSM::Arguments; -std::vector > ListSplattingSM::Arguments; -std::vector > ListSphereMapSM::Arguments; -std::vector > ListUnlitSM::Arguments; -std::vector > ListDetailSM::Arguments; std::vector > ListBlendTransparent::Arguments; std::vector > ListAdditiveTransparent::Arguments; -std::vector > ListDisplacement::Arguments; std::vector > ListBlendTransparentFog::Arguments; std::vector > ListAdditiveTransparentFog::Arguments; -std::vector > ListGrassSM::Arguments; +std::vector > ListDisplacement::Arguments; \ No newline at end of file diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 5c184e663..ca435130a 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -11,27 +11,17 @@ #include #include -enum GeometricMaterial +enum MeshMaterial { - FPSM_DEFAULT_STANDARD, - FPSM_DEFAULT_2TCOORD, - FPSM_ALPHA_REF_TEXTURE, - FPSM_NORMAL_MAP, - FPSM_GRASS, - FPSM_COUNT -}; - -enum ShadedMaterial -{ - SM_DEFAULT_STANDARD, - SM_DEFAULT_TANGENT, - SM_ALPHA_REF_TEXTURE, - SM_SPHEREMAP, - SM_SPLATTING, - SM_GRASS, - SM_UNLIT, - SM_DETAILS, - SM_COUNT + MAT_DEFAULT, + MAT_ALPHA_REF, + MAT_NORMAL_MAP, + MAT_GRASS, + MAT_SPHEREMAP, + MAT_SPLATTING, + MAT_UNLIT, + MAT_DETAIL, + MAT_COUNT }; enum TransparentMaterial @@ -69,109 +59,54 @@ bool isObject(video::E_MATERIAL_TYPE type); core::vector3df getWind(); // Pass 1 shader (ie shaders that outputs normals and depth) -class ListDefaultStandardG +class ListMatDefault +{ +public: + static std::vector > Arguments; +}; + +class ListMatAlphaRef +{ +public: + static std::vector > Arguments; +}; + +class ListMatNormalMap +{ +public: + static std::vector > Arguments; +}; + +class ListMatGrass +{ +public: + static std::vector > Arguments; +}; + +class ListMatSphereMap +{ +public: + static std::vector > Arguments; +}; + +class ListMatSplatting +{ +public: + static std::vector > Arguments; +}; + +class ListMatUnlit { public: static std::vector > Arguments; }; -class ListDefault2TCoordG +class ListMatDetails { public: - static std::vector > Arguments; + static std::vector > Arguments; }; -class ListAlphaRefG -{ -public: - static std::vector > Arguments; -}; - -class ListNormalG -{ -public: - static std::vector > Arguments; -}; - -class ListGrassG -{ -public: - static std::vector > Arguments; -}; - -template -void draw(const GLMesh *mesh, uniforms... Args) -{ - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh->PrimitiveType; - GLenum itype = mesh->IndexType; - size_t count = mesh->IndexCount; - - Shader::setUniforms(Args...); - glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex); -} - - -template -void draw(const T *Shader, const GLMesh *mesh, uniforms... Args) -{ - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh->PrimitiveType; - GLenum itype = mesh->IndexType; - size_t count = mesh->IndexCount; - - Shader->setUniforms(Args...); - glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh->vaoOffset, mesh->vaoBaseVertex); -} - -// Pass 2 shader (ie shaders that outputs final color) -class ListDefaultStandardSM -{ -public: - static std::vector > Arguments; -}; - -class ListDefaultTangentSM -{ -public: - static std::vector > Arguments; -}; - -class ListAlphaRefSM -{ -public: - static std::vector > Arguments; -}; - -class ListSphereMapSM -{ -public: - static std::vector > Arguments; -}; - -class ListSplattingSM -{ -public: - static std::vector > Arguments; -}; - -class ListUnlitSM -{ -public: - static std::vector > Arguments; -}; - -class ListDetailSM -{ -public: - static std::vector > Arguments; -}; - -class ListGrassSM -{ -public: - static std::vector > Arguments; -}; class ListBlendTransparent { @@ -206,8 +141,7 @@ public: // Forward pass (for transparents meshes) void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix); -GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE, video::E_VERTEX_TYPE); -ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE, irr::video::ITexture **textures, video::E_VERTEX_TYPE tp); +MeshMaterial MaterialTypeToMeshMaterial(video::E_MATERIAL_TYPE, video::E_VERTEX_TYPE); TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE, f32 MaterialTypeParam); #endif // STKMESH_H diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index 96ee82d1b..7ce60fbf8 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -78,8 +78,7 @@ void STKMeshSceneNode::setFirstTimeMaterial() else { assert(!isDisplacement); - GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type, mb->getVertexType()); - ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures, mb->getVertexType()); + MeshMaterial MatType = MaterialTypeToMeshMaterial(type, mb->getVertexType()); if (immediate_draw) { fillLocalBuffer(mesh, mb); @@ -87,10 +86,7 @@ void STKMeshSceneNode::setFirstTimeMaterial() glBindVertexArray(0); } else - { - GeometricMesh[GeometricType].push_back(&mesh); - ShadedMesh[ShadedType].push_back(&mesh); - } + MeshSolidMaterials[MatType].push_back(&mesh); } if (!immediate_draw) @@ -117,10 +113,8 @@ void STKMeshSceneNode::cleanGLMeshes() glDeleteBuffers(1, &(mesh.index_buffer)); } GLmeshes.clear(); - for (unsigned i = 0; i < FPSM_COUNT; i++) - GeometricMesh[i].clearWithoutDeleting(); - for (unsigned i = 0; i < SM_COUNT; i++) - ShadedMesh[i].clearWithoutDeleting(); + for (unsigned i = 0; i < MAT_COUNT; i++) + MeshSolidMaterials[i].clearWithoutDeleting(); } void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh) @@ -215,53 +209,65 @@ void STKMeshSceneNode::render() GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0); } - if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS && immediate_draw) { core::matrix4 invmodel; AbsoluteTransformation.getInverse(invmodel); - if (immediate_draw) + + glDisable(GL_CULL_FACE); + if (update_each_frame) + updatevbo(); + glUseProgram(MeshShader::ObjectPass1Shader::getInstance()->Program); + // Only untextured + for (unsigned i = 0; i < GLmeshes.size(); i++) { - glDisable(GL_CULL_FACE); - if (update_each_frame) - updatevbo(); - glUseProgram(MeshShader::ObjectPass1Shader::getInstance()->Program); - // Only untextured - for (unsigned i = 0; i < GLmeshes.size(); i++) - { - irr_driver->IncreaseObjectCount(); - GLMesh &mesh = GLmeshes[i]; - GLenum ptype = mesh.PrimitiveType; - GLenum itype = mesh.IndexType; - size_t count = mesh.IndexCount; + irr_driver->IncreaseObjectCount(); + GLMesh &mesh = GLmeshes[i]; + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; - MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel); - assert(mesh.vao); - glBindVertexArray(mesh.vao); - glDrawElements(ptype, count, itype, 0); - glBindVertexArray(0); - } - glEnable(GL_CULL_FACE); - return; + MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel); + assert(mesh.vao); + glBindVertexArray(mesh.vao); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); } + glEnable(GL_CULL_FACE); + return; + } + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS || irr_driver->getPhase() == SHADOW_PASS) + { + core::matrix4 invmodel; + AbsoluteTransformation.getInverse(invmodel); GLMesh* mesh; - for_in(mesh, GeometricMesh[FPSM_DEFAULT_STANDARD]) - ListDefaultStandardG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel)); + for_in(mesh, MeshSolidMaterials[MAT_DEFAULT]) + ListMatDefault::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); - for_in(mesh, GeometricMesh[FPSM_DEFAULT_2TCOORD]) - ListDefault2TCoordG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel)); + for_in(mesh, MeshSolidMaterials[MAT_ALPHA_REF]) + ListMatAlphaRef::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); - for_in(mesh, GeometricMesh[FPSM_ALPHA_REF_TEXTURE]) - ListAlphaRefG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix)); + for_in(mesh, MeshSolidMaterials[MAT_SPHEREMAP]) + ListMatSphereMap::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); - for_in(mesh, GeometricMesh[FPSM_NORMAL_MAP]) - ListNormalG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel)); + for_in(mesh, MeshSolidMaterials[MAT_DETAIL]) + ListMatDetails::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); windDir = getWind(); - for_in(mesh, GeometricMesh[FPSM_GRASS]) - ListGrassG::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel, windDir)); + for_in(mesh, MeshSolidMaterials[MAT_GRASS]) + ListMatGrass::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, windDir, irr_driver->getSceneManager()->getAmbientLight()); + + for_in(mesh, MeshSolidMaterials[MAT_UNLIT]) + ListMatUnlit::Arguments.emplace_back(mesh, AbsoluteTransformation, core::matrix4::EM4CONST_IDENTITY); + + for_in(mesh, MeshSolidMaterials[MAT_SPLATTING]) + ListMatSplatting::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, irr_driver->getSceneManager()->getAmbientLight()); + + for_in(mesh, MeshSolidMaterials[MAT_NORMAL_MAP]) + ListMatNormalMap::Arguments.emplace_back(mesh, AbsoluteTransformation, invmodel, core::matrix4::EM4CONST_IDENTITY, irr_driver->getSceneManager()->getAmbientLight()); return; } @@ -276,7 +282,7 @@ void STKMeshSceneNode::render() glDisable(GL_CULL_FACE); if (!spareWhiteTex) spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - glUseProgram(MeshShader::ObjectPass2ShaderInstance->Program); + glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program); // Only untextured for (unsigned i = 0; i < GLmeshes.size(); i++) { @@ -286,8 +292,8 @@ void STKMeshSceneNode::render() GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(MeshShader::ObjectPass2ShaderInstance->TU_Albedo, getTextureGLuint(spareWhiteTex), GL_NEAREST, GL_NEAREST, false); - MeshShader::ObjectPass2ShaderInstance->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); + setTexture(MeshShader::ObjectPass2Shader::getInstance()->TU_Albedo, getTextureGLuint(spareWhiteTex), GL_NEAREST, GL_NEAREST, false); + MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, irr_driver->getSceneManager()->getAmbientLight()); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); @@ -297,31 +303,6 @@ void STKMeshSceneNode::render() return; } - GLMesh* mesh; - for_in(mesh, ShadedMesh[SM_DEFAULT_STANDARD]) - ListDefaultStandardSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_DEFAULT_TANGENT]) - ListDefaultTangentSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_ALPHA_REF_TEXTURE]) - ListAlphaRefSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_SPHEREMAP]) - ListSphereMapSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, invmodel, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_SPLATTING]) - ListSplattingSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_UNLIT]) - ListUnlitSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation)); - - for_in(mesh, ShadedMesh[SM_DETAILS]) - ListDetailSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, irr_driver->getSceneManager()->getAmbientLight())); - - for_in(mesh, ShadedMesh[SM_GRASS]) - ListGrassSM::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, windDir, irr_driver->getSceneManager()->getAmbientLight())); - return; } @@ -350,7 +331,7 @@ void STKMeshSceneNode::render() if (World::getWorld() && World::getWorld()->isFogEnabled()) { - glUseProgram(MeshShader::TransparentFogShaderInstance->Program); + glUseProgram(MeshShader::TransparentFogShader::getInstance()->Program); for (unsigned i = 0; i < GLmeshes.size(); i++) { GLMesh &mesh = GLmeshes[i]; @@ -374,8 +355,8 @@ void STKMeshSceneNode::render() tmpcol.getBlue() / 255.0f); compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::TransparentFogShaderInstance->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col); + setTexture(MeshShader::TransparentFogShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + MeshShader::TransparentFogShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col); assert(mesh.vao); glBindVertexArray(mesh.vao); @@ -385,7 +366,7 @@ void STKMeshSceneNode::render() } else { - glUseProgram(MeshShader::TransparentShaderInstance->Program); + glUseProgram(MeshShader::TransparentShader::getInstance()->Program); for (unsigned i = 0; i < GLmeshes.size(); i++) { irr_driver->IncreaseObjectCount(); @@ -395,9 +376,9 @@ void STKMeshSceneNode::render() size_t count = mesh.IndexCount; compressTexture(mesh.textures[0], true); - setTexture(MeshShader::TransparentShaderInstance->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::TransparentShader::getInstance()->TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::TransparentShaderInstance->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); + MeshShader::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); @@ -426,25 +407,23 @@ void STKMeshSceneNode::render() tmpcol.getBlue() / 255.0f); for_in(mesh, TransparentMesh[TM_DEFAULT]) - ListBlendTransparentFog::Arguments.push_back( - std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, - fogmax, startH, endH, start, end, col)); + ListBlendTransparentFog::Arguments.emplace_back(mesh, AbsoluteTransformation, mesh->TextureMatrix, + fogmax, startH, endH, start, end, col); for_in(mesh, TransparentMesh[TM_ADDITIVE]) - ListAdditiveTransparentFog::Arguments.push_back( - std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, - fogmax, startH, endH, start, end, col)); + ListAdditiveTransparentFog::Arguments.emplace_back(mesh, AbsoluteTransformation, mesh->TextureMatrix, + fogmax, startH, endH, start, end, col); } else { for_in(mesh, TransparentMesh[TM_DEFAULT]) - ListBlendTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); + ListBlendTransparent::Arguments.emplace_back(mesh, AbsoluteTransformation, mesh->TextureMatrix); for_in(mesh, TransparentMesh[TM_ADDITIVE]) - ListAdditiveTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); + ListAdditiveTransparent::Arguments.emplace_back(mesh, AbsoluteTransformation, mesh->TextureMatrix); } for_in(mesh, TransparentMesh[TM_DISPLACEMENT]) - ListDisplacement::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation)); + ListDisplacement::Arguments.emplace_back(mesh, AbsoluteTransformation); if (!TransparentMesh[TM_BUBBLE].empty()) glUseProgram(MeshShader::BubbleShader::Program); diff --git a/src/graphics/stkmeshscenenode.hpp b/src/graphics/stkmeshscenenode.hpp index 23b1af56e..8cee51772 100644 --- a/src/graphics/stkmeshscenenode.hpp +++ b/src/graphics/stkmeshscenenode.hpp @@ -7,8 +7,7 @@ class STKMeshSceneNode : public irr::scene::CMeshSceneNode { protected: - PtrVector GeometricMesh[FPSM_COUNT]; - PtrVector ShadedMesh[SM_COUNT]; + PtrVector MeshSolidMaterials[MAT_COUNT]; PtrVector TransparentMesh[TM_COUNT]; std::vector GLmeshes; core::matrix4 ModelViewProjectionMatrix; diff --git a/src/guiengine/abstract_state_manager.cpp b/src/guiengine/abstract_state_manager.cpp index 3b7989370..bafed2a3a 100644 --- a/src/guiengine/abstract_state_manager.cpp +++ b/src/guiengine/abstract_state_manager.cpp @@ -140,6 +140,9 @@ void AbstractStateManager::pushScreen(Screen* screen) void AbstractStateManager::replaceTopMostScreen(Screen* screen, GUIEngine::GameState gameState) { + if (gameState == GUIEngine::CURRENT) + gameState = getGameState(); + //assert(m_game_mode != GAME); // you need to close any dialog before calling this assert(!ModalDialog::isADialogActive()); diff --git a/src/guiengine/abstract_state_manager.hpp b/src/guiengine/abstract_state_manager.hpp index b8ace0901..07f8bf8fd 100644 --- a/src/guiengine/abstract_state_manager.hpp +++ b/src/guiengine/abstract_state_manager.hpp @@ -40,7 +40,9 @@ namespace GUIEngine { MENU, GAME, - INGAME_MENU + INGAME_MENU, + /** Dummy GameState e. g. for parameters. */ + CURRENT = MENU | GAME | INGAME_MENU }; // GameState /** @@ -82,7 +84,7 @@ namespace GUIEngine * without displaying the second-topmost menu of the stack * in-between) */ - void replaceTopMostScreen(Screen* screen, GUIEngine::GameState gameState = GUIEngine::MENU); + void replaceTopMostScreen(Screen* screen, GUIEngine::GameState gameState = GUIEngine::CURRENT); /** * \brief removes the menu at the top of the screens stack diff --git a/src/guiengine/abstract_top_level_container.hpp b/src/guiengine/abstract_top_level_container.hpp index 1f7bb874f..3387f51aa 100644 --- a/src/guiengine/abstract_top_level_container.hpp +++ b/src/guiengine/abstract_top_level_container.hpp @@ -87,12 +87,9 @@ namespace GUIEngine Widget* out = getWidget(name); T* outCasted = dynamic_cast( out ); if (out != NULL && outCasted == NULL) - { - fprintf(stderr, "Screen::getWidget : Widget '%s' of type '%s'" - "cannot be casted to requested type '%s'!\n", name, - typeid(*out).name(), typeid(T).name()); - abort(); - } + Log::fatal("Screen::getWidget", "Widget '%s' of type '%s'" + "cannot be casted to requested type '%s'!\n", name, + typeid(*out).name(), typeid(T).name()); return outCasted; } diff --git a/src/guiengine/event_handler.cpp b/src/guiengine/event_handler.cpp index 217641049..3546473e5 100644 --- a/src/guiengine/event_handler.cpp +++ b/src/guiengine/event_handler.cpp @@ -608,7 +608,7 @@ EventPropagation EventHandler::onGUIEvent(const SEvent& event) if (w == NULL) break; - if (!w->m_focusable) return GUIEngine::EVENT_BLOCK; + if (!w->isFocusable() || !w->isActivated()) return GUIEngine::EVENT_BLOCK; // When a modal dialog is shown, don't select widgets out of the dialog if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(w)) diff --git a/src/guiengine/layout_manager.cpp b/src/guiengine/layout_manager.cpp index 32643e221..268d45605 100644 --- a/src/guiengine/layout_manager.cpp +++ b/src/guiengine/layout_manager.cpp @@ -47,7 +47,7 @@ int atoi_p(const char* val) } else { - fprintf(stderr, "[LayoutManager] WARNING: Invalid value '%s' found in XML file where integer was expected\n", val); + Log::warn("LayoutManager", "Invalid value '%s' found in XML file where integer was expected.", val); return 0; } } @@ -461,7 +461,7 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev if (left_space < 0) { - fprintf(stderr, "[LayoutManager] WARNING: statically sized widgets took all the place!!\n"); + Log::warn("LayoutManager", "Statically sized widgets took all the place!!"); left_space = 0; } @@ -536,9 +536,9 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev if (widgets[n].m_w <= 0) { - fprintf(stderr, "WARNING: widget '%s' has a width of %i (left_space = %i, " - "fraction = %f, max_width = %s)\n", widgets[n].m_properties[PROP_ID].c_str(), - widgets[n].m_w, left_space, fraction, widgets[n].m_properties[PROP_MAX_WIDTH].c_str()); + Log::warn("LayoutManager", "Widget '%s' has a width of %i (left_space = %i, " + "fraction = %f, max_width = %s)", widgets[n].m_properties[PROP_ID].c_str(), + widgets[n].m_w, left_space, fraction, widgets[n].m_properties[PROP_MAX_WIDTH].c_str()); widgets[n].m_w = 1; } @@ -556,9 +556,9 @@ void LayoutManager::doCalculateLayout(PtrVector& widgets, AbstractTopLev if (widgets[n].m_h <= 0) { - fprintf(stderr, "WARNING: widget '%s' has a height of %i (left_space = %i, " - "fraction = %f, max_width = %s)\n", widgets[n].m_properties[PROP_ID].c_str(), - widgets[n].m_h, left_space, fraction, widgets[n].m_properties[PROP_MAX_WIDTH].c_str()); + Log::warn("LayoutManager", "Widget '%s' has a height of %i (left_space = %i, " + "fraction = %f, max_width = %s)\n", widgets[n].m_properties[PROP_ID].c_str(), + widgets[n].m_h, left_space, fraction, widgets[n].m_properties[PROP_MAX_WIDTH].c_str()); widgets[n].m_h = 1; } diff --git a/src/guiengine/modaldialog.cpp b/src/guiengine/modaldialog.cpp index 56ab935ed..544f4c012 100644 --- a/src/guiengine/modaldialog.cpp +++ b/src/guiengine/modaldialog.cpp @@ -26,6 +26,7 @@ #include "utils/log.hpp" #include +#include using namespace irr; using namespace core; @@ -134,6 +135,8 @@ void ModalDialog::doInit() m_irrlicht_window = GUIEngine::getGUIEnv()->addWindow(m_area, true /* modal */); + m_irrlicht_window->setDrawTitlebar(false); + m_irrlicht_window->getCloseButton()->setVisible(false); GUIEngine::getSkin()->m_dialog = true; GUIEngine::getSkin()->m_dialog_size = 0.0f; diff --git a/src/guiengine/scalable_font.cpp b/src/guiengine/scalable_font.cpp index f31a933fe..17cdcb78e 100644 --- a/src/guiengine/scalable_font.cpp +++ b/src/guiengine/scalable_font.cpp @@ -57,8 +57,7 @@ ScalableFont::ScalableFont(IGUIEnvironment *env, const std::string &filename) io::IXMLReader* reader = file_manager->createXMLReader(filename.c_str()); if (!load( reader )) { - fprintf(stderr, "[ScalableFont] Loading font failed\n"); - assert(false); + Log::fatal("ScalableFont", "Loading font failed"); } reader->drop(); @@ -157,7 +156,7 @@ void ScalableFont::doReadXmlFile(io::IXMLReader* xml) #ifdef DEBUG if (m_texture_files.find(i) != m_texture_files.end()) { - fprintf(stderr, "[ScalableFont] WARNING: Font conflict, two images have texture %i\n", i); + Log::warn("ScalableFont", "Font conflict, two images have texture %i.", i); } #endif @@ -258,7 +257,7 @@ bool ScalableFont::load(io::IXMLReader* xml) { if (!SpriteBank) { - fprintf(stderr, "[ScalableFont::load] SpriteBank is NULL!!\n"); + Log::error("ScalableFont::load", "SpriteBank is NULL!!"); return false; } @@ -633,7 +632,7 @@ void ScalableFont::draw(const core::stringw& text, if (texture == NULL) { - fprintf(stderr, "WARNING: character not found in current font\n"); + Log::warn("ScalableFont", "Character not found in current font"); continue; // no such character } } @@ -709,7 +708,7 @@ void ScalableFont::lazyLoadTexture(int texID) // couldn't load texture, abort. if (!SpriteBank->getTexture(texID)) { - fprintf(stderr, "!!!!! Unable to load all textures in the font\n"); + Log::error("ScalableFont::lazyLoadTexture", "Unable to load all textures in the font"); _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; return; } diff --git a/src/guiengine/screen.cpp b/src/guiengine/screen.cpp index 4bc8b4e07..7adc7cf90 100644 --- a/src/guiengine/screen.cpp +++ b/src/guiengine/screen.cpp @@ -184,7 +184,7 @@ void Screen::addWidgets() Widget* w = getFirstWidget(); //std::cout << "First widget is " << (w == NULL ? "null" : w->m_properties[PROP_ID].c_str()) << std::endl; if (w != NULL) w->setFocusForPlayer( PLAYER_ID_GAME_MASTER ); - else fprintf(stderr, "Couldn't select first widget, NULL was returned\n"); + else Log::warn("Screen::AddWidgets", "Couldn't select first widget, NULL was returned"); } // addWidgets // ----------------------------------------------------------------------------- @@ -206,9 +206,9 @@ void Screen::manualRemoveWidget(Widget* w) #ifdef DEBUG if(!m_widgets.contains(w)) { - fprintf(stderr, "Widget '%d' not found in screen when removing.\n", - w->m_id); - fprintf(stderr, "This can be ignored, but is probably wrong.\n"); + Log::info("Screen", "Widget '%d' not found in screen when removing.", + w->m_id); + Log::info("Screen", "This can be ignored, but is probably wrong."); } #endif m_widgets.remove(w); diff --git a/src/guiengine/widget.hpp b/src/guiengine/widget.hpp index aa3dd5391..57eb8a1ed 100644 --- a/src/guiengine/widget.hpp +++ b/src/guiengine/widget.hpp @@ -71,7 +71,7 @@ namespace GUIEngine GAMEPAD_BADGE = 16, /** A keyboard icon */ KEYBOARD_BADGE = 32, - /** An hourglass badge to indocate loading */ + /** An hourglass badge to indicate loading */ LOADING_BADGE = 64 }; diff --git a/src/guiengine/widgets/dynamic_ribbon_widget.cpp b/src/guiengine/widgets/dynamic_ribbon_widget.cpp index aaab4685b..0ef2b97e0 100644 --- a/src/guiengine/widgets/dynamic_ribbon_widget.cpp +++ b/src/guiengine/widgets/dynamic_ribbon_widget.cpp @@ -189,7 +189,7 @@ void DynamicRibbonWidget::add() if (m_child_width <= 0 || m_child_height <= 0) { - std::cerr << "/!\\ Warning /!\\ : ribbon grid widgets require 'child_width' and 'child_height' arguments" << std::endl; + Log::warn("DynamicRibbonWidget", "Ribbon grid widgets require 'child_width' and 'child_height' arguments"); m_child_width = 256; m_child_height = 256; } @@ -206,7 +206,7 @@ void DynamicRibbonWidget::add() if (m_h - m_label_height < 0) { - fprintf(stderr, "[DynamicRibbonWidget] WARNING: the widget is too small for anything to fit in it!!\n"); + Log::warn("DynamicRibbonWidget", "The widget is too small for anything to fit in it!!"); m_row_amount = 1; } else diff --git a/src/guiengine/widgets/kart_stats_widget.cpp b/src/guiengine/widgets/kart_stats_widget.cpp index b146b91ce..cb31311d6 100644 --- a/src/guiengine/widgets/kart_stats_widget.cpp +++ b/src/guiengine/widgets/kart_stats_widget.cpp @@ -63,13 +63,9 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id, } if(!props) - { - fprintf(stderr, - "[KartSelectionScreen] WARNING: Can't find default " - "kart '%s' nor any other kart.\n", - default_kart.c_str()); - exit(-1); - } + Log::fatal("KartSelectionScreen", "Can't find default " + "kart '%s' nor any other kart.", + default_kart.c_str()); } diff --git a/src/guiengine/widgets/label_widget.cpp b/src/guiengine/widgets/label_widget.cpp index f7c202014..c27ec1d22 100644 --- a/src/guiengine/widgets/label_widget.cpp +++ b/src/guiengine/widgets/label_widget.cpp @@ -50,6 +50,8 @@ LabelWidget::LabelWidget(bool title, bool bright) : Widget(WTYPE_LABEL) } else m_has_color = false; + + setFocusable(false); } // LabelWidget // ---------------------------------------------------------------------------- diff --git a/src/guiengine/widgets/list_widget.cpp b/src/guiengine/widgets/list_widget.cpp index d8ed4da81..8f920dd13 100644 --- a/src/guiengine/widgets/list_widget.cpp +++ b/src/guiengine/widgets/list_widget.cpp @@ -43,6 +43,7 @@ ListWidget::ListWidget() : Widget(WTYPE_LIST) m_sort_desc = false; m_sort_default = true; m_sort_col = 0; + m_sortable = false; } // ----------------------------------------------------------------------------- @@ -270,9 +271,11 @@ std::string ListWidget::getSelectionInternalName() CGUISTKListBox* list = getIrrlichtElement(); assert(list != NULL); - if (getSelectionID() == -1 || (getSelectionID() >= (int)list->getItemCount())) + int selectionID = getSelectionID(); + if (selectionID == -1 || selectionID >= (int)list->getItemCount()) return ""; - return list->getItem(getSelectionID()).m_internal_name; + const CGUISTKListBox::ListItem& item = list->getItem(selectionID); + return item.m_internal_name; } // ----------------------------------------------------------------------------- @@ -418,6 +421,8 @@ EventPropagation ListWidget::transmitEvent(Widget* w, if (originator.find(m_properties[PROP_ID] + "_column_") != std::string::npos) { + if (!m_sortable) return EVENT_BLOCK; + if (m_sort_col != originator[(m_properties[PROP_ID] + "_column_").size()] - '0') { m_sort_desc = false; diff --git a/src/guiengine/widgets/list_widget.hpp b/src/guiengine/widgets/list_widget.hpp index 434ac1175..720032736 100644 --- a/src/guiengine/widgets/list_widget.hpp +++ b/src/guiengine/widgets/list_widget.hpp @@ -87,6 +87,8 @@ namespace GUIEngine IListWidgetHeaderListener* m_listener; + bool m_sortable; + public: typedef irr::gui::CGUISTKListBox::ListItem ListItem; typedef ListItem::ListCell ListCell; @@ -240,6 +242,8 @@ namespace GUIEngine void addColumn(irr::core::stringw col, int proportion=1) { m_header.push_back( Column(col, proportion) ); } void clearColumns() { m_header.clear(); } + + void setSortable(bool sortable) { m_sortable = sortable; } }; } diff --git a/src/guiengine/widgets/progress_bar_widget.cpp b/src/guiengine/widgets/progress_bar_widget.cpp index 479329f33..77e31260b 100644 --- a/src/guiengine/widgets/progress_bar_widget.cpp +++ b/src/guiengine/widgets/progress_bar_widget.cpp @@ -36,6 +36,7 @@ ProgressBarWidget::ProgressBarWidget(bool show_label) : Widget(WTYPE_PROGRESS) m_target_value = 0; m_previous_value = 0; m_show_label = show_label; + setFocusable(false); } ProgressBarWidget::~ProgressBarWidget() diff --git a/src/guiengine/widgets/ribbon_widget.cpp b/src/guiengine/widgets/ribbon_widget.cpp index f73315ff4..3f3481288 100644 --- a/src/guiengine/widgets/ribbon_widget.cpp +++ b/src/guiengine/widgets/ribbon_widget.cpp @@ -115,8 +115,8 @@ void RibbonWidget::add() if (m_active_children[i].m_type != WTYPE_ICON_BUTTON && m_active_children[i].m_type != WTYPE_BUTTON) { - fprintf(stderr, "/!\\ Warning /!\\ : ribbon widgets can only have " - "(icon)button widgets as children\n"); + Log::warn("RiggonWidget", "Ribbon widgets can only have " + "(icon)button widgets as children"); continue; } @@ -275,7 +275,7 @@ void RibbonWidget::add() } else { - fprintf(stderr, "Invalid tab bar contents\n"); + Log::error("RibbonWidget", "Invalid tab bar contents"); } m_active_children[i].m_element = subbtn; @@ -375,8 +375,7 @@ void RibbonWidget::add() } else { - fprintf(stderr, - "/!\\ Warning /!\\ : Invalid contents type in ribbon\n"); + Log::warn("RiggonWidget", "Invalid contents type in ribbon"); } diff --git a/src/input/binding.cpp b/src/input/binding.cpp index dcac002ea..062f8172c 100644 --- a/src/input/binding.cpp +++ b/src/input/binding.cpp @@ -51,7 +51,7 @@ bool Binding::deserialize(irr::io::IrrXMLReader* xml) // Proceed only if neccesary tags were found if ((id_string == NULL) || (event_string == NULL)) { - printf("No id-string or event-string given - ignored.\n"); + Log::warn("Binding", "No id-string or event-string given - ignored."); return false; } @@ -66,7 +66,7 @@ bool Binding::deserialize(irr::io::IrrXMLReader* xml) // If the action is a stick motion & a direction is defined if (dir_string == NULL) { - printf("WARNING: IT_STICKMOTION without direction, ignoring.\n"); + Log::warn("Binding", "IT_STICKMOTION without direction, ignoring."); return false; } diff --git a/src/input/input_device.cpp b/src/input/input_device.cpp index 70278fdfe..368d71f1d 100644 --- a/src/input/input_device.cpp +++ b/src/input/input_device.cpp @@ -156,7 +156,7 @@ void GamePadDevice::resetAxisDirection(const int axis, AbstractKart* pk = player->getKart(); if (pk == NULL) { - fprintf(stderr, "Error, trying to reset axis for an unknown player\n"); + Log::error("Binding", "Trying to reset axis for an unknown player."); return; } diff --git a/src/network/client_network_manager.hpp b/src/network/client_network_manager.hpp index 422d08dc0..1c54d62dc 100644 --- a/src/network/client_network_manager.hpp +++ b/src/network/client_network_manager.hpp @@ -30,7 +30,7 @@ */ class ClientNetworkManager : public NetworkManager { - friend class Singleton; + friend class AbstractSingleton; public: /*! \brief Get the instance. * This is a utility function to avoid passing templates parameters @@ -38,7 +38,7 @@ class ClientNetworkManager : public NetworkManager */ static ClientNetworkManager* getInstance() { - return Singleton::getInstance(); + return AbstractSingleton::getInstance(); } /*! \brief Initializes network. diff --git a/src/network/network_interface.hpp b/src/network/network_interface.hpp index 6b82e6f41..4da28b430 100644 --- a/src/network/network_interface.hpp +++ b/src/network/network_interface.hpp @@ -33,9 +33,9 @@ /** \class NetworkInterface * \ingroup network */ -class NetworkInterface : public Singleton +class NetworkInterface : public AbstractSingleton { - friend class Singleton; + friend class AbstractSingleton; public: /*! \brief Used to init the network. diff --git a/src/network/network_manager.hpp b/src/network/network_manager.hpp index e660137f9..80cd42210 100644 --- a/src/network/network_manager.hpp +++ b/src/network/network_manager.hpp @@ -43,9 +43,9 @@ * Here are defined some functions that will be specifically implemented by * the ServerNetworkManager and the ClientNetworkManager. */ -class NetworkManager : public Singleton +class NetworkManager : public AbstractSingleton { - friend class Singleton; + friend class AbstractSingleton; public: /** \brief Function to start the Network Manager (start threads) */ virtual void run(); diff --git a/src/network/network_world.hpp b/src/network/network_world.hpp index 3adc90faf..f9b4f820f 100644 --- a/src/network/network_world.hpp +++ b/src/network/network_world.hpp @@ -34,9 +34,9 @@ class Item; /*! \brief Manages the world updates during an online game * This function's update is to be called instead of the normal World update */ -class NetworkWorld : public Singleton +class NetworkWorld : public AbstractSingleton { - friend class Singleton; + friend class AbstractSingleton; public: void update(float dt); diff --git a/src/network/protocol_manager.hpp b/src/network/protocol_manager.hpp index f7507a584..b54b5d0e2 100644 --- a/src/network/protocol_manager.hpp +++ b/src/network/protocol_manager.hpp @@ -102,9 +102,9 @@ typedef struct EventProcessingInfo * frames per second. Then, the management of protocols is thread-safe: any * object can start/pause/stop protocols whithout problems. */ -class ProtocolManager : public Singleton +class ProtocolManager : public AbstractSingleton { - friend class Singleton; + friend class AbstractSingleton; friend void* protocolManagerAsynchronousUpdate(void* data); public: diff --git a/src/network/protocols/get_public_address.cpp b/src/network/protocols/get_public_address.cpp index 3fe92501c..33379e71b 100644 --- a/src/network/protocols/get_public_address.cpp +++ b/src/network/protocols/get_public_address.cpp @@ -118,7 +118,7 @@ void GetPublicAddress::asynchronousUpdate() hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(stun_servers[rand_result].c_str(), NULL, &hints, &res)) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status)); + Log::error("getaddrinfo", gai_strerror(status)); return; } for(p = res;p != NULL; p = p->ai_next) diff --git a/src/network/server_network_manager.hpp b/src/network/server_network_manager.hpp index 1f85e879a..460cf6031 100644 --- a/src/network/server_network_manager.hpp +++ b/src/network/server_network_manager.hpp @@ -27,11 +27,11 @@ class ServerNetworkManager : public NetworkManager { - friend class Singleton; + friend class AbstractSingleton; public: static ServerNetworkManager* getInstance() { - return Singleton::getInstance(); + return AbstractSingleton::getInstance(); } virtual void run(); diff --git a/src/physics/physical_object.cpp b/src/physics/physical_object.cpp index f6a612336..57d2fa1c1 100644 --- a/src/physics/physical_object.cpp +++ b/src/physics/physical_object.cpp @@ -238,10 +238,7 @@ void PhysicalObject::init() } else { - fprintf(stderr, "[PhysicalObject] Unknown node type\n"); - max = 1.0f; - min = 0.0f; - assert(false); + Log::fatal("PhysicalObject", "Unknown node type"); } } else if (dynamic_cast(presentation) != NULL) @@ -256,10 +253,7 @@ void PhysicalObject::init() } else { - fprintf(stderr, "[PhysicalObject] Unknown node type\n"); - max = 1.0f; - min = 0.0f; - assert(false); + Log::fatal("PhysicalObject", "Unknown node type"); } Vec3 extend = max-min; // Adjust the mesth of the graphical object so that its center is where it @@ -453,7 +447,7 @@ void PhysicalObject::init() } case MP_NONE: default: - fprintf(stderr, "WARNING: Uninitialised moving shape\n"); + Log::warn("PhysicalObject", "Uninitialised moving shape"); // intended fall-through case MP_BOX: { diff --git a/src/physics/triangle_mesh.cpp b/src/physics/triangle_mesh.cpp index f8690b19c..e790950d0 100644 --- a/src/physics/triangle_mesh.cpp +++ b/src/physics/triangle_mesh.cpp @@ -112,7 +112,7 @@ void TriangleMesh::createCollisionShape(bool create_collision_object, const char btOptimizedBvh* bhv = btOptimizedBvh::deSerializeInPlace(bytes, pos, !IS_LITTLE_ENDIAN); if (bhv == NULL) { - fprintf(stderr, "[TriangleMesh] WARNING, failed to load serialized BHV\n"); + Log::warn("TriangleMesh", "Failed to load serialized BHV"); bhv_triangle_mesh = new btBvhTriangleMeshShape(&m_mesh, false /* useQuantizedAabbCompression */); } else diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp index 1405e01c8..a378cd537 100644 --- a/src/race/grand_prix_data.cpp +++ b/src/race/grand_prix_data.cpp @@ -37,6 +37,9 @@ // ---------------------------------------------------------------------------- +/** Loads a grand prix definition from a file. + * \param filename Name of the file to load. + */ GrandPrixData::GrandPrixData(const std::string& filename) { m_filename = filename; @@ -44,18 +47,34 @@ GrandPrixData::GrandPrixData(const std::string& filename) StringUtils::removeExtension(filename)); m_editable = (filename.find(file_manager->getGPDir(), 0) == 0); reload(); -} +} // GrandPrixData // ---------------------------------------------------------------------------- -GrandPrixData::GrandPrixData(const unsigned int number_of_tracks, - const std::string& track_group, - const RandomGPInfoDialog::REVERSED use_reverse) +/** Creates a random grand prix from the specified parameters. + * \param number_of_tracks How many tracks to select. + * \param track_group From which track group to select the tracks. + * \param use_reverse How the reverse setting is to be determined. + * \param new_tracks If true, new tracks are selected, otherwise existing + * tracks will not be changed (used to e.g. increase the number of + * tracks in an already existing random grand prix). + * + */ +void GrandPrixData::createRandomGP(const unsigned int number_of_tracks, + const std::string &track_group, + const GPReverseType use_reverse, + bool new_tracks) { m_filename = "Random GP - Not loaded from a file!"; m_id = "random"; m_name = "Random Grand Prix"; m_editable = false; + if(new_tracks) + { + m_tracks.clear(); + m_laps.clear(); + m_reversed.clear(); + } m_tracks.reserve(number_of_tracks); m_laps.reserve(number_of_tracks); m_reversed.reserve(number_of_tracks); @@ -117,48 +136,64 @@ void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks, } // ---------------------------------------------------------------------------- - -void GrandPrixData::changeReverse(const RandomGPInfoDialog::REVERSED use_reverse) +/** Updates the GP data with newly decided reverse requirements. + * \param use_reverse How reverse setting for each track is to be determined. + */ +void GrandPrixData::changeReverse(const GrandPrixData::GPReverseType use_reverse) { for (unsigned int i = 0; i < m_tracks.size(); i++) { - if (use_reverse == RandomGPInfoDialog::NO_REVERSE) + if (use_reverse == GP_NO_REVERSE) m_reversed[i] = false; - else if (use_reverse == RandomGPInfoDialog::MIXED) + else if (use_reverse == GP_RANDOM_REVERSE) if (track_manager->getTrack(m_tracks[i])->reverseAvailable()) m_reversed[i] = (rand() % 2 != 0); else m_reversed[i] = false; else // all reversed m_reversed[i] = track_manager->getTrack(m_tracks[i])->reverseAvailable(); - } -} + } // for i < m_tracks.size() +} // changeReverse // ---------------------------------------------------------------------------- +/** Sets the id of this grand prix. + * \param id The new id. + */ void GrandPrixData::setId(const std::string& id) { m_id = id; -} +} // setId // ---------------------------------------------------------------------------- +/** Sets the name of the grand prix. + * \param name New name. + */ void GrandPrixData::setName(const irr::core::stringw& name) { m_name = name; -} +} // setName // ---------------------------------------------------------------------------- +/** Sets the filename of this grand prix. + * \param filename New filename. + */ void GrandPrixData::setFilename(const std::string& filename) { m_filename = filename; -} +} // setFilename // ---------------------------------------------------------------------------- +/** Sets if this grand prix can be edited. + * \param editable New value. + */ void GrandPrixData::setEditable(const bool editable) { m_editable = editable; -} +} // setEditable // ---------------------------------------------------------------------------- +/** Reloads grand prix from file. + */ void GrandPrixData::reload() { m_tracks.clear(); @@ -270,6 +305,8 @@ void GrandPrixData::reload() } // reload() // ---------------------------------------------------------------------------- +/** Saves the grand prix data to a file. + */ bool GrandPrixData::writeToFile() { try @@ -303,9 +340,12 @@ bool GrandPrixData::writeToFile() m_filename.c_str(), e.what()); return false; } -} +} // writeToFile // ---------------------------------------------------------------------------- +/** Checks if the grand prix data are consistent. + * \param log_error: If errors should be sent to the logger. + */ bool GrandPrixData::checkConsistency(bool log_error) const { for (unsigned int i = 0; i < m_tracks.size(); i++) @@ -323,8 +363,7 @@ bool GrandPrixData::checkConsistency(bool log_error) const } } return true; -} - +} // checkConsistency // ---------------------------------------------------------------------------- /** Returns true if the track is available. This is used to test if Fort Magma @@ -332,76 +371,99 @@ bool GrandPrixData::checkConsistency(bool log_error) const * story mode, but will be available once all challenges are done and nolok * is unlocked). It also prevents people from using the grand prix editor as * a way to play tracks that still haven't been unlocked + * \param id Name of the track to test. + * \param include_locked If set to true, all tracks (including locked tracks) + * are considered to be available. */ bool GrandPrixData::isTrackAvailable(const std::string &id, - bool includeLocked ) const + bool include_locked ) const { - if (includeLocked) + if (include_locked) return true; else if (id == "fortmagma") return !PlayerManager::getCurrentPlayer()->isLocked("fortmagma"); else return (!m_editable || !PlayerManager::get()->getCurrentPlayer()->isLocked(id)); -} +} // isTrackAvailable // ---------------------------------------------------------------------------- -std::vector GrandPrixData::getTrackNames(bool includeLocked) const +/** Returns the list of tracks that is available (i.e. unlocked) of this + * grand prix. + * \param include_locked If data for locked tracks should be included or not. + * \return A copy of the list of available tracks in this grand prix. + */ +std::vector GrandPrixData::getTrackNames(bool include_locked) const { std::vector names; for (unsigned int i = 0; i < m_tracks.size(); i++) { - if(isTrackAvailable(m_tracks[i], includeLocked)) + if(isTrackAvailable(m_tracks[i], include_locked)) names.push_back(m_tracks[i]); } return names; -} +} // getTrackNames // ---------------------------------------------------------------------------- -std::vector GrandPrixData::getLaps(bool includeLocked) const +/** Returns the laps for each available track of the grand prix. + * \param include_locked If data for locked tracks should be included or not. + * \return a std::vector containing the laps for each grand prix. + */ +std::vector GrandPrixData::getLaps(bool include_locked) const { std::vector laps; for (unsigned int i = 0; i< m_tracks.size(); i++) - if(isTrackAvailable(m_tracks[i], includeLocked)) + if(isTrackAvailable(m_tracks[i], include_locked)) laps.push_back(m_laps[i]); return laps; -} +} // getLaps // ---------------------------------------------------------------------------- -std::vector GrandPrixData::getReverse(bool includeLocked) const +/** Returns the reverse setting for each available grand prix. + * \param include_locked If data for locked tracks should be included or not. + * \return A copy of alist with the reverse status for each track. + */ +std::vector GrandPrixData::getReverse(bool include_locked) const { std::vector reverse; for (unsigned int i = 0; i< m_tracks.size(); i++) - if(isTrackAvailable(m_tracks[i], includeLocked)) + if(isTrackAvailable(m_tracks[i], include_locked)) reverse.push_back(m_reversed[i]); return reverse; -} +} // getReverse // ---------------------------------------------------------------------------- +/** Returns true if this grand prix can be edited. + */ bool GrandPrixData::isEditable() const { return m_editable; -} +} // isEditable // ---------------------------------------------------------------------------- +/** Returns the number of tracks in this grand prix. + * \param include_locked If data for locked tracks should be included or not. + */ unsigned int GrandPrixData::getNumberOfTracks(bool includeLocked) const { if (includeLocked) return m_tracks.size(); else return getTrackNames(false).size(); -} +} // getNumberOfTracks // ---------------------------------------------------------------------------- +/** Returns the (translated) name of the track with the specified index. + */ irr::core::stringw GrandPrixData::getTrackName(const unsigned int track) const { assert(track < getNumberOfTracks(true)); Track* t = track_manager->getTrack(m_tracks[track]); assert(t != NULL); return t->getName(); -} +} // getTrackName // ---------------------------------------------------------------------------- const std::string& GrandPrixData::getTrackId(const unsigned int track) const diff --git a/src/race/grand_prix_data.hpp b/src/race/grand_prix_data.hpp index 742ec15f7..ea8422e43 100644 --- a/src/race/grand_prix_data.hpp +++ b/src/race/grand_prix_data.hpp @@ -24,7 +24,6 @@ #include #include -#include "states_screens/dialogs/random_gp_dialog.hpp" #include "utils/translation.hpp" using irr::core::stringw; @@ -69,21 +68,35 @@ private: */ bool isTrackAvailable(const std::string &id, bool includeLocked) const; +public: + /** Used to define the reverse setting when creating a random GP: + * No reverse, all reverse (if available on the track), random + * selection. */ + enum GPReverseType + { + GP_NO_REVERSE = 0, + GP_ALL_REVERSE = 1, + GP_RANDOM_REVERSE = 2 + }; // GPReverseType + public: #if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__) # pragma warning(disable:4290) #endif /** Load the GrandPrixData from the given filename */ GrandPrixData(const std::string& filename); + /** Needed for simple creation of an instance of GrandPrixData */ GrandPrixData() {}; - /** Creates a new random GP */ - GrandPrixData(const unsigned int number_of_tracks, - const std::string& track_group, - const RandomGPInfoDialog::REVERSED use_reverse); + void changeTrackNumber(const unsigned int number_of_tracks, const std::string& track_group); - void changeReverse(const RandomGPInfoDialog::REVERSED use_reverse); + void changeReverse(const GPReverseType use_reverse); + + void createRandomGP(const unsigned int number_of_tracks, + const std::string& track_group, + const GPReverseType use_reverse, + bool new_tracks=false); // Methods for the GP editor void setId(const std::string& id); diff --git a/src/race/grand_prix_manager.cpp b/src/race/grand_prix_manager.cpp index 9270bac06..ce9f00b6e 100644 --- a/src/race/grand_prix_manager.cpp +++ b/src/race/grand_prix_manager.cpp @@ -34,7 +34,6 @@ const char* GrandPrixManager::SUFFIX = ".grandprix"; // ---------------------------------------------------------------------------- GrandPrixManager::GrandPrixManager() { - m_random_gp = NULL; // better do it explicitly and avoid weird stuff loadFiles(); } // GrandPrixManager @@ -42,10 +41,7 @@ GrandPrixManager::GrandPrixManager() GrandPrixManager::~GrandPrixManager() { for(unsigned int i=0; igetId() == s) diff --git a/src/race/grand_prix_manager.hpp b/src/race/grand_prix_manager.hpp index 314ddcc59..d4800204a 100644 --- a/src/race/grand_prix_manager.hpp +++ b/src/race/grand_prix_manager.hpp @@ -22,7 +22,8 @@ #include #include -#include "race/grand_prix_data.hpp" +#include "irrlicht.h" +class GrandPrixData; /** * \ingroup race @@ -47,10 +48,6 @@ private: bool existsName(const irr::core::stringw& name) const; public: - /** saved here by a random GP dialog to avoid dangling pinters or - * memory leaks */ - GrandPrixData* m_random_gp; - GrandPrixManager(); ~GrandPrixManager(); void reload(); diff --git a/src/race/highscores.cpp b/src/race/highscores.cpp index f00fd036a..4056730c3 100644 --- a/src/race/highscores.cpp +++ b/src/race/highscores.cpp @@ -212,10 +212,10 @@ void Highscores::getEntry(int number, std::string &kart_name, { if(number<0 || number>getNumberEntries()) { - fprintf(stderr, "Error, accessing undefined highscore entry:\n"); - fprintf(stderr,"number %d, but %d entries are defined\n",number, - getNumberEntries()); - fprintf(stderr, "This error can be ignored, but no highscores are available\n"); + Log::warn("Highscores", "Accessing undefined highscore entry:"); + Log::warn("Highscores", "Number %d, but %d entries are defined.", number, + getNumberEntries()); + Log::warn("Highscores", "This error can be ignored, but no highscores are available."); return; } kart_name = m_kart_name[number]; diff --git a/src/race/history.cpp b/src/race/history.cpp index f7c117f66..17cf3110e 100644 --- a/src/race/history.cpp +++ b/src/race/history.cpp @@ -127,7 +127,7 @@ void History::updateReplay(float dt) World *world = World::getWorld(); if(m_current>=(int)m_all_deltas.size()) { - printf("Replay finished.\n"); + Log::info("History", "Replay finished"); m_current = 0; // Note that for physics replay all physics parameters // need to be reset, e.g. velocity, ... @@ -158,20 +158,19 @@ void History::Save() { FILE *fd = fopen("history.dat","w"); if(fd) - printf("History saved in ./history.dat.\n"); + Log::info("History", "Saved in ./history.dat."); else { std::string fn = file_manager->getUserConfigFile("history.dat"); fd = fopen(fn.c_str(), "w"); if(fd) - printf("History saved in '%s'.\n",fn.c_str()); - + Log::info("History", "Saved in '%s'.", fn.c_str()); } if(!fd) { - printf("Can't open history.dat file for writing - can't save history.\n"); - printf("Make sure history.dat in the current directory or the config\n"); - printf("directory is writable.\n"); + Log::info("History", "Can't open history.dat file for writing - can't save history."); + Log::info("History", "Make sure history.dat in the current directory " + "or the config directory is writable."); return; } @@ -231,75 +230,46 @@ void History::Load() FILE *fd = fopen("history.dat","r"); if(fd) - printf("Reading ./history.dat\n"); + Log::info("History", "Reading ./history.dat"); else { std::string fn = file_manager->getUserConfigFile("history.dat"); fd = fopen(fn.c_str(), "r"); if(fd) - printf("Reading '%s'.\n", fn.c_str()); + Log::info("History", "Reading '%s'.", fn.c_str()); } if(!fd) - { - fprintf(stderr, "ERROR: could not open history.dat\n"); - exit(-2); - } + Log::fatal("History", "Could not open history.dat"); if (fgets(s, 1023, fd) == NULL) - { - fprintf(stderr, "ERROR: could not read history.dat\n"); - exit(-2); - } + Log::fatal("History", "Could not read history.dat."); if (sscanf(s,"Version: %1023s",s1)!=1) - { - fprintf(stderr, "ERROR: no Version information found in history file (bogus history file)\n"); - exit(-2); - } - else - { - if (strcmp(s1,STK_VERSION)) - { - fprintf(stderr, "WARNING: history is version '%s'\n",s1); - fprintf(stderr, " STK version is '%s'\n",STK_VERSION); - } - } + Log::fatal("History", "No Version information found in history file (bogus history file)."); + else if (strcmp(s1,STK_VERSION)) + Log::warn("History", "History is version '%s', STK version is '%s'.", s1, STK_VERSION); if (fgets(s, 1023, fd) == NULL) - { - fprintf(stderr, "ERROR: could not read history.dat\n"); - exit(-2); - } + Log::fatal("History", "Could not read history.dat."); unsigned int num_karts; if(sscanf(s, "numkarts: %d",&num_karts)!=1) - { - fprintf(stderr,"WARNING: No number of karts found in history file.\n"); - exit(-2); - } + Log::fatal("History", "No number of karts found in history file."); race_manager->setNumKarts(num_karts); fgets(s, 1023, fd); if(sscanf(s, "numplayers: %d",&n)!=1) - { - fprintf(stderr,"WARNING: No number of players found in history file.\n"); - exit(-2); - } + Log::fatal("History", "No number of players found in history file."); race_manager->setNumLocalPlayers(n); fgets(s, 1023, fd); if(sscanf(s, "difficulty: %d",&n)!=1) - { - fprintf(stderr,"WARNING: No difficulty found in history file.\n"); - exit(-2); - } + Log::fatal("History", "No difficulty found in history file."); race_manager->setDifficulty((RaceManager::Difficulty)n); fgets(s, 1023, fd); if(sscanf(s, "track: %1023s",s1)!=1) - { - fprintf(stderr,"WARNING: Track not found in history file.\n"); - } + Log::warn("History", "Track not found in history file."); race_manager->setTrack(s1); // This value doesn't really matter, but should be defined, otherwise // the racing phase can switch to 'ending' @@ -308,12 +278,8 @@ void History::Load() for(unsigned int i=0; igetNumPlayers()) { @@ -323,10 +289,8 @@ void History::Load() // FIXME: The model information is currently ignored fgets(s, 1023, fd); if(sscanf(s,"size: %d",&m_size)!=1) - { - fprintf(stderr,"WARNING: Number of records not found in history file.\n"); - exit(-2); - } + Log::fatal("History", "Number of records not found in history file."); + allocateMemory(m_size); m_current = -1; diff --git a/src/replay/replay_play.cpp b/src/replay/replay_play.cpp index ed3534023..a3af26002 100644 --- a/src/replay/replay_play.cpp +++ b/src/replay/replay_play.cpp @@ -88,70 +88,51 @@ void ReplayPlay::Load() FILE *fd = openReplayFile(/*writeable*/false); if(!fd) { - printf("Can't read '%s', ghost replay disabled.\n", + Log::error("Replay", "Can't read '%s', ghost replay disabled.", getReplayFilename().c_str()); destroy(); return; } - printf("Reading replay file '%s'.\n", getReplayFilename().c_str()); + Log::info("Replay", "Reading replay file '%s'.", getReplayFilename().c_str()); if (fgets(s, 1023, fd) == NULL) - { - fprintf(stderr, "ERROR: could not read '%s'.\n", - getReplayFilename().c_str()); - exit(-2); - } + Log::fatal("Replay", "Could not read '%s'.", getReplayFilename().c_str()); unsigned int version; - if (sscanf(s,"Version: %d", &version)!=1) - { - fprintf(stderr, "ERROR: no Version information found in replay file" - " (bogus replay file)\n"); - exit(-2); - } + if (sscanf(s,"Version: %d", &version) != 1) + Log::fatal("Replay", "No Version information found in replay file (bogus replay file)."); - if (version!=getReplayVersion()) + if (version != getReplayVersion()) { - fprintf(stderr, "WARNING: replay is version '%d'\n",version); - fprintf(stderr, " STK version is '%d'\n",getReplayVersion()); - fprintf(stderr, " We try to proceed, but it may fail.\n"); + Log::warn("Replay", "Replay is version '%d'",version); + Log::warn("Replay", "STK version is '%d'",getReplayVersion()); + Log::warn("Replay", "We try to proceed, but it may fail."); } if (fgets(s, 1023, fd) == NULL) - { - fprintf(stderr, "ERROR: could not read '%s'.\n", - getReplayFilename().c_str()); - exit(-2); - } + Log::fatal("Replay", "Could not read '%s'.", getReplayFilename().c_str()); int n; - if(sscanf(s, "difficulty: %d",&n)!=1) - { - fprintf(stderr,"WARNING: No difficulty found in replay file.\n"); - exit(-2); - } + if(sscanf(s, "difficulty: %d", &n) != 1) + Log::fatal("Replay", " No difficulty found in replay file."); if(race_manager->getDifficulty()!=(RaceManager::Difficulty)n) - printf("Warning, difficulty of replay is '%d', " - "while '%d' is selected.\n", - race_manager->getDifficulty(), n); + Log::warn("Replay", "Difficulty of replay is '%d', " + "while '%d' is selected.", + race_manager->getDifficulty(), n); fgets(s, 1023, fd); - if(sscanf(s, "track: %s",s1)!=1) - { - fprintf(stderr,"WARNING: Track not found in replay file.\n"); - } + if(sscanf(s, "track: %s", s1) != 1) + Log::warn("Replay", "Track not found in replay file."); assert(std::string(s1)==race_manager->getTrackName()); race_manager->setTrack(s1); unsigned int num_laps; fgets(s, 1023, fd); - if(sscanf(s, "Laps: %d",&num_laps)!=1) - { - fprintf(stderr,"WARNING: No number of laps found in replay file.\n"); - exit(-2); - } + if(sscanf(s, "Laps: %d", &num_laps) != 1) + Log::fatal("Replay", "No number of laps found in replay file."); + race_manager->setNumLaps(num_laps); // eof actually doesn't trigger here, since it requires first to try @@ -175,25 +156,18 @@ void ReplayPlay::readKartData(FILE *fd, char *next_line) { char s[1024]; if(sscanf(next_line, "model: %s", s)!=1) - { - fprintf(stderr, - "WARNING: No model information for kart %d found.\n", + Log::fatal("Replay", "No model information for kart %d found.", m_ghost_karts.size()); - exit(-2); - } + m_ghost_karts.push_back(new GhostKart(std::string(s))); m_ghost_karts[m_ghost_karts.size()-1].init(RaceManager::KT_GHOST); fgets(s, 1023, fd); unsigned int size; if(sscanf(s,"size: %d",&size)!=1) - { - fprintf(stderr, - "WARNING: Number of records not found in replay file " - "for kart %d.\n", + Log::fatal("Replay", "Number of records not found in replay file " + "for kart %d.", m_ghost_karts.size()-1); - exit(-2); - } for(unsigned int i=0; igetIdent().c_str()); + Log::warn("ReplayRecorder", buffer); + } continue; } TransformEvent *p = &(m_transform_events[i][m_count_transforms[i]-1]); @@ -153,12 +157,12 @@ void ReplayRecorder::Save() FILE *fd = openReplayFile(/*writeable*/true); if(!fd) { - printf("Can't open '%s' for writing - can't save replay data.\n", - getReplayFilename().c_str()); + Log::error("ReplayRecorder", "Can't open '%s' for writing - can't save replay data.", + getReplayFilename().c_str()); return; } - printf("Replay saved in '%s'.\n", getReplayFilename().c_str()); + Log::info("ReplayRecorder", "Replay saved in '%s'.\n", getReplayFilename().c_str()); World *world = World::getWorld(); unsigned int num_karts = world->getNumKarts(); diff --git a/src/states_screens/credits.cpp b/src/states_screens/credits.cpp index 4927175d9..019aa3476 100644 --- a/src/states_screens/credits.cpp +++ b/src/states_screens/credits.cpp @@ -85,7 +85,7 @@ bool CreditsScreen::getWideLine(std::ifstream& file, core::stringw* out) { if (!file.good()) { - fprintf(stderr, "getWideLine : File is not good!\n"); + Log::error("CreditsScreen", "getWideLine: File is not good!"); return false; } wchar_t wide_char; @@ -147,8 +147,8 @@ void CreditsScreen::loadedFromFile() if (file.fail() || !file.is_open() || file.eof()) { - fprintf(stderr, "\n/!\\ Failed to open file at '%s'\n\n", - creditsfile.c_str()); + Log::error("CreditsScreen", "Failed to open file at '%s'.", + creditsfile.c_str()); return; } @@ -160,10 +160,8 @@ void CreditsScreen::loadedFromFile() if (file.fail() || !file.is_open() || file.eof()) { - fprintf(stderr, - "\n/!\\ Failed to read file at '%s', unexpected EOF\n\n", - creditsfile.c_str()); - assert(false); + Log::error("CreditsScreen", "Failed to read file at '%s', unexpected EOF.", + creditsfile.c_str()); return; } @@ -203,9 +201,7 @@ void CreditsScreen::loadedFromFile() if (lineCount == 0) { - fprintf(stderr, - "\n/!\\ Could not read anything from CREDITS file!\n\n"); - assert(false); + Log::error("CreditsScreen", "Could not read anything from CREDITS file!"); return; } diff --git a/src/states_screens/dialogs/addons_loading.cpp b/src/states_screens/dialogs/addons_loading.cpp index 2d6f1ef2d..1d82e4b13 100644 --- a/src/states_screens/dialogs/addons_loading.cpp +++ b/src/states_screens/dialogs/addons_loading.cpp @@ -384,11 +384,10 @@ void AddonsLoading::doUninstall() error = !addons_manager->uninstall(m_addon); if(error) { - printf("[addons]Directory '%s' can not be removed.\n", - m_addon.getDataDir().c_str()); - printf("[addons]Please remove this directory manually.\n"); - core::stringw msg = StringUtils::insertValues( - _("Problems removing the addon '%s'."), + Log::warn("Addons", "Directory '%s' can not be removed.", + m_addon.getDataDir().c_str()); + Log::warn("Addons", "Please remove this directory manually."); + core::stringw msg = StringUtils::insertValues(_("Problems removing the addon '%s'."), core::stringw(m_addon.getName().c_str())); getWidget("description")->setText(msg.c_str()); } diff --git a/src/states_screens/dialogs/custom_video_settings.cpp b/src/states_screens/dialogs/custom_video_settings.cpp index f5c270d7c..2be8a7eb2 100644 --- a/src/states_screens/dialogs/custom_video_settings.cpp +++ b/src/states_screens/dialogs/custom_video_settings.cpp @@ -102,29 +102,19 @@ GUIEngine::EventPropagation CustomVideoSettingsDialog::processEvent(const std::s { if (eventSource == "close") { - bool dynamic_light = getWidget("dynamiclight")->getState(); - UserConfigParams::m_dynamic_lights = dynamic_light; + bool advanced_pipeline = getWidget("dynamiclight")->getState(); + UserConfigParams::m_dynamic_lights = advanced_pipeline; - UserConfigParams::m_graphical_effects = - getWidget("anim_gfx")->getState(); - UserConfigParams::m_weather_effects = - getWidget("weather_gfx")->getState(); - UserConfigParams::m_ubo_disabled = - !getWidget("ubo")->getState(); UserConfigParams::m_dof = - getWidget("dof")->getState(); - UserConfigParams::m_high_definition_textures = - getWidget("hd-textures")->getState(); - + advanced_pipeline && getWidget("dof")->getState(); + UserConfigParams::m_motionblur = - getWidget("motionblur")->getState(); - UserConfigParams::m_show_steering_animations = - getWidget("steering_animations")->getValue(); - - if (dynamic_light) + advanced_pipeline && getWidget("motionblur")->getState(); + + if (advanced_pipeline) { UserConfigParams::m_shadows = - getWidget("shadows")->getValue(); + advanced_pipeline && getWidget("shadows")->getValue(); } else { @@ -132,26 +122,41 @@ GUIEngine::EventPropagation CustomVideoSettingsDialog::processEvent(const std::s } UserConfigParams::m_mlaa = - getWidget("mlaa")->getState(); + advanced_pipeline && getWidget("mlaa")->getState(); UserConfigParams::m_ssao = - getWidget("ssao")->getState(); + advanced_pipeline && getWidget("ssao")->getState(); UserConfigParams::m_light_shaft = - getWidget("lightshaft")->getState(); + advanced_pipeline && getWidget("lightshaft")->getState(); UserConfigParams::m_gi = - getWidget("global_illumination")->getState(); + advanced_pipeline && getWidget("global_illumination")->getState(); UserConfigParams::m_glow = - getWidget("glow")->getState(); + advanced_pipeline && getWidget("glow")->getState(); UserConfigParams::m_bloom = - getWidget("bloom")->getState(); + advanced_pipeline && getWidget("bloom")->getState(); UserConfigParams::m_texture_compression = getWidget("texture_compression")->getState(); + UserConfigParams::m_graphical_effects = + getWidget("anim_gfx")->getState(); + + UserConfigParams::m_weather_effects = + getWidget("weather_gfx")->getState(); + + UserConfigParams::m_ubo_disabled = + !getWidget("ubo")->getState(); + + UserConfigParams::m_high_definition_textures = + getWidget("hd-textures")->getState(); + + UserConfigParams::m_show_steering_animations = + getWidget("steering_animations")->getValue(); + switch (getWidget("filtering")->getValue()) { case 0: diff --git a/src/states_screens/dialogs/gp_info_dialog.cpp b/src/states_screens/dialogs/gp_info_dialog.cpp index f9cdf80c1..79ad221ca 100644 --- a/src/states_screens/dialogs/gp_info_dialog.cpp +++ b/src/states_screens/dialogs/gp_info_dialog.cpp @@ -53,8 +53,8 @@ GPInfoDialog::GPInfoDialog(const std::string& gp_ident) doInit(); m_curr_time = 0.0f; - m_gp = grand_prix_manager->getGrandPrix(gp_ident); - m_gp->checkConsistency(); + m_gp = *grand_prix_manager->getGrandPrix(gp_ident); + m_gp.checkConsistency(); m_under_title = m_area.getHeight()/7; m_over_body = m_area.getHeight()/7; @@ -72,7 +72,7 @@ GPInfoDialog::~GPInfoDialog() { GUIEngine::Screen* curr_screen = GUIEngine::getCurrentScreen(); if (curr_screen->getName() == "tracks.stkgui") - static_cast(curr_screen)->setFocusOnGP(m_gp->getId()); + static_cast(curr_screen)->setFocusOnGP(m_gp.getId()); } // ---------------------------------------------------------------------------- @@ -81,7 +81,7 @@ void GPInfoDialog::addTitle() { core::rect< s32 > area_top(0, 0, m_area.getWidth(), m_under_title); IGUIStaticText* title = GUIEngine::getGUIEnv()->addStaticText( - translations->fribidize(m_gp->getName()), + translations->fribidize(m_gp.getName()), area_top, false, true, // border, word wrap m_irrlicht_window); title->setTabStop(false); @@ -92,7 +92,7 @@ void GPInfoDialog::addTitle() void GPInfoDialog::addTracks() { - const std::vector tracks = m_gp->getTrackNames(); + const std::vector tracks = m_gp.getTrackNames(); const unsigned int track_amount = tracks.size(); int height_of_one_line = std::min((m_lower_bound - m_over_body)/(track_amount+1), @@ -119,7 +119,7 @@ void GPInfoDialog::addTracks() Label* widget = dynamic_cast(m_widgets.get(widgets_iter)); widget->setText(translations->fribidize(track->getName()), false); - widget->move(20, m_over_body + height_of_one_line*(i+1), + widget->move(20, m_over_body + height_of_one_line*i, m_area.getWidth()/2 - 20, height_of_one_line); widgets_iter++; @@ -141,7 +141,7 @@ void GPInfoDialog::addTracks() m_widgets.push_back(widget); widget->add(); - widget->move(20, m_over_body + height_of_one_line*(i+1), + widget->move(20, m_over_body + height_of_one_line*i, m_area.getWidth()/2 - 20, height_of_one_line); } } @@ -185,7 +185,7 @@ void GPInfoDialog::addScreenshot() m_screenshot_widget->m_h = m_area.getWidth()*3/8; // *(3/4)*(1/2) } - Track* track = track_manager->getTrack(m_gp->getTrackNames()[0]); + Track* track = track_manager->getTrack(m_gp.getTrackNames()[0]); m_screenshot_widget->m_properties[GUIEngine::PROP_ICON] = (track->getScreenshotFile().c_str()); m_screenshot_widget->setParent(m_irrlicht_window); m_screenshot_widget->add(); @@ -203,7 +203,7 @@ void GPInfoDialog::addButtons() SavedGrandPrix* saved_gp = SavedGrandPrix::getSavedGP( StateManager::get() ->getActivePlayerProfile(0) ->getUniqueID(), - m_gp->getId(), + m_gp.getId(), race_manager->getDifficulty(), race_manager->getNumberOfKarts(), race_manager->getNumLocalPlayers()); @@ -250,7 +250,7 @@ void GPInfoDialog::addButtons() void GPInfoDialog::onEnterPressedInternal() { // Save the GP id because dismiss() will destroy this instance - std::string gp_id = m_gp->getId(); + std::string gp_id = m_gp.getId(); ModalDialog::dismiss(); // Disable accidentally unlocking of a challenge PlayerManager::getCurrentPlayer()->setCurrentChallenge(""); @@ -264,7 +264,7 @@ GUIEngine::EventPropagation GPInfoDialog::processEvent(const std::string& event_ if (event_source == "start" || event_source == "continue") { // Save GP identifier, since dismiss will delete this object. - std::string gp_id = m_gp->getId(); + std::string gp_id = m_gp.getId(); // Also create a copy of the string: it is a reference to data // in a widget in the dialog - so if we call dismiss, this reference // becomes invalid! @@ -288,7 +288,7 @@ void GPInfoDialog::onUpdate(float dt) m_curr_time += dt; int frameAfter = (int)(m_curr_time / 1.5f); - const std::vector tracks = m_gp->getTrackNames(); + const std::vector tracks = m_gp.getTrackNames(); if (frameAfter >= (int)tracks.size()) { frameAfter = 0; diff --git a/src/states_screens/dialogs/gp_info_dialog.hpp b/src/states_screens/dialogs/gp_info_dialog.hpp index d221d44d9..93158162e 100644 --- a/src/states_screens/dialogs/gp_info_dialog.hpp +++ b/src/states_screens/dialogs/gp_info_dialog.hpp @@ -20,7 +20,7 @@ #define HEADER_GP_INFO_DIALOG_HPP #include "guiengine/modaldialog.hpp" -// Don't include grand_prix_data.hpp here or the compilation will fail +#include "race/grand_prix_data.hpp" class GrandPrixData; @@ -39,7 +39,9 @@ class GPInfoDialog : public GUIEngine::ModalDialog protected: // Necessary for RandomGPInfoDialog GUIEngine::IconButtonWidget* m_screenshot_widget; float m_curr_time; - GrandPrixData* m_gp; + + /** The grand prix data. */ + GrandPrixData m_gp; /** height of the separator over the body */ int m_over_body; diff --git a/src/states_screens/dialogs/random_gp_dialog.cpp b/src/states_screens/dialogs/random_gp_dialog.cpp index 5a7406e5e..dbb98f219 100644 --- a/src/states_screens/dialogs/random_gp_dialog.cpp +++ b/src/states_screens/dialogs/random_gp_dialog.cpp @@ -33,11 +33,12 @@ using irr::gui::IGUIStaticText; typedef GUIEngine::SpinnerWidget Spinner; RandomGPInfoDialog::RandomGPInfoDialog() + { // Defaults - loading selection from last time frrom a file would be better m_number_of_tracks = 2; // We can assume that there are at least 2 standard tracks m_trackgroup = "standard"; - m_use_reverse = NO_REVERSE; + m_use_reverse = GrandPrixData::GP_NO_REVERSE; doInit(); m_curr_time = 0.0f; @@ -46,14 +47,7 @@ RandomGPInfoDialog::RandomGPInfoDialog() m_over_body = m_area.getHeight()/7 + SPINNER_HEIGHT + 10; // 10px space m_lower_bound = m_area.getHeight()*6/7; - // The GP manager is be used to make the GP live longer than this dialog - if (grand_prix_manager->m_random_gp) - { - delete grand_prix_manager->m_random_gp; - grand_prix_manager->m_random_gp = NULL; - } - m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse); - grand_prix_manager->m_random_gp = m_gp; + m_gp.createRandomGP(m_number_of_tracks, m_trackgroup, m_use_reverse); addTitle(); addSpinners(); @@ -67,8 +61,18 @@ RandomGPInfoDialog::RandomGPInfoDialog() void RandomGPInfoDialog::addSpinners() { - const int trackgroup_width = 200, laps_with = 150, reverse_width = 200; - const int left = (m_area.getWidth() - trackgroup_width - 150 - 250)/2; + const int laps_width = 150; + // "20*4" because there a 4 separators between the spinners with 20px each + int label_spinner_width = m_area.getWidth() - laps_width - 20*4; + // This scaling ensures that the spinners are smaller than the available + // area, look well and are (hopefully) big enough for their labels + if (m_area.getWidth() < 700) + label_spinner_width /= 2; + else if (m_area.getWidth() < 1500) + label_spinner_width /= 3; + else + label_spinner_width /= 4; + const int left = (m_area.getWidth() - label_spinner_width*2 - laps_width)/2; // Trackgroup chooser Spinner* spinner = new Spinner(false); @@ -77,7 +81,7 @@ void RandomGPInfoDialog::addSpinners() spinner->setParent(m_irrlicht_window); m_widgets.push_back(spinner); spinner->add(); - spinner->move(left, m_under_title, trackgroup_width, SPINNER_HEIGHT); + spinner->move(left, m_under_title, label_spinner_width, SPINNER_HEIGHT); // Fill it with all the track group names spinner->addLabel("all"); int index_standard; @@ -106,7 +110,7 @@ void RandomGPInfoDialog::addSpinners() spinner->m_properties[GUIEngine::PROP_WRAP_AROUND] = "true"; m_widgets.push_back(spinner); spinner->add(); - spinner->move(left + trackgroup_width + 10, m_under_title, laps_with, SPINNER_HEIGHT); + spinner->move(left + label_spinner_width + 20/2, m_under_title, laps_width, SPINNER_HEIGHT); // reverse choose spinner = new Spinner(false); @@ -115,7 +119,7 @@ void RandomGPInfoDialog::addSpinners() spinner->m_properties[GUIEngine::PROP_WRAP_AROUND] = "true"; m_widgets.push_back(spinner); spinner->add(); - spinner->move(left + trackgroup_width + laps_with + 10, m_under_title, reverse_width, SPINNER_HEIGHT); + spinner->move(left + label_spinner_width + laps_width + 20/2, m_under_title, label_spinner_width, SPINNER_HEIGHT); spinner->addLabel("no reverse"); spinner->addLabel("all reverse"); spinner->addLabel("mixed"); @@ -141,15 +145,17 @@ GUIEngine::EventPropagation RandomGPInfoDialog::processEvent( { if (eventSource == "start") { + // Save GP data, since dismiss will delete this object. + GrandPrixData gp = m_gp; ModalDialog::dismiss(); - race_manager->startGP(grand_prix_manager->m_random_gp, false, false); + race_manager->startGP(&gp, false, false); return GUIEngine::EVENT_BLOCK; } else if (eventSource == "Number of tracks") { // The old gp can be reused because there's only track deletion/adding m_number_of_tracks = getWidget("Number of tracks")->getValue(); - m_gp->changeTrackNumber(m_number_of_tracks, m_trackgroup); + m_gp.changeTrackNumber(m_number_of_tracks, m_trackgroup); addTracks(); } else if (eventSource == "Trackgroup") @@ -171,22 +177,22 @@ GUIEngine::EventPropagation RandomGPInfoDialog::processEvent( if (s->getValue() > (signed)max) s->setValue(max); - delete m_gp; - m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse); - grand_prix_manager->m_random_gp = m_gp; + // Create a new (i.e. with new tracks) random gp, since the old + // tracks might not all belong to the newly selected group. + m_gp.createRandomGP(m_number_of_tracks, m_trackgroup, m_use_reverse, + /*new_tracks*/true); addTracks(); } else if (eventSource == "reverse") { Spinner* r = getWidget("reverse"); - m_use_reverse = static_cast(r->getValue()); - m_gp->changeReverse(m_use_reverse); + m_use_reverse = static_cast(r->getValue()); + m_gp.changeReverse(m_use_reverse); } else if (eventSource == "reload") { - delete m_gp; - m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse); - grand_prix_manager->m_random_gp = m_gp; + m_gp.createRandomGP(m_number_of_tracks, m_trackgroup, m_use_reverse, + /*new_tracks*/true); addTracks(); } diff --git a/src/states_screens/dialogs/random_gp_dialog.hpp b/src/states_screens/dialogs/random_gp_dialog.hpp index 698217eec..35a058825 100644 --- a/src/states_screens/dialogs/random_gp_dialog.hpp +++ b/src/states_screens/dialogs/random_gp_dialog.hpp @@ -24,17 +24,15 @@ class RandomGPInfoDialog : public GPInfoDialog { -public: - enum REVERSED - { - NO_REVERSE = 0, - ALL_REVERSE = 1, - MIXED = 2 - }; private: + /** How many tracks to pick. */ unsigned int m_number_of_tracks; + + /** Name of the track group from which to pick tracks. */ std::string m_trackgroup; - REVERSED m_use_reverse; + + /** How reverse settings should be determined. */ + GrandPrixData::GPReverseType m_use_reverse; public: static const int SPINNER_HEIGHT = 40; diff --git a/src/states_screens/grand_prix_lose.cpp b/src/states_screens/grand_prix_lose.cpp index f9bc459fd..27673542b 100644 --- a/src/states_screens/grand_prix_lose.cpp +++ b/src/states_screens/grand_prix_lose.cpp @@ -252,9 +252,9 @@ void GrandPrixLose::setKarts(std::vector ident_arg) } else { - fprintf(stderr, "[GrandPrixLose] WARNING: could not find a kart named '%s'\n", ident_arg[n].c_str()); + Log::warn("GrandPrixLose", "Could not find a kart named '%s'.", ident_arg[n].c_str()); m_kart_node[n] = NULL; - }// if kart !=NULL + } // if kart != NULL } } // setKarts diff --git a/src/states_screens/help_screen_1.cpp b/src/states_screens/help_screen_1.cpp index 2323be697..6a4ae514c 100644 --- a/src/states_screens/help_screen_1.cpp +++ b/src/states_screens/help_screen_1.cpp @@ -71,8 +71,8 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) { - fprintf(stderr, "[MainMenuScreen] WARNING: cannot find kart '%s', will revert to default\n", - UserConfigParams::m_default_kart.c_str()); + Log::warn("HelpScreen1", "Cannot find kart '%s', will revert to default", + UserConfigParams::m_default_kart.c_str()); UserConfigParams::m_default_kart.revertToDefaults(); } race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); @@ -89,13 +89,19 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i } else if (name == "category") { - std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - //if (selection == "page1") StateManager::get()->replaceTopMostScreen(Help1Screen::getInstance()); - //else - if (selection == "page2") StateManager::get()->replaceTopMostScreen(HelpScreen2::getInstance()); - else if (selection == "page3") StateManager::get()->replaceTopMostScreen(HelpScreen3::getInstance()); - else if (selection == "page4") StateManager::get()->replaceTopMostScreen(HelpScreen4::getInstance()); + Screen *screen = NULL; + //if (selection == "page1") + // screen = HelpScreen1::getInstance(); + if (selection == "page2") + screen = HelpScreen2::getInstance(); + else if (selection == "page3") + screen = HelpScreen3::getInstance(); + else if (selection == "page4") + screen = HelpScreen4::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if (name == "back") { diff --git a/src/states_screens/help_screen_2.cpp b/src/states_screens/help_screen_2.cpp index f3c751474..b2b08a0a1 100644 --- a/src/states_screens/help_screen_2.cpp +++ b/src/states_screens/help_screen_2.cpp @@ -46,12 +46,19 @@ void HelpScreen2::eventCallback(Widget* widget, const std::string& name, const i { if (name == "category") { - std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - if(selection == "page1") StateManager::get()->replaceTopMostScreen(HelpScreen1::getInstance()); - //else if(selection == "page2") StateManager::get()->replaceTopMostScreen(HelpScreen2::getInstance()); - else if(selection == "page3") StateManager::get()->replaceTopMostScreen(HelpScreen3::getInstance()); - else if(selection == "page4") StateManager::get()->replaceTopMostScreen(HelpScreen4::getInstance()); + Screen *screen = NULL; + if (selection == "page1") + screen = HelpScreen1::getInstance(); + //else if (selection == "page2") + // screen = HelpScreen2::getInstance(); + else if (selection == "page3") + screen = HelpScreen3::getInstance(); + else if (selection == "page4") + screen = HelpScreen4::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if (name == "back") { diff --git a/src/states_screens/help_screen_3.cpp b/src/states_screens/help_screen_3.cpp index 35693dd94..a8a7cb4f6 100644 --- a/src/states_screens/help_screen_3.cpp +++ b/src/states_screens/help_screen_3.cpp @@ -47,12 +47,20 @@ void HelpScreen3::eventCallback(Widget* widget, const std::string& name, const i { if (name == "category") { - std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); + + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - if (selection == "page1") StateManager::get()->replaceTopMostScreen(HelpScreen1::getInstance()); - else if (selection == "page2") StateManager::get()->replaceTopMostScreen(HelpScreen2::getInstance()); - //else if(selection == "page3") StateManager::get()->replaceTopMostScreen(Help3Screen::getInstance()); - else if(selection == "page4") StateManager::get()->replaceTopMostScreen(HelpScreen4::getInstance()); + Screen *screen = NULL; + if (selection == "page1") + screen = HelpScreen1::getInstance(); + else if (selection == "page2") + screen = HelpScreen2::getInstance(); + //else if (selection == "page3") + // screen = HelpScreen3::getInstance(); + else if (selection == "page4") + screen = HelpScreen4::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if (name == "back") { diff --git a/src/states_screens/help_screen_4.cpp b/src/states_screens/help_screen_4.cpp index 97ddf3809..c271467db 100644 --- a/src/states_screens/help_screen_4.cpp +++ b/src/states_screens/help_screen_4.cpp @@ -47,11 +47,20 @@ void HelpScreen4::eventCallback(Widget* widget, const std::string& name, const i { if (name == "category") { - std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); + + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - if (selection == "page1") StateManager::get()->replaceTopMostScreen(HelpScreen1::getInstance()); - else if (selection == "page2") StateManager::get()->replaceTopMostScreen(HelpScreen2::getInstance()); - else if(selection == "page3") StateManager::get()->replaceTopMostScreen(HelpScreen3::getInstance()); + Screen *screen = NULL; + if (selection == "page1") + screen = HelpScreen1::getInstance(); + else if (selection == "page2") + screen = HelpScreen2::getInstance(); + else if (selection == "page3") + screen = HelpScreen3::getInstance(); + //else if (selection == "page4") + // screen = HelpScreen4::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if (name == "back") { diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index b73eceec9..4c5a519eb 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -339,13 +339,9 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent, } if(!props) - { - fprintf(stderr, - "[KartSelectionScreen] WARNING: Can't find default " - "kart '%s' nor any other kart.\n", - default_kart.c_str()); - exit(-1); - } + Log::fatal("KartSelectionScreen", "Can't find default " + "kart '%s' nor any other kart.", + default_kart.c_str()); } m_kartInternalName = props->getIdent(); @@ -431,14 +427,12 @@ void PlayerKartWidget::setPlayerID(const int newPlayerID) if (StateManager::get()->getActivePlayer(newPlayerID) != m_associated_player) { - Log::warn("[KartSelectionScreen]", "Internal " - "inconsistency, PlayerKartWidget has IDs and " - "pointers that do not correspond to one player"); - fprintf(stderr, - " Player: %p - Index: %d - m_associated_player: %p\n", - StateManager::get()->getActivePlayer(newPlayerID), - newPlayerID, m_associated_player); - assert(false); + Log::error("KartSelectionScreen", "Internal " + "inconsistency, PlayerKartWidget has IDs and " + "pointers that do not correspond to one player"); + Log::fatal("KartSelectionScreen", " Player: %p - Index: %d - m_associated_player: %p", + StateManager::get()->getActivePlayer(newPlayerID), + newPlayerID, m_associated_player); } // Remove current focus, but remember it @@ -1658,11 +1652,9 @@ void KartSelectionScreen::updateKartWidgetModel(uint8_t widget_id, ->setText( selectionText.c_str(), false ); } else - { - fprintf(stderr, "[KartSelectionScreen] WARNING: could not " - "find a kart named '%s'\n", - selection.c_str()); - } + Log::warn("KartSelectionScreen", "could not " + "find a kart named '%s'", + selection.c_str()); } } diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 55938fb3f..45a038b11 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -380,8 +380,8 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL) { - fprintf(stderr, "[MainMenuScreen] WARNING: cannot find kart '%s', will revert to default\n", - UserConfigParams::m_default_kart.c_str()); + Log::warn("MainMenuScreen", "Cannot find kart '%s', will revert to default", + UserConfigParams::m_default_kart.c_str()); UserConfigParams::m_default_kart.revertToDefaults(); } race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); diff --git a/src/states_screens/options_screen_audio.cpp b/src/states_screens/options_screen_audio.cpp index 10df8ed22..1cad3443e 100644 --- a/src/states_screens/options_screen_audio.cpp +++ b/src/states_screens/options_screen_audio.cpp @@ -103,13 +103,21 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name, { if (name == "options_choice") { - std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance()); - else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance()); - else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance()); - else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance()); - else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance()); + Screen *screen = NULL; + //if (selection == "tab_audio") + // screen = OptionsScreenAudio::getInstance(); + if (selection == "tab_video") + screen = OptionsScreenVideo::getInstance(); + else if (selection == "tab_players") + screen = TabbedUserScreen::getInstance(); + else if (selection == "tab_controls") + screen = OptionsScreenInput::getInstance(); + else if (selection == "tab_ui") + screen = OptionsScreenUI::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if(name == "back") { diff --git a/src/states_screens/options_screen_input.cpp b/src/states_screens/options_screen_input.cpp index 2570d2d38..41b6396dc 100644 --- a/src/states_screens/options_screen_input.cpp +++ b/src/states_screens/options_screen_input.cpp @@ -154,6 +154,15 @@ void OptionsScreenInput::init() const std::string name2("devices"); eventCallback(devices, name2, PLAYER_ID_GAME_MASTER); */ + // Disable adding keyboard configurations + if (StateManager::get()->getGameState() == GUIEngine::INGAME_MENU) + { + getWidget("add_device")->setDeactivated(); + } + else + { + getWidget("add_device")->setActivated(); + } } // init // ----------------------------------------------------------------------------- @@ -184,13 +193,21 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name, if (name == "options_choice") { - std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance()); - else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance()); - else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance()); - else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance()); - else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance()); + Screen *screen = NULL; + if (selection == "tab_audio") + screen = OptionsScreenAudio::getInstance(); + else if (selection == "tab_video") + screen = OptionsScreenVideo::getInstance(); + else if (selection == "tab_players") + screen = TabbedUserScreen::getInstance(); + //else if (selection == "tab_controls") + // screen = OptionsScreenInput::getInstance(); + else if (selection == "tab_ui") + screen = OptionsScreenUI::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if (name == "add_device") { diff --git a/src/states_screens/options_screen_input2.cpp b/src/states_screens/options_screen_input2.cpp index 6e941a2ae..2f72ce1ed 100644 --- a/src/states_screens/options_screen_input2.cpp +++ b/src/states_screens/options_screen_input2.cpp @@ -61,6 +61,19 @@ void OptionsScreenInput2::loadedFromFile() // ---------------------------------------------------------------------------- +void OptionsScreenInput2::beforeAddingWidget() +{ + GUIEngine::ListWidget* w_list = + getWidget("actions"); + assert(w_list != NULL); + w_list->clearColumns(); + w_list->addColumn(_("Action"), 1); + w_list->addColumn(_("Key binding"), 1); + w_list->setSortable(false); +} + +// ---------------------------------------------------------------------------- + void OptionsScreenInput2::init() { Screen::init(); @@ -127,43 +140,72 @@ void OptionsScreenInput2::init() // their actualy contents will be adapted as needed after //I18N: Key binding section - actions->addItem("game_keys_section", _("Game Keys") ); - actions->addItem(KartActionStrings[PA_STEER_LEFT], L"" ); - actions->addItem(KartActionStrings[PA_STEER_RIGHT], L"" ); - actions->addItem(KartActionStrings[PA_ACCEL], L"" ); - actions->addItem(KartActionStrings[PA_BRAKE], L"" ); - actions->addItem(KartActionStrings[PA_FIRE], L"" ); - actions->addItem(KartActionStrings[PA_NITRO], L"" ); - actions->addItem(KartActionStrings[PA_DRIFT], L"" ); - actions->addItem(KartActionStrings[PA_LOOK_BACK], L"" ); - actions->addItem(KartActionStrings[PA_RESCUE], L"" ); - actions->addItem(KartActionStrings[PA_PAUSE_RACE], L"" ); + addListItemSubheader(actions, "game_keys_section", _("Game Keys")); + addListItem(actions, PA_STEER_LEFT); + addListItem(actions, PA_STEER_RIGHT); + addListItem(actions, PA_ACCEL); + addListItem(actions, PA_BRAKE); + addListItem(actions, PA_FIRE); + addListItem(actions, PA_NITRO); + addListItem(actions, PA_DRIFT); + addListItem(actions, PA_LOOK_BACK); + addListItem(actions, PA_RESCUE); + addListItem(actions, PA_PAUSE_RACE); //I18N: Key binding section - actions->addItem("menu_keys_section", _("Menu Keys") ); - actions->addItem(KartActionStrings[PA_MENU_UP], L"" ); - actions->addItem(KartActionStrings[PA_MENU_DOWN], L"" ); - actions->addItem(KartActionStrings[PA_MENU_LEFT], L"" ); - actions->addItem(KartActionStrings[PA_MENU_RIGHT], L"" ); - actions->addItem(KartActionStrings[PA_MENU_SELECT], L""); - actions->addItem(KartActionStrings[PA_MENU_CANCEL], L"" ); + addListItemSubheader(actions, "menu_keys_section", _("Menu Keys")); + addListItem(actions, PA_MENU_UP); + addListItem(actions, PA_MENU_DOWN); + addListItem(actions, PA_MENU_LEFT); + addListItem(actions, PA_MENU_RIGHT); + addListItem(actions, PA_MENU_SELECT); + addListItem(actions, PA_MENU_CANCEL); updateInputButtons(); + + // Disable deletion keyboard configurations + if (StateManager::get()->getGameState() == GUIEngine::INGAME_MENU) + { + getWidget("delete")->setDeactivated(); + } else + { + getWidget("delete")->setActivated(); + } } // init // ----------------------------------------------------------------------------- -irr::core::stringw OptionsScreenInput2::makeLabel( +void OptionsScreenInput2::addListItemSubheader(GUIEngine::ListWidget* actions, + const char* id, + const core::stringw& text) +{ + std::vector row; + row.push_back(GUIEngine::ListWidget::ListCell(text, -1, 1, false)); + row.push_back(GUIEngine::ListWidget::ListCell(L"", -1, 1, false)); + actions->addItem(id, row); +} + +// ----------------------------------------------------------------------------- + +void OptionsScreenInput2::addListItem(GUIEngine::ListWidget* actions, PlayerAction pa) +{ + std::vector row; + row.push_back(GUIEngine::ListWidget::ListCell(core::stringw(KartActionStrings[pa].c_str()), -1, 1, false)); + row.push_back(GUIEngine::ListWidget::ListCell(L"", -1, 1, false)); + actions->addItem(KartActionStrings[pa], row); +} + +// ----------------------------------------------------------------------------- + +void OptionsScreenInput2::renameRow(GUIEngine::ListWidget* actions, + int idRow, const irr::core::stringw &translatedName, PlayerAction action) const { - //hack: one tab character is supported by out font object, it moves the - // cursor to the middle of the area - core::stringw out = irr::core::stringw(" ") + translatedName + L"\t"; + actions->renameCell(idRow, 0, core::stringw(" ") + translatedName); + actions->renameCell(idRow, 1, m_config->getBindingAsString(action)); - out += m_config->getBindingAsString(action); - return out; } // makeLabel // ----------------------------------------------------------------------------- @@ -182,54 +224,54 @@ void OptionsScreenInput2::updateInputButtons() i++; // section header //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Steer Left"), PA_STEER_LEFT) ); + renameRow(actions, i++, _("Steer Left"), PA_STEER_LEFT); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Steer Right"), PA_STEER_RIGHT) ); + renameRow(actions, i++, _("Steer Right"), PA_STEER_RIGHT); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Accelerate"), PA_ACCEL) ); + renameRow(actions, i++, _("Accelerate"), PA_ACCEL); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Brake"), PA_BRAKE) ); + renameRow(actions, i++, _("Brake"), PA_BRAKE); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Fire"), PA_FIRE) ); + renameRow(actions, i++, _("Fire"), PA_FIRE); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Nitro"), PA_NITRO) ); + renameRow(actions, i++, _("Nitro"), PA_NITRO); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Skidding"), PA_DRIFT) ); + renameRow(actions, i++, _("Skidding"), PA_DRIFT); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Look Back"), PA_LOOK_BACK) ); + renameRow(actions, i++, _("Look Back"), PA_LOOK_BACK); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Rescue"), PA_RESCUE) ); + renameRow(actions, i++, _("Rescue"), PA_RESCUE); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Pause Game"), PA_PAUSE_RACE) ); + renameRow(actions, i++, _("Pause Game"), PA_PAUSE_RACE); i++; // section header //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Up"), PA_MENU_UP) ); + renameRow(actions, i++, _("Up"), PA_MENU_UP); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Down"), PA_MENU_DOWN) ); + renameRow(actions, i++, _("Down"), PA_MENU_DOWN); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Left"), PA_MENU_LEFT) ); + renameRow(actions, i++, _("Left"), PA_MENU_LEFT); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Right"), PA_MENU_RIGHT) ); + renameRow(actions, i++, _("Right"), PA_MENU_RIGHT); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Select"), PA_MENU_SELECT) ); + renameRow(actions, i++, _("Select"), PA_MENU_SELECT); //I18N: Key binding name - actions->renameItem(i++, makeLabel( _("Cancel/Back"), PA_MENU_CANCEL) ); + renameRow(actions, i++, _("Cancel/Back"), PA_MENU_CANCEL); @@ -443,18 +485,21 @@ void OptionsScreenInput2::eventCallback(Widget* widget, StateManager *sm = StateManager::get(); if (name == "options_choice") { - const std::string &selection = - ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - if (selection == "tab_audio") - sm->replaceTopMostScreen(OptionsScreenAudio::getInstance()); - else if (selection == "tab_video") - sm->replaceTopMostScreen(OptionsScreenVideo::getInstance()); + Screen *screen = NULL; + if (selection == "tab_audio") + screen = OptionsScreenAudio::getInstance(); + //else if (selection == "tab_video") + // screen = OptionsScreenVideo::getInstance(); else if (selection == "tab_players") - sm->replaceTopMostScreen(TabbedUserScreen::getInstance()); + screen = TabbedUserScreen::getInstance(); + //else if (selection == "tab_controls") + // screen = OptionsScreenInput::getInstance(); else if (selection == "tab_ui") - sm->replaceTopMostScreen(OptionsScreenUI::getInstance()); - else if (selection == "tab_controls") {} + screen = OptionsScreenUI::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if (name == "back_to_device_list") { @@ -555,7 +600,8 @@ void OptionsScreenInput2::onConfirm() const bool success = input_manager->getDeviceList()->deleteConfig(m_config); assert(success); - if (!success) fprintf(stderr, "Failed to delete config!\n"); + if (!success) + Log::error("OptionsScreenInput2", "Failed to delete config!"); m_config = NULL; input_manager->getDeviceList()->serialize(); diff --git a/src/states_screens/options_screen_input2.hpp b/src/states_screens/options_screen_input2.hpp index 5bf3aeab1..1c273769f 100644 --- a/src/states_screens/options_screen_input2.hpp +++ b/src/states_screens/options_screen_input2.hpp @@ -25,7 +25,7 @@ #include "guiengine/screen.hpp" #include "states_screens/dialogs/message_dialog.hpp" -namespace GUIEngine { class Widget; } +namespace GUIEngine { class Widget; class ListWidget; } class DeviceConfig; namespace irr { namespace gui { class STKModifiedSpriteBank; } } @@ -50,8 +50,15 @@ class OptionsScreenInput2 : public GUIEngine::Screen, DeviceConfig* m_config; - irr::core::stringw makeLabel(const irr::core::stringw &translatedName, - PlayerAction action) const; + void renameRow(GUIEngine::ListWidget* actions, + int idRow, + const irr::core::stringw &translatedName, + PlayerAction action) const; + + void addListItem(GUIEngine::ListWidget* actions, PlayerAction pa); + void addListItemSubheader(GUIEngine::ListWidget* actions, + const char* id, + const core::stringw& text); public: friend class GUIEngine::ScreenSingleton; @@ -84,6 +91,8 @@ public: /** \brief Implement IConfirmDialogListener callback */ virtual void onConfirm() OVERRIDE; + + virtual void beforeAddingWidget() OVERRIDE; }; #endif diff --git a/src/states_screens/options_screen_ui.cpp b/src/states_screens/options_screen_ui.cpp index 73ba03208..23d370022 100644 --- a/src/states_screens/options_screen_ui.cpp +++ b/src/states_screens/options_screen_ui.cpp @@ -206,12 +206,21 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con { if (name == "options_choice") { - std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str(); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance()); - else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance()); - else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance()); - else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance()); + Screen *screen = NULL; + if (selection == "tab_audio") + screen = OptionsScreenAudio::getInstance(); + else if (selection == "tab_video") + screen = OptionsScreenVideo::getInstance(); + else if (selection == "tab_players") + screen = TabbedUserScreen::getInstance(); + else if (selection == "tab_controls") + screen = OptionsScreenInput::getInstance(); + //else if (selection == "tab_ui") + // screen = OptionsScreenUI::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else if(name == "back") { diff --git a/src/states_screens/options_screen_video.cpp b/src/states_screens/options_screen_video.cpp index 5c6a16a4c..c433c6a0c 100644 --- a/src/states_screens/options_screen_video.cpp +++ b/src/states_screens/options_screen_video.cpp @@ -167,15 +167,6 @@ void OptionsScreenVideo::init() if (UserConfigParams::m_fullscreen) rememberWinpos->setDeactivated(); else rememberWinpos->setActivated(); - // Enable back widgets if they were visited in-game previously - if (StateManager::get()->getGameState() != GUIEngine::INGAME_MENU) - { - res->setActivated(); - full->setActivated(); - applyBtn->setActivated(); - gfx->setActivated(); - getWidget("custom")->setActivated(); - } // --- get resolution list from irrlicht the first time if (!m_inited) @@ -342,6 +333,15 @@ void OptionsScreenVideo::init() gfx->setDeactivated(); getWidget("custom")->setDeactivated(); } + else + { + // Enable back widgets if they were visited in-game previously + res->setActivated(); + full->setActivated(); + applyBtn->setActivated(); + gfx->setActivated(); + getWidget("custom")->setActivated(); + } } // init // ---------------------------------------------------------------------------- @@ -469,15 +469,13 @@ void OptionsScreenVideo::eventCallback(Widget* widget, const std::string& name, { if (name == "options_choice") { - std::string selection = - ((RibbonWidget*)widget) - ->getSelectionIDString(PLAYER_ID_GAME_MASTER); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); Screen *screen = NULL; if (selection == "tab_audio") screen = OptionsScreenAudio::getInstance(); - else if (selection == "tab_video") - screen = OptionsScreenVideo::getInstance(); + //else if (selection == "tab_video") + // screen = OptionsScreenVideo::getInstance(); else if (selection == "tab_players") screen = TabbedUserScreen::getInstance(); else if (selection == "tab_controls") diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 2b1c492e1..40c4474ee 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -108,7 +108,7 @@ RaceGUI::RaceGUI() int n = race_manager->getNumberOfKarts(); m_animation_states.resize(n); - m_rank_animation_start_times.resize(n); + m_rank_animation_duration.resize(n); m_last_ranks.resize(n); } // RaceGUI @@ -211,7 +211,7 @@ void RaceGUI::renderPlayerView(const Camera *camera, float dt) if(!World::getWorld()->isRacePhase()) return; drawPowerupIcons (kart, viewport, scaling); - drawSpeedEnergyRank(kart, viewport, scaling); + drawSpeedEnergyRank(kart, viewport, scaling, dt); if (!m_is_tutorial) drawLap(kart, viewport, scaling); @@ -601,10 +601,18 @@ void RaceGUI::drawEnergyMeter(int x, int y, const AbstractKart *kart, } // drawEnergyMeter //----------------------------------------------------------------------------- +/** Draws the rank of a player. + * \param kart The kart of the player. + * \param offset Offset of top left corner for this display (for splitscreen). + * \param min_ratio Scaling of the screen (for splitscreen). + * \param meter_width Width of the meter (inside which the rank is shown). + * \param meter_height Height of the meter (inside which the rank is shown). + * \param dt Time step size. + */ void RaceGUI::drawRank(const AbstractKart *kart, const core::vector2df &offset, float min_ratio, int meter_width, - int meter_height) + int meter_height, float dt) { // Draw rank WorldWithRank *world = dynamic_cast(World::getWorld()); @@ -617,10 +625,14 @@ void RaceGUI::drawRank(const AbstractKart *kart, { if (m_last_ranks[id] != kart->getPosition()) { - m_rank_animation_start_times[id] = world->getTime(); + m_rank_animation_duration[id] = 0.0f; m_animation_states[id] = AS_SMALLER; } } + else + { + m_rank_animation_duration[id] += dt; + } float scale = 1.0f; int rank = kart->getPosition(); @@ -628,13 +640,12 @@ void RaceGUI::drawRank(const AbstractKart *kart, const float MIN_SHRINK = 0.3f; if (m_animation_states[id] == AS_SMALLER) { - scale = 1.0f - (world->getTime() - m_rank_animation_start_times[id]) - / DURATION; + scale = 1.0f - m_rank_animation_duration[id]/ DURATION; rank = m_last_ranks[id]; if (scale < MIN_SHRINK) { m_animation_states[id] = AS_BIGGER; - m_rank_animation_start_times[id] = world->getTime(); + m_rank_animation_duration[id] = 0.0f; // Store the new rank m_last_ranks[id] = kart->getPosition(); scale = MIN_SHRINK; @@ -642,8 +653,7 @@ void RaceGUI::drawRank(const AbstractKart *kart, } else if (m_animation_states[id] == AS_BIGGER) { - scale = (world->getTime() - m_rank_animation_start_times[id]) - / DURATION + MIN_SHRINK; + scale = m_rank_animation_duration[id] / DURATION + MIN_SHRINK; rank = m_last_ranks[id]; if (scale > 1.0f) { @@ -680,10 +690,12 @@ void RaceGUI::drawRank(const AbstractKart *kart, * \param kart The kart for which to show the data. * \param viewport The viewport to use. * \param scaling Which scaling to apply to the speedometer. + * \param dt Time step size. */ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart, const core::recti &viewport, - const core::vector2df &scaling) + const core::vector2df &scaling, + float dt) { float min_ratio = std::min(scaling.X, scaling.Y); const int SPEEDWIDTH = 128; @@ -712,7 +724,7 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart, const float speed = kart->getSpeed(); - drawRank(kart, offset, min_ratio, meter_width, meter_height); + drawRank(kart, offset, min_ratio, meter_width, meter_height, dt); if(speed <=0) return; // Nothing to do if speed is negative. diff --git a/src/states_screens/race_gui.hpp b/src/states_screens/race_gui.hpp index dca0b2669..8ae4d626b 100644 --- a/src/states_screens/race_gui.hpp +++ b/src/states_screens/race_gui.hpp @@ -89,8 +89,8 @@ private: enum AnimationState {AS_NONE, AS_SMALLER, AS_BIGGER}; std::vector m_animation_states; - /** When the animation state was changed. */ - std::vector m_rank_animation_start_times; + /** How long the rank animation has been shown. */ + std::vector m_rank_animation_duration; /** Stores the previous rank for each kart. Used for the rank animation. */ std::vector m_last_ranks; @@ -103,14 +103,14 @@ private: const core::vector2df &scaling); void drawSpeedEnergyRank (const AbstractKart* kart, const core::recti &viewport, - const core::vector2df &scaling); + const core::vector2df &scaling, float dt); void drawLap (const AbstractKart* kart, const core::recti &viewport, const core::vector2df &scaling); void drawRank (const AbstractKart *kart, const core::vector2df &offset, float min_ratio, int meter_width, - int meter_height); + int meter_height, float dt); /** Display items that are shown once only (for all karts). */ void drawGlobalMiniMap (); diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index f7cd19e05..cdef71b1e 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -471,8 +471,8 @@ void RaceGUIOverworld::drawGlobalMiniMap() if (challenge == NULL) { - fprintf(stderr, "[RaceGUIOverworld] ERROR: Cannot find challenge <%s>\n", - challenges[n].m_challenge_id.c_str()); + Log::error("RaceGUIOverworld", "Cannot find challenge <%s>.", + challenges[n].m_challenge_id.c_str()); break; } @@ -483,10 +483,10 @@ void RaceGUIOverworld::drawGlobalMiniMap() if (gp == NULL) { - fprintf(stderr, "[RaceGUIOverworld] ERROR: Cannot find GP <%s>, " - "referenced from challenge <%s>\n", - challenge->getGPId().c_str(), - challenges[n].m_challenge_id.c_str()); + Log::error("RaceGUIOverworld", "Cannot find GP <%s>, " + "referenced from challenge <%s>", + challenge->getGPId().c_str(), + challenges[n].m_challenge_id.c_str()); break; } @@ -508,10 +508,10 @@ void RaceGUIOverworld::drawGlobalMiniMap() Track* track = track_manager->getTrack(challenge->getTrackId()); if (track == NULL) { - fprintf(stderr, "[RaceGUIOverworld] ERROR: Cannot find track <%s>, " - "referenced from challenge <%s>\n", - challenge->getTrackId().c_str(), - challenges[n].m_challenge_id.c_str()); + Log::error("RaceGUIOverworld", "Cannot find track <%s>, " + "referenced from challenge <%s>", + challenge->getTrackId().c_str(), + challenges[n].m_challenge_id.c_str()); break; } diff --git a/src/states_screens/race_result_gui.cpp b/src/states_screens/race_result_gui.cpp index 9b5803421..73c7b3577 100644 --- a/src/states_screens/race_result_gui.cpp +++ b/src/states_screens/race_result_gui.cpp @@ -297,9 +297,8 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, } return; } - fprintf(stderr, "Incorrect event '%s' when things are unlocked.\n", - name.c_str()); - assert(false); + Log::fatal("RaceResultGUI", "Incorrect event '%s' when things are unlocked.", + name.c_str()); } // If we're playing online : @@ -342,11 +341,8 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, MessageDialog::MESSAGE_DIALOG_CONFIRM, this, false); } else if (!getWidget(name.c_str())->isVisible()) - { - fprintf(stderr, "Incorrect event '%s' when things are unlocked.\n", - name.c_str()); - assert(false); - } + Log::fatal("RaceResultGUI", "Incorrect event '%s' when things are unlocked.", + name.c_str()); return; } @@ -387,10 +383,8 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget, } } else - { - fprintf(stderr, "Incorrect event '%s' for normal race.\n", - name.c_str()); - } + Log::fatal("RaceResultGUI", "Incorrect event '%s' for normal race.", + name.c_str()); return; } // eventCallback @@ -615,8 +609,8 @@ void RaceResultGUI::onUpdate(float dt) } catch (std::exception& e) { - fprintf(stderr, "[RaceResultGUI] WARNING: exception caught when " - "trying to load music: %s\n", e.what()); + Log::error("RaceResultGUI", "Exception caught when " + "trying to load music: %s", e.what()); } } } // onUpdate diff --git a/src/states_screens/user_screen.cpp b/src/states_screens/user_screen.cpp index de5b1fa72..64b93630c 100644 --- a/src/states_screens/user_screen.cpp +++ b/src/states_screens/user_screen.cpp @@ -108,6 +108,21 @@ void BaseUserScreen::init() else if (PlayerManager::get()->getNumPlayers() > 0) selectUser(0); + // Disable changing the user while in game + if (StateManager::get()->getGameState() == GUIEngine::INGAME_MENU) + { + getWidget("ok")->setDeactivated(); + getWidget("new_user")->setDeactivated(); + getWidget("rename")->setDeactivated(); + getWidget("delete")->setDeactivated(); + } + else + { + getWidget("ok")->setActivated(); + getWidget("new_user")->setActivated(); + getWidget("rename")->setActivated(); + getWidget("delete")->setActivated(); + } } // init // ---------------------------------------------------------------------------- @@ -572,16 +587,21 @@ void TabbedUserScreen::eventCallback(GUIEngine::Widget* widget, { if (name == "options_choice") { - const std::string &selection = - ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); - Screen *s; - if (selection=="tab_audio" ) s = OptionsScreenAudio::getInstance(); - else if (selection=="tab_video" ) s = OptionsScreenVideo::getInstance(); - else if (selection=="tab_players" ) s = TabbedUserScreen::getInstance(); - else if (selection=="tab_controls") s = OptionsScreenInput::getInstance(); - else if (selection=="tab_ui" ) s = OptionsScreenUI::getInstance(); - assert(s); - StateManager::get()->replaceTopMostScreen(s); + std::string selection = ((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER); + + Screen *screen = NULL; + if (selection == "tab_audio") + screen = OptionsScreenAudio::getInstance(); + else if (selection == "tab_video") + screen = OptionsScreenVideo::getInstance(); + //else if (selection == "tab_players") + // screen = TabbedUserScreen::getInstance(); + else if (selection == "tab_controls") + screen = OptionsScreenInput::getInstance(); + else if (selection == "tab_ui") + screen = OptionsScreenUI::getInstance(); + if(screen) + StateManager::get()->replaceTopMostScreen(screen); } else BaseUserScreen::eventCallback(widget, name, player_id); diff --git a/src/tracks/check_cannon.cpp b/src/tracks/check_cannon.cpp index 4b0120e6b..7effbe71b 100644 --- a/src/tracks/check_cannon.cpp +++ b/src/tracks/check_cannon.cpp @@ -36,12 +36,8 @@ CheckCannon::CheckCannon(const XMLNode &node, unsigned int index) : CheckLine(node, index) { core::vector3df p1, p2; - if(!node.get("target-p1", &p1) || - !node.get("target-p2", &p2) ) - { - printf("CheckCannon has no target line specified.\n"); - exit(-1); - } + if(!node.get("target-p1", &p1) || !node.get("target-p2", &p2)) + Log::fatal("CheckCannon", "No target line specified."); m_target.setLine(p1, p2); m_curve = new Ipo(*(node.getNode("curve")), /*fps*/25, diff --git a/src/tracks/check_goal.cpp b/src/tracks/check_goal.cpp index 736859cbf..f582f182f 100644 --- a/src/tracks/check_goal.cpp +++ b/src/tracks/check_goal.cpp @@ -72,8 +72,8 @@ void CheckGoal::update(float dt) if(isTriggered(m_previous_position[ball_index], xyz, ball_index)) { if(UserConfigParams::m_check_debug) - printf("CHECK: Goal check structure %d triggered for object %s.\n", - m_index, obj->getPresentation()->getNode()->getDebugName()); + Log::info("CheckGoal", "Goal check structure %d triggered for object %s.", + m_index, obj->getPresentation()->getNode()->getDebugName()); trigger(ball_index); } m_previous_position[ball_index] = xyz; diff --git a/src/tracks/check_lap.cpp b/src/tracks/check_lap.cpp index 71f6591af..bf92b9b10 100644 --- a/src/tracks/check_lap.cpp +++ b/src/tracks/check_lap.cpp @@ -71,11 +71,10 @@ bool CheckLap::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, bool result =(m_previous_distance[indx]>0.95f*track_length && current_distance<7.0f); if(UserConfigParams::m_check_debug && result) - { - printf("CHECK: Kart %s crossed start line from %f to %f.\n", - World::getWorld()->getKart(indx)->getIdent().c_str(), - m_previous_distance[indx], current_distance); - } + Log::info("CheckLap", "Kart %s crossed start line from %f to %f.", + World::getWorld()->getKart(indx)->getIdent().c_str(), + m_previous_distance[indx], current_distance); + m_previous_distance[indx] = current_distance; return result; diff --git a/src/tracks/check_line.cpp b/src/tracks/check_line.cpp index 36015b334..f67c76b29 100644 --- a/src/tracks/check_line.cpp +++ b/src/tracks/check_line.cpp @@ -173,14 +173,14 @@ bool CheckLine::isTriggered(const Vec3 &old_pos, const Vec3 &new_pos, if(UserConfigParams::m_check_debug && !result) { if(World::getWorld()->getNumKarts()>0) - printf("CHECK: Kart %s crosses line, but wrong height " - "(%f vs %f).\n", - World::getWorld()->getKart(indx)->getIdent().c_str(), - new_pos.getY(), m_min_height); + Log::info("CheckLine", "Kart %s crosses line, but wrong height " + "(%f vs %f).", + World::getWorld()->getKart(indx)->getIdent().c_str(), + new_pos.getY(), m_min_height); else - printf("CHECK: Kart %d crosses line, but wrong height " - "(%f vs %f).\n", - indx, new_pos.getY(), m_min_height); + Log::info("CheckLine", "Kart %d crosses line, but wrong height " + "(%f vs %f).", + indx, new_pos.getY(), m_min_height); } } diff --git a/src/tracks/check_manager.cpp b/src/tracks/check_manager.cpp index f80b6be39..7ece0621e 100644 --- a/src/tracks/check_manager.cpp +++ b/src/tracks/check_manager.cpp @@ -64,7 +64,7 @@ void CheckManager::load(const XMLNode &node) m_all_checks.push_back(cs); } // checksphere else - printf("Unknown check structure '%s' - ignored.\n", type.c_str()); + Log::warn("CheckManager", "Unknown check structure '%s' - ignored.", type.c_str()); } // for i(c) != NULL) return i; } - fprintf(stderr, - "No check-lap structure found! This can cause incorrect kart\n"); - fprintf(stderr, - "ranking when crossing the line, but can otherwise be ignored.\n"); + Log::warn("CheckManager", "No check-lap structure found! This can cause incorrect kart"); + Log::warn("CheckManager", "ranking when crossing the line, but can otherwise be ignored."); for (unsigned int i=0; igetType()==CheckStructure::CT_NEW_LAP) return i; } - fprintf(stderr, "Error, no kind of lap line for track found, aborting.\n"); - exit(-1); + Log::fatal("CheckManager", "Error, no kind of lap line for track found, aborting."); } // getLapLineIndex // ---------------------------------------------------------------------------- diff --git a/src/tracks/check_structure.cpp b/src/tracks/check_structure.cpp index 5a3f8b05e..a99b19ca9 100644 --- a/src/tracks/check_structure.cpp +++ b/src/tracks/check_structure.cpp @@ -54,9 +54,7 @@ CheckStructure::CheckStructure(const XMLNode &node, unsigned int index) else if(node.getName()=="cannon") m_check_type = CT_CANNON; else - { - printf("Unknown check structure '%s' - ignored.\n", kind.c_str()); - } + Log::warn("CheckStructure", "Unknown check structure '%s' - ignored.", kind.c_str()); node.get("same-group", &m_same_group); // Make sure that the index of this check structure is included in @@ -108,8 +106,8 @@ void CheckStructure::update(float dt) if(m_is_active[i] && isTriggered(m_previous_position[i], xyz, i)) { if(UserConfigParams::m_check_debug) - printf("CHECK: Check structure %d triggered for kart %s.\n", - m_index, world->getKart(i)->getIdent().c_str()); + Log::info("CheckStructure", "Check structure %d triggered for kart %s.", + m_index, world->getKart(i)->getIdent().c_str()); trigger(i); } m_previous_position[i] = xyz; @@ -144,18 +142,18 @@ void CheckStructure::changeStatus(const std::vector indices, cs->m_is_active[kart_index] = false; if(UserConfigParams::m_check_debug) { - printf("CHECK: Deactivating %d for %s.\n", - indices[i], - World::getWorld()->getKart(kart_index)->getIdent().c_str()); + Log::info("CheckStructure", "Deactivating %d for %s.", + indices[i], + World::getWorld()->getKart(kart_index)->getIdent().c_str()); } break; case CS_ACTIVATE: cs->m_is_active[kart_index] = true; if(UserConfigParams::m_check_debug) { - printf("CHECK: Activating %d for %s.\n", - indices[i], - World::getWorld()->getKart(kart_index)->getIdent().c_str()); + Log::info("CheckStructure", "Activating %d for %s.", + indices[i], + World::getWorld()->getKart(kart_index)->getIdent().c_str()); } break; case CS_TOGGLE: @@ -166,10 +164,10 @@ void CheckStructure::changeStatus(const std::vector indices, // non-POD type 'struct std::_Bit_reference' through '...'; // call will abort at runtime"). So we use this somewhat // unusual but portable construct. - printf("CHECK: Toggling %d for %s from %d.\n", - indices[i], - World::getWorld()->getKart(kart_index)->getIdent().c_str(), - cs->m_is_active[kart_index]==true); + Log::info("CheckStructure", "Toggling %d for %s from %d.", + indices[i], + World::getWorld()->getKart(kart_index)->getIdent().c_str(), + cs->m_is_active[kart_index]==true); } cs->m_is_active[kart_index] = !cs->m_is_active[kart_index]; } // switch @@ -213,9 +211,9 @@ void CheckStructure::trigger(unsigned int kart_index) World::getWorld()->newLap(kart_index); if(UserConfigParams::m_check_debug) { - printf("CHECK: %s new lap %d triggered\n", - World::getWorld()->getKart(kart_index)->getIdent().c_str(), - m_index); + Log::info("CheckStructure", "%s new lap %d triggered", + World::getWorld()->getKart(kart_index)->getIdent().c_str(), + m_index); } changeStatus(m_check_structures_to_change_state, kart_index, CS_ACTIVATE); diff --git a/src/tracks/graph_node.cpp b/src/tracks/graph_node.cpp index e43eeb988..ac5967de5 100644 --- a/src/tracks/graph_node.cpp +++ b/src/tracks/graph_node.cpp @@ -30,10 +30,8 @@ GraphNode::GraphNode(unsigned int quad_index, unsigned int node_index) { if (quad_index >= QuadSet::get()->getNumberOfQuads()) - { - fprintf(stderr, "[GraphNode] ERROR: No driveline found, or empty driveline"); - abort(); - } + Log::fatal("GraphNode", "No driveline found, or empty driveline."); + m_quad_index = quad_index; m_node_index = node_index; m_distance_from_start = -1.0f; @@ -130,10 +128,10 @@ void GraphNode::setupPathsToNode() gn.markAllSuccessorsToUse(i, &m_path_to_node); } #ifdef DEBUG - for(unsigned int i=0; i #include @@ -31,10 +32,10 @@ Quad::Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, if(p1.sideOfLine2D(p0, p2)>0 || p3.sideOfLine2D(p0, p2)<0) { - printf("Warning: quad has wrong orientation: p0=%f %f %f p1=%f %f %f\n", - p0.getX(), p0.getY(), p0.getZ(),p1.getX(), p1.getY(), p1.getZ()); - printf("The quad will be swapped, nevertheless test for correctness -\n"); - printf("quads must be counter-clockwise oriented.\n"); + Log::warn("Quad", "Quad has wrong orientation: p0=%f %f %f p1=%f %f %f", + p0.getX(), p0.getY(), p0.getZ(),p1.getX(), p1.getY(), p1.getZ()); + Log::warn("Quad", "The quad will be swapped, nevertheless test for correctness -"); + Log::warn("Quad", "quads must be counter-clockwise oriented."); m_p[0]=p1; m_p[1]=p0; m_p[2]=p3; m_p[3]=p2; } else diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 1d7073569..6b715dac9 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -498,10 +498,7 @@ public: btTransform getStartTransform (unsigned int index) const { if (index >= m_start_transforms.size()) - { - fprintf(stderr, "No start position for kart %i\n", index); - abort(); - } + Log::fatal("Tracj", "No start position for kart %i.", index); return m_start_transforms[index]; } // ------------------------------------------------------------------------ diff --git a/src/tracks/track_manager.cpp b/src/tracks/track_manager.cpp index c987ec522..b2092b13e 100644 --- a/src/tracks/track_manager.cpp +++ b/src/tracks/track_manager.cpp @@ -98,9 +98,8 @@ void TrackManager::setUnavailableTracks(const std::vector &tracks) if (std::find(tracks.begin(), tracks.end(), id)==tracks.end()) { m_track_avail[i-m_tracks.begin()] = false; - fprintf(stderr, - "Track '%s' not available on all clients, disabled.\n", - id.c_str()); + Log::warn("TrackManager", "Track '%s' not available on all clients, disabled.", + id.c_str()); } // if id not in tracks } // for all available tracks in track manager @@ -174,7 +173,7 @@ bool TrackManager::loadTrack(const std::string& dirname) } catch (std::exception& e) { - fprintf(stderr, "[TrackManager] ERROR: Cannot load track <%s> : %s\n", + Log::error("TrackManager", "Cannot load track <%s> : %s\n", dirname.c_str(), e.what()); return false; } @@ -182,12 +181,12 @@ bool TrackManager::loadTrack(const std::string& dirname) if (track->getVersion()m_min_track_version || track->getVersion()>stk_config->m_max_track_version) { - fprintf(stderr, "[TrackManager] Warning: track '%s' is not supported " + Log::warn("TrackManager", "Track '%s' is not supported " "by this binary, ignored. (Track is version %i, this " - "executable supports from %i to %i)\n", - track->getIdent().c_str(), track->getVersion(), - stk_config->m_min_track_version, - stk_config->m_max_track_version); + "executable supports from %i to %i).", + track->getIdent().c_str(), track->getVersion(), + stk_config->m_min_track_version, + stk_config->m_max_track_version); delete track; return false; } @@ -206,22 +205,15 @@ void TrackManager::removeTrack(const std::string &ident) { Track *track = getTrack(ident); if (track == NULL) - { - fprintf(stderr, "[TrackManager] ERROR: There is no track named '%s'!!\n", ident.c_str()); - assert(false); - return; - } + Log::fatal("TrackManager", "There is no track named '%s'!!", ident.c_str()); if (track->isInternal()) return; std::vector::iterator it = std::find(m_tracks.begin(), m_tracks.end(), track); if (it == m_tracks.end()) - { - fprintf(stderr, "[TrackManager] INTERNAL ERROR: Cannot find track '%s' in map!!\n", ident.c_str()); - assert(false); - return; - } + Log::fatal("TrackManager", "Cannot find track '%s' in map!!", ident.c_str()); + int index = it - m_tracks.begin(); // Remove the track from all groups it belongs to diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index b62663cec..6aef4dcc7 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -387,7 +387,7 @@ void TrackObjectPresentationMesh::init(const XMLNode* xml_node, scene::ISceneNod m_frame_start = 0; m_frame_end = 0; - if (World::getWorld() != NULL && World::getWorld()->getTrack() != NULL) + if (World::getWorld() != NULL && World::getWorld()->getTrack() != NULL && xml_node != NULL) World::getWorld()->getTrack()->handleAnimatedTextures(m_node, *xml_node); } //#ifdef DEBUG @@ -496,10 +496,7 @@ TrackObjectPresentationSound::TrackObjectPresentationSound(const XMLNode& xml_no } } else - { - fprintf(stderr, - "[TrackObject] Sound emitter object could not be created\n"); - } + Log::error("TrackObject", "Sound emitter object could not be created."); if (trigger_when_near) { @@ -753,9 +750,7 @@ TrackObjectPresentationActionTrigger::TrackObjectPresentationActionTrigger(const m_action_active = true; if (m_action.size() == 0) - { - fprintf(stderr, "[TrackObject] WARNING: action-trigger has no action defined\n"); - } + Log::warn("TrackObject", "Action-trigger has no action defined."); ItemManager::get()->newItem(m_init_xyz, trigger_distance, this); } @@ -891,10 +886,7 @@ void TrackObjectPresentationActionTrigger::onTriggerItemApproached(Item* who) return; } else - { - fprintf(stderr, "[TrackObject] WARNING: unknown action <%s>\n", - m_action.c_str()); - } + Log::warn("TrackObject", "Unknown action '%s'", m_action.c_str()); } diff --git a/src/utils/singleton.hpp b/src/utils/singleton.hpp index fa48ca6bd..96ac90023 100644 --- a/src/utils/singleton.hpp +++ b/src/utils/singleton.hpp @@ -31,13 +31,13 @@ * classes. */ template -class Singleton +class AbstractSingleton { protected: /*! \brief Constructor */ - Singleton () { m_singleton = NULL; } + AbstractSingleton() { m_singleton = NULL; } /*! \brief Destructor */ - virtual ~Singleton () + virtual ~AbstractSingleton() { Log::info("Singleton", "Destroyed singleton."); } @@ -80,6 +80,44 @@ class Singleton static T *m_singleton; }; +template T *AbstractSingleton::m_singleton = NULL; + +template +class Singleton +{ +protected: + /*! \brief Constructor */ + Singleton() { m_singleton = NULL; } + /*! \brief Destructor */ + virtual ~Singleton() + { + Log::info("Singleton", "Destroyed singleton."); + } + +public: + /*! \brief Used to get the instance. */ + static T *getInstance() + { + if (m_singleton == NULL) + m_singleton = new T; + return m_singleton; + } + + /*! \brief Used to kill the singleton, if needed. */ + static void kill() + { + if (m_singleton) + { + delete m_singleton; + m_singleton = NULL; + } + } + +private: + static T *m_singleton; +}; + template T *Singleton::m_singleton = NULL; + #endif // SINGLETON_HPP diff --git a/src/utils/string_utils.cpp b/src/utils/string_utils.cpp index a096f88c5..091440a0c 100644 --- a/src/utils/string_utils.cpp +++ b/src/utils/string_utils.cpp @@ -520,7 +520,7 @@ namespace StringUtils // which admittedly only works for min < 100000 - which is about 68 // days - good enough. char s[12]; - sprintf ( s, "%02d:%02d:%02d", min, sec, hundredths) ; + sprintf(s, "%02d:%02d:%02d", min, sec, hundredths); return std::string(s); } // timeToString @@ -738,8 +738,8 @@ namespace StringUtils + 10*very_minor + release_candidate; - if(version<=0) - printf("Invalid version string '%s'.\n", s.c_str()); + if(version <= 0) + Log::error("StringUtils", "Invalid version string '%s'.", s.c_str()); return version; } // versionToInt